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