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_STACK_SUCCESS(
47 NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
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);
58 if (!NSIsStartedConsumer())
60 return OC_STACK_DELETE_TRANSACTION;
63 OCPresencePayload * payload = (OCPresencePayload *)clientResponse->payload;
64 if (payload->trigger == OC_PRESENCE_TRIGGER_DELETE ||
65 clientResponse->result == OC_STACK_PRESENCE_STOPPED)
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));
73 NSTask * task = NSMakeTask(TASK_CONSUMER_PROVIDER_DELETED, addr);
74 NS_VERIFY_NOT_NULL(task, OC_STACK_KEEP_TRANSACTION);
77 else if (payload->trigger == OC_PRESENCE_TRIGGER_CREATE)
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);
85 return OC_STACK_KEEP_TRANSACTION;
88 OCStackApplicationResult NSProviderDiscoverListener(
89 void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
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);
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);
106 if (!NSIsStartedConsumer())
108 return OC_STACK_DELETE_TRANSACTION;
111 OCResourcePayload * resource = ((OCDiscoveryPayload *)clientResponse->payload)->resources;
114 if (strstr(resource->uri, NS_RESOURCE_URI))
116 OCConnectivityType type = CT_DEFAULT;
117 if (clientResponse->addr->adapter == OC_ADAPTER_TCP)
119 type = CT_ADAPTER_TCP;
122 NSInvokeRequest(NULL, OC_REST_GET, clientResponse->addr,
123 resource->uri, NULL, NSIntrospectProvider, ctx,
126 resource = resource->next;
129 return OC_STACK_KEEP_TRANSACTION;
132 OCStackApplicationResult NSIntrospectProvider(
133 void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
137 NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
138 NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
140 NS_LOG_V(DEBUG, "GET response income : %s:%d",
141 clientResponse->devAddr.addr, clientResponse->devAddr.port);
142 NS_LOG_V(DEBUG, "GET response result : %d",
143 clientResponse->result);
144 NS_LOG_V(DEBUG, "GET response sequenceNum : %d",
145 clientResponse->sequenceNumber);
146 NS_LOG_V(DEBUG, "GET response resource uri : %s",
147 clientResponse->resourceUri);
148 NS_LOG_V(DEBUG, "GET response Transport Type : %d",
149 clientResponse->devAddr.adapter);
151 if (!NSIsStartedConsumer())
153 return OC_STACK_DELETE_TRANSACTION;
156 NSProvider_internal * newProvider = NSGetProvider(clientResponse);
157 NS_VERIFY_NOT_NULL(newProvider, OC_STACK_KEEP_TRANSACTION);
158 if (ctx && *((NSConsumerDiscoverType *)ctx) == NS_DISCOVER_CLOUD )
160 newProvider->connection->isCloudConnection = true;
164 NS_LOG(DEBUG, "build NSTask");
165 NSTask * task = NSMakeTask(TASK_CONSUMER_PROVIDER_DISCOVERED, (void *) newProvider);
166 NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveProvider_internal(newProvider));
168 NSConsumerPushEvent(task);
170 return OC_STACK_KEEP_TRANSACTION;
173 void NSGetProviderPostClean(
174 char * pId, char * mUri, char * sUri, char * tUri, NSProviderConnectionInfo * connection)
180 NSRemoveConnections(connection);
183 NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse)
185 NS_LOG(DEBUG, "create NSProvider");
186 NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
188 OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
191 NS_LOG_V(DEBUG, "Payload Key : %s", payload->values->name);
192 payload = payload->next;
195 payload = (OCRepPayload *)clientResponse->payload;
197 char * providerId = NULL;
198 char * messageUri = NULL;
199 char * syncUri = NULL;
200 char * topicUri = NULL;
201 int64_t accepter = 0;
202 NSProviderConnectionInfo * connection = NULL;
204 NS_LOG(DEBUG, "get information of accepter");
205 bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_POLICY, & accepter);
206 NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
208 NS_LOG(DEBUG, "get provider ID");
209 getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, & providerId);
210 NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
212 NS_LOG(DEBUG, "get message URI");
213 getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_MESSAGE, & messageUri);
214 NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
215 NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
217 NS_LOG(DEBUG, "get sync URI");
218 getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SYNC, & syncUri);
219 NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
220 NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
222 NS_LOG(DEBUG, "get topic URI");
223 getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TOPIC, & topicUri);
224 NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
225 NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
227 NS_LOG(DEBUG, "get provider connection information");
228 NS_VERIFY_NOT_NULL(clientResponse->addr, NULL);
229 connection = NSCreateProviderConnections(clientResponse->addr);
230 NS_VERIFY_NOT_NULL(connection, NULL);
232 NSProvider_internal * newProvider
233 = (NSProvider_internal *)OICMalloc(sizeof(NSProvider_internal));
234 NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProvider, NULL,
235 NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
237 OICStrcpy(newProvider->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
238 NSOICFree(providerId);
239 newProvider->messageUri = messageUri;
240 newProvider->syncUri = syncUri;
241 newProvider->topicUri = topicUri;
242 newProvider->accessPolicy = (NSSelector)accepter;
243 newProvider->connection = connection;
244 newProvider->topicLL = NULL;
249 OCDevAddr * NSChangeAddress(const char * address)
251 NS_VERIFY_NOT_NULL(address, NULL);
252 OCDevAddr * retAddr = NULL;
255 while(address[index] != '\0')
257 if (address[index] == ':')
264 if (address[index] == '\0')
270 uint16_t port = address[tmp++];
272 while(address[tmp] != '\0')
275 port += address[tmp++] - '0';
278 retAddr = (OCDevAddr *) OICMalloc(sizeof(OCDevAddr));
279 NS_VERIFY_NOT_NULL(retAddr, NULL);
281 retAddr->adapter = OC_ADAPTER_TCP;
282 OICStrcpy(retAddr->addr, index - 1, address);
283 retAddr->addr[index] = '\0';
284 retAddr->port = port;
289 void NSConsumerHandleRequestDiscover(OCDevAddr * address, NSConsumerDiscoverType rType)
291 OCConnectivityType type = CT_DEFAULT;
292 NSConsumerDiscoverType * callbackData = NULL;
296 if (address->adapter == OC_ADAPTER_IP)
298 type = CT_ADAPTER_IP;
299 NS_LOG(DEBUG, "Request discover [UDP]");
301 else if (address->adapter == OC_ADAPTER_TCP)
303 type = CT_ADAPTER_TCP;
304 NS_LOG(DEBUG, "Request discover and subscribe presence [TCP]");
305 NS_LOG(DEBUG, "Subscribe presence [TCP]");
306 NSInvokeRequest(NULL, OC_REST_PRESENCE, address, NS_PRESENCE_SUBSCRIBE_QUERY_TCP,
307 NULL, NSConsumerPresenceListener, NULL, type);
309 if (rType == NS_DISCOVER_CLOUD)
311 callbackData = (NSConsumerDiscoverType *)OICMalloc(sizeof(NSConsumerDiscoverType));
312 *callbackData = NS_DISCOVER_CLOUD;
317 NS_LOG_V(DEBUG, "Request discover But Adapter is not IP : %d", address->adapter);
322 NS_LOG(DEBUG, "Request Multicast discover [UDP]");
325 NSInvokeRequest(NULL, OC_REST_DISCOVER, address, NS_DISCOVER_QUERY,
326 NULL, NSProviderDiscoverListener, (void *)callbackData, type);
329 void NSConsumerDiscoveryTaskProcessing(NSTask * task)
331 NS_VERIFY_NOT_NULL_V(task);
333 NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
334 if (task->taskType == TASK_CONSUMER_REQ_DISCOVER)
336 char * address = (char *) task->taskData;
337 NSConsumerDiscoverType dType = NS_DISCOVER_DEFAULT;
339 OCDevAddr * addr = NULL;
342 addr = NSChangeAddress(address);
343 dType = NS_DISCOVER_CLOUD;
346 NSConsumerHandleRequestDiscover(addr, dType);
347 NSOICFree(task->taskData);
350 else if (task->taskType == TASK_EVENT_CONNECTED || task->taskType == TASK_EVENT_CONNECTED_TCP)
352 NSConsumerHandleRequestDiscover((OCDevAddr *) task->taskData, NS_DISCOVER_DEFAULT);
353 NSOICFree(task->taskData);
357 NS_LOG(ERROR, "Unknown type message");