replace : iotivity -> iotivity-sec
[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 "NSUtil.h"
26 #include "NSConsumerCommon.h"
27 #include "NSConstants.h"
28 #include "ocpayload.h"
29 #include "oic_malloc.h"
30 #include "oic_string.h"
31
32 #define NS_DISCOVER_QUERY "/oic/res?rt=x.org.iotivity.notification"
33 #define NS_PRESENCE_SUBSCRIBE_QUERY_TCP "/oic/ad?rt=x.org.iotivity.notification"
34
35 OCStackApplicationResult NSConsumerPresenceListener(
36         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
37 {
38     (void) ctx;
39     (void) handle;
40
41     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
42     NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);
43     NS_VERIFY_STACK_SUCCESS(
44             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
45
46     NS_LOG_V(INFO_PRIVATE, "Presence income : %s:%d",
47             clientResponse->devAddr.addr, clientResponse->devAddr.port);
48     NS_LOG_V(DEBUG, "Presence result : %d",
49             clientResponse->result);
50     NS_LOG_V(DEBUG, "Presence sequenceNum : %d",
51             clientResponse->sequenceNumber);
52     NS_LOG_V(DEBUG, "Presence Transport Type : %d",
53                 clientResponse->devAddr.adapter);
54
55     if (!NSIsStartedConsumer())
56     {
57         return OC_STACK_DELETE_TRANSACTION;
58     }
59
60     OCPresencePayload * payload = (OCPresencePayload *)clientResponse->payload;
61     if (payload->trigger == OC_PRESENCE_TRIGGER_DELETE ||
62             clientResponse->result == OC_STACK_PRESENCE_STOPPED)
63     {
64         NS_LOG(DEBUG, "stopped presence or resource is deleted.");
65         NS_LOG(DEBUG, "build NSTask");
66         OCDevAddr * addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
67         NS_VERIFY_NOT_NULL(addr, OC_STACK_KEEP_TRANSACTION);
68         memcpy(addr, clientResponse->addr, sizeof(OCDevAddr));
69
70         NSTask * task = NSMakeTask(TASK_CONSUMER_PROVIDER_DELETED, addr);
71         NS_VERIFY_NOT_NULL(task, OC_STACK_KEEP_TRANSACTION);
72
73         NSConsumerPushEvent(task);
74     }
75
76     else if (payload->trigger == OC_PRESENCE_TRIGGER_CREATE)
77     {
78         NS_LOG(DEBUG, "started presence or resource is created.");
79         NSInvokeRequest(NULL, OC_REST_DISCOVER, clientResponse->addr,
80             NS_DISCOVER_QUERY, NULL, NSProviderDiscoverListener, NULL, NULL,
81             clientResponse->addr->adapter);
82     }
83
84     return OC_STACK_KEEP_TRANSACTION;
85 }
86
87 OCStackApplicationResult NSProviderDiscoverListener(
88         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
89 {
90     (void) handle;
91
92     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
93     NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);
94     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
95
96     NS_LOG_V(INFO_PRIVATE, "Discover income : %s:%d",
97             clientResponse->devAddr.addr, clientResponse->devAddr.port);
98     NS_LOG_V(DEBUG, "Discover result : %d",
99             clientResponse->result);
100     NS_LOG_V(DEBUG, "Discover sequenceNum : %d",
101             clientResponse->sequenceNumber);
102     NS_LOG_V(DEBUG, "Discover Transport Type : %d",
103                     clientResponse->devAddr.adapter);
104
105     if (!NSIsStartedConsumer())
106     {
107         return OC_STACK_DELETE_TRANSACTION;
108     }
109
110     OCDiscoveryPayload * discoveryPayload = (OCDiscoveryPayload *)clientResponse->payload;
111
112     while (discoveryPayload)
113     {
114         OCResourcePayload * resource = discoveryPayload->resources;
115         while (resource)
116         {
117             NS_LOG_V(DEBUG, "Discovered resource uri : %s", resource->uri);
118             NS_VERIFY_NOT_NULL(resource->uri, OC_STACK_KEEP_TRANSACTION);
119             if (strstr(resource->uri, NS_RESOURCE_URI))
120             {
121                 NS_LOG_V(DEBUG, "Request GET to provider : %s", resource->uri);
122                 OCConnectivityType type = CT_DEFAULT;
123                 if (clientResponse->addr->adapter == OC_ADAPTER_TCP)
124                 {
125                     type = CT_ADAPTER_TCP;
126                 }
127
128                 OCDevAddr * addr = clientResponse->addr;
129                 if (resource->secure)
130                 {
131                     addr->port = resource->port;
132                     addr->flags |= OC_FLAG_SECURE;
133                 }
134
135                 NSInvokeRequest(NULL, OC_REST_GET, addr,
136                         resource->uri, NULL, NSIntrospectProvider, ctx,
137                         NULL, type);
138             }
139             resource = resource->next;
140         }
141         discoveryPayload = discoveryPayload->next;
142     }
143
144     return OC_STACK_KEEP_TRANSACTION;
145 }
146
147 OCStackApplicationResult NSIntrospectProvider(
148         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
149 {
150     (void) handle;
151
152     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
153     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
154
155     NS_LOG_V(INFO_PRIVATE, "GET response income : %s:%d",
156             clientResponse->devAddr.addr, clientResponse->devAddr.port);
157     NS_LOG_V(DEBUG, "GET response result : %d",
158             clientResponse->result);
159     NS_LOG_V(DEBUG, "GET response sequenceNum : %d",
160             clientResponse->sequenceNumber);
161     NS_LOG_V(DEBUG, "GET response resource uri : %s",
162             clientResponse->resourceUri);
163     NS_LOG_V(DEBUG, "GET response Transport Type : %d",
164                     clientResponse->devAddr.adapter);
165
166     if (!NSIsStartedConsumer())
167     {
168         return OC_STACK_DELETE_TRANSACTION;
169     }
170
171     NSProvider_internal * newProvider = NSGetProvider(clientResponse);
172     NS_VERIFY_NOT_NULL(newProvider, OC_STACK_KEEP_TRANSACTION);
173     if (ctx && ctx == (void *)NS_DISCOVER_CLOUD )
174     {
175         newProvider->connection->isCloudConnection = true;
176     }
177
178     NS_LOG(DEBUG, "build NSTask");
179     NSTask * task = NSMakeTask(TASK_CONSUMER_PROVIDER_DISCOVERED, (void *) newProvider);
180     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveProvider_internal(newProvider));
181
182     NSConsumerPushEvent(task);
183
184     return OC_STACK_KEEP_TRANSACTION;
185 }
186
187 void NSConsumerHandleRequestDiscover(OCDevAddr * address, NSConsumerDiscoverType rType)
188 {
189     OCConnectivityType type = CT_ADAPTER_IP;
190     NSConsumerDiscoverType * callbackData = NULL;
191
192     if (address)
193     {
194         if (address->adapter == OC_ADAPTER_IP)
195         {
196             NS_LOG(DEBUG, "Request discover [UDP]");
197         }
198         else if (address->adapter == OC_ADAPTER_TCP)
199         {
200             type = CT_ADAPTER_TCP;
201             NS_LOG(DEBUG, "Request discover and subscribe presence [TCP]");
202             NS_LOG(DEBUG, "Subscribe presence [TCP]");
203             NSInvokeRequest(NULL, OC_REST_PRESENCE, address, NS_PRESENCE_SUBSCRIBE_QUERY_TCP,
204                     NULL, NSConsumerPresenceListener, NULL, NULL, type);
205
206             if (rType == NS_DISCOVER_CLOUD)
207             {
208                 callbackData = (void *) NS_DISCOVER_CLOUD;
209             }
210         }
211         else
212         {
213             NS_LOG_V(INFO_PRIVATE, "Request discover But Adapter is not IP : %d", address->adapter);
214         }
215     }
216     else
217     {
218         NS_LOG(DEBUG, "Request Multicast discover [UDP]");
219     }
220
221     NSInvokeRequest(NULL, OC_REST_DISCOVER, address, NS_DISCOVER_QUERY,
222             NULL, NSProviderDiscoverListener, (void *)callbackData, NULL, type);
223 }
224
225 void NSConsumerDiscoveryTaskProcessing(NSTask * task)
226 {
227     NS_VERIFY_NOT_NULL_V(task);
228
229     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
230     if (task->taskType == TASK_CONSUMER_REQ_DISCOVER)
231     {
232         char * address = (char *) task->taskData;
233         NSConsumerDiscoverType dType = NS_DISCOVER_DEFAULT;
234
235         OCDevAddr * addr = NULL;
236         if (address)
237         {
238             addr = NSChangeAddress(address);
239             dType = NS_DISCOVER_CLOUD;
240         }
241
242         NSConsumerHandleRequestDiscover(addr, dType);
243         NSOICFree(task->taskData);
244         NSOICFree(addr);
245     }
246     else if (task->taskType == TASK_EVENT_CONNECTED || task->taskType == TASK_EVENT_CONNECTED_TCP)
247     {
248         NSConsumerHandleRequestDiscover((OCDevAddr *) task->taskData, NS_DISCOVER_DEFAULT);
249         NSOICFree(task->taskData);
250     }
251     else
252     {
253         NS_LOG(ERROR, "Unknown type message");
254     }
255
256     NSOICFree(task);
257 }