b069742f74dc0d3e5463b1f45b8ba9165943f222
[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         NSStorageDestroy(cache);
77     }
78
79     NSSetProviderCacheList(NULL);
80
81     NSDestroyMessageStateList();
82     pthread_mutex_destroy(*NSGetMessageListMutex());
83     *NSGetMessageListMutex() = NULL;
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 = NSStorageCreate();
95         NS_VERIFY_NOT_NULL(ProviderCache, NULL);
96
97         ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
98         NSSetProviderCacheList(ProviderCache);
99     }
100
101     NSCacheElement * cacheElement = NSStorageRead(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 = NSStorageCreate();
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 = NSStorageWrite(ProviderCache, obj);
149     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == NS_OK ? (void *) 1 : NULL,
150             NS_ERROR, NSOICFree(obj));
151
152     return NS_OK;
153 }
154
155 void NSCancelAllSubscription()
156 {
157     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
158     if (!ProviderCache)
159     {
160         NS_LOG(DEBUG, "Provider Cache Init");
161         ProviderCache = NSStorageCreate();
162         NS_VERIFY_NOT_NULL_V(ProviderCache);
163
164         ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
165         NSSetProviderCacheList(ProviderCache);
166     }
167
168     NSCacheElement * obj = NULL;
169     while ((obj = NSPopProviderCacheList(ProviderCache)))
170     {
171         NS_LOG(DEBUG, "build NSTask");
172         NSProvider * prov = NSCopyProvider((NSProvider_internal *) obj->data);
173         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(prov,
174                     NSRemoveProvider_internal((NSProvider_internal *) obj->data));
175
176         NSTask * task = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, prov);
177         NS_VERIFY_NOT_NULL_V(task);
178
179         NSConsumerPushEvent(task);
180     }
181 }
182
183 void NSConsumerHandleProviderDiscovered(NSProvider_internal * provider)
184 {
185     NS_VERIFY_NOT_NULL_V(provider);
186
187     bool isAdded = true;
188     bool isSubscribing = false;
189
190     NSProvider_internal * providerCacheDataFromAddr
191         = NSFindProviderFromAddr(provider->connection->addr);
192
193     if (providerCacheDataFromAddr)
194     {
195         if (!strcmp(providerCacheDataFromAddr->providerId, provider->providerId))
196         {
197             NSProviderConnectionInfo * infos = providerCacheDataFromAddr->connection;
198             while (infos)
199             {
200                 isSubscribing |= infos->isSubscribing;
201                 infos = infos->next;
202             }
203
204             if (isSubscribing == false)
205             {
206                 NSProvider * providerForCb = NSCopyProvider(providerCacheDataFromAddr);
207                 NSProviderChanged(providerForCb, NS_DISCOVERED);
208                 NSRemoveProvider(providerForCb);
209             }
210             NSRemoveProvider_internal(providerCacheDataFromAddr);
211             return ;
212         }
213         NSRemoveProvider_internal(providerCacheDataFromAddr);
214     }
215
216     NSProvider_internal * providerCacheData = NSProviderCacheFind(provider->providerId);
217
218     if (providerCacheData == NULL)
219     {
220         isAdded = false;
221     }
222     else
223     {
224         providerCacheData->accessPolicy = provider->accessPolicy;
225         NSProviderConnectionInfo * infos = providerCacheData->connection;
226         OCTransportAdapter newAdapter = provider->connection->addr->adapter;
227         while (infos)
228         {
229             isSubscribing |= infos->isSubscribing;
230             if (infos->addr->adapter == newAdapter && infos->isSubscribing == true)
231             {
232                 NS_LOG_V(DEBUG, "This provider already discovered : %s:%d",
233                          infos->addr->addr, infos->addr->port);
234                 NS_LOG_V(DEBUG, "Subscription : %d", infos->isSubscribing);
235                 return;
236             }
237             infos = infos->next;
238         }
239     }
240
241     NSResult ret = NSProviderCacheUpdate(provider);
242     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
243
244     if (isAdded == false)
245     {
246         NS_LOG(DEBUG, "New provider is discovered");
247     }
248     else
249     {
250         provider = providerCacheData;
251         NS_LOG(DEBUG, "provider's connection is updated.");
252     }
253
254     if (provider->accessPolicy == NS_SELECTION_CONSUMER && isSubscribing == false)
255     {
256         NS_LOG(DEBUG, "accepter is NS_ACCEPTER_CONSUMER, Callback to user");
257         NSProvider * providerForCb = NSCopyProvider(provider);
258         NSProviderChanged(providerForCb, NS_DISCOVERED);
259         NSRemoveProvider(providerForCb);
260     }
261     else
262     {
263         NS_LOG(DEBUG, "accepter is NS_ACCEPTER_PROVIDER, request subscribe");
264         NSProvider_internal * subProvider = NSCopyProvider_internal(provider);
265         NSTask * task = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE, (void *) subProvider);
266         NS_VERIFY_NOT_NULL_V(task);
267
268         NSConsumerPushEvent(task);
269     }
270
271     NSRemoveProvider_internal(providerCacheData);
272 }
273
274 void NSConsumerHandleProviderDeleted(NSProvider_internal * provider)
275 {
276     NS_VERIFY_NOT_NULL_V(provider);
277
278     NSCacheList * providerCache = *(NSGetProviderCacheList());
279     NS_VERIFY_NOT_NULL_V(providerCache);
280
281     NSResult ret = NSStorageDelete(providerCache, provider->providerId);
282     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
283
284     NS_LOG_V(DEBUG, "Stopped Provider : %s", provider->providerId);
285     NSProvider * providerForCb = NSCopyProvider(provider);
286     NSProviderChanged(providerForCb, NS_STOPPED);
287 }
288
289 void NSConsumerHandleSubscribeSucceed(NSProvider_internal * provider)
290 {
291     NS_VERIFY_NOT_NULL_V(provider);
292
293     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
294
295     NSCacheElement * cacheElement = NSStorageRead(ProviderCache, provider->providerId);
296     NS_VERIFY_NOT_NULL_V(cacheElement);
297
298     pthread_mutex_t * mutex = NSGetCacheMutex();
299     pthread_mutex_lock(mutex);
300
301     NS_VERIFY_NOT_NULL_V(cacheElement);
302     NSProvider_internal * prov = (NSProvider_internal *)cacheElement->data;
303     NSProviderConnectionInfo *infos = prov->connection;
304     while(infos)
305     {
306         infos->isSubscribing = true;
307         infos = infos->next;
308     }
309
310     pthread_mutex_unlock(mutex);
311 }
312
313 void NSConsumerHandleRecvProviderChanged(NSMessage * msg)
314 {
315     NS_VERIFY_NOT_NULL_V(msg);
316
317     NS_LOG_V(DEBUG, "confirmed by : %s", msg->providerId);
318
319     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
320
321     NSCacheElement * cacheElement = NSStorageRead(ProviderCache, msg->providerId);
322     NS_VERIFY_NOT_NULL_V(cacheElement);
323
324     pthread_mutex_t * mutex = NSGetCacheMutex();
325     pthread_mutex_lock(mutex);
326     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(cacheElement, pthread_mutex_unlock(mutex));
327     NSProvider_internal * provider = (NSProvider_internal *) cacheElement->data;
328     if (provider->state == (NSProviderState) msg->messageId)
329     {
330         NS_LOG_V(DEBUG, "Already receive message(ALLOW/DENY) : %d", (int) msg->messageId);
331         pthread_mutex_unlock(mutex);
332         return;
333     }
334
335     NS_LOG_V(DEBUG, "Provider State Changed %d -> %d",
336              (int) provider->state, (int) msg->messageId);
337     NS_LOG(DEBUG, "call back to user");
338     provider->state = (NSProviderState) msg->messageId;
339
340     NSProvider * prov = NSCopyProvider(provider);
341
342     pthread_mutex_unlock(mutex);
343     NSProviderChanged(prov, (NSProviderState) msg->messageId);
344 }
345
346 void NSConsumerHandleRecvMessage(NSMessage * msg)
347 {
348     NS_VERIFY_NOT_NULL_V(msg);
349
350     if (NSInsertMessageState(msg->messageId, NS_SYNC_UNREAD))
351     {
352         NSMessagePost(msg);
353     }
354 }
355
356 void NSConsumerHandleRecvSyncInfo(NSSyncInfo * sync)
357 {
358     NS_VERIFY_NOT_NULL_V(sync);
359
360     if (NSUpdateMessageState(sync->messageId, sync->state))
361     {
362         NSNotificationSync(sync);
363     }
364
365     if (sync->state == NS_SYNC_DELETED)
366     {
367         NSDeleteMessageState(sync->messageId);
368     }
369 }
370
371 void NSConsumerHandleMakeSyncInfo(NSSyncInfo * sync)
372 {
373     NS_VERIFY_NOT_NULL_V(sync);
374
375     NSProvider_internal * provider = NSProviderCacheFind(sync->providerId);
376     NS_VERIFY_NOT_NULL_V (provider);
377
378     NSProviderConnectionInfo * connections = NSCopyProviderConnections(provider->connection);
379     NSRemoveProvider_internal(provider);
380     NS_VERIFY_NOT_NULL_V (connections);
381
382     NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)OICMalloc(sizeof(NSSyncInfo_internal));
383     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncInfo, NSRemoveConnections(connections));
384
385     OICStrcpy(syncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, sync->providerId);
386     syncInfo->messageId = sync->messageId;
387     syncInfo->state = sync->state;
388     syncInfo->connection = connections;
389
390     NSTask * syncTask = NSMakeTask(TASK_SEND_SYNCINFO, (void *) syncInfo);
391     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncTask, NSOICFree(syncInfo));
392
393     NSConsumerPushEvent(syncTask);
394 }
395
396 void NSConsumerHandleGetTopicUri(NSMessage * msg)
397 {
398     NS_VERIFY_NOT_NULL_V(msg);
399
400     NSProvider_internal * provider = NSProviderCacheFind(msg->providerId);
401     NS_VERIFY_NOT_NULL_V(provider);
402
403     NSTask * topicTask = NSMakeTask(TASK_CONSUMER_REQ_TOPIC_LIST, (void *) provider);
404     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(topicTask, NSRemoveProvider_internal(provider));
405
406     NSConsumerPushEvent(topicTask);
407 }
408
409 void NSConsumerHandleRecvTopicLL(NSProvider_internal * provider)
410 {
411     NS_VERIFY_NOT_NULL_V(provider);
412
413     NSRemoveConnections(provider->connection);
414     provider->connection = NULL;
415
416     NSProvider_internal * cachedProvider = NSProviderCacheFind(provider->providerId);
417     NS_VERIFY_NOT_NULL_V(cachedProvider);
418
419     if (!cachedProvider->topicLL && !provider->topicLL)
420     {
421         NS_LOG(DEBUG, "topic is null and previous status is same.");
422         NSRemoveProvider_internal(cachedProvider);
423         return;
424     }
425     NSRemoveProvider_internal(cachedProvider);
426
427     NSResult ret = NSProviderCacheUpdate(provider);
428     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
429
430     NS_LOG(DEBUG, "call back to user");
431     NSProvider * prov = NSCopyProvider(provider);
432     NSProviderChanged((NSProvider *) prov, (NSProviderState) NS_TOPIC);
433 }
434
435 void NSConsumerInternalTaskProcessing(NSTask * task)
436 {
437     NS_VERIFY_NOT_NULL_V(task);
438
439     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
440     switch (task->taskType)
441     {
442         case TASK_CONSUMER_SENT_REQ_OBSERVE:
443         {
444             NS_LOG(DEBUG, "Receive Subscribe succeed from provider.");
445             NSConsumerHandleSubscribeSucceed((NSProvider_internal *)task->taskData);
446             NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
447             break;
448         }
449         case TASK_CONSUMER_RECV_PROVIDER_CHANGED:
450         {
451             NS_LOG(DEBUG, "Receive Provider Changed");
452             NSConsumerHandleRecvProviderChanged((NSMessage *)task->taskData);
453             NSRemoveMessage((NSMessage *)task->taskData);
454             break;
455         }
456         case TASK_CONSUMER_RECV_MESSAGE:
457         {
458             NS_LOG(DEBUG, "Receive New Notification");
459             NSConsumerHandleRecvMessage((NSMessage *)task->taskData);
460             NSRemoveMessage((NSMessage *)task->taskData);
461             break;
462         }
463         case TASK_CONSUMER_PROVIDER_DISCOVERED:
464         {
465             NS_LOG(DEBUG, "Receive New Provider is discovered.");
466             NSConsumerHandleProviderDiscovered((NSProvider_internal *)task->taskData);
467             NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
468             break;
469         }
470         case TASK_RECV_SYNCINFO:
471         {
472             NS_LOG(DEBUG, "Receive SyncInfo.");
473             NSConsumerHandleRecvSyncInfo((NSSyncInfo *)task->taskData);
474             NSOICFree(task->taskData);
475             break;
476         }
477         case TASK_MAKE_SYNCINFO:
478         {
479             NS_LOG(DEBUG, "Make SyncInfo, get Provider's Addr");
480             NSConsumerHandleMakeSyncInfo((NSSyncInfo *)task->taskData);
481             NSOICFree(task->taskData);
482             break;
483         }
484         case TASK_CONSUMER_REQ_TOPIC_URI:
485         {
486             NS_LOG(DEBUG, "Request Topic Uri");
487             NSConsumerHandleGetTopicUri((NSMessage *)task->taskData);
488             NSRemoveMessage((NSMessage *)task->taskData);
489             break;
490         }
491         case TASK_CONSUMER_RECV_TOPIC_LIST:
492         {
493             NS_LOG(DEBUG, "Receive Topic List");
494             NSConsumerHandleRecvTopicLL((NSProvider_internal *)task->taskData);
495             NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
496             break;
497         }
498         case TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL:
499         {
500             NS_LOG(DEBUG, "Make Subscribe cancel from provider.");
501             NSConsumerHandleProviderDeleted((NSProvider_internal *)task->taskData);
502             NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
503             break;
504         }
505         default :
506         {
507             NS_LOG(ERROR, "Unknown TASK Type");
508             return ;
509         }
510     }
511     NSOICFree(task);
512 }
513
514 // implements of MessageState function
515 pthread_mutex_t ** NSGetMessageListMutex()
516 {
517     static pthread_mutex_t * g_mutex = NULL;
518     if (g_mutex == NULL)
519     {
520         g_mutex = (pthread_mutex_t *) OICMalloc(sizeof(pthread_mutex_t));
521         NS_VERIFY_NOT_NULL(g_mutex, NULL);
522
523         pthread_mutex_init(g_mutex, NULL);
524     }
525     return & g_mutex;
526 }
527
528 void NSLockMessageListMutex()
529 {
530     NS_LOG_V(DEBUG, "%s", __func__);
531     pthread_mutex_lock(*NSGetMessageListMutex());
532 }
533
534 void NSUnlockMessageListMutex()
535 {
536     NS_LOG_V(DEBUG, "%s", __func__);
537     pthread_mutex_unlock(*NSGetMessageListMutex());
538 }
539
540 NSMessageStateList * NSGetMessageStateList()
541 {
542     static NSMessageStateList * g_messageStateList = NULL;
543     if (g_messageStateList == NULL)
544     {
545         g_messageStateList = (NSMessageStateList *)OICMalloc(sizeof(NSMessageStateList));
546         NS_VERIFY_NOT_NULL(g_messageStateList, NULL);
547
548         g_messageStateList->head = NULL;
549         g_messageStateList->tail = NULL;
550     }
551
552     return g_messageStateList;
553 }
554
555 NSMessageStateLL * NSFindMessageState(uint64_t msgId)
556 {
557     NS_LOG_V(DEBUG, "%s", __func__);
558     if (msgId <= NS_RESERVED_MESSAGEID) return NULL;
559     NSMessageStateLL * iter = NULL;
560
561     NSLockMessageListMutex();
562     if (NSGetMessageStateList()->head == NULL)
563     {
564         NSUnlockMessageListMutex();
565         return false;
566     }
567
568     for (iter = NSGetMessageStateList()->head; iter; iter = iter->next)
569     {
570         if (iter->messageId == msgId)
571         {
572             NSUnlockMessageListMutex();
573             return iter;
574         }
575     }
576
577     NSUnlockMessageListMutex();
578     return NULL;
579 }
580
581 bool NSUpdateMessageState(uint64_t msgId, NSSyncType state)
582 {
583     NS_LOG_V(DEBUG, "%s", __func__);
584     if (msgId <= NS_RESERVED_MESSAGEID) return NULL;
585     NSMessageStateLL * iter = NULL;
586
587     NSLockMessageListMutex();
588     for (iter = NSGetMessageStateList()->head; iter; iter = iter->next)
589     {
590         if (iter->messageId == msgId && state != iter->state)
591         {
592             iter->state = state;
593             NSUnlockMessageListMutex();
594             return true;
595         }
596     }
597
598     NSUnlockMessageListMutex();
599     return false;
600 }
601
602 bool NSDeleteMessageState(uint64_t msgId)
603 {
604     NS_LOG_V(DEBUG, "%s", __func__);
605     if (msgId <= NS_RESERVED_MESSAGEID) return NULL;
606     NSMessageStateLL * iter = NULL;
607     NSMessageStateLL * prev = NULL;
608
609     NSLockMessageListMutex();
610     for (iter = NSGetMessageStateList()->head; iter; iter = iter->next)
611     {
612         if (iter->messageId == msgId)
613         {
614             if (iter == NSGetMessageStateList()->head)
615             {
616                 NSGetMessageStateList()->head = NULL;
617                 NSGetMessageStateList()->tail = NULL;
618             }
619             else if (iter == NSGetMessageStateList()->tail)
620             {
621                 prev->next = NULL;
622                 NSGetMessageStateList()->tail = prev;
623             }
624             else
625             {
626                 prev->next = iter->next;
627             }
628             NSUnlockMessageListMutex();
629
630             NSOICFree(iter);
631             return true;
632         }
633         prev = iter;
634     }
635
636     NSUnlockMessageListMutex();
637     return false;
638 }
639
640 bool NSInsertMessageState(uint64_t msgId, NSSyncType state)
641 {
642     NS_LOG_V(DEBUG, "%s", __func__);
643     if (NSFindMessageState(msgId))
644     {
645         return false;
646     }
647
648     NSMessageStateLL * insertMsg = (NSMessageStateLL * )OICMalloc(sizeof(NSMessageStateLL));
649     NS_VERIFY_NOT_NULL(insertMsg, false);
650
651     insertMsg->messageId = msgId;
652     insertMsg->state = state;
653     insertMsg->next = NULL;
654
655     NSLockMessageListMutex();
656     if (NSGetMessageStateList()->head == NULL)
657     {
658         NSGetMessageStateList()->head = insertMsg;
659     }
660     else
661     {
662         NSGetMessageStateList()->tail->next = insertMsg;
663     }
664     NSGetMessageStateList()->tail = insertMsg;
665     NSUnlockMessageListMutex();
666
667     return true;
668 }
669
670 void NSDestroyMessageStateList()
671 {
672     NS_LOG_V(DEBUG, "%s", __func__);
673     NSLockMessageListMutex();
674
675     NSMessageStateLL * iter = NSGetMessageStateList()->head;
676     while (iter)
677     {
678         NSMessageStateLL * del = iter;
679         iter = iter->next;
680         NSOICFree(del);
681     }
682
683     NSGetMessageStateList()->head = NULL;
684     NSGetMessageStateList()->tail = NULL;
685
686     NSUnlockMessageListMutex();
687 }