a87fb0b252df12c466a83ba291121b28019644fd
[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 "coap://224.0.1.187:5683/oic/ad?rt=oic.r.notification"
33 #define NS_PRESENCE_SUBSCRIBE_QUERY_TCP "/oic/ad?rt=oic.r.notification"
34 #define NS_GET_INFORMATION_QUERY "/notification?if=oic.if.notification"
35
36 NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse);
37
38 OCStackApplicationResult NSConsumerPresenceListener(
39         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
40 {
41     (void) ctx;
42     (void) handle;
43
44     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
45     NS_VERIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
46
47     NS_LOG_V(DEBUG, "Presence income : %s:%d",
48             clientResponse->devAddr.addr, clientResponse->devAddr.port);
49     NS_LOG_V(DEBUG, "Presence result : %d",
50             clientResponse->result);
51     NS_LOG_V(DEBUG, "Presence sequenceNum : %d",
52             clientResponse->sequenceNumber);
53
54     if (!NSIsStartedConsumer())
55     {
56         return OC_STACK_DELETE_TRANSACTION;
57     }
58
59     OCPresencePayload * payload = (OCPresencePayload *)clientResponse->payload;
60     if (payload->trigger == OC_PRESENCE_TRIGGER_DELETE ||
61             clientResponse->result == OC_STACK_PRESENCE_STOPPED)
62     {
63         // TODO find request and cancel
64         NS_LOG(DEBUG, "stopped presence or resource is deleted.");
65         //OCCancel(handle, NS_QOS, NULL, 0);
66     }
67
68     else if (payload->trigger == OC_PRESENCE_TRIGGER_CREATE)
69     {
70         NS_LOG(DEBUG, "started presence or resource is created.");
71         NSInvokeRequest(NULL, OC_REST_DISCOVER, clientResponse->addr,
72             NS_DISCOVER_QUERY, NULL, NSProviderDiscoverListener, NULL,
73             clientResponse->addr->adapter);
74     }
75
76     return OC_STACK_KEEP_TRANSACTION;
77 }
78
79 OCStackApplicationResult NSProviderDiscoverListener(
80         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
81 {
82     (void) ctx;
83     (void) handle;
84
85     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
86     NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);
87     NS_VERIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
88
89     NS_LOG_V(DEBUG, "Discover income : %s:%d",
90             clientResponse->devAddr.addr, clientResponse->devAddr.port);
91     NS_LOG_V(DEBUG, "Discover result : %d",
92             clientResponse->result);
93     NS_LOG_V(DEBUG, "Discover sequenceNum : %d",
94             clientResponse->sequenceNumber);
95
96     if (!NSIsStartedConsumer())
97     {
98         return OC_STACK_DELETE_TRANSACTION;
99     }
100
101     OCResourcePayload * resource = ((OCDiscoveryPayload *)clientResponse->payload)->resources;
102     while (resource)
103     {
104         if (strstr(resource->uri, NS_RESOURCE_URI))
105         {
106             NSInvokeRequest(NULL, OC_REST_GET, clientResponse->addr,
107                     resource->uri, NULL, NSIntrospectProvider, NULL,
108                     clientResponse->addr->adapter);
109         }
110         resource = resource->next;
111     }
112
113     return OC_STACK_KEEP_TRANSACTION;
114 }
115
116 void NSRemoveProviderObj(NSProvider_internal * provider)
117 {
118     NSOICFree(provider->messageUri);
119     NSOICFree(provider->syncUri);
120
121     provider->i_messageHandle = NULL;
122     provider->i_syncHandle = NULL;
123     NSOICFree(provider->i_addr);
124
125     NSOICFree(provider);
126 }
127
128 OCStackApplicationResult NSIntrospectProvider(
129         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
130 {
131     (void) ctx;
132     (void) handle;
133
134     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
135     NS_VERIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
136
137     NS_LOG_V(DEBUG, "GET response income : %s:%d",
138             clientResponse->devAddr.addr, clientResponse->devAddr.port);
139     NS_LOG_V(DEBUG, "GET response result : %d",
140             clientResponse->result);
141     NS_LOG_V(DEBUG, "GET response sequenceNum : %d",
142             clientResponse->sequenceNumber);
143     NS_LOG_V(DEBUG, "GET response resource uri : %s",
144             clientResponse->resourceUri);
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
154     NS_LOG(DEBUG, "build NSTask");
155     NSTask * task = NSMakeTask(TASK_CONSUMER_PROVIDER_DISCOVERED, (void *) newProvider);
156     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveProviderObj(newProvider));
157
158     NSConsumerPushEvent(task);
159
160     return OC_STACK_KEEP_TRANSACTION;
161 }
162
163 void NSGetProviderPostClean(char * pId, char * mUri, char * sUri, OCDevAddr * addr)
164 {
165     NSOICFree(pId);
166     NSOICFree(mUri);
167     NSOICFree(sUri);
168     NSOICFree(addr);
169 }
170
171 NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse)
172 {
173     NS_LOG(DEBUG, "create NSProvider");
174     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
175
176     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
177     while (payload)
178     {
179         NS_LOG_V(DEBUG, "Payload Key : %s", payload->values->name);
180         payload = payload->next;
181     }
182
183     payload = (OCRepPayload *)clientResponse->payload;
184
185     char * providerId = NULL;
186     char * messageUri = NULL;
187     char * syncUri = NULL;
188     int64_t accepter = 0;
189     OCDevAddr * addr = NULL;
190
191     NS_LOG(DEBUG, "get information of accepter");
192     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_POLICY, & accepter);
193     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
194
195     NS_LOG(DEBUG, "get provider ID");
196     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, & providerId);
197     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
198
199     NS_LOG(DEBUG, "get message URI");
200     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_MESSAGE, & messageUri);
201     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
202             NSGetProviderPostClean(providerId, messageUri, syncUri, addr));
203
204     NS_LOG(DEBUG, "get sync URI");
205     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SYNC, & syncUri);
206     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
207             NSGetProviderPostClean(providerId, messageUri, syncUri, addr));
208
209     NS_LOG(DEBUG, "get provider address");
210     addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
211     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(addr, NULL,
212            NSGetProviderPostClean(providerId, messageUri, syncUri, addr));
213
214     memcpy(addr, clientResponse->addr, sizeof(OCDevAddr));
215
216     NSProvider_internal * newProvider
217         = (NSProvider_internal *)OICMalloc(sizeof(NSProvider_internal));
218     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProvider, NULL,
219           NSGetProviderPostClean(providerId, messageUri, syncUri, addr));
220
221     OICStrcpy(newProvider->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
222     NSOICFree(providerId);
223     newProvider->messageUri = messageUri;
224     newProvider->syncUri = syncUri;
225     newProvider->accessPolicy = (NSAccessPolicy)accepter;
226     newProvider->i_addr = addr;
227     newProvider->i_messageHandle = NULL;
228     newProvider->i_syncHandle = NULL;
229
230     return newProvider;
231 }
232
233 void NSConsumerDiscoveryTaskProcessing(NSTask * task)
234 {
235     NS_VERIFY_NOT_NULL_V(task);
236
237     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
238     if (task->taskType == TASK_EVENT_CONNECTED || task->taskType == TASK_CONSUMER_REQ_DISCOVER)
239     {
240         OCDevAddr * addr = (OCDevAddr *) task->taskData;
241
242         NS_LOG(DEBUG, "Request discover [UDP]");
243         NSInvokeRequest(NULL, OC_REST_DISCOVER, addr, NS_DISCOVER_QUERY,
244                 NULL, NSProviderDiscoverListener, NULL, addr->adapter);
245     }
246     else if (task->taskType == TASK_EVENT_CONNECTED_TCP)
247     {
248         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(task->taskData, NSOICFree(task));
249         OCDevAddr * addr = (OCDevAddr *) task->taskData;
250
251         NS_LOG(DEBUG, "Request discover [TCP]");
252         NSInvokeRequest(NULL, OC_REST_DISCOVER, addr, NS_DISCOVER_QUERY,
253                 NULL, NSProviderDiscoverListener, NULL, addr->adapter);
254
255         NS_LOG(DEBUG, "Subscribe presence [TCP]");
256         NSInvokeRequest(NULL, OC_REST_PRESENCE, addr, NS_PRESENCE_SUBSCRIBE_QUERY_TCP,
257                 NULL, NSConsumerPresenceListener, NULL, addr->adapter);
258
259         NSOICFree(task->taskData);
260     }
261     else
262     {
263         NS_LOG(ERROR, "Unknown type message");
264     }
265
266     NSOICFree(task);
267 }