replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerInternalTaskController.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 "NSConstants.h"
22 #include "NSConsumerCommon.h"
23 #include "NSConsumerInternalTaskController.h"
24 #include "NSStructs.h"
25
26 #include "oic_malloc.h"
27 #include "oic_string.h"
28
29 #define NS_RESERVED_MESSAGEID 10
30
31 // MessageState storage structure
32 typedef struct _NSMessageStateLL
33 {
34     uint64_t messageId;
35     NSSyncType state;
36     struct _NSMessageStateLL * next;
37
38 } NSMessageStateLL;
39
40 typedef struct
41 {
42     NSMessageStateLL * head;
43     NSMessageStateLL * tail;
44
45 } NSMessageStateList;
46
47 // Mutex of MessageState storage
48 pthread_mutex_t ** NSGetMessageListMutex();
49 void NSLockMessageListMutex();
50 void NSUnlockMessageListMutex();
51
52 // Function for MessageState
53 NSMessageStateList * NSGetMessageStateList();
54 NSMessageStateLL * NSFindMessageState(uint64_t msgId);
55 bool NSUpdateMessageState(uint64_t msgId, NSSyncType state);
56 bool NSDeleteMessageState(uint64_t msgId);
57 bool NSInsertMessageState(uint64_t msgId, NSSyncType state);
58 void NSDestroyMessageStateList();
59
60 NSCacheList ** NSGetProviderCacheList()
61 {
62     static NSCacheList * providerCache = NULL;
63     return & providerCache;
64 }
65
66 void NSSetProviderCacheList(NSCacheList * cache)
67 {
68     *(NSGetProviderCacheList()) = cache;
69 }
70
71 void NSDestroyInternalCachedList()
72 {
73     NSCacheList * cache = *(NSGetProviderCacheList());
74     if (cache)
75     {
76         NSConsumerStorageDestroy(cache);
77     }
78
79     NSSetProviderCacheList(NULL);
80
81     NSDestroyMessageStateList();
82     pthread_mutex_destroy(*NSGetMessageListMutex());
83     NSOICFree(*NSGetMessageListMutex());
84 }
85
86 NSProvider_internal * NSProviderCacheFind(const char * providerId)
87 {
88     NS_VERIFY_NOT_NULL(providerId, NULL);
89
90     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
91     if (!ProviderCache)
92     {
93         NS_LOG(DEBUG, "Provider Cache Init");
94         ProviderCache = NSConsumerStorageCreate();
95         NS_VERIFY_NOT_NULL(ProviderCache, NULL);
96
97         ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
98         NSSetProviderCacheList(ProviderCache);
99     }
100
101     NSCacheElement * cacheElement = NSConsumerStorageRead(ProviderCache, providerId);
102     NS_VERIFY_NOT_NULL(cacheElement, NULL);
103
104     return NSCopyProvider_internal((NSProvider_internal *) cacheElement->data);
105 }
106
107 NSProvider_internal * NSFindProviderFromAddr(OCDevAddr * addr)
108 {
109     NS_VERIFY_NOT_NULL(addr, NULL);
110
111     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
112     if (!ProviderCache)
113     {
114         NS_LOG(DEBUG, "Provider Cache does not intialized.");
115         return NULL;
116     }
117
118     NSCacheElement * cacheElement =
119             NSGetProviderFromAddr(ProviderCache, addr->addr, addr->port);
120
121     NS_VERIFY_NOT_NULL(cacheElement, NULL);
122
123     return NSCopyProvider_internal((NSProvider_internal *) cacheElement->data);
124 }
125
126 NSResult NSProviderCacheUpdate(NSProvider_internal * provider)
127 {
128     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
129     if (!ProviderCache)
130     {
131         NS_LOG(DEBUG, "Provider Cache Init");
132         ProviderCache = NSConsumerStorageCreate();
133         NS_VERIFY_NOT_NULL(ProviderCache, NS_ERROR);
134
135         ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
136         NSSetProviderCacheList(ProviderCache);
137     }
138
139     NS_VERIFY_NOT_NULL(provider, NS_ERROR);
140
141     NSCacheElement * obj = (NSCacheElement *)OICMalloc(sizeof(NSCacheElement));
142     NS_VERIFY_NOT_NULL(obj, NS_ERROR);
143
144     obj->data = (NSCacheData *) provider;
145     obj->next = NULL;
146
147     NS_LOG(DEBUG, "try to write to storage");
148     NSResult ret = NSConsumerStorageWrite(ProviderCache, obj);
149     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == NS_OK ? (void *) 1 : NULL,
150             NS_ERROR, NSOICFree(obj));
151
152     NSOICFree(obj);
153
154     return NS_OK;
155 }
156
157 void NSCancelAllSubscription()
158 {
159     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
160     if (!ProviderCache)
161     {
162         NS_LOG(DEBUG, "Provider Cache Init");
163         ProviderCache = NSConsumerStorageCreate();
164         NS_VERIFY_NOT_NULL_V(ProviderCache);
165
166         ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
167         NSSetProviderCacheList(ProviderCache);
168     }
169
170     NSCacheElement * obj = NSPopProviderCacheList(ProviderCache);
171     while (obj)
172     {
173         NS_LOG(DEBUG, "build NSTask");
174         NSProvider * prov = NSCopyProvider((NSProvider_internal *) obj->data);
175         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(prov,
176                     NSRemoveProvider_internal((void *) obj->data));
177
178         NSTask * task = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, prov);
179         NS_VERIFY_NOT_NULL_V(task);
180
181         NSConsumerPushEvent(task);
182         NSRemoveProvider_internal((void *) obj->data);
183         NSOICFree(obj);
184
185         obj = NSPopProviderCacheList(ProviderCache);
186     }
187 }
188
189 void NSConsumerHandleProviderDiscovered(NSProvider_internal * provider)
190 {
191     NS_VERIFY_NOT_NULL_V(provider);
192
193     bool isAdded = true;
194     bool isSubscribing = false;
195
196     NSProvider_internal * providerCacheDataFromAddr
197         = NSFindProviderFromAddr(provider->connection->addr);
198
199     if (providerCacheDataFromAddr)
200     {
201         if (!strcmp(providerCacheDataFromAddr->providerId, provider->providerId))
202         {
203             NSProviderConnectionInfo * infos = providerCacheDataFromAddr->connection;
204             while (infos)
205             {
206                 isSubscribing |= infos->isSubscribing;
207                 infos = infos->next;
208             }
209
210             if (isSubscribing == false)
211             {
212                 NSProvider * providerForCb = NSCopyProvider(providerCacheDataFromAddr);
213                 NSProviderChanged(providerForCb, NS_DISCOVERED);
214                 NSRemoveProvider(providerForCb);
215             }
216             NSRemoveProvider_internal(providerCacheDataFromAddr);
217             return ;
218         }
219         NSRemoveProvider_internal(providerCacheDataFromAddr);
220     }
221
222     NSProvider_internal * providerCacheData = NSProviderCacheFind(provider->providerId);
223
224     if (providerCacheData == NULL)
225     {
226         isAdded = false;
227     }
228     else
229     {
230         providerCacheData->accessPolicy = provider->accessPolicy;
231         NSProviderConnectionInfo * infos = providerCacheData->connection;
232         OCTransportAdapter newAdapter = provider->connection->addr->adapter;
233         while (infos)
234         {
235             isSubscribing |= infos->isSubscribing;
236             if (infos->addr->adapter == newAdapter && infos->isSubscribing == true)
237             {
238                 NS_LOG_V(INFO_PRIVATE, "This provider already discovered : %s:%d",
239                          infos->addr->addr, infos->addr->port);
240                 NS_LOG_V(DEBUG, "Subscription : %d", infos->isSubscribing);
241                 return;
242             }
243             infos = infos->next;
244         }
245     }
246
247     NSResult ret = NSProviderCacheUpdate(provider);
248     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(ret == NS_OK ? (void *) 1 : NULL,
249             NSRemoveProvider_internal(providerCacheData));
250
251     if (isAdded == false)
252     {
253         NS_LOG(DEBUG, "New provider is discovered");
254     }
255     else
256     {
257         provider = providerCacheData;
258         NS_LOG(DEBUG, "provider's connection is updated.");
259     }
260
261     if (provider->accessPolicy == NS_SELECTION_CONSUMER && isSubscribing == false)
262     {
263         NS_LOG(DEBUG, "accepter is NS_ACCEPTER_CONSUMER, Callback to user");
264         NSProvider * prov = NSCopyProvider(provider);
265         NSProviderChanged(prov, NS_DISCOVERED);
266         NSRemoveProvider(prov);
267     }
268     else
269     {
270         NS_LOG(DEBUG, "accepter is NS_ACCEPTER_PROVIDER, request subscribe");
271         NSProvider * subProvider = NSCopyProvider(provider);
272         NSTask * task = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE, (void *) subProvider);
273         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(task,
274                 NSRemoveProvider_internal(providerCacheData));
275
276         NSConsumerPushEvent(task);
277     }
278
279     NSRemoveProvider_internal(providerCacheData);
280 }
281
282 void NSConsumerHandleProviderDeleted(NSProvider_internal * provider)
283 {
284     NS_VERIFY_NOT_NULL_V(provider);
285
286     NSCacheList * providerCache = *(NSGetProviderCacheList());
287     NS_VERIFY_NOT_NULL_V(providerCache);
288
289     NSResult ret = NSConsumerStorageDelete(providerCache, provider->providerId);
290     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
291
292     NS_LOG_V(INFO_PRIVATE, "Stopped Provider : %s", provider->providerId);
293     NSProvider * prov = NSCopyProvider(provider);
294     NSProviderChanged(prov, NS_STOPPED);
295     NSRemoveProvider(prov);
296 }
297
298 void NSConsumerHandleSubscribeSucceed(NSProvider_internal * provider)
299 {
300     NS_VERIFY_NOT_NULL_V(provider);
301
302     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
303
304     NSCacheElement * cacheElement = NSConsumerStorageRead(ProviderCache, provider->providerId);
305     NS_VERIFY_NOT_NULL_V(cacheElement);
306
307     pthread_mutex_t * mutex = NSGetCacheMutex();
308     pthread_mutex_lock(mutex);
309
310     NS_VERIFY_NOT_NULL_V(cacheElement);
311     NSProvider_internal * prov = (NSProvider_internal *)cacheElement->data;
312     NSProviderConnectionInfo *infos = prov->connection;
313     while(infos)
314     {
315         infos->isSubscribing = true;
316         infos = infos->next;
317     }
318
319     pthread_mutex_unlock(mutex);
320 }
321
322 void NSConsumerHandleRecvProviderChanged(NSMessage * msg)
323 {
324     NS_VERIFY_NOT_NULL_V(msg);
325
326     NS_LOG_V(INFO_PRIVATE, "confirmed by : %s", msg->providerId);
327
328     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
329
330     NSCacheElement * cacheElement = NSConsumerStorageRead(ProviderCache, msg->providerId);
331     NS_VERIFY_NOT_NULL_V(cacheElement);
332
333     pthread_mutex_t * mutex = NSGetCacheMutex();
334     pthread_mutex_lock(mutex);
335     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(cacheElement, pthread_mutex_unlock(mutex));
336     NSProvider_internal * provider = (NSProvider_internal *) cacheElement->data;
337     if (provider->state == (NSProviderState) msg->messageId)
338     {
339         NS_LOG_V(DEBUG, "Already receive message(ALLOW/DENY) : %d", (int) msg->messageId);
340         pthread_mutex_unlock(mutex);
341         return;
342     }
343
344     NS_LOG_V(DEBUG, "Provider State Changed %d -> %d",
345              (int) provider->state, (int) msg->messageId);
346     NS_LOG(DEBUG, "call back to user");
347     provider->state = (NSProviderState) msg->messageId;
348
349     NSProvider * prov = NSCopyProvider(provider);
350
351     pthread_mutex_unlock(mutex);
352     NSProviderChanged(prov, (NSProviderState) msg->messageId);
353     NSRemoveProvider(prov);
354 }
355
356 void NSConsumerHandleRecvMessage(NSMessage * msg)
357 {
358     NS_VERIFY_NOT_NULL_V(msg);
359
360     if (NSInsertMessageState(msg->messageId, NS_SYNC_UNREAD))
361     {
362         NSMessagePost(msg);
363     }
364 }
365
366 void NSConsumerHandleRecvSyncInfo(NSSyncInfo * sync)
367 {
368     NS_VERIFY_NOT_NULL_V(sync);
369
370     if (NSUpdateMessageState(sync->messageId, sync->state))
371     {
372         NSNotificationSync(sync);
373     }
374
375     if (sync->state == NS_SYNC_DELETED)
376     {
377         NSDeleteMessageState(sync->messageId);
378     }
379 }
380
381 void NSConsumerHandleMakeSyncInfo(NSSyncInfo * sync)
382 {
383     NS_VERIFY_NOT_NULL_V(sync);
384
385     NSProvider_internal * provider = NSProviderCacheFind(sync->providerId);
386     NS_VERIFY_NOT_NULL_V (provider);
387
388     NSProviderConnectionInfo * connections = NSCopyProviderConnections(provider->connection);
389     NSRemoveProvider_internal((void *) provider);
390     NS_VERIFY_NOT_NULL_V (connections);
391
392     NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)OICMalloc(sizeof(NSSyncInfo_internal));
393     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncInfo, NSRemoveConnections(connections));
394
395     OICStrcpy(syncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, sync->providerId);
396     syncInfo->messageId = sync->messageId;
397     syncInfo->state = sync->state;
398     syncInfo->connection = connections;
399
400     NSTask * syncTask = NSMakeTask(TASK_SEND_SYNCINFO, (void *) syncInfo);
401     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncTask, NSOICFree(syncInfo));
402
403     NSConsumerPushEvent(syncTask);
404 }
405
406 void NSConsumerHandleGetTopicUri(NSMessage * msg)
407 {
408     NS_VERIFY_NOT_NULL_V(msg);
409
410     NSProvider_internal * provider = NSProviderCacheFind(msg->providerId);
411     NS_VERIFY_NOT_NULL_V(provider);
412
413     NSTask * topicTask = NSMakeTask(TASK_CONSUMER_REQ_TOPIC_LIST, (void *) provider);
414     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(topicTask, NSRemoveProvider_internal(provider));
415
416     NSConsumerPushEvent(topicTask);
417 }
418
419 void NSConsumerHandleRecvTopicLL(NSProvider_internal * provider)
420 {
421     NS_VERIFY_NOT_NULL_V(provider);
422
423     NSRemoveConnections(provider->connection);
424     provider->connection = NULL;
425
426     NSProvider_internal * cachedProvider = NSProviderCacheFind(provider->providerId);
427     NS_VERIFY_NOT_NULL_V(cachedProvider);
428
429     if (!cachedProvider->topicLL && !provider->topicLL)
430     {
431         NS_LOG(DEBUG, "topic is null and previous status is same.");
432         NSRemoveProvider_internal(cachedProvider);
433         return;
434     }
435     NSRemoveProvider_internal(cachedProvider);
436
437     NSResult ret = NSProviderCacheUpdate(provider);
438     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
439
440     NS_LOG(DEBUG, "call back to user");
441     NSProvider * prov = NSCopyProvider(provider);
442     NSProviderChanged((NSProvider *) prov, (NSProviderState) NS_TOPIC);
443     NSRemoveProvider(prov);
444 }
445
446 void NSConsumerInternalTaskProcessing(NSTask * task)
447 {
448     NS_VERIFY_NOT_NULL_V(task);
449
450     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
451     switch (task->taskType)
452     {
453         case TASK_CONSUMER_SENT_REQ_OBSERVE:
454         {
455             NS_LOG(DEBUG, "Receive Subscribe succeed from provider.");
456             NSConsumerHandleSubscribeSucceed((NSProvider_internal *)task->taskData);
457             NSRemoveProvider_internal((void *)task->taskData);
458             break;
459         }
460         case TASK_CONSUMER_RECV_PROVIDER_CHANGED:
461         {
462             NS_LOG(DEBUG, "Receive Provider Changed");
463             NSConsumerHandleRecvProviderChanged((NSMessage *)task->taskData);
464             NSRemoveMessage((NSMessage *)task->taskData);
465             break;
466         }
467         case TASK_CONSUMER_RECV_MESSAGE:
468         {
469             NS_LOG(DEBUG, "Receive New Notification");
470             NSConsumerHandleRecvMessage((NSMessage *)task->taskData);
471             NSRemoveMessage((NSMessage *)task->taskData);
472             break;
473         }
474         case TASK_CONSUMER_PROVIDER_DISCOVERED:
475         {
476             NS_LOG(DEBUG, "Receive New Provider is discovered.");
477             NSConsumerHandleProviderDiscovered((NSProvider_internal *)task->taskData);
478             NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
479             break;
480         }
481         case TASK_RECV_SYNCINFO:
482         {
483             NS_LOG(DEBUG, "Receive SyncInfo.");
484             NSConsumerHandleRecvSyncInfo((NSSyncInfo *)task->taskData);
485             NSOICFree(task->taskData);
486             break;
487         }
488         case TASK_MAKE_SYNCINFO:
489         {
490             NS_LOG(DEBUG, "Make SyncInfo, get Provider's Addr");
491             NSConsumerHandleMakeSyncInfo((NSSyncInfo *)task->taskData);
492             NSOICFree(task->taskData);
493             break;
494         }
495         case TASK_CONSUMER_REQ_TOPIC_URI:
496         {
497             NS_LOG(DEBUG, "Request Topic Uri");
498             NSConsumerHandleGetTopicUri((NSMessage *)task->taskData);
499             NSRemoveMessage((NSMessage *)task->taskData);
500             break;
501         }
502         case TASK_CONSUMER_RECV_TOPIC_LIST:
503         {
504             NS_LOG(DEBUG, "Receive Topic List");
505             NSConsumerHandleRecvTopicLL((NSProvider_internal *)task->taskData);
506             NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
507             break;
508         }
509         case TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL:
510         {
511             NS_LOG(DEBUG, "Make Subscribe cancel from provider.");
512             NSConsumerHandleProviderDeleted((NSProvider_internal *)task->taskData);
513             NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
514             break;
515         }
516         default :
517         {
518             NS_LOG(ERROR, "Unknown TASK Type");
519             return ;
520         }
521     }
522     NSOICFree(task);
523 }
524
525 // implements of MessageState function
526 pthread_mutex_t ** NSGetMessageListMutex()
527 {
528     static pthread_mutex_t * g_mutex = NULL;
529     if (g_mutex == NULL)
530     {
531         g_mutex = (pthread_mutex_t *) OICMalloc(sizeof(pthread_mutex_t));
532         NS_VERIFY_NOT_NULL(g_mutex, NULL);
533
534         pthread_mutex_init(g_mutex, NULL);
535     }
536     return & g_mutex;
537 }
538
539 void NSLockMessageListMutex()
540 {
541     NS_LOG_V(DEBUG, "%s", __func__);
542     pthread_mutex_lock(*NSGetMessageListMutex());
543 }
544
545 void NSUnlockMessageListMutex()
546 {
547     NS_LOG_V(DEBUG, "%s", __func__);
548     pthread_mutex_unlock(*NSGetMessageListMutex());
549 }
550
551 NSMessageStateList ** NSGetMessageStateListAddr()
552 {
553     static NSMessageStateList * g_messageStateList = NULL;
554     if (g_messageStateList == NULL)
555     {
556         g_messageStateList = (NSMessageStateList *)OICMalloc(sizeof(NSMessageStateList));
557         NS_VERIFY_NOT_NULL(g_messageStateList, NULL);
558
559         g_messageStateList->head = NULL;
560         g_messageStateList->tail = NULL;
561     }
562
563     return & g_messageStateList;
564 }
565
566 NSMessageStateList * NSGetMessageStateList()
567 {
568     return * NSGetMessageStateListAddr();
569 }
570
571 NSMessageStateLL * NSFindMessageState(uint64_t msgId)
572 {
573     NS_LOG_V(DEBUG, "%s", __func__);
574     if (msgId <= NS_RESERVED_MESSAGEID)
575     {
576         return NULL;
577     }
578     NSMessageStateLL * iter = NULL;
579
580     NSLockMessageListMutex();
581     if (NSGetMessageStateList()->head == NULL)
582     {
583         NSUnlockMessageListMutex();
584         return NULL;
585     }
586
587     for (iter = NSGetMessageStateList()->head; iter; iter = iter->next)
588     {
589         if (iter->messageId == msgId)
590         {
591             NSUnlockMessageListMutex();
592             return iter;
593         }
594     }
595
596     NSUnlockMessageListMutex();
597     return NULL;
598 }
599
600 bool NSUpdateMessageState(uint64_t msgId, NSSyncType state)
601 {
602     NS_LOG_V(DEBUG, "%s", __func__);
603     if (msgId <= NS_RESERVED_MESSAGEID)
604     {
605         return false;
606     }
607     NSMessageStateLL * iter = NULL;
608
609     NSLockMessageListMutex();
610     for (iter = NSGetMessageStateList()->head; iter; iter = iter->next)
611     {
612         if (iter->messageId == msgId && state != iter->state)
613         {
614             iter->state = state;
615             NSUnlockMessageListMutex();
616             return true;
617         }
618     }
619
620     NSUnlockMessageListMutex();
621     return false;
622 }
623
624 bool NSDeleteMessageState(uint64_t msgId)
625 {
626     NS_LOG_V(DEBUG, "%s", __func__);
627     if (msgId <= NS_RESERVED_MESSAGEID)
628     {
629         return false;
630     }
631
632     NSMessageStateLL * iter = NULL;
633     NSMessageStateLL * prev = NULL;
634
635     NSLockMessageListMutex();
636     for (iter = NSGetMessageStateList()->head; iter; iter = iter->next)
637     {
638         if (iter->messageId == msgId)
639         {
640             if (iter == NSGetMessageStateList()->head)
641             {
642                 NSGetMessageStateList()->head = NULL;
643                 NSGetMessageStateList()->tail = NULL;
644             }
645             else if (iter == NSGetMessageStateList()->tail)
646             {
647                 prev->next = NULL;
648                 NSGetMessageStateList()->tail = prev;
649             }
650             else
651             {
652                 prev->next = iter->next;
653             }
654             NSUnlockMessageListMutex();
655
656             NSOICFree(iter);
657             return true;
658         }
659         prev = iter;
660     }
661
662     NSUnlockMessageListMutex();
663     return false;
664 }
665
666 bool NSInsertMessageState(uint64_t msgId, NSSyncType state)
667 {
668     NS_LOG_V(DEBUG, "%s", __func__);
669     if (NSFindMessageState(msgId))
670     {
671         return false;
672     }
673
674     NSMessageStateLL * insertMsg = (NSMessageStateLL * )OICMalloc(sizeof(NSMessageStateLL));
675     NS_VERIFY_NOT_NULL(insertMsg, false);
676
677     insertMsg->messageId = msgId;
678     insertMsg->state = state;
679     insertMsg->next = NULL;
680
681     NSLockMessageListMutex();
682     if (NSGetMessageStateList()->head == NULL)
683     {
684         NSGetMessageStateList()->head = insertMsg;
685     }
686     else
687     {
688         NSGetMessageStateList()->tail->next = insertMsg;
689     }
690     NSGetMessageStateList()->tail = insertMsg;
691     NSUnlockMessageListMutex();
692
693     return true;
694 }
695
696 void NSDestroyMessageStateList()
697 {
698     NS_LOG_V(DEBUG, "%s", __func__);
699     NSLockMessageListMutex();
700
701     NSMessageStateLL * iter = NSGetMessageStateList()->head;
702     while (iter)
703     {
704         NSMessageStateLL * del = iter;
705         iter = iter->next;
706         NSOICFree(del);
707     }
708
709     NSGetMessageStateList()->head = NULL;
710     NSGetMessageStateList()->tail = NULL;
711
712     NSUnlockMessageListMutex();
713
714     pthread_mutex_t * mu = *NSGetMessageListMutex();
715     pthread_mutex_destroy(mu);
716     NSOICFree(mu);
717     *NSGetMessageListMutex() = NULL;
718
719     NSMessageStateList * list = NSGetMessageStateList();
720     NSOICFree(list);
721     *NSGetMessageStateListAddr() = NULL;
722 }