Merge remote-tracking branch 'origin/notification-service'
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerCommon.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 "NSConsumerCommon.h"
22 #include "NSConstants.h"
23 #include "NSThread.h"
24 #include "oic_malloc.h"
25 #include "oic_string.h"
26
27 #include <pthread.h>
28
29 #define NS_QUERY_CONSUMER_ID "consumerid"
30
31 pthread_mutex_t ** NSGetStackMutex()
32 {
33     static pthread_mutex_t * g_stackMutext = NULL;
34     if (g_stackMutext == NULL)
35     {
36         g_stackMutext = (pthread_mutex_t *)OICMalloc(sizeof(pthread_mutex_t));
37         NS_VERIFY_NOT_NULL(g_stackMutext, NULL);
38         pthread_mutex_init(g_stackMutext, NULL);
39     }
40
41     return & g_stackMutext;
42 }
43
44 char ** NSGetConsumerId()
45 {
46     static char * g_consumerId = NULL;
47     return & g_consumerId;
48 }
49
50 void NSSetConsumerId(char * cId)
51 {
52     NS_VERIFY_NOT_NULL_V(cId);
53     char ** consumerId = NSGetConsumerId();
54     NSOICFree(*consumerId);
55     *consumerId = (char *)OICMalloc(sizeof(char) * NS_DEVICE_ID_LENGTH);
56     NS_VERIFY_NOT_NULL_V(*consumerId);
57
58     OICStrcpy(*consumerId, sizeof(char) * NS_DEVICE_ID_LENGTH, cId);
59 }
60
61 char * NSMakeRequestUriWithConsumerId(const char * uri)
62 {
63     NS_VERIFY_NOT_NULL(uri, NULL);
64
65     char * consumerId = OICStrdup(*NSGetConsumerId());
66     NS_VERIFY_NOT_NULL(consumerId, NULL);
67
68     size_t uriLen = strlen(uri) + 1;
69     size_t qKeyLen = sizeof(NS_QUERY_CONSUMER_ID);
70     size_t queryLen = NS_DEVICE_ID_LENGTH + uriLen + qKeyLen + 2;
71
72     char * retQuery = (char *)OICMalloc(sizeof(char) * queryLen);
73     NS_VERIFY_NOT_NULL(retQuery, NULL);
74
75     size_t index = 0;
76     OICStrcpy((retQuery + index), uriLen, uri);
77     index += uriLen - 1;
78     OICStrcpy((retQuery + index), 2, "?");
79     index += 1;
80     OICStrcpy((retQuery + index), qKeyLen, NS_QUERY_CONSUMER_ID);
81     index += qKeyLen - 1;
82     OICStrcpy((retQuery + index), 2, "=");
83     index += 1;
84     OICStrcpy((retQuery + index), NS_DEVICE_ID_LENGTH, consumerId);
85
86     NSOICFree(consumerId);
87
88     return retQuery;
89 }
90
91 bool * NSGetBoneIsStartedConsumer()
92 {
93     static bool g_isStartedConsumer = false;
94
95     return & g_isStartedConsumer;
96 }
97
98 void NSSetIsStartedConsumer(bool setValue)
99 {
100     * NSGetBoneIsStartedConsumer() = setValue;
101 }
102
103 bool NSIsStartedConsumer()
104 {
105     return * NSGetBoneIsStartedConsumer();
106 }
107
108 NSProviderDiscoveredCallback * NSGetBoneDiscoverCb()
109 {
110     static NSProviderDiscoveredCallback g_discoverCb = NULL;
111
112     return & g_discoverCb;
113 }
114
115 void NSSetDiscoverProviderCb(NSProviderDiscoveredCallback cb)
116 {
117     * NSGetBoneDiscoverCb() = cb;
118 }
119
120 NSProviderDiscoveredCallback NSGetDiscoverCb()
121 {
122     return * NSGetBoneDiscoverCb();
123 }
124
125 void * NSDiscoveredProviderFunc(void * provider)
126 {
127     NSGetDiscoverCb()((NSProvider *) provider);
128
129     return NULL;
130 }
131
132 void NSDiscoveredProvider(NSProvider * provider)
133 {
134     NS_VERIFY_NOT_NULL_V(provider);
135
136     NSConsumerThread * thread = NSThreadInit(NSDiscoveredProviderFunc, (void *) provider);
137     NS_VERIFY_NOT_NULL_V(thread);
138 }
139
140 NSProviderChangedCallback * NSGetProviderChangedCb()
141 {
142     static NSProviderChangedCallback g_changedCb = NULL;
143
144     return & g_changedCb;
145 }
146
147 void NSSetProviderChangedCb(NSProviderChangedCallback cb)
148 {
149     *(NSGetProviderChangedCb()) = cb;
150 }
151
152 void NSProviderChanged(NSProvider * provider, NSResponse response)
153 {
154     (*(NSGetProviderChangedCb()))(provider, response);
155 }
156
157 NSSyncInfoReceivedCallback * NSGetBoneNotificationSyncCb()
158 {
159     static NSSyncInfoReceivedCallback g_syncCb = NULL;
160
161     return & g_syncCb;
162 }
163
164 void NSSetNotificationSyncCb(NSSyncInfoReceivedCallback cb)
165 {
166     * NSGetBoneNotificationSyncCb() = cb;
167 }
168
169 void * NSNotificationSyncFunc(void * obj)
170 {
171     (* NSGetBoneNotificationSyncCb())((NSSyncInfo *) obj);
172     return NULL;
173 }
174
175 void NSNotificationSync(NSSyncInfo * sync)
176 {
177     NS_VERIFY_NOT_NULL_V(sync);
178
179     NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
180     NS_VERIFY_NOT_NULL_V(retSync);
181     memcpy(retSync, sync, sizeof(NSSyncInfo));
182
183     NSConsumerThread * thread = NSThreadInit(NSNotificationSyncFunc, (void *) retSync);
184     NS_VERIFY_NOT_NULL_V(thread);
185 }
186
187 NSMessageReceivedCallback  * NSGetBoneMessagePostedCb()
188 {
189     static NSMessageReceivedCallback  g_postCb = NULL;
190
191     return & g_postCb;
192 }
193
194 void NSSetMessagePostedCb(NSMessageReceivedCallback  cb)
195 {
196     * NSGetBoneMessagePostedCb() = cb;
197 }
198
199 NSMessageReceivedCallback  NSGetMessagePostedCb()
200 {
201     return * NSGetBoneMessagePostedCb();
202 }
203
204 void * NSMessagePostFunc(void * obj)
205 {
206     NSGetMessagePostedCb()((NSMessage *) obj);
207     return NULL;
208 }
209
210 void NSMessagePost(NSMessage * msg)
211 {
212     NS_VERIFY_NOT_NULL_V(msg);
213
214     NSMessage * retMsg = NSCopyMessage(msg);
215     NS_VERIFY_NOT_NULL_V(retMsg);
216
217     NSConsumerThread * thread = NSThreadInit(NSMessagePostFunc, (void *) retMsg);
218     NS_VERIFY_NOT_NULL_V(thread);
219 }
220
221 NSTask * NSMakeTask(NSTaskType type, void * data)
222 {
223     NSTask * retTask = OICMalloc(sizeof(NSTask));
224     NS_VERIFY_NOT_NULL(retTask, NULL);
225
226     retTask->taskType = type;
227     retTask->taskData = data;
228     retTask->nextTask = NULL;
229
230     return retTask;
231 }
232
233 NSMessage * NSCopyMessage(NSMessage * msg)
234 {
235     NS_VERIFY_NOT_NULL(msg, NULL);
236
237     NSMessage * newMsg = (NSMessage *)OICMalloc(sizeof(NSMessage));
238     NS_VERIFY_NOT_NULL(newMsg, NULL);
239
240     OICStrcpy(newMsg->providerId, NS_DEVICE_ID_LENGTH, msg->providerId);
241
242     newMsg->messageId = msg->messageId;
243     newMsg->title = OICStrdup(msg->title);
244     newMsg->contentText = OICStrdup(msg->contentText);
245     newMsg->sourceName = OICStrdup(msg->sourceName);
246     newMsg->dateTime = OICStrdup(msg->dateTime);
247     newMsg->type = msg->type;
248     newMsg->topic = NULL;
249     if (msg->topic && strlen(msg->topic) > 0)
250     {
251         newMsg->topic = OICStrdup(msg->topic);
252     }
253
254     // TODO change to copy function.
255     newMsg->mediaContents = msg->mediaContents;
256
257     return newMsg;
258 }
259 void NSRemoveMessage(NSMessage * msg)
260 {
261     NS_VERIFY_NOT_NULL_V(msg);
262
263     msg->messageId = 0;
264     NSOICFree(msg->title);
265     NSOICFree(msg->contentText);
266     NSOICFree(msg->sourceName);
267     NSOICFree(msg->dateTime);
268     NSOICFree(msg->topic);
269
270     // TODO change to remove function.
271     NSOICFree(msg->mediaContents);
272
273     NSOICFree(msg);
274 }
275
276 void NSRemoveConnections(NSProviderConnectionInfo * connections)
277 {
278     NS_VERIFY_NOT_NULL_V(connections);
279
280     NSProviderConnectionInfo * tmp = connections;
281
282     while(tmp)
283     {
284         tmp->messageHandle = NULL;
285         tmp->syncHandle = NULL;
286         NSOICFree(tmp->addr);
287         tmp = tmp->next;
288     }
289
290     NSOICFree(connections);
291 }
292
293 NSProviderConnectionInfo * NSCreateProviderConnections(OCDevAddr * inAddr)
294 {
295     NSProviderConnectionInfo * connections
296         = (NSProviderConnectionInfo *)OICMalloc(sizeof(NSProviderConnectionInfo));
297     NS_VERIFY_NOT_NULL(connections, NULL);
298
299     connections->addr = NULL;
300     connections->messageHandle = NULL;
301     connections->syncHandle = NULL;
302     connections->isCloudConnection = false;
303     connections->isSubscribing = false;
304     connections->next = NULL;
305
306     if (inAddr)
307     {
308         connections->addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
309         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(connections->addr, NULL, NSRemoveConnections(connections));
310         memcpy(connections->addr, inAddr, sizeof(OCDevAddr));
311     }
312
313     return connections;
314 }
315
316 NSProviderConnectionInfo * NSCopyProviderConnections(NSProviderConnectionInfo * conn)
317 {
318     NS_VERIFY_NOT_NULL(conn, NULL);
319     NSProviderConnectionInfo * tmp = conn;
320
321     NSProviderConnectionInfo * retInfo = NSCreateProviderConnections(tmp->addr);
322     NS_VERIFY_NOT_NULL(retInfo, NULL);
323     retInfo->messageHandle = tmp->messageHandle;
324     retInfo->syncHandle = tmp->syncHandle;
325     retInfo->isCloudConnection = tmp->isCloudConnection;
326     retInfo->isSubscribing = tmp->isSubscribing;
327
328     tmp = tmp->next;
329     NSProviderConnectionInfo * copyInfo = retInfo;
330
331     while(tmp)
332     {
333         NSProviderConnectionInfo * tmpInfo = NSCreateProviderConnections(tmp->addr);
334         NS_VERIFY_NOT_NULL(tmpInfo, NULL);
335
336         tmpInfo->messageHandle = tmp->messageHandle;
337         tmpInfo->syncHandle = tmp->syncHandle;
338         tmpInfo->isCloudConnection = tmp->isCloudConnection;
339         tmpInfo->isSubscribing = tmp->isSubscribing;
340         tmp = tmp->next;
341         copyInfo->next = tmpInfo;
342         copyInfo = tmpInfo;
343     }
344
345     return retInfo;
346 }
347
348 void NSRemoveTopicNode(NSTopicLL * topicNode)
349 {
350     NS_VERIFY_NOT_NULL_V(topicNode);
351
352     NSOICFree(topicNode->topicName);
353     topicNode->next = NULL;
354
355     NSOICFree(topicNode);
356 }
357
358 NSTopicLL * NSCopyTopicNode(NSTopicLL * topicNode)
359 {
360     NS_VERIFY_NOT_NULL(topicNode, NULL);
361
362     NSTopicLL * newTopicNode = (NSTopicLL *)OICMalloc(sizeof(NSTopicLL));
363     NS_VERIFY_NOT_NULL(newTopicNode, NULL);
364
365     newTopicNode->topicName = OICStrdup(topicNode->topicName);
366     newTopicNode->state = topicNode->state;
367     newTopicNode->next = NULL;
368
369     return newTopicNode;
370 }
371
372 NSResult NSInsertTopicNode(NSTopicLL * topicHead, NSTopicLL * topicNode)
373 {
374     NS_VERIFY_NOT_NULL(topicHead, NS_ERROR);
375     NS_VERIFY_NOT_NULL(topicNode, NS_ERROR);
376
377     NSTopicLL * iter = topicHead;
378     NSTopicLL * prev = NULL;
379
380     while (iter)
381     {
382         prev = iter;
383         iter = (NSTopicLL *) iter->next;
384     }
385
386     prev->next = topicNode;
387     topicNode->next = NULL;
388
389     return NS_OK;
390 }
391
392 void NSRemoveTopicLL(NSTopicLL * topicHead)
393 {
394     NS_VERIFY_NOT_NULL_V(topicHead);
395
396     NSTopicLL * iter = topicHead;
397     NSTopicLL * following = NULL;
398
399     while (iter)
400     {
401         following = (NSTopicLL *) iter->next;
402
403         NSRemoveTopicNode(iter);
404
405         iter = following;
406     }
407 }
408
409 NSTopicLL * NSCopyTopicLL(NSTopicLL * topicHead)
410 {
411     NS_VERIFY_NOT_NULL(topicHead, NULL);
412
413     NSTopicLL * iter = topicHead;
414
415     NS_LOG_V(DEBUG, "[NSCopyTopicLL] Name:%s\t State:%d", iter->topicName, iter->state);
416     NSTopicLL * newTopicHead = NSCopyTopicNode(iter);
417     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicHead, NULL, NSRemoveTopicLL(newTopicHead));
418
419     iter = (NSTopicLL *) iter->next;
420
421     while (iter)
422     {
423         NS_LOG_V(DEBUG, "[NSCopyTopicLL] Name:%s\t State:%d", iter->topicName, iter->state);
424         NSTopicLL * newTopicNode = NSCopyTopicNode(iter);
425         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicNode, NULL, NSRemoveTopicLL(newTopicHead));
426
427         NSResult ret = NSInsertTopicNode(newTopicHead, newTopicNode);
428         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(ret, NULL, NSRemoveTopicLL(newTopicHead));
429
430         iter = (NSTopicLL *) iter->next;
431     }
432
433     return newTopicHead;
434 }
435
436 void NSCopyProviderPostClean(
437         NSProviderConnectionInfo * connections, NSProvider_internal * provider)
438 {
439     NSRemoveConnections(connections);
440     NSOICFree(provider);
441 }
442
443 NSProvider_internal * NSCopyProvider_internal(NSProvider_internal * prov)
444 {
445     NS_VERIFY_NOT_NULL(prov, NULL);
446
447     NSProviderConnectionInfo * connections = NSCopyProviderConnections(prov->connection);
448     NS_VERIFY_NOT_NULL(connections, NULL);
449
450     NSProvider_internal * newProv = (NSProvider_internal *) OICMalloc(sizeof(NSProvider_internal));
451     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProv, NULL, NSRemoveConnections(connections));
452
453     newProv->topicLL = NULL;
454
455     if (prov->topicLL)
456     {
457         NSTopicLL * newTopicLL = NSCopyTopicLL(prov->topicLL);
458         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicLL, NULL,
459                     NSCopyProviderPostClean(connections, newProv));
460
461         newProv->topicLL = newTopicLL;
462     }
463
464     newProv->connection = connections;
465     OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
466     newProv->messageUri = OICStrdup(prov->messageUri);
467     newProv->syncUri = OICStrdup(prov->syncUri);
468     newProv->topicUri = OICStrdup(prov->topicUri);
469     newProv->accessPolicy = prov->accessPolicy;
470
471     return newProv;
472 }
473
474 NSProvider * NSCopyProvider(NSProvider_internal * prov)
475 {
476     NS_VERIFY_NOT_NULL(prov, NULL);
477
478     NSProvider * newProv = (NSProvider *) OICMalloc(sizeof(NSProvider));
479     NS_VERIFY_NOT_NULL(newProv, NULL);
480
481     newProv->topicLL = NULL;
482
483     if (prov->topicLL)
484     {
485         NSTopicLL * topicList = NSCopyTopicLL(prov->topicLL);
486         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(topicList, NULL, NSRemoveProvider(newProv));
487
488         newProv->topicLL = topicList;
489     }
490
491     OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
492
493     return newProv;
494 }
495
496 void NSRemoveProvider_internal(NSProvider_internal * prov)
497 {
498     NS_VERIFY_NOT_NULL_V(prov);
499
500     NSOICFree(prov->messageUri);
501     NSOICFree(prov->syncUri);
502     NSOICFree(prov->topicUri);
503     NSRemoveConnections(prov->connection);
504     if (prov->topicLL)
505     {
506         NSRemoveTopicLL(prov->topicLL);
507     }
508
509     NSOICFree(prov);
510 }
511
512 void NSRemoveProvider(NSProvider * prov)
513 {
514     NS_VERIFY_NOT_NULL_V(prov);
515
516     if (prov->topicLL)
517     {
518         NSRemoveTopicLL(prov->topicLL);
519     }
520
521     NSOICFree(prov);
522 }
523
524 NSSyncInfo_internal * NSCopySyncInfo(NSSyncInfo_internal * syncInfo)
525 {
526     NS_VERIFY_NOT_NULL(syncInfo, NULL);
527
528     NSProviderConnectionInfo * connections = NSCopyProviderConnections(syncInfo->connection);
529     NS_VERIFY_NOT_NULL(connections, NULL);
530
531     NSSyncInfo_internal * newSyncInfo = (NSSyncInfo_internal *)OICMalloc(sizeof(NSSyncInfo_internal));
532     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newSyncInfo, NULL, NSRemoveConnections(connections));
533
534     OICStrcpy(newSyncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, syncInfo->providerId);
535     newSyncInfo->messageId = syncInfo->messageId;
536     newSyncInfo->state = syncInfo->state;
537     newSyncInfo->connection = connections;
538
539     return newSyncInfo;
540 }
541
542 void NSRemoveSyncInfo(NSSyncInfo_internal * syncInfo)
543 {
544     NS_VERIFY_NOT_NULL_V(syncInfo);
545
546     NSRemoveConnections(syncInfo->connection);
547
548     NSOICFree(syncInfo);
549 }
550
551 OCStackResult NSInvokeRequest(OCDoHandle * handle,
552         OCMethod method, const OCDevAddr * addr,
553         const char * queryUrl, OCPayload * payload,
554         void * callbackFunc, void * callbackData, OCConnectivityType type)
555 {
556     int mutexRet = pthread_mutex_lock(*(NSGetStackMutex()));
557     NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
558
559     OCCallbackData cbdata = { 0, };
560
561     cbdata.cb = callbackFunc;
562     cbdata.context = callbackData;
563     cbdata.cd = NULL;
564
565     OCStackResult ret = OCDoResource(handle, method, queryUrl, addr,
566                                      payload, type, NS_QOS, &cbdata, NULL, 0);
567
568     mutexRet = pthread_mutex_unlock(*(NSGetStackMutex()));
569     NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
570
571     return ret;
572 }
573
574 bool NSOCResultToSuccess(OCStackResult ret)
575 {
576     switch (ret)
577     {
578         case OC_STACK_OK:
579         case OC_STACK_RESOURCE_CREATED:
580         case OC_STACK_RESOURCE_DELETED:
581         case OC_STACK_PRESENCE_STOPPED:
582         case OC_STACK_CONTINUE:
583         case OC_STACK_RESOURCE_CHANGED:
584             return true;
585         default:
586             NS_LOG_V(DEBUG, "OCStackResult : %d", (int)ret);
587             return false;
588     }
589 }