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