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