Fixed bug for duplicated request to subscribe and invalid storage logic.
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerDiscovery.c
1 //******************************************************************
2 //
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "NSConsumerDiscovery.h"
22
23 #include <string.h>
24 #include "NSCommon.h"
25 #include "NSConsumerCommon.h"
26 #include "NSConstants.h"
27 #include "ocpayload.h"
28 #include "oic_malloc.h"
29 #include "oic_string.h"
30
31 #define NS_DISCOVER_QUERY "/oic/res?rt=oic.r.notification"
32 #define NS_PRESENCE_SUBSCRIBE_QUERY "coap://224.0.1.187:5683/oic/ad?rt=oic.r.notification"
33 #define NS_PRESENCE_SUBSCRIBE_QUERY_TCP "/oic/ad?rt=oic.r.notification"
34 #define NS_GET_INFORMATION_QUERY "/notification?if=oic.if.notification"
35
36 NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse);
37
38 OCDevAddr * NSChangeAddress(const char * address);
39
40 OCStackApplicationResult NSConsumerPresenceListener(
41         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
42 {
43     (void) ctx;
44     (void) handle;
45
46     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
47     NS_VERIFY_STACK_SUCCESS(
48             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
49
50     NS_LOG_V(DEBUG, "Presence income : %s:%d",
51             clientResponse->devAddr.addr, clientResponse->devAddr.port);
52     NS_LOG_V(DEBUG, "Presence result : %d",
53             clientResponse->result);
54     NS_LOG_V(DEBUG, "Presence sequenceNum : %d",
55             clientResponse->sequenceNumber);
56     NS_LOG_V(DEBUG, "Presence Transport Type : %d",
57                 clientResponse->devAddr.adapter);
58
59     if (!NSIsStartedConsumer())
60     {
61         return OC_STACK_DELETE_TRANSACTION;
62     }
63
64     OCPresencePayload * payload = (OCPresencePayload *)clientResponse->payload;
65     if (payload->trigger == OC_PRESENCE_TRIGGER_DELETE ||
66             clientResponse->result == OC_STACK_PRESENCE_STOPPED)
67     {
68         // TODO find request and cancel
69         NS_LOG(DEBUG, "stopped presence or resource is deleted.");
70         //OCCancel(handle, NS_QOS, NULL, 0);
71     }
72
73     else if (payload->trigger == OC_PRESENCE_TRIGGER_CREATE)
74     {
75         NS_LOG(DEBUG, "started presence or resource is created.");
76         NSInvokeRequest(NULL, OC_REST_DISCOVER, clientResponse->addr,
77             NS_DISCOVER_QUERY, NULL, NSProviderDiscoverListener, NULL,
78             clientResponse->addr->adapter);
79     }
80
81     return OC_STACK_KEEP_TRANSACTION;
82 }
83
84 OCStackApplicationResult NSProviderDiscoverListener(
85         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
86 {
87     (void) handle;
88
89     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
90     NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);
91     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
92
93     NS_LOG_V(DEBUG, "Discover income : %s:%d",
94             clientResponse->devAddr.addr, clientResponse->devAddr.port);
95     NS_LOG_V(DEBUG, "Discover result : %d",
96             clientResponse->result);
97     NS_LOG_V(DEBUG, "Discover sequenceNum : %d",
98             clientResponse->sequenceNumber);
99     NS_LOG_V(DEBUG, "Discover Transport Type : %d",
100                     clientResponse->devAddr.adapter);
101
102     if (!NSIsStartedConsumer())
103     {
104         return OC_STACK_DELETE_TRANSACTION;
105     }
106
107     OCResourcePayload * resource = ((OCDiscoveryPayload *)clientResponse->payload)->resources;
108     while (resource)
109     {
110         if (strstr(resource->uri, NS_RESOURCE_URI))
111         {
112             OCConnectivityType type = CT_DEFAULT;
113             if (clientResponse->addr->adapter == OC_ADAPTER_TCP)
114             {
115                 type = CT_ADAPTER_TCP;
116             }
117
118             NSInvokeRequest(NULL, OC_REST_GET, clientResponse->addr,
119                     resource->uri, NULL, NSIntrospectProvider, ctx,
120                     type);
121         }
122         resource = resource->next;
123     }
124
125     return OC_STACK_KEEP_TRANSACTION;
126 }
127
128 void NSRemoveProviderObj(NSProvider_internal * provider)
129 {
130     NSOICFree(provider->messageUri);
131     NSOICFree(provider->syncUri);
132
133     NSRemoveConnections(provider->connection);
134     NSOICFree(provider);
135 }
136
137 OCStackApplicationResult NSIntrospectProvider(
138         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
139 {
140     (void) handle;
141
142     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
143     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
144
145     NS_LOG_V(DEBUG, "GET response income : %s:%d",
146             clientResponse->devAddr.addr, clientResponse->devAddr.port);
147     NS_LOG_V(DEBUG, "GET response result : %d",
148             clientResponse->result);
149     NS_LOG_V(DEBUG, "GET response sequenceNum : %d",
150             clientResponse->sequenceNumber);
151     NS_LOG_V(DEBUG, "GET response resource uri : %s",
152             clientResponse->resourceUri);
153     NS_LOG_V(DEBUG, "GET response Transport Type : %d",
154                     clientResponse->devAddr.adapter);
155
156     if (!NSIsStartedConsumer())
157     {
158         return OC_STACK_DELETE_TRANSACTION;
159     }
160
161     NSProvider_internal * newProvider = NSGetProvider(clientResponse);
162     NS_VERIFY_NOT_NULL(newProvider, OC_STACK_KEEP_TRANSACTION);
163     if (ctx && *((NSConsumerDiscoverType *)ctx) == NS_DISCOVER_CLOUD )
164     {
165         newProvider->connection->isCloudConnection = true;
166         NSOICFree(ctx);
167     }
168
169     NS_LOG(DEBUG, "build NSTask");
170     NSTask * task = NSMakeTask(TASK_CONSUMER_PROVIDER_DISCOVERED, (void *) newProvider);
171     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveProviderObj(newProvider));
172
173     NSConsumerPushEvent(task);
174
175     return OC_STACK_KEEP_TRANSACTION;
176 }
177
178 void NSGetProviderPostClean(
179         char * pId, char * mUri, char * sUri, NSProviderConnectionInfo * connection)
180 {
181     NSOICFree(pId);
182     NSOICFree(mUri);
183     NSOICFree(sUri);
184     NSRemoveConnections(connection);
185 }
186
187 NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse)
188 {
189     NS_LOG(DEBUG, "create NSProvider");
190     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
191
192     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
193     while (payload)
194     {
195         NS_LOG_V(DEBUG, "Payload Key : %s", payload->values->name);
196         payload = payload->next;
197     }
198
199     payload = (OCRepPayload *)clientResponse->payload;
200
201     char * providerId = NULL;
202     char * messageUri = NULL;
203     char * syncUri = NULL;
204     int64_t accepter = 0;
205     NSProviderConnectionInfo * connection = NULL;
206
207     NS_LOG(DEBUG, "get information of accepter");
208     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_POLICY, & accepter);
209     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
210
211     NS_LOG(DEBUG, "get provider ID");
212     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, & providerId);
213     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
214
215     NS_LOG(DEBUG, "get message URI");
216     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_MESSAGE, & messageUri);
217     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
218             NSGetProviderPostClean(providerId, messageUri, syncUri, connection));
219
220     NS_LOG(DEBUG, "get sync URI");
221     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SYNC, & syncUri);
222     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
223             NSGetProviderPostClean(providerId, messageUri, syncUri, connection));
224
225     NS_LOG(DEBUG, "get provider connection information");
226     NS_VERIFY_NOT_NULL(clientResponse->addr, NULL);
227     connection = NSCreateProviderConnections(clientResponse->addr);
228     NS_VERIFY_NOT_NULL(connection, NULL);
229
230     NSProvider_internal * newProvider
231         = (NSProvider_internal *)OICMalloc(sizeof(NSProvider_internal));
232     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProvider, NULL,
233           NSGetProviderPostClean(providerId, messageUri, syncUri, connection));
234
235     OICStrcpy(newProvider->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
236     NSOICFree(providerId);
237     newProvider->messageUri = messageUri;
238     newProvider->syncUri = syncUri;
239     newProvider->accessPolicy = (NSAccessPolicy)accepter;
240     newProvider->connection = connection;
241
242     return newProvider;
243 }
244
245 OCDevAddr * NSChangeAddress(const char * address)
246 {
247     NS_VERIFY_NOT_NULL(address, NULL);
248     OCDevAddr * retAddr = NULL;
249
250     int index = 0;
251     while(address[index] != '\0')
252     {
253         if (address[index] == ':')
254         {
255             break;
256         }
257         index++;
258     }
259
260     if (address[index] == '\0')
261     {
262         return NULL;
263     }
264
265     int tmp = index + 1;
266     uint16_t port = address[tmp++];
267
268     while(address[tmp] != '\0')
269     {
270         port *= 10;
271         port += address[tmp++] - '0';
272     }
273
274     retAddr = (OCDevAddr *) OICMalloc(sizeof(OCDevAddr));
275     NS_VERIFY_NOT_NULL(retAddr, NULL);
276
277     retAddr->adapter = OC_ADAPTER_TCP;
278     OICStrcpy(retAddr->addr, index - 1, address);
279     retAddr->addr[index] = '\0';
280     retAddr->port = port;
281
282     return retAddr;
283 }
284
285 void NSConsumerHandleRequestDiscover(OCDevAddr * address, NSConsumerDiscoverType rType)
286 {
287     OCConnectivityType type = CT_DEFAULT;
288     NSConsumerDiscoverType * callbackData = NULL;
289
290     if (address)
291     {
292         if (address->adapter == OC_ADAPTER_IP)
293         {
294             type = CT_ADAPTER_IP;
295             NS_LOG(DEBUG, "Request discover [UDP]");
296         }
297         else if (address->adapter == OC_ADAPTER_TCP)
298         {
299             type = CT_ADAPTER_TCP;
300             NS_LOG(DEBUG, "Request discover and subscribe presence [TCP]");
301             NS_LOG(DEBUG, "Subscribe presence [TCP]");
302             NSInvokeRequest(NULL, OC_REST_PRESENCE, address, NS_PRESENCE_SUBSCRIBE_QUERY_TCP,
303                     NULL, NSConsumerPresenceListener, NULL, type);
304
305             if (rType == NS_DISCOVER_CLOUD)
306             {
307                 callbackData = (NSConsumerDiscoverType *)OICMalloc(sizeof(NSConsumerDiscoverType));
308                 *callbackData = NS_DISCOVER_CLOUD;
309             }
310         }
311         else
312         {
313             NS_LOG_V(DEBUG, "Request discover But Adapter is not IP : %d", address->adapter);
314         }
315     }
316     else
317     {
318         NS_LOG(DEBUG, "Request Multicast discover [UDP]");
319     }
320
321     NSInvokeRequest(NULL, OC_REST_DISCOVER, address, NS_DISCOVER_QUERY,
322             NULL, NSProviderDiscoverListener, (void *)callbackData, type);
323 }
324
325 void NSConsumerDiscoveryTaskProcessing(NSTask * task)
326 {
327     NS_VERIFY_NOT_NULL_V(task);
328
329     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
330     if (task->taskType == TASK_CONSUMER_REQ_DISCOVER)
331     {
332         char * address = (char *) task->taskData;
333         NSConsumerDiscoverType dType = NS_DISCOVER_DEFAULT;
334
335         OCDevAddr * addr = NULL;
336         if (address)
337         {
338             addr = NSChangeAddress(address);
339             dType = NS_DISCOVER_CLOUD;
340         }
341
342         NSConsumerHandleRequestDiscover(addr, dType);
343         NSOICFree(task->taskData);
344         NSOICFree(addr);
345     }
346     else if (task->taskType == TASK_EVENT_CONNECTED || task->taskType == TASK_EVENT_CONNECTED_TCP)
347     {
348         NSConsumerHandleRequestDiscover((OCDevAddr *) task->taskData, NS_DISCOVER_DEFAULT);
349         NSOICFree(task->taskData);
350     }
351     else
352     {
353         NS_LOG(ERROR, "Unknown type message");
354     }
355
356     NSOICFree(task);
357 }