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