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