1 //******************************************************************
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "NSConsumerDiscovery.h"
25 #include "NSConsumerCommon.h"
26 #include "NSConstants.h"
27 #include "ocpayload.h"
28 #include "oic_malloc.h"
29 #include "oic_string.h"
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"
35 NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse);
37 OCDevAddr * NSChangeAddress(const char * address);
39 OCStackApplicationResult NSConsumerPresenceListener(
40 void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
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);
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);
59 if (!NSIsStartedConsumer())
61 return OC_STACK_DELETE_TRANSACTION;
64 OCPresencePayload * payload = (OCPresencePayload *)clientResponse->payload;
65 if (payload->trigger == OC_PRESENCE_TRIGGER_DELETE ||
66 clientResponse->result == OC_STACK_PRESENCE_STOPPED)
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));
74 NSTask * task = NSMakeTask(TASK_CONSUMER_PROVIDER_DELETED, addr);
75 NS_VERIFY_NOT_NULL(task, OC_STACK_KEEP_TRANSACTION);
77 NSConsumerPushEvent(task);
80 else if (payload->trigger == OC_PRESENCE_TRIGGER_CREATE)
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);
88 return OC_STACK_KEEP_TRANSACTION;
91 OCStackApplicationResult NSProviderDiscoverListener(
92 void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
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);
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);
109 if (!NSIsStartedConsumer())
111 return OC_STACK_DELETE_TRANSACTION;
114 OCResourcePayload * resource = ((OCDiscoveryPayload *)clientResponse->payload)->resources;
115 NS_LOG_V(DEBUG, "Discovered resource uri : %s",
119 NS_VERIFY_NOT_NULL(resource->uri, OC_STACK_KEEP_TRANSACTION);
120 if (strstr(resource->uri, NS_RESOURCE_URI))
122 OCConnectivityType type = CT_DEFAULT;
123 if (clientResponse->addr->adapter == OC_ADAPTER_TCP)
125 type = CT_ADAPTER_TCP;
128 NSInvokeRequest(NULL, OC_REST_GET, clientResponse->addr,
129 resource->uri, NULL, NSIntrospectProvider, ctx,
132 resource = resource->next;
135 return OC_STACK_KEEP_TRANSACTION;
138 OCStackApplicationResult NSIntrospectProvider(
139 void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
143 NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
144 NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
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);
157 if (!NSIsStartedConsumer())
159 return OC_STACK_DELETE_TRANSACTION;
162 NSProvider_internal * newProvider = NSGetProvider(clientResponse);
163 NS_VERIFY_NOT_NULL(newProvider, OC_STACK_KEEP_TRANSACTION);
164 if (ctx && ctx == (void *)NS_DISCOVER_CLOUD )
166 newProvider->connection->isCloudConnection = true;
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));
173 NSConsumerPushEvent(task);
175 return OC_STACK_KEEP_TRANSACTION;
178 void NSGetProviderPostClean(
179 char * pId, char * mUri, char * sUri, char * tUri, NSProviderConnectionInfo * connection)
185 NSRemoveConnections(connection);
188 NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse)
190 NS_LOG(DEBUG, "create NSProvider");
191 NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
193 OCRepPayloadPropType accepterType = OCREP_PROP_BOOL;
195 OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
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))
202 accepterType = payload->values->type;
204 payload = payload->next;
207 payload = (OCRepPayload *)clientResponse->payload;
209 char * providerId = NULL;
210 char * messageUri = NULL;
211 char * syncUri = NULL;
212 char * topicUri = NULL;
214 int64_t iAccepter = 0;
215 NSProviderConnectionInfo * connection = NULL;
217 NS_LOG(DEBUG, "get information of accepter");
218 bool getResult = false;
219 if (accepterType == OCREP_PROP_BOOL)
221 getResult = OCRepPayloadGetPropBool(payload, NS_ATTRIBUTE_POLICY, & bAccepter);
223 else if (accepterType == OCREP_PROP_INT)
225 getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_POLICY, & iAccepter);
227 NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
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);
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));
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));
243 NS_LOG(DEBUG, "get topic URI");
244 getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TOPIC, & topicUri);
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);
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));
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)
263 newProvider->topicUri = topicUri;
265 if (accepterType == OCREP_PROP_BOOL)
267 newProvider->accessPolicy = (NSSelector)bAccepter;
269 else if (accepterType == OCREP_PROP_INT)
271 newProvider->accessPolicy = (NSSelector)iAccepter;
274 newProvider->connection = connection;
275 newProvider->topicLL = NULL;
276 newProvider->state = NS_DISCOVERED;
281 OCDevAddr * NSChangeAddress(const char * address)
283 NS_VERIFY_NOT_NULL(address, NULL);
284 OCDevAddr * retAddr = NULL;
287 while(address[index] != '\0')
289 if (address[index] == ':')
296 if (address[index] == '\0')
302 uint16_t port = address[tmp++] - '0';
304 while(address[tmp] != '\0')
307 port += address[tmp++] - '0';
310 retAddr = (OCDevAddr *) OICMalloc(sizeof(OCDevAddr));
311 NS_VERIFY_NOT_NULL(retAddr, NULL);
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;
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);
327 void NSConsumerHandleRequestDiscover(OCDevAddr * address, NSConsumerDiscoverType rType)
329 OCConnectivityType type = CT_ADAPTER_IP;
330 NSConsumerDiscoverType * callbackData = NULL;
334 if (address->adapter == OC_ADAPTER_IP)
336 NS_LOG(DEBUG, "Request discover [UDP]");
338 else if (address->adapter == OC_ADAPTER_TCP)
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);
346 if (rType == NS_DISCOVER_CLOUD)
348 callbackData = (void *) NS_DISCOVER_CLOUD;
353 NS_LOG_V(DEBUG, "Request discover But Adapter is not IP : %d", address->adapter);
358 NS_LOG(DEBUG, "Request Multicast discover [UDP]");
361 NSInvokeRequest(NULL, OC_REST_DISCOVER, address, NS_DISCOVER_QUERY,
362 NULL, NSProviderDiscoverListener, (void *)callbackData, type);
365 void NSConsumerDiscoveryTaskProcessing(NSTask * task)
367 NS_VERIFY_NOT_NULL_V(task);
369 NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
370 if (task->taskType == TASK_CONSUMER_REQ_DISCOVER)
372 char * address = (char *) task->taskData;
373 NSConsumerDiscoverType dType = NS_DISCOVER_DEFAULT;
375 OCDevAddr * addr = NULL;
378 addr = NSChangeAddress(address);
379 dType = NS_DISCOVER_CLOUD;
382 NSConsumerHandleRequestDiscover(addr, dType);
383 NSOICFree(task->taskData);
386 else if (task->taskType == TASK_EVENT_CONNECTED || task->taskType == TASK_EVENT_CONNECTED_TCP)
388 NSConsumerHandleRequestDiscover((OCDevAddr *) task->taskData, NS_DISCOVER_DEFAULT);
389 NSOICFree(task->taskData);
393 NS_LOG(ERROR, "Unknown type message");