Modify(Fix) Logic bugs in Notification consumer
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerCommon.c
1
2 //******************************************************************
3 //
4 // Copyright 2016 Samsung Electronics All Rights Reserved.
5 //
6 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 //
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 //
12 //      http://www.apache.org/licenses/LICENSE-2.0
13 //
14 // Unless required by applicable law or agreed to in writing, software
15 // distributed under the License is distributed on an "AS IS" BASIS,
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 // See the License for the specific language governing permissions and
18 // limitations under the License.
19 //
20 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21
22 #include "NSConsumerCommon.h"
23 #include "NSConstants.h"
24 #include "NSThread.h"
25 #include "oic_malloc.h"
26 #include "oic_string.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
104 bool NSIsStartedConsumer()
105 {
106     return * NSGetBoneIsStartedConsumer();
107 }
108
109 NSProviderDiscoveredCallback * NSGetBoneDiscoverCb()
110 {
111     static NSProviderDiscoveredCallback g_discoverCb = NULL;
112
113     return & g_discoverCb;
114 }
115
116 void NSSetDiscoverProviderCb(NSProviderDiscoveredCallback cb)
117 {
118     * NSGetBoneDiscoverCb() = cb;
119 }
120
121 NSProviderDiscoveredCallback NSGetDiscoverCb()
122 {
123     return * NSGetBoneDiscoverCb();
124 }
125
126 void * NSDiscoveredProviderFunc(void * provider)
127 {
128     NSGetDiscoverCb()((NSProvider *) provider);
129
130     return NULL;
131 }
132
133 void NSDiscoveredProvider(NSProvider * provider)
134 {
135     NS_VERIFY_NOT_NULL_V(provider);
136
137     NSProvider * retProvider = (NSProvider *)NSCopyProvider_internal((NSProvider_internal *)provider);
138     NS_VERIFY_NOT_NULL_V(retProvider);
139
140     NSConsumerThread * thread = NSThreadInit(NSDiscoveredProviderFunc, (void *) retProvider);
141     NS_VERIFY_NOT_NULL_V(thread);
142 }
143
144 NSProviderChangedCallback * NSGetProviderChangedCb()
145 {
146     static NSProviderChangedCallback g_changedCb = NULL;
147
148     return & g_changedCb;
149 }
150
151 void NSSetProviderChangedCb(NSProviderChangedCallback cb)
152 {
153     *(NSGetProviderChangedCb()) = cb;
154 }
155
156 void NSProviderChanged(NSProvider * provider, NSResponse response)
157 {
158     (*(NSGetProviderChangedCb()))(provider, response);
159 }
160
161 NSSyncInfoReceivedCallback * NSGetBoneNotificationSyncCb()
162 {
163     static NSSyncInfoReceivedCallback g_syncCb = NULL;
164
165     return & g_syncCb;
166 }
167
168 void NSSetNotificationSyncCb(NSSyncInfoReceivedCallback cb)
169 {
170     * NSGetBoneNotificationSyncCb() = cb;
171 }
172
173 void * NSNotificationSyncFunc(void * obj)
174 {
175     (* NSGetBoneNotificationSyncCb())((NSSyncInfo *) obj);
176     return NULL;
177 }
178
179 void NSNotificationSync(NSSyncInfo * sync)
180 {
181     NS_VERIFY_NOT_NULL_V(sync);
182
183     NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
184     NS_VERIFY_NOT_NULL_V(retSync);
185     memcpy(retSync, sync, sizeof(NSSyncInfo));
186
187     NSConsumerThread * thread = NSThreadInit(NSNotificationSyncFunc, (void *) retSync);
188     NS_VERIFY_NOT_NULL_V(thread);
189 }
190
191 NSMessageReceivedCallback  * NSGetBoneMessagePostedCb()
192 {
193     static NSMessageReceivedCallback  g_postCb = NULL;
194
195     return & g_postCb;
196 }
197
198 void NSSetMessagePostedCb(NSMessageReceivedCallback  cb)
199 {
200     * NSGetBoneMessagePostedCb() = cb;
201 }
202
203 NSMessageReceivedCallback  NSGetMessagePostedCb()
204 {
205     return * NSGetBoneMessagePostedCb();
206 }
207
208 void * NSMessagePostFunc(void * obj)
209 {
210     NSGetMessagePostedCb()((NSMessage *) obj);
211     return NULL;
212 }
213
214 void NSMessagePost(NSMessage * msg)
215 {
216     NS_VERIFY_NOT_NULL_V(msg);
217
218     NSMessage * retMsg = NSCopyMessage(msg);
219     NS_VERIFY_NOT_NULL_V(retMsg);
220
221     NSConsumerThread * thread = NSThreadInit(NSMessagePostFunc, (void *) retMsg);
222     NS_VERIFY_NOT_NULL_V(thread);
223 }
224
225 NSTask * NSMakeTask(NSTaskType type, void * data)
226 {
227     NSTask * retTask = OICMalloc(sizeof(NSTask));
228     NS_VERIFY_NOT_NULL(retTask, NULL);
229
230     retTask->taskType = type;
231     retTask->taskData = data;
232     retTask->nextTask = NULL;
233
234     return retTask;
235 }
236
237 NSMessage * NSCopyMessage(NSMessage * msg)
238 {
239     NS_VERIFY_NOT_NULL(msg, NULL);
240
241     NSMessage * newMsg = (NSMessage *)OICMalloc(sizeof(NSMessage));
242     NS_VERIFY_NOT_NULL(newMsg, NULL);
243
244     OICStrcpy(newMsg->providerId, NS_DEVICE_ID_LENGTH, msg->providerId);
245
246     newMsg->messageId = msg->messageId;
247     newMsg->title = OICStrdup(msg->title);
248     newMsg->contentText = OICStrdup(msg->contentText);
249     newMsg->sourceName = OICStrdup(msg->sourceName);
250     newMsg->dateTime = OICStrdup(msg->dateTime);
251     newMsg->type = msg->type;
252
253     // TODO change to copy function.
254     newMsg->mediaContents = msg->mediaContents;
255
256     return newMsg;
257 }
258 void NSRemoveMessage(NSMessage * msg)
259 {
260     NS_VERIFY_NOT_NULL_V(msg);
261
262     msg->messageId = 0;
263     NSOICFree(msg->title);
264     NSOICFree(msg->contentText);
265     NSOICFree(msg->sourceName);
266     NSOICFree(msg->dateTime);
267
268     // TODO change to remove function.
269     NSOICFree(msg->mediaContents);
270
271     NSOICFree(msg);
272 }
273
274 void NSRemoveConnections(NSProviderConnectionInfo * connections)
275 {
276     NS_VERIFY_NOT_NULL_V(connections);
277
278     NSProviderConnectionInfo * tmp = connections;
279
280     while(tmp)
281     {
282         tmp->messageHandle = NULL;
283         tmp->syncHandle = NULL;
284         NSOICFree(tmp->addr);
285         tmp = tmp->next;
286     }
287
288     NSOICFree(connections);
289 }
290
291 NSProviderConnectionInfo * NSCreateProviderConnections(OCDevAddr * inAddr)
292 {
293     NSProviderConnectionInfo * connections
294         = (NSProviderConnectionInfo *)OICMalloc(sizeof(NSProviderConnectionInfo));
295     NS_VERIFY_NOT_NULL(connections, NULL);
296
297     connections->addr = NULL;
298     connections->messageHandle = NULL;
299     connections->syncHandle = NULL;
300     connections->isCloudConnection = false;
301     connections->isSubscribing = false;
302     connections->next = NULL;
303
304     if (inAddr)
305     {
306         connections->addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
307         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(connections->addr, NULL, NSRemoveConnections(connections));
308         memcpy(connections->addr, inAddr, sizeof(OCDevAddr));
309     }
310
311     return connections;
312 }
313
314 NSProviderConnectionInfo * NSCopyProviderConnections(NSProviderConnectionInfo * conn)
315 {
316     NS_VERIFY_NOT_NULL(conn, NULL);
317     NSProviderConnectionInfo * tmp = conn;
318
319     NSProviderConnectionInfo * retInfo = NSCreateProviderConnections(tmp->addr);
320     NS_VERIFY_NOT_NULL(retInfo, NULL);
321     tmp = tmp->next;
322     NSProviderConnectionInfo * copyInfo = retInfo;
323
324     while(tmp)
325     {
326         copyInfo = NSCreateProviderConnections(tmp->addr);
327         NS_VERIFY_NOT_NULL(copyInfo, NULL);
328
329         copyInfo->messageHandle = tmp->messageHandle;
330         copyInfo->syncHandle = tmp->syncHandle;
331         copyInfo->isCloudConnection = tmp->isCloudConnection;
332         copyInfo->isSubscribing = tmp->isSubscribing;
333         tmp = tmp->next;
334         copyInfo = copyInfo->next;
335     }
336
337     return retInfo;
338 }
339
340 void NSRemoveTopicNode(NSTopicLL * topicNode)
341 {
342     NS_VERIFY_NOT_NULL_V(topicNode);
343
344     NSOICFree(topicNode->topicName);
345     topicNode->next = NULL;
346
347     NSOICFree(topicNode);
348 }
349
350 NSTopicLL * NSCopyTopicNode(NSTopicLL * topicNode)
351 {
352     NS_VERIFY_NOT_NULL(topicNode, NULL);
353
354     NSTopicLL * newTopicNode = (NSTopicLL *)OICMalloc(sizeof(NSTopicLL));
355     NS_VERIFY_NOT_NULL(newTopicNode, NULL);
356
357     newTopicNode->topicName = OICStrdup(topicNode->topicName);
358     newTopicNode->state = topicNode->state;
359     newTopicNode->next = NULL;
360
361     return newTopicNode;
362 }
363
364 NSResult NSInsertTopicNode(NSTopicLL * topicHead, NSTopicLL * topicNode)
365 {
366     NS_VERIFY_NOT_NULL(topicHead, NS_ERROR);
367     NS_VERIFY_NOT_NULL(topicNode, NS_ERROR);
368
369     NSTopicLL * iter = topicHead;
370     NSTopicLL * prev = NULL;
371
372     while (iter)
373     {
374         prev = iter;
375         iter = (NSTopicLL *) iter->next;
376     }
377
378     prev->next = topicNode;
379     topicNode->next = NULL;
380
381     return NS_OK;
382 }
383
384 void NSRemoveTopicLL(NSTopicLL * topicHead)
385 {
386     NS_VERIFY_NOT_NULL_V(topicHead);
387
388     NSTopicLL * iter = topicHead;
389     NSTopicLL * following = NULL;
390
391     while (iter)
392     {
393         following = (NSTopicLL *) iter->next;
394
395         NSRemoveTopicNode(iter);
396
397         iter = following;
398     }
399 }
400
401 NSTopicLL * NSCopyTopicLL(NSTopicLL * topicHead)
402 {
403     NS_VERIFY_NOT_NULL(topicHead, NULL);
404
405     NSTopicLL * iter = topicHead;
406
407     NSTopicLL * newTopicHead = NSCopyTopicNode(iter);
408     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicHead, NULL, NSRemoveTopicLL(newTopicHead));
409
410     iter = (NSTopicLL *) iter->next;
411
412     while (iter)
413     {
414         NSTopicLL * newTopicNode = NSCopyTopicNode(iter);
415         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicNode, NULL, NSRemoveTopicLL(newTopicHead));
416
417         NSResult ret = NSInsertTopicNode(newTopicHead, newTopicNode);
418         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(ret, NULL, NSRemoveTopicLL(newTopicHead));
419
420         iter = (NSTopicLL *) iter->next;
421     }
422
423     return newTopicHead;
424 }
425
426 void NSCopyProviderPostClean(
427         NSProviderConnectionInfo * connections, NSProvider_internal * provider)
428 {
429     NSRemoveConnections(connections);
430     NSOICFree(provider);
431 }
432
433 NSProvider_internal * NSCopyProvider_internal(NSProvider_internal * prov)
434 {
435     NS_VERIFY_NOT_NULL(prov, NULL);
436
437     NSProviderConnectionInfo * connections = NSCopyProviderConnections(prov->connection);
438     NS_VERIFY_NOT_NULL(connections, NULL);
439
440     NSProvider_internal * newProv = (NSProvider_internal *) OICMalloc(sizeof(NSProvider_internal));
441     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProv, NULL, NSRemoveConnections(connections));
442
443     newProv->topicLL = NULL;
444
445     if (prov->topicLL)
446     {
447         NSTopicLL * newTopicLL = NSCopyTopicLL(prov->topicLL);
448         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicLL, NULL,
449                     NSCopyProviderPostClean(connections, newProv));
450
451         newProv->topicLL = newTopicLL;
452     }
453
454     newProv->connection = connections;
455     OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
456     newProv->messageUri = OICStrdup(prov->messageUri);
457     newProv->syncUri = OICStrdup(prov->syncUri);
458     newProv->topicUri = OICStrdup(prov->topicUri);
459     newProv->accessPolicy = prov->accessPolicy;
460
461     return newProv;
462 }
463
464 NSProvider * NSCopyProvider(NSProvider_internal * prov)
465 {
466     NS_VERIFY_NOT_NULL(prov, NULL);
467
468     NSProvider * newProv = (NSProvider *) OICMalloc(sizeof(NSProvider));
469     NS_VERIFY_NOT_NULL(newProv, NULL);
470
471     newProv->topicLL = NULL;
472
473     if (prov->topicLL)
474     {
475         NSTopicLL * topicList = NSCopyTopicLL(prov->topicLL);
476         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(topicList, NULL, NSRemoveProvider(newProv));
477
478         newProv->topicLL = topicList;
479     }
480
481     OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
482
483     return newProv;
484 }
485
486 void NSRemoveProvider_internal(NSProvider_internal * prov)
487 {
488     NS_VERIFY_NOT_NULL_V(prov);
489
490     NSOICFree(prov->messageUri);
491     NSOICFree(prov->syncUri);
492     NSOICFree(prov->topicUri);
493     NSRemoveConnections(prov->connection);
494     if (prov->topicLL)
495     {
496         NSRemoveTopicLL(prov->topicLL);
497     }
498
499     NSOICFree(prov);
500 }
501
502 void NSRemoveProvider(NSProvider * prov)
503 {
504     NS_VERIFY_NOT_NULL_V(prov);
505
506     if (prov->topicLL)
507     {
508         NSRemoveTopicLL(prov->topicLL);
509     }
510
511     NSOICFree(prov);
512 }
513
514 NSSyncInfo_internal * NSCopySyncInfo(NSSyncInfo_internal * syncInfo)
515 {
516     NS_VERIFY_NOT_NULL(syncInfo, NULL);
517
518     NSProviderConnectionInfo * connections = NSCopyProviderConnections(syncInfo->connection);
519     NS_VERIFY_NOT_NULL(connections, NULL);
520
521     NSSyncInfo_internal * newSyncInfo = (NSSyncInfo_internal *)OICMalloc(sizeof(NSSyncInfo_internal));
522     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newSyncInfo, NULL, NSRemoveConnections(connections));
523
524     OICStrcpy(newSyncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, syncInfo->providerId);
525     newSyncInfo->messageId = syncInfo->messageId;
526     newSyncInfo->state = syncInfo->state;
527     newSyncInfo->connection = connections;
528
529     return newSyncInfo;
530 }
531
532 void NSRemoveSyncInfo(NSSyncInfo_internal * syncInfo)
533 {
534     NS_VERIFY_NOT_NULL_V(syncInfo);
535
536     NSRemoveConnections(syncInfo->connection);
537
538     NSOICFree(syncInfo);
539 }
540
541 OCStackResult NSInvokeRequest(OCDoHandle * handle,
542         OCMethod method, const OCDevAddr * addr,
543         const char * queryUrl, OCPayload * payload,
544         void * callbackFunc, void * callbackData, OCConnectivityType type)
545 {
546     int mutexRet = pthread_mutex_lock(*(NSGetStackMutex()));
547     NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
548
549     OCCallbackData cbdata = { 0, };
550
551     cbdata.cb = callbackFunc;
552     cbdata.context = callbackData;
553     cbdata.cd = NULL;
554
555     OCStackResult ret = OCDoResource(handle, method, queryUrl, addr,
556                                      payload, type, NS_QOS, &cbdata, NULL, 0);
557
558     mutexRet = pthread_mutex_unlock(*(NSGetStackMutex()));
559     NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
560
561     return ret;
562 }
563
564 bool NSOCResultToSuccess(OCStackResult ret)
565 {
566     switch (ret)
567     {
568         case OC_STACK_OK:
569         case OC_STACK_RESOURCE_CREATED:
570         case OC_STACK_RESOURCE_DELETED:
571         case OC_STACK_CONTINUE:
572         case OC_STACK_RESOURCE_CHANGED:
573             return true;
574         default:
575             return false;
576     }
577 }