d00895a66db778055a1bc03d18618caac97e4757
[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     if (setValue == false)
103     {
104         pthread_mutex_destroy(*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_V(thread);
159
160     NSDestroyThreadHandle(thread);
161 }
162
163 NSSyncInfoReceivedCallback * NSGetBoneNotificationSyncCb()
164 {
165     static NSSyncInfoReceivedCallback g_syncCb = NULL;
166
167     return & g_syncCb;
168 }
169
170 void NSSetNotificationSyncCb(NSSyncInfoReceivedCallback cb)
171 {
172     * NSGetBoneNotificationSyncCb() = cb;
173 }
174
175 void * NSNotificationSyncFunc(void * obj)
176 {
177     (* NSGetBoneNotificationSyncCb())((NSSyncInfo *) obj);
178     return NULL;
179 }
180
181 void NSNotificationSync(NSSyncInfo * sync)
182 {
183     NS_VERIFY_NOT_NULL_V(sync);
184
185     NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
186     NS_VERIFY_NOT_NULL_V(retSync);
187     memcpy(retSync, sync, sizeof(NSSyncInfo));
188
189     NSConsumerThread * thread = NSThreadInit(NSNotificationSyncFunc, (void *) retSync);
190     NS_VERIFY_NOT_NULL_V(thread);
191
192     NSDestroyThreadHandle(thread);
193 }
194
195 NSMessageReceivedCallback  * NSGetBoneMessagePostedCb()
196 {
197     static NSMessageReceivedCallback  g_postCb = NULL;
198
199     return & g_postCb;
200 }
201
202 void NSSetMessagePostedCb(NSMessageReceivedCallback  cb)
203 {
204     * NSGetBoneMessagePostedCb() = cb;
205 }
206
207 NSMessageReceivedCallback  NSGetMessagePostedCb()
208 {
209     return * NSGetBoneMessagePostedCb();
210 }
211
212 void * NSMessagePostFunc(void * obj)
213 {
214     NSGetMessagePostedCb()((NSMessage *) obj);
215     return NULL;
216 }
217
218 void NSMessagePost(NSMessage * msg)
219 {
220     NS_VERIFY_NOT_NULL_V(msg);
221
222     NSMessage * retMsg = NSCopyMessage(msg);
223     NS_VERIFY_NOT_NULL_V(retMsg);
224
225     NSConsumerThread * thread = NSThreadInit(NSMessagePostFunc, (void *) retMsg);
226     NS_VERIFY_NOT_NULL_V(thread);
227
228     NSDestroyThreadHandle(thread);
229 }
230
231 NSTask * NSMakeTask(NSTaskType type, void * data)
232 {
233     NSTask * retTask = OICMalloc(sizeof(NSTask));
234     NS_VERIFY_NOT_NULL(retTask, NULL);
235
236     retTask->taskType = type;
237     retTask->taskData = data;
238     retTask->nextTask = NULL;
239
240     return retTask;
241 }
242
243 NSMessage * NSCopyMessage(NSMessage * msg)
244 {
245     NS_VERIFY_NOT_NULL(msg, NULL);
246
247     NSMessage * newMsg = (NSMessage *)OICMalloc(sizeof(NSMessage));
248     NS_VERIFY_NOT_NULL(newMsg, NULL);
249
250     OICStrcpy(newMsg->providerId, NS_DEVICE_ID_LENGTH, msg->providerId);
251
252     newMsg->messageId = msg->messageId;
253     newMsg->title = OICStrdup(msg->title);
254     newMsg->contentText = OICStrdup(msg->contentText);
255     newMsg->sourceName = OICStrdup(msg->sourceName);
256     newMsg->dateTime = OICStrdup(msg->dateTime);
257     newMsg->type = msg->type;
258     newMsg->topic = NULL;
259     if (msg->topic && strlen(msg->topic) > 0)
260     {
261         newMsg->topic = OICStrdup(msg->topic);
262     }
263     if (msg->mediaContents)
264     {
265         newMsg->mediaContents = (NSMediaContents *)OICMalloc(sizeof(NSMediaContents));
266         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(
267                 newMsg->mediaContents, NULL, NSRemoveMessage(newMsg));
268         newMsg->mediaContents->iconImage =
269                 (char *)OICMalloc(sizeof(char)*strlen(msg->mediaContents->iconImage));
270         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(
271                 newMsg->mediaContents->iconImage, NULL, NSRemoveMessage(newMsg));
272         memcpy(newMsg->mediaContents->iconImage, msg->mediaContents->iconImage,
273                strlen(msg->mediaContents->iconImage));
274     }
275
276     return newMsg;
277 }
278 void NSRemoveMessage(NSMessage * msg)
279 {
280     NS_VERIFY_NOT_NULL_V(msg);
281
282     msg->messageId = 0;
283     NSOICFree(msg->title);
284     NSOICFree(msg->contentText);
285     NSOICFree(msg->sourceName);
286     NSOICFree(msg->dateTime);
287     NSOICFree(msg->topic);
288
289     if (msg->mediaContents)
290     {
291         NSOICFree(msg->mediaContents->iconImage);
292     }
293     NSOICFree(msg->mediaContents);
294
295     NSOICFree(msg);
296 }
297
298 void NSRemoveConnections(NSProviderConnectionInfo * connections)
299 {
300     NS_VERIFY_NOT_NULL_V(connections);
301
302     NSProviderConnectionInfo * tmp = connections;
303
304     while(tmp)
305     {
306         tmp->messageHandle = NULL;
307         tmp->syncHandle = NULL;
308         NSOICFree(tmp->addr);
309         tmp = tmp->next;
310     }
311
312     NSOICFree(connections);
313 }
314
315 NSProviderConnectionInfo * NSCreateProviderConnections(OCDevAddr * inAddr)
316 {
317     NSProviderConnectionInfo * connections
318         = (NSProviderConnectionInfo *)OICMalloc(sizeof(NSProviderConnectionInfo));
319     NS_VERIFY_NOT_NULL(connections, NULL);
320
321     connections->addr = NULL;
322     connections->messageHandle = NULL;
323     connections->syncHandle = NULL;
324     connections->isCloudConnection = false;
325     connections->isSubscribing = false;
326     connections->next = NULL;
327
328     if (inAddr)
329     {
330         connections->addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
331         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(connections->addr, NULL, NSRemoveConnections(connections));
332         memcpy(connections->addr, inAddr, sizeof(OCDevAddr));
333     }
334
335     return connections;
336 }
337
338 NSProviderConnectionInfo * NSCopyProviderConnections(NSProviderConnectionInfo * conn)
339 {
340     NS_VERIFY_NOT_NULL(conn, NULL);
341     NSProviderConnectionInfo * tmp = conn;
342
343     NSProviderConnectionInfo * retInfo = NSCreateProviderConnections(tmp->addr);
344     NS_VERIFY_NOT_NULL(retInfo, NULL);
345     retInfo->messageHandle = tmp->messageHandle;
346     retInfo->syncHandle = tmp->syncHandle;
347     retInfo->isCloudConnection = tmp->isCloudConnection;
348     retInfo->isSubscribing = tmp->isSubscribing;
349
350     tmp = tmp->next;
351     NSProviderConnectionInfo * copyInfo = retInfo;
352
353     while(tmp)
354     {
355         NSProviderConnectionInfo * tmpInfo = NSCreateProviderConnections(tmp->addr);
356         NS_VERIFY_NOT_NULL(tmpInfo, NULL);
357
358         tmpInfo->messageHandle = tmp->messageHandle;
359         tmpInfo->syncHandle = tmp->syncHandle;
360         tmpInfo->isCloudConnection = tmp->isCloudConnection;
361         tmpInfo->isSubscribing = tmp->isSubscribing;
362         tmp = tmp->next;
363         copyInfo->next = tmpInfo;
364         copyInfo = tmpInfo;
365     }
366
367     return retInfo;
368 }
369
370 void NSRemoveTopicNode(NSTopicLL * topicNode)
371 {
372     NS_VERIFY_NOT_NULL_V(topicNode);
373
374     NSOICFree(topicNode->topicName);
375     topicNode->next = NULL;
376
377     NSOICFree(topicNode);
378 }
379
380 NSTopicLL * NSCopyTopicNode(NSTopicLL * topicNode)
381 {
382     NS_VERIFY_NOT_NULL(topicNode, NULL);
383
384     NSTopicLL * newTopicNode = (NSTopicLL *)OICMalloc(sizeof(NSTopicLL));
385     NS_VERIFY_NOT_NULL(newTopicNode, NULL);
386
387     newTopicNode->topicName = OICStrdup(topicNode->topicName);
388     newTopicNode->state = topicNode->state;
389     newTopicNode->next = NULL;
390
391     return newTopicNode;
392 }
393
394 NSResult NSInsertTopicNode(NSTopicLL * topicHead, NSTopicLL * topicNode)
395 {
396     NS_VERIFY_NOT_NULL(topicHead, NS_ERROR);
397     NS_VERIFY_NOT_NULL(topicNode, NS_ERROR);
398
399     NSTopicLL * iter = topicHead;
400     NSTopicLL * prev = NULL;
401
402     while (iter)
403     {
404         prev = iter;
405         iter = (NSTopicLL *) iter->next;
406     }
407
408     prev->next = topicNode;
409     topicNode->next = NULL;
410
411     return NS_OK;
412 }
413
414 void NSRemoveTopicLL(NSTopicLL * topicHead)
415 {
416     NS_VERIFY_NOT_NULL_V(topicHead);
417
418     NSTopicLL * iter = topicHead;
419     NSTopicLL * following = NULL;
420
421     while (iter)
422     {
423         following = iter->next;
424
425         NSRemoveTopicNode(iter);
426
427         iter = following;
428     }
429 }
430
431 NSTopicLL * NSCopyTopicLL(NSTopicLL * topicHead)
432 {
433     NS_VERIFY_NOT_NULL(topicHead, NULL);
434
435     NSTopicLL * iter = topicHead;
436
437     NS_LOG_V(DEBUG, "[NSCopyTopicLL] Name:%s\t State:%d", iter->topicName, iter->state);
438     NSTopicLL * newTopicHead = NSCopyTopicNode(iter);
439     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicHead, NULL, NSRemoveTopicLL(newTopicHead));
440
441     iter = (NSTopicLL *) iter->next;
442
443     while (iter)
444     {
445         NS_LOG_V(DEBUG, "[NSCopyTopicLL] Name:%s\t State:%d", iter->topicName, iter->state);
446         NSTopicLL * newTopicNode = NSCopyTopicNode(iter);
447         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicNode, NULL, NSRemoveTopicLL(newTopicHead));
448
449         NSResult ret = NSInsertTopicNode(newTopicHead, newTopicNode);
450         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == NS_OK ? (void *)1 : NULL,
451                                                     NULL, NSRemoveTopicLL(newTopicHead));
452
453         iter = (NSTopicLL *) iter->next;
454     }
455
456     return newTopicHead;
457 }
458
459 void NSCopyProviderPostClean(
460         NSProviderConnectionInfo * connections, NSProvider_internal * provider)
461 {
462     NSRemoveConnections(connections);
463     NSOICFree(provider);
464 }
465
466 NSProvider_internal * NSCopyProvider_internal(NSProvider_internal * prov)
467 {
468     NS_VERIFY_NOT_NULL(prov, NULL);
469
470     NSProviderConnectionInfo * connections = NSCopyProviderConnections(prov->connection);
471     NS_VERIFY_NOT_NULL(connections, NULL);
472
473     NSProvider_internal * newProv = (NSProvider_internal *) OICMalloc(sizeof(NSProvider_internal));
474     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProv, NULL, NSRemoveConnections(connections));
475
476     newProv->topicLL = NULL;
477
478     if (prov->topicLL)
479     {
480         NSTopicLL * newTopicLL = NSCopyTopicLL(prov->topicLL);
481         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicLL, NULL,
482                     NSCopyProviderPostClean(connections, newProv));
483
484         newProv->topicLL = newTopicLL;
485     }
486
487     newProv->connection = connections;
488     OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
489     newProv->messageUri = OICStrdup(prov->messageUri);
490     newProv->syncUri = OICStrdup(prov->syncUri);
491     newProv->topicUri = OICStrdup(prov->topicUri);
492     newProv->accessPolicy = prov->accessPolicy;
493     newProv->state = prov->state;
494
495     return newProv;
496 }
497
498 NSProvider * NSCopyProvider(NSProvider_internal * prov)
499 {
500     NS_VERIFY_NOT_NULL(prov, NULL);
501
502     NSProvider * newProv = (NSProvider *) OICMalloc(sizeof(NSProvider));
503     NS_VERIFY_NOT_NULL(newProv, NULL);
504
505     OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
506
507     return newProv;
508 }
509
510 void NSRemoveProvider_internal(NSProvider_internal * prov)
511 {
512     NS_VERIFY_NOT_NULL_V(prov);
513
514     NSOICFree(prov->messageUri);
515     NSOICFree(prov->syncUri);
516     NSOICFree(prov->topicUri);
517     NSRemoveConnections(prov->connection);
518     if (prov->topicLL)
519     {
520         NSRemoveTopicLL(prov->topicLL);
521     }
522
523     NSOICFree(prov);
524 }
525
526 void NSRemoveProvider(NSProvider * prov)
527 {
528     NS_VERIFY_NOT_NULL_V(prov);
529     NSOICFree(prov);
530 }
531
532 OCStackResult NSInvokeRequest(OCDoHandle * handle,
533         OCMethod method, const OCDevAddr * addr,
534         const char * queryUrl, OCPayload * payload,
535         void * callbackFunc, void * callbackData, OCConnectivityType type)
536 {
537     int mutexRet = pthread_mutex_lock(*(NSGetStackMutex()));
538     NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
539
540     OCCallbackData cbdata = { 0, };
541
542     cbdata.cb = callbackFunc;
543     cbdata.context = callbackData;
544     cbdata.cd = NULL;
545
546     OCStackResult ret = OCDoResource(handle, method, queryUrl, addr,
547                                      payload, type, NS_QOS, &cbdata, NULL, 0);
548
549     mutexRet = pthread_mutex_unlock(*(NSGetStackMutex()));
550     NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
551
552     return ret;
553 }
554
555 bool NSOCResultToSuccess(OCStackResult ret)
556 {
557     switch (ret)
558     {
559         case OC_STACK_OK:
560         case OC_STACK_RESOURCE_CREATED:
561         case OC_STACK_RESOURCE_DELETED:
562         case OC_STACK_PRESENCE_STOPPED:
563         case OC_STACK_CONTINUE:
564         case OC_STACK_RESOURCE_CHANGED:
565             return true;
566         default:
567             NS_LOG_V(DEBUG, "OCStackResult : %d", (int)ret);
568             return false;
569     }
570 }