Merge branch 'master' into notification-service
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerCommunication.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 "NSConstants.h"
22 #include "NSConsumerCommon.h"
23 #include "NSConsumerCommunication.h"
24 #include "oic_malloc.h"
25 #include "oic_string.h"
26 #include "ocpayload.h"
27
28 #define NS_SYNC_URI "/notification/sync"
29
30 unsigned long NS_MESSAGE_ACCEPTANCE = 1;
31
32 NSMessage * NSCreateMessage_internal(uint64_t msgId, const char * providerId);
33 NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state);
34
35 NSMessage * NSGetMessage(OCClientResponse * clientResponse);
36 NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse);
37
38 char * NSGetCloudUri(const char * providerId, char * uri);
39
40 NSResult NSConsumerSubscribeProvider(NSProvider * provider)
41 {
42     NSProvider_internal * provider_internal = (NSProvider_internal *) provider;
43     NS_VERIFY_NOT_NULL(provider_internal, NS_ERROR);
44
45     NSProviderConnectionInfo * connections = provider_internal->connection;
46     while(connections)
47     {
48         if (connections->isSubscribing == true)
49         {
50             connections = connections->next;
51             continue;
52         }
53
54         char * msgUri = OICStrdup(provider_internal->messageUri);
55         NS_VERIFY_NOT_NULL(msgUri, NS_ERROR);
56         char * syncUri = OICStrdup(provider_internal->syncUri);
57         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(syncUri, NS_ERROR, NSOICFree(msgUri));
58
59         OCConnectivityType type = CT_DEFAULT;
60         if (connections->addr->adapter == OC_ADAPTER_TCP)
61         {
62             type = CT_ADAPTER_TCP;
63             if (connections->isCloudConnection == true)
64             {
65                 msgUri = NSGetCloudUri(provider_internal->providerId, msgUri);
66                 NS_VERIFY_NOT_NULL(msgUri, NS_ERROR);
67                 syncUri = NSGetCloudUri(provider_internal->providerId, syncUri);
68                 NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(syncUri, NS_ERROR, NSOICFree(msgUri));
69             }
70         }
71
72         NS_LOG_V(DEBUG, "subscribe to %s:%d", connections->addr->addr, connections->addr->port);
73
74         NS_LOG(DEBUG, "get subscribe message query");
75         char * query = NULL;
76         query = NSMakeRequestUriWithConsumerId(msgUri);
77         NS_VERIFY_NOT_NULL(query, NS_ERROR);
78
79         NS_LOG(DEBUG, "subscribe message");
80         NS_LOG_V(DEBUG, "subscribe query : %s", query);
81         OCStackResult ret = NSInvokeRequest(&(connections->messageHandle),
82                               OC_REST_OBSERVE, connections->addr, query, NULL,
83                               NSConsumerMessageListener, NULL, type);
84         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(
85                 NSOCResultToSuccess(ret), NS_ERROR, NSOICFree(query));
86         NSOICFree(query);
87         NSOICFree(msgUri);
88
89         NS_LOG(DEBUG, "get subscribe sync query");
90         query = NSMakeRequestUriWithConsumerId(syncUri);
91         NS_VERIFY_NOT_NULL(query, NS_ERROR);
92
93         NS_LOG(DEBUG, "subscribe sync");
94         NS_LOG_V(DEBUG, "subscribe query : %s", query);
95         ret = NSInvokeRequest(&(connections->syncHandle),
96                               OC_REST_OBSERVE, connections->addr, query, NULL,
97                               NSConsumerSyncInfoListener, NULL, type);
98         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(
99                 NSOCResultToSuccess(ret), NS_ERROR, NSOICFree(query));
100         NSOICFree(query);
101         NSOICFree(syncUri);
102
103         connections->isSubscribing = true;
104
105         connections = connections->next;
106     }
107
108     return NS_OK;
109 }
110
111 OCStackApplicationResult NSConsumerCheckPostResult(
112         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
113 {
114     (void) ctx;
115     (void) handle;
116
117     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
118     NS_VERIFY_STACK_SUCCESS(
119             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
120
121     return OC_STACK_KEEP_TRANSACTION;
122 }
123
124 void NSRemoveSyncInfoObj(NSSyncInfo * sync)
125 {
126     NSOICFree(sync);
127 }
128
129 OCStackApplicationResult NSConsumerSyncInfoListener(
130         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
131 {
132     (void) ctx;
133     (void) handle;
134
135     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
136     NS_VERIFY_STACK_SUCCESS(
137             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
138
139     NS_LOG(DEBUG, "get NSSyncInfo");
140     NSSyncInfo * newSync = NSGetSyncInfoc(clientResponse);
141     NS_VERIFY_NOT_NULL(newSync, OC_STACK_KEEP_TRANSACTION);
142
143     NSTaskType taskType = TASK_RECV_SYNCINFO;
144
145     NS_LOG(DEBUG, "build NSTask");
146     NSTask * task = NSMakeTask(taskType, (void *) newSync);
147     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task,
148                OC_STACK_KEEP_TRANSACTION, NSRemoveSyncInfoObj(newSync));
149
150     NSConsumerPushEvent(task);
151
152     return OC_STACK_KEEP_TRANSACTION;
153 }
154
155 OCStackApplicationResult NSConsumerMessageListener(
156         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
157 {
158     (void) ctx;
159     (void) handle;
160
161     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
162     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
163
164     NS_LOG(DEBUG, "build NSMessage");
165     NSMessage * newNoti = NSGetMessage(clientResponse);
166     NS_VERIFY_NOT_NULL(newNoti, OC_STACK_KEEP_TRANSACTION);
167
168     NSTaskType type = TASK_CONSUMER_RECV_MESSAGE;
169
170     if (newNoti->messageId == NS_MESSAGE_ACCEPTANCE)
171     {
172         NS_LOG(DEBUG, "Receive Subscribe confirm");
173         type = TASK_CONSUMER_RECV_SUBSCRIBE_CONFIRMED;
174     }
175     else
176     {
177         NS_LOG(DEBUG, "Receive new message");
178     }
179
180     NS_LOG(DEBUG, "build NSTask");
181     NSTask * task = NSMakeTask(type, (void *) newNoti);
182     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveMessage(newNoti));
183
184     NSConsumerPushEvent(task);
185
186     return OC_STACK_KEEP_TRANSACTION;
187 }
188
189 void NSGetMessagePostClean(char * pId, OCDevAddr * addr)
190 {
191     NSOICFree(pId);
192     NSOICFree(addr);
193 }
194
195 NSMessage * NSGetMessage(OCClientResponse * clientResponse)
196 {
197     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
198     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
199
200     NS_LOG(DEBUG, "get msg id");
201     uint64_t id = NULL;
202     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
203     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
204
205     NS_LOG(DEBUG, "get provider id");
206     char * pId = NULL;
207     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
208     NS_LOG_V (DEBUG, "provider id: %s", pId);
209     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
210
211     NS_LOG(DEBUG, "create NSMessage");
212     NSMessage * retMsg = NSCreateMessage_internal(id, pId);
213     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(retMsg, NULL, NSOICFree(pId));
214     NSOICFree(pId);
215
216     NS_LOG(DEBUG, "get msg optional field");
217     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TITLE, &retMsg->title);
218     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TEXT, &retMsg->contentText);
219     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SOURCE, &retMsg->sourceName);
220
221     OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TYPE, (int64_t *)&retMsg->type);
222     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_DATETIME, &retMsg->dateTime);
223     OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TTL, (int64_t *)&retMsg->ttl);
224
225     NS_LOG_V(DEBUG, "Msg ID      : %lld", (long long int)retMsg->messageId);
226     NS_LOG_V(DEBUG, "Msg Title   : %s", retMsg->title);
227     NS_LOG_V(DEBUG, "Msg Content : %s", retMsg->contentText);
228     NS_LOG_V(DEBUG, "Msg Source  : %s", retMsg->sourceName);
229     NS_LOG_V(DEBUG, "Msg Type    : %d", retMsg->type);
230     NS_LOG_V(DEBUG, "Msg Date    : %s", retMsg->dateTime);
231     NS_LOG_V(DEBUG, "Msg ttl     : %lld", (long long int)retMsg->ttl);
232
233     return retMsg;
234 }
235
236 NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse)
237 {
238     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
239
240     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
241
242     NS_LOG(DEBUG, "get msg id");
243     uint64_t id = NULL;
244     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
245     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
246
247     NS_LOG(DEBUG, "get provider id");
248     char * pId = NULL;
249     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
250     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
251
252     NS_LOG(DEBUG, "get state");
253     int64_t state = 0;
254     getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_STATE, & state);
255     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
256
257     NS_LOG(DEBUG, "create NSSyncInfo");
258     NSSyncInfo * retSync = NSCreateSyncInfo_consumer(id, pId, (NSSyncType)state);
259     NS_VERIFY_NOT_NULL(retSync, NULL);
260
261     NS_LOG_V(DEBUG, "Sync ID : %lld", (long long int)retSync->messageId);
262     NS_LOG_V(DEBUG, "Sync State : %d", (int) retSync->state);
263     NS_LOG_V(DEBUG, "Sync Provider ID : %s", retSync->providerId);
264
265     return retSync;
266 }
267
268 NSMessage * NSCreateMessage_internal(uint64_t id, const char * providerId)
269 {
270     NSMessage * retMsg = (NSMessage *)OICMalloc(sizeof(NSMessage));
271     NS_VERIFY_NOT_NULL(retMsg, NULL);
272
273     retMsg->messageId = id;
274     OICStrcpy(retMsg->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
275     retMsg->title = NULL;
276     retMsg->contentText = NULL;
277     retMsg->sourceName = NULL;
278     retMsg->type = NS_MESSAGE_INFO;
279     retMsg->dateTime = NULL;
280     retMsg->ttl = 0;
281     retMsg->mediaContents = NULL;
282
283     return retMsg;
284 }
285
286 NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state)
287 {
288     NS_VERIFY_NOT_NULL(providerId, NULL);
289
290     NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
291     NS_VERIFY_NOT_NULL(retSync, NULL);
292
293     retSync->messageId = msgId;
294     retSync->state = state;
295     OICStrcpy(retSync->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
296
297     return retSync;
298 }
299
300 OCStackResult NSSendSyncInfo(NSSyncInfo * syncInfo, OCDevAddr * addr)
301 {
302     NS_VERIFY_NOT_NULL(syncInfo, OC_STACK_ERROR);
303     NS_VERIFY_NOT_NULL(addr, OC_STACK_ERROR);
304
305     OCRepPayload * payload = OCRepPayloadCreate();
306     NS_VERIFY_NOT_NULL(payload, OC_STACK_ERROR);
307
308     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t)syncInfo->messageId);
309     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_STATE, syncInfo->state);
310     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, syncInfo->providerId);
311
312     char * uri = (char*)OICStrdup(NS_SYNC_URI);
313     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(uri, OC_STACK_ERROR, OCRepPayloadDestroy(payload));
314
315     OCConnectivityType type = CT_DEFAULT;
316     if(addr->adapter == OC_ADAPTER_TCP)
317     {
318         type = CT_ADAPTER_TCP;
319         uri = NSGetCloudUri(syncInfo->providerId, uri);
320         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(uri, OC_STACK_ERROR, OCRepPayloadDestroy(payload));
321     }
322
323     OCStackResult ret = NSInvokeRequest(NULL, OC_REST_POST, addr,
324                             uri, (OCPayload*)payload,
325                             NSConsumerCheckPostResult, NULL, type);
326     NSOICFree(uri);
327
328     return ret;
329 }
330
331 char * NSGetCloudUri(const char * providerId, char * uri)
332 {
333     size_t uriLen = NS_DEVICE_ID_LENGTH + 1 + strlen(uri) + 1;
334     char * retUri = (char *)OICMalloc(uriLen);
335     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(retUri, NULL, NSOICFree(uri));
336
337     snprintf(retUri, uriLen, "/%s%s", providerId, uri);
338     NSOICFree(uri);
339     NS_LOG_V(DEBUG, "Cloud uri : %s", retUri);
340
341     return retUri;
342 }
343
344 void NSConsumerCommunicationTaskProcessing(NSTask * task)
345 {
346     NS_VERIFY_NOT_NULL_V(task);
347
348     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
349     if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE)
350     {
351         NS_VERIFY_NOT_NULL_V(task->taskData);
352         NS_LOG(DEBUG, "Request Subscribe");
353         NSResult ret = NSConsumerSubscribeProvider((NSProvider *)task->taskData);
354         NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
355     }
356     else if (task->taskType == TASK_SEND_SYNCINFO)
357     {
358         NS_VERIFY_NOT_NULL_V(task->taskData);
359         NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)task->taskData;
360         NSProviderConnectionInfo * info = syncInfo->connection;
361
362         while(info)
363         {
364             OCStackResult ret = NSSendSyncInfo((NSSyncInfo *)(task->taskData), info->addr);
365             if (ret != OC_STACK_OK)
366             {
367                 NS_LOG_V(ERROR, "send sync info fail : %d", info->addr->adapter);
368             }
369
370             info = info->next;
371         }
372
373         NSRemoveConnections(syncInfo->connection);
374         NSOICFree(syncInfo);
375     }
376     else if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL)
377     {
378         NSProvider_internal * provider = (NSProvider_internal *)task->taskData;
379
380         NSProviderConnectionInfo * connections = provider->connection;
381         while(connections)
382         {
383             if (connections->isSubscribing == false)
384             {
385                 NS_LOG_V(DEBUG, "unsubscribed to %s:%d",
386                      connections->addr->addr, connections->addr->port);
387                 connections = connections->next;
388                 continue;
389             }
390             NS_LOG_V(DEBUG, "cancel subscribe to %s:%d",
391                      connections->addr->addr, connections->addr->port);
392             OCCancel(connections->messageHandle, NS_QOS, NULL, 0);
393             OCCancel(connections->syncHandle, NS_QOS, NULL, 0);
394             connections->messageHandle = NULL;
395             connections->syncHandle = NULL;
396             connections->isSubscribing = false;
397             connections = connections->next;
398         }
399     }
400     else
401     {
402         NS_LOG(ERROR, "Unknown type message");
403     }
404     NSOICFree(task);
405 }