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