Merge notification service from master branch
[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.wk.notification"
32 #define NS_PRESENCE_SUBSCRIBE_QUERY_TCP "/oic/ad?rt=oic.wk.notification"
33
34 NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse);
35
36 OCDevAddr * NSChangeAddress(const char * address);
37
38 OCStackApplicationResult NSConsumerPresenceListener(
39         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
40 {
41     (void) ctx;
42     (void) handle;
43
44     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
45     NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);
46     NS_VERIFY_STACK_SUCCESS(
47             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
48
49     NS_LOG_V(DEBUG, "Presence income : %s:%d",
50             clientResponse->devAddr.addr, clientResponse->devAddr.port);
51     NS_LOG_V(DEBUG, "Presence result : %d",
52             clientResponse->result);
53     NS_LOG_V(DEBUG, "Presence sequenceNum : %d",
54             clientResponse->sequenceNumber);
55     NS_LOG_V(DEBUG, "Presence Transport Type : %d",
56                 clientResponse->devAddr.adapter);
57
58     if (!NSIsStartedConsumer())
59     {
60         return OC_STACK_DELETE_TRANSACTION;
61     }
62
63     OCPresencePayload * payload = (OCPresencePayload *)clientResponse->payload;
64     if (payload->trigger == OC_PRESENCE_TRIGGER_DELETE ||
65             clientResponse->result == OC_STACK_PRESENCE_STOPPED)
66     {
67         NS_LOG(DEBUG, "stopped presence or resource is deleted.");
68         NS_LOG(DEBUG, "build NSTask");
69         OCDevAddr * addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
70         NS_VERIFY_NOT_NULL(addr, OC_STACK_KEEP_TRANSACTION);
71         memcpy(addr, clientResponse->addr, sizeof(OCDevAddr));
72
73         NSTask * task = NSMakeTask(TASK_CONSUMER_PROVIDER_DELETED, addr);
74         NS_VERIFY_NOT_NULL(task, OC_STACK_KEEP_TRANSACTION);
75
76         NSConsumerPushEvent(task);
77     }
78
79     else if (payload->trigger == OC_PRESENCE_TRIGGER_CREATE)
80     {
81         NS_LOG(DEBUG, "started presence or resource is created.");
82         NSInvokeRequest(NULL, OC_REST_DISCOVER, clientResponse->addr,
83             NS_DISCOVER_QUERY, NULL, NSProviderDiscoverListener, NULL,
84             clientResponse->addr->adapter);
85     }
86
87     return OC_STACK_KEEP_TRANSACTION;
88 }
89
90 OCStackApplicationResult NSProviderDiscoverListener(
91         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
92 {
93     (void) handle;
94
95     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
96     NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);
97     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
98
99     NS_LOG_V(DEBUG, "Discover income : %s:%d",
100             clientResponse->devAddr.addr, clientResponse->devAddr.port);
101     NS_LOG_V(DEBUG, "Discover result : %d",
102             clientResponse->result);
103     NS_LOG_V(DEBUG, "Discover sequenceNum : %d",
104             clientResponse->sequenceNumber);
105     NS_LOG_V(DEBUG, "Discover Transport Type : %d",
106                     clientResponse->devAddr.adapter);
107
108     if (!NSIsStartedConsumer())
109     {
110         return OC_STACK_DELETE_TRANSACTION;
111     }
112
113     OCResourcePayload * resource = ((OCDiscoveryPayload *)clientResponse->payload)->resources;
114     NS_LOG_V(DEBUG, "Discovered resource uri : %s",
115                         resource->uri);
116     while (resource)
117     {
118         NS_VERIFY_NOT_NULL(resource->uri, OC_STACK_KEEP_TRANSACTION);
119         if (strstr(resource->uri, NS_RESOURCE_URI))
120         {
121             OCConnectivityType type = CT_DEFAULT;
122             if (clientResponse->addr->adapter == OC_ADAPTER_TCP)
123             {
124                 type = CT_ADAPTER_TCP;
125             }
126
127             OCDevAddr * addr = clientResponse->addr;
128             if (resource->secure)
129             {
130                 addr->port = resource->port;
131                 addr->flags |= OC_FLAG_SECURE;
132             }
133
134             NSInvokeRequest(NULL, OC_REST_GET, addr,
135                     resource->uri, NULL, NSIntrospectProvider, ctx,
136                     type);
137         }
138         resource = resource->next;
139     }
140
141     return OC_STACK_KEEP_TRANSACTION;
142 }
143
144 OCStackApplicationResult NSIntrospectProvider(
145         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
146 {
147     (void) handle;
148
149     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
150     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
151
152     NS_LOG_V(DEBUG, "GET response income : %s:%d",
153             clientResponse->devAddr.addr, clientResponse->devAddr.port);
154     NS_LOG_V(DEBUG, "GET response result : %d",
155             clientResponse->result);
156     NS_LOG_V(DEBUG, "GET response sequenceNum : %d",
157             clientResponse->sequenceNumber);
158     NS_LOG_V(DEBUG, "GET response resource uri : %s",
159             clientResponse->resourceUri);
160     NS_LOG_V(DEBUG, "GET response Transport Type : %d",
161                     clientResponse->devAddr.adapter);
162
163     if (!NSIsStartedConsumer())
164     {
165         return OC_STACK_DELETE_TRANSACTION;
166     }
167
168     NSProvider_internal * newProvider = NSGetProvider(clientResponse);
169     NS_VERIFY_NOT_NULL(newProvider, OC_STACK_KEEP_TRANSACTION);
170     if (ctx && ctx == (void *)NS_DISCOVER_CLOUD )
171     {
172         newProvider->connection->isCloudConnection = true;
173     }
174
175     NS_LOG(DEBUG, "build NSTask");
176     NSTask * task = NSMakeTask(TASK_CONSUMER_PROVIDER_DISCOVERED, (void *) newProvider);
177     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveProvider_internal(newProvider));
178
179     NSConsumerPushEvent(task);
180
181     return OC_STACK_KEEP_TRANSACTION;
182 }
183
184 void NSGetProviderPostClean(
185         char * pId, char * mUri, char * sUri, char * tUri, NSProviderConnectionInfo * connection)
186 {
187     NSOICFree(pId);
188     NSOICFree(mUri);
189     NSOICFree(sUri);
190     NSOICFree(tUri);
191     NSRemoveConnections(connection);
192 }
193
194 NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse)
195 {
196     NS_LOG(DEBUG, "create NSProvider");
197     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
198
199     OCRepPayloadPropType accepterType = OCREP_PROP_BOOL;
200
201     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
202     OCRepPayloadValue * value = payload->values;
203     while (value)
204     {
205         NS_LOG_V(DEBUG, "Payload Key : %s", value->name);
206         NS_LOG_V(DEBUG, "Payload Type : %d", (int) value->type);
207         if (!strcmp(value->name, NS_ATTRIBUTE_POLICY))
208         {
209             accepterType = value->type;
210         }
211         value = value->next;
212     }
213
214     char * providerId = NULL;
215     char * messageUri = NULL;
216     char * syncUri = NULL;
217     char * topicUri = NULL;
218     bool bAccepter = 0;
219     int64_t iAccepter = 0;
220     NSProviderConnectionInfo * connection = NULL;
221
222     NS_LOG(DEBUG, "get information of accepter");
223     bool getResult = false;
224     if (accepterType == OCREP_PROP_BOOL)
225     {
226         getResult = OCRepPayloadGetPropBool(payload, NS_ATTRIBUTE_POLICY, & bAccepter);
227     }
228     else if (accepterType == OCREP_PROP_INT)
229     {
230         getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_POLICY, & iAccepter);
231     }
232     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
233
234     NS_LOG(DEBUG, "get provider ID");
235     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, & providerId);
236     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
237
238     NS_LOG(DEBUG, "get message URI");
239     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_MESSAGE, & messageUri);
240     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
241             NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
242
243     NS_LOG(DEBUG, "get sync URI");
244     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SYNC, & syncUri);
245     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
246             NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
247
248     NS_LOG(DEBUG, "get topic URI");
249     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TOPIC, & topicUri);
250
251     NS_LOG(DEBUG, "get provider connection information");
252     NS_VERIFY_NOT_NULL(clientResponse->addr, NULL);
253     connection = NSCreateProviderConnections(clientResponse->addr);
254     NS_VERIFY_NOT_NULL(connection, NULL);
255
256     NSProvider_internal * newProvider
257         = (NSProvider_internal *)OICMalloc(sizeof(NSProvider_internal));
258     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProvider, NULL,
259           NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
260
261     OICStrcpy(newProvider->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
262     NSOICFree(providerId);
263     newProvider->messageUri = messageUri;
264     newProvider->syncUri = syncUri;
265     newProvider->topicUri = NULL;
266     if (topicUri && strlen(topicUri) > 0)
267     {
268         newProvider->topicUri = topicUri;
269     }
270     if (accepterType == OCREP_PROP_BOOL)
271     {
272         newProvider->accessPolicy = (NSSelector)bAccepter;
273     }
274     else if (accepterType == OCREP_PROP_INT)
275     {
276         newProvider->accessPolicy = (NSSelector)iAccepter;
277     }
278
279     newProvider->connection = connection;
280     newProvider->topicLL = NULL;
281     newProvider->state = NS_DISCOVERED;
282
283     return newProvider;
284 }
285
286 OCDevAddr * NSChangeAddress(const char * address)
287 {
288     NS_VERIFY_NOT_NULL(address, NULL);
289     OCDevAddr * retAddr = NULL;
290
291     int index = 0;
292     while(address[index] != '\0')
293     {
294         if (address[index] == ':')
295         {
296             break;
297         }
298         index++;
299     }
300
301     if (address[index] == '\0')
302     {
303         return NULL;
304     }
305
306     int tmp = index + 1;
307     uint16_t port = address[tmp++] - '0';
308
309     while(address[tmp] != '\0')
310     {
311         port *= 10;
312         port += address[tmp++] - '0';
313     }
314
315     retAddr = (OCDevAddr *) OICMalloc(sizeof(OCDevAddr));
316     NS_VERIFY_NOT_NULL(retAddr, NULL);
317
318     retAddr->adapter = OC_ADAPTER_TCP;
319     OICStrcpy(retAddr->addr, index + 1, address);
320     retAddr->addr[index] = '\0';
321     retAddr->port = port;
322     retAddr->flags = OC_IP_USE_V6;
323
324     NS_LOG(DEBUG, "Change Address for TCP request");
325     NS_LOG_V(DEBUG, "Origin : %s", address);
326     NS_LOG_V(DEBUG, "Changed Addr : %s", retAddr->addr);
327     NS_LOG_V(DEBUG, "Changed Port : %d", retAddr->port);
328
329     return retAddr;
330 }
331
332 void NSConsumerHandleRequestDiscover(OCDevAddr * address, NSConsumerDiscoverType rType)
333 {
334     OCConnectivityType type = CT_ADAPTER_IP;
335     NSConsumerDiscoverType * callbackData = NULL;
336
337     if (address)
338     {
339         if (address->adapter == OC_ADAPTER_IP)
340         {
341             NS_LOG(DEBUG, "Request discover [UDP]");
342         }
343         else if (address->adapter == OC_ADAPTER_TCP)
344         {
345             type = CT_ADAPTER_TCP;
346             NS_LOG(DEBUG, "Request discover and subscribe presence [TCP]");
347             NS_LOG(DEBUG, "Subscribe presence [TCP]");
348             NSInvokeRequest(NULL, OC_REST_PRESENCE, address, NS_PRESENCE_SUBSCRIBE_QUERY_TCP,
349                     NULL, NSConsumerPresenceListener, NULL, type);
350
351             if (rType == NS_DISCOVER_CLOUD)
352             {
353                 callbackData = (void *) NS_DISCOVER_CLOUD;
354             }
355         }
356         else
357         {
358             NS_LOG_V(DEBUG, "Request discover But Adapter is not IP : %d", address->adapter);
359         }
360     }
361     else
362     {
363         NS_LOG(DEBUG, "Request Multicast discover [UDP]");
364     }
365
366     NSInvokeRequest(NULL, OC_REST_DISCOVER, address, NS_DISCOVER_QUERY,
367             NULL, NSProviderDiscoverListener, (void *)callbackData, type);
368 }
369
370 void NSConsumerDiscoveryTaskProcessing(NSTask * task)
371 {
372     NS_VERIFY_NOT_NULL_V(task);
373
374     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
375     if (task->taskType == TASK_CONSUMER_REQ_DISCOVER)
376     {
377         char * address = (char *) task->taskData;
378         NSConsumerDiscoverType dType = NS_DISCOVER_DEFAULT;
379
380         OCDevAddr * addr = NULL;
381         if (address)
382         {
383             addr = NSChangeAddress(address);
384             dType = NS_DISCOVER_CLOUD;
385         }
386
387         NSConsumerHandleRequestDiscover(addr, dType);
388         NSOICFree(task->taskData);
389         NSOICFree(addr);
390     }
391     else if (task->taskType == TASK_EVENT_CONNECTED || task->taskType == TASK_EVENT_CONNECTED_TCP)
392     {
393         NSConsumerHandleRequestDiscover((OCDevAddr *) task->taskData, NS_DISCOVER_DEFAULT);
394         NSOICFree(task->taskData);
395     }
396     else
397     {
398         NS_LOG(ERROR, "Unknown type message");
399     }
400
401     NSOICFree(task);
402 }