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