#include "NSStructs.h"
#include "oic_malloc.h"
+#include "oic_string.h"
-NSCacheList ** NSGetCacheList()
+#define NS_RESERVED_MESSAGEID 10
+
+// MessageState storage structure
+typedef struct _NSMessageStateLL
+{
+ uint64_t messageId;
+ NSSyncType state;
+ struct _NSMessageStateLL * next;
+
+} NSMessageStateLL;
+
+typedef struct
+{
+ NSMessageStateLL * head;
+ NSMessageStateLL * tail;
+
+} NSMessageStateList;
+
+// Mutex of MessageState storage
+pthread_mutex_t ** NSGetMessageListMutex();
+void NSLockMessageListMutex();
+void NSUnlockMessageListMutex();
+
+// Function for MessageState
+NSMessageStateList * NSGetMessageStateList();
+NSMessageStateLL * NSFindMessageState(uint64_t msgId);
+bool NSUpdateMessageState(uint64_t msgId, NSSyncType state);
+bool NSDeleteMessageState(uint64_t msgId);
+bool NSInsertMessageState(uint64_t msgId, NSSyncType state);
+void NSDestroyMessageStateList();
+
+NSCacheList ** NSGetProviderCacheList()
{
- static NSCacheList * cache = NULL;
- return & cache;
+ static NSCacheList * providerCache = NULL;
+ return & providerCache;
}
-void NSSetCacheList(NSCacheList * cache)
+void NSSetProviderCacheList(NSCacheList * cache)
{
- *(NSGetCacheList()) = cache;
+ *(NSGetProviderCacheList()) = cache;
}
-void NSDestroyCacheList()
+void NSDestroyInternalCachedList()
{
- NSCacheList * cache;
- cache = *(NSGetCacheList());
- if (!cache)
+ NSCacheList * cache = *(NSGetProviderCacheList());
+ if (cache)
{
- NSStorageDestroy(cache);
+ NSConsumerStorageDestroy(cache);
}
+
+ NSSetProviderCacheList(NULL);
+
+ NSDestroyMessageStateList();
+ pthread_mutex_destroy(*NSGetMessageListMutex());
+ NSOICFree(*NSGetMessageListMutex());
}
-NSResult NSCacheUpdate(NSCacheList * cache, NSTask * task, NSConsumerMessageTypes type)
+NSProvider_internal * NSProviderCacheFind(const char * providerId)
{
- NSMessage_consumer * noti = (NSMessage_consumer *) task->taskData;
- noti->type = type;
+ NS_VERIFY_NOT_NULL(providerId, NULL);
- NSCacheElement * obj = (NSCacheElement *)OICMalloc(sizeof(NSCacheElement));
- if (!obj)
+ NSCacheList * ProviderCache = *(NSGetProviderCacheList());
+ if (!ProviderCache)
{
- NS_LOG(ERROR, "Cache allocation is failed");
+ NS_LOG(DEBUG, "Provider Cache Init");
+ ProviderCache = NSConsumerStorageCreate();
+ NS_VERIFY_NOT_NULL(ProviderCache, NULL);
+
+ ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
+ NSSetProviderCacheList(ProviderCache);
}
- obj->data = (NSCacheData *) noti;
- obj->next = NULL;
- if (NS_OK != NSStorageWrite(cache, obj))
+ NSCacheElement * cacheElement = NSConsumerStorageRead(ProviderCache, providerId);
+ NS_VERIFY_NOT_NULL(cacheElement, NULL);
+
+ return NSCopyProvider_internal((NSProvider_internal *) cacheElement->data);
+}
+
+NSProvider_internal * NSFindProviderFromAddr(OCDevAddr * addr)
+{
+ NS_VERIFY_NOT_NULL(addr, NULL);
+
+ NSCacheList * ProviderCache = *(NSGetProviderCacheList());
+ if (!ProviderCache)
{
- NS_LOG(ERROR, "Cache write fail");
- return NS_ERROR;
+ NS_LOG(DEBUG, "Provider Cache does not intialized.");
+ return NULL;
}
- NSRemoveMessage(noti);
- OICFree(obj);
+ NSCacheElement * cacheElement =
+ NSGetProviderFromAddr(ProviderCache, addr->addr, addr->port);
+
+ NS_VERIFY_NOT_NULL(cacheElement, NULL);
+
+ return NSCopyProvider_internal((NSProvider_internal *) cacheElement->data);
+}
+
+NSResult NSProviderCacheUpdate(NSProvider_internal * provider)
+{
+ NSCacheList * ProviderCache = *(NSGetProviderCacheList());
+ if (!ProviderCache)
+ {
+ NS_LOG(DEBUG, "Provider Cache Init");
+ ProviderCache = NSConsumerStorageCreate();
+ NS_VERIFY_NOT_NULL(ProviderCache, NS_ERROR);
+
+ ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
+ NSSetProviderCacheList(ProviderCache);
+ }
+
+ NS_VERIFY_NOT_NULL(provider, NS_ERROR);
+
+ NSCacheElement * obj = (NSCacheElement *)OICMalloc(sizeof(NSCacheElement));
+ NS_VERIFY_NOT_NULL(obj, NS_ERROR);
+
+ obj->data = (NSCacheData *) provider;
+ obj->next = NULL;
+
+ NS_LOG(DEBUG, "try to write to storage");
+ NSResult ret = NSConsumerStorageWrite(ProviderCache, obj);
+ NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == NS_OK ? (void *) 1 : NULL,
+ NS_ERROR, NSOICFree(obj));
+
+ NSOICFree(obj);
return NS_OK;
}
-void NSConsumerSubscriptionTaskProcessing(NSTask * task)
+void NSCancelAllSubscription()
{
- if (!task)
+ NSCacheList * ProviderCache = *(NSGetProviderCacheList());
+ if (!ProviderCache)
{
- NS_LOG(ERROR, "task is null");
- return;
+ NS_LOG(DEBUG, "Provider Cache Init");
+ ProviderCache = NSConsumerStorageCreate();
+ NS_VERIFY_NOT_NULL_V(ProviderCache);
+
+ ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
+ NSSetProviderCacheList(ProviderCache);
}
- NSCacheList * cache;
- if (!*(NSGetCacheList()))
+ NSCacheElement * obj = NSPopProviderCacheList(ProviderCache);
+ while (obj)
{
- NS_LOG(DEBUG, "Cache Init");
- cache = NSStorageCreate();
- cache->cacheType = NS_CONSUMER_CACHE_MESSAGE;
- if (!cache)
- {
- NS_LOG(ERROR, "Cache create fail");
- return;
- }
- NSSetCacheList(cache);
+ NS_LOG(DEBUG, "build NSTask");
+ NSProvider * prov = NSCopyProvider((NSProvider_internal *) obj->data);
+ NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(prov,
+ NSRemoveProvider_internal((void *) obj->data));
+
+ NSTask * task = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, prov);
+ NS_VERIFY_NOT_NULL_V(task);
+
+ NSConsumerPushEvent(task);
+ NSRemoveProvider_internal((void *) obj->data);
+ NSOICFree(obj);
+
+ obj = NSPopProviderCacheList(ProviderCache);
}
- cache = *(NSGetCacheList());
+}
- NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
+void NSConsumerHandleProviderDiscovered(NSProvider_internal * provider)
+{
+ NS_VERIFY_NOT_NULL_V(provider);
- switch (task->taskType)
+ bool isAdded = true;
+ bool isSubscribing = false;
+
+ NSProvider_internal * providerCacheDataFromAddr
+ = NSFindProviderFromAddr(provider->connection->addr);
+
+ if (providerCacheDataFromAddr)
{
- case TASK_CONSUMER_RECV_NOTIFICATION:
+ if (!strcmp(providerCacheDataFromAddr->providerId, provider->providerId))
{
- NS_LOG(DEBUG, "Receive New Notification");
+ NSProviderConnectionInfo * infos = providerCacheDataFromAddr->connection;
+ while (infos)
+ {
+ isSubscribing |= infos->isSubscribing;
+ infos = infos->next;
+ }
- if (NS_OK != NSCacheUpdate(cache, task, Notification))
+ if (isSubscribing == false)
{
- NS_LOG(ERROR, "Cache Update fail");
- return;
+ NSProvider * providerForCb = NSCopyProvider(providerCacheDataFromAddr);
+ NSProviderChanged(providerForCb, NS_DISCOVERED);
+ NSRemoveProvider(providerForCb);
}
- break;
+ NSRemoveProvider_internal(providerCacheDataFromAddr);
+ return ;
}
- case TASK_RECV_READ:
- {
- NS_LOG(DEBUG, "Receive Read Notification");
+ NSRemoveProvider_internal(providerCacheDataFromAddr);
+ }
- if (NS_OK != NSCacheUpdate(cache, task, Read))
+ NSProvider_internal * providerCacheData = NSProviderCacheFind(provider->providerId);
+
+ if (providerCacheData == NULL)
+ {
+ isAdded = false;
+ }
+ else
+ {
+ providerCacheData->accessPolicy = provider->accessPolicy;
+ NSProviderConnectionInfo * infos = providerCacheData->connection;
+ OCTransportAdapter newAdapter = provider->connection->addr->adapter;
+ while (infos)
+ {
+ isSubscribing |= infos->isSubscribing;
+ if (infos->addr->adapter == newAdapter && infos->isSubscribing == true)
{
- NS_LOG(ERROR, "Cache Update fail");
+ NS_LOG_V(INFO_PRIVATE, "This provider already discovered : %s:%d",
+ infos->addr->addr, infos->addr->port);
+ NS_LOG_V(DEBUG, "Subscription : %d", infos->isSubscribing);
return;
}
+ infos = infos->next;
+ }
+ }
+
+ NSResult ret = NSProviderCacheUpdate(provider);
+ NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(ret == NS_OK ? (void *) 1 : NULL,
+ NSRemoveProvider_internal(providerCacheData));
+
+ if (isAdded == false)
+ {
+ NS_LOG(DEBUG, "New provider is discovered");
+ }
+ else
+ {
+ provider = providerCacheData;
+ NS_LOG(DEBUG, "provider's connection is updated.");
+ }
+
+ if (provider->accessPolicy == NS_SELECTION_CONSUMER && isSubscribing == false)
+ {
+ NS_LOG(DEBUG, "accepter is NS_ACCEPTER_CONSUMER, Callback to user");
+ NSProvider * prov = NSCopyProvider(provider);
+ NSProviderChanged(prov, NS_DISCOVERED);
+ NSRemoveProvider(prov);
+ }
+ else
+ {
+ NS_LOG(DEBUG, "accepter is NS_ACCEPTER_PROVIDER, request subscribe");
+ NSProvider * subProvider = NSCopyProvider(provider);
+ NSTask * task = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE, (void *) subProvider);
+ NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(task,
+ NSRemoveProvider_internal(providerCacheData));
+
+ NSConsumerPushEvent(task);
+ }
+
+ NSRemoveProvider_internal(providerCacheData);
+}
+
+void NSConsumerHandleProviderDeleted(NSProvider_internal * provider)
+{
+ NS_VERIFY_NOT_NULL_V(provider);
+
+ NSCacheList * providerCache = *(NSGetProviderCacheList());
+ NS_VERIFY_NOT_NULL_V(providerCache);
+
+ NSResult ret = NSConsumerStorageDelete(providerCache, provider->providerId);
+ NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
+
+ NS_LOG_V(INFO_PRIVATE, "Stopped Provider : %s", provider->providerId);
+ NSProvider * prov = NSCopyProvider(provider);
+ NSProviderChanged(prov, NS_STOPPED);
+ NSRemoveProvider(prov);
+}
+
+void NSConsumerHandleSubscribeSucceed(NSProvider_internal * provider)
+{
+ NS_VERIFY_NOT_NULL_V(provider);
+
+ NSCacheList * ProviderCache = *(NSGetProviderCacheList());
+
+ NSCacheElement * cacheElement = NSConsumerStorageRead(ProviderCache, provider->providerId);
+ NS_VERIFY_NOT_NULL_V(cacheElement);
+
+ pthread_mutex_t * mutex = NSGetCacheMutex();
+ pthread_mutex_lock(mutex);
+
+ NS_VERIFY_NOT_NULL_V(cacheElement);
+ NSProvider_internal * prov = (NSProvider_internal *)cacheElement->data;
+ NSProviderConnectionInfo *infos = prov->connection;
+ while(infos)
+ {
+ infos->isSubscribing = true;
+ infos = infos->next;
+ }
+
+ pthread_mutex_unlock(mutex);
+}
+
+void NSConsumerHandleRecvProviderChanged(NSMessage * msg)
+{
+ NS_VERIFY_NOT_NULL_V(msg);
+
+ NS_LOG_V(INFO_PRIVATE, "confirmed by : %s", msg->providerId);
+
+ NSCacheList * ProviderCache = *(NSGetProviderCacheList());
+
+ NSCacheElement * cacheElement = NSConsumerStorageRead(ProviderCache, msg->providerId);
+ NS_VERIFY_NOT_NULL_V(cacheElement);
+
+ pthread_mutex_t * mutex = NSGetCacheMutex();
+ pthread_mutex_lock(mutex);
+ NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(cacheElement, pthread_mutex_unlock(mutex));
+ NSProvider_internal * provider = (NSProvider_internal *) cacheElement->data;
+ if (provider->state == (NSProviderState) msg->messageId)
+ {
+ NS_LOG_V(DEBUG, "Already receive message(ALLOW/DENY) : %d", (int) msg->messageId);
+ pthread_mutex_unlock(mutex);
+ return;
+ }
+
+ NS_LOG_V(DEBUG, "Provider State Changed %d -> %d",
+ (int) provider->state, (int) msg->messageId);
+ NS_LOG(DEBUG, "call back to user");
+ provider->state = (NSProviderState) msg->messageId;
+
+ NSProvider * prov = NSCopyProvider(provider);
+
+ pthread_mutex_unlock(mutex);
+ NSProviderChanged(prov, (NSProviderState) msg->messageId);
+ NSRemoveProvider(prov);
+}
+
+void NSConsumerHandleRecvMessage(NSMessage * msg)
+{
+ NS_VERIFY_NOT_NULL_V(msg);
+
+ if (NSInsertMessageState(msg->messageId, NS_SYNC_UNREAD))
+ {
+ NSMessagePost(msg);
+ }
+}
+
+void NSConsumerHandleRecvSyncInfo(NSSyncInfo * sync)
+{
+ NS_VERIFY_NOT_NULL_V(sync);
+
+ if (NSUpdateMessageState(sync->messageId, sync->state))
+ {
+ NSNotificationSync(sync);
+ }
+
+ if (sync->state == NS_SYNC_DELETED)
+ {
+ NSDeleteMessageState(sync->messageId);
+ }
+}
+
+void NSConsumerHandleMakeSyncInfo(NSSyncInfo * sync)
+{
+ NS_VERIFY_NOT_NULL_V(sync);
+
+ NSProvider_internal * provider = NSProviderCacheFind(sync->providerId);
+ NS_VERIFY_NOT_NULL_V (provider);
+
+ NSProviderConnectionInfo * connections = NSCopyProviderConnections(provider->connection);
+ NSRemoveProvider_internal((void *) provider);
+ NS_VERIFY_NOT_NULL_V (connections);
+
+ NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)OICMalloc(sizeof(NSSyncInfo_internal));
+ NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncInfo, NSRemoveConnections(connections));
+
+ OICStrcpy(syncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, sync->providerId);
+ syncInfo->messageId = sync->messageId;
+ syncInfo->state = sync->state;
+ syncInfo->connection = connections;
+
+ NSTask * syncTask = NSMakeTask(TASK_SEND_SYNCINFO, (void *) syncInfo);
+ NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncTask, NSOICFree(syncInfo));
+
+ NSConsumerPushEvent(syncTask);
+}
+
+void NSConsumerHandleGetTopicUri(NSMessage * msg)
+{
+ NS_VERIFY_NOT_NULL_V(msg);
+
+ NSProvider_internal * provider = NSProviderCacheFind(msg->providerId);
+ NS_VERIFY_NOT_NULL_V(provider);
+
+ NSTask * topicTask = NSMakeTask(TASK_CONSUMER_REQ_TOPIC_LIST, (void *) provider);
+ NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(topicTask, NSRemoveProvider_internal(provider));
+
+ NSConsumerPushEvent(topicTask);
+}
+
+void NSConsumerHandleRecvTopicLL(NSProvider_internal * provider)
+{
+ NS_VERIFY_NOT_NULL_V(provider);
+
+ NSRemoveConnections(provider->connection);
+ provider->connection = NULL;
+
+ NSProvider_internal * cachedProvider = NSProviderCacheFind(provider->providerId);
+ NS_VERIFY_NOT_NULL_V(cachedProvider);
+
+ if (!cachedProvider->topicLL && !provider->topicLL)
+ {
+ NS_LOG(DEBUG, "topic is null and previous status is same.");
+ NSRemoveProvider_internal(cachedProvider);
+ return;
+ }
+ NSRemoveProvider_internal(cachedProvider);
+
+ NSResult ret = NSProviderCacheUpdate(provider);
+ NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
+
+ NS_LOG(DEBUG, "call back to user");
+ NSProvider * prov = NSCopyProvider(provider);
+ NSProviderChanged((NSProvider *) prov, (NSProviderState) NS_TOPIC);
+ NSRemoveProvider(prov);
+}
+
+void NSConsumerInternalTaskProcessing(NSTask * task)
+{
+ NS_VERIFY_NOT_NULL_V(task);
+
+ NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
+ switch (task->taskType)
+ {
+ case TASK_CONSUMER_SENT_REQ_OBSERVE:
+ {
+ NS_LOG(DEBUG, "Receive Subscribe succeed from provider.");
+ NSConsumerHandleSubscribeSucceed((NSProvider_internal *)task->taskData);
+ NSRemoveProvider_internal((void *)task->taskData);
break;
}
- case TASK_RECV_DISMISS:
+ case TASK_CONSUMER_RECV_PROVIDER_CHANGED:
{
- NS_LOG(DEBUG, "Receive Dismiss Notification");
- if (NS_OK != NSCacheUpdate(cache, task, Dismiss))
- {
- NS_LOG(ERROR, "Cache Update fail");
- return;
- }
+ NS_LOG(DEBUG, "Receive Provider Changed");
+ NSConsumerHandleRecvProviderChanged((NSMessage *)task->taskData);
+ NSRemoveMessage((NSMessage *)task->taskData);
+ break;
+ }
+ case TASK_CONSUMER_RECV_MESSAGE:
+ {
+ NS_LOG(DEBUG, "Receive New Notification");
+ NSConsumerHandleRecvMessage((NSMessage *)task->taskData);
+ NSRemoveMessage((NSMessage *)task->taskData);
+ break;
+ }
+ case TASK_CONSUMER_PROVIDER_DISCOVERED:
+ {
+ NS_LOG(DEBUG, "Receive New Provider is discovered.");
+ NSConsumerHandleProviderDiscovered((NSProvider_internal *)task->taskData);
+ NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
+ break;
+ }
+ case TASK_RECV_SYNCINFO:
+ {
+ NS_LOG(DEBUG, "Receive SyncInfo.");
+ NSConsumerHandleRecvSyncInfo((NSSyncInfo *)task->taskData);
+ NSOICFree(task->taskData);
+ break;
+ }
+ case TASK_MAKE_SYNCINFO:
+ {
+ NS_LOG(DEBUG, "Make SyncInfo, get Provider's Addr");
+ NSConsumerHandleMakeSyncInfo((NSSyncInfo *)task->taskData);
+ NSOICFree(task->taskData);
+ break;
+ }
+ case TASK_CONSUMER_REQ_TOPIC_URI:
+ {
+ NS_LOG(DEBUG, "Request Topic Uri");
+ NSConsumerHandleGetTopicUri((NSMessage *)task->taskData);
+ NSRemoveMessage((NSMessage *)task->taskData);
+ break;
+ }
+ case TASK_CONSUMER_RECV_TOPIC_LIST:
+ {
+ NS_LOG(DEBUG, "Receive Topic List");
+ NSConsumerHandleRecvTopicLL((NSProvider_internal *)task->taskData);
+ NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
+ break;
+ }
+ case TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL:
+ {
+ NS_LOG(DEBUG, "Make Subscribe cancel from provider.");
+ NSConsumerHandleProviderDeleted((NSProvider_internal *)task->taskData);
+ NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
break;
}
default :
return ;
}
}
+ NSOICFree(task);
+}
+
+// implements of MessageState function
+pthread_mutex_t ** NSGetMessageListMutex()
+{
+ static pthread_mutex_t * g_mutex = NULL;
+ if (g_mutex == NULL)
+ {
+ g_mutex = (pthread_mutex_t *) OICMalloc(sizeof(pthread_mutex_t));
+ NS_VERIFY_NOT_NULL(g_mutex, NULL);
+
+ pthread_mutex_init(g_mutex, NULL);
+ }
+ return & g_mutex;
+}
+
+void NSLockMessageListMutex()
+{
+ NS_LOG_V(DEBUG, "%s", __func__);
+ pthread_mutex_lock(*NSGetMessageListMutex());
+}
+
+void NSUnlockMessageListMutex()
+{
+ NS_LOG_V(DEBUG, "%s", __func__);
+ pthread_mutex_unlock(*NSGetMessageListMutex());
+}
+
+NSMessageStateList ** NSGetMessageStateListAddr()
+{
+ static NSMessageStateList * g_messageStateList = NULL;
+ if (g_messageStateList == NULL)
+ {
+ g_messageStateList = (NSMessageStateList *)OICMalloc(sizeof(NSMessageStateList));
+ NS_VERIFY_NOT_NULL(g_messageStateList, NULL);
+
+ g_messageStateList->head = NULL;
+ g_messageStateList->tail = NULL;
+ }
+
+ return & g_messageStateList;
+}
+
+NSMessageStateList * NSGetMessageStateList()
+{
+ return * NSGetMessageStateListAddr();
+}
+
+NSMessageStateLL * NSFindMessageState(uint64_t msgId)
+{
+ NS_LOG_V(DEBUG, "%s", __func__);
+ if (msgId <= NS_RESERVED_MESSAGEID)
+ {
+ return NULL;
+ }
+ NSMessageStateLL * iter = NULL;
+
+ NSLockMessageListMutex();
+ if (NSGetMessageStateList()->head == NULL)
+ {
+ NSUnlockMessageListMutex();
+ return NULL;
+ }
+
+ for (iter = NSGetMessageStateList()->head; iter; iter = iter->next)
+ {
+ if (iter->messageId == msgId)
+ {
+ NSUnlockMessageListMutex();
+ return iter;
+ }
+ }
+
+ NSUnlockMessageListMutex();
+ return NULL;
+}
+
+bool NSUpdateMessageState(uint64_t msgId, NSSyncType state)
+{
+ NS_LOG_V(DEBUG, "%s", __func__);
+ if (msgId <= NS_RESERVED_MESSAGEID)
+ {
+ return false;
+ }
+ NSMessageStateLL * iter = NULL;
+
+ NSLockMessageListMutex();
+ for (iter = NSGetMessageStateList()->head; iter; iter = iter->next)
+ {
+ if (iter->messageId == msgId && state != iter->state)
+ {
+ iter->state = state;
+ NSUnlockMessageListMutex();
+ return true;
+ }
+ }
+
+ NSUnlockMessageListMutex();
+ return false;
+}
+
+bool NSDeleteMessageState(uint64_t msgId)
+{
+ NS_LOG_V(DEBUG, "%s", __func__);
+ if (msgId <= NS_RESERVED_MESSAGEID)
+ {
+ return false;
+ }
+
+ NSMessageStateLL * iter = NULL;
+ NSMessageStateLL * prev = NULL;
+
+ NSLockMessageListMutex();
+ for (iter = NSGetMessageStateList()->head; iter; iter = iter->next)
+ {
+ if (iter->messageId == msgId)
+ {
+ if (iter == NSGetMessageStateList()->head)
+ {
+ NSGetMessageStateList()->head = NULL;
+ NSGetMessageStateList()->tail = NULL;
+ }
+ else if (iter == NSGetMessageStateList()->tail)
+ {
+ prev->next = NULL;
+ NSGetMessageStateList()->tail = prev;
+ }
+ else
+ {
+ prev->next = iter->next;
+ }
+ NSUnlockMessageListMutex();
+
+ NSOICFree(iter);
+ return true;
+ }
+ prev = iter;
+ }
+
+ NSUnlockMessageListMutex();
+ return false;
+}
+
+bool NSInsertMessageState(uint64_t msgId, NSSyncType state)
+{
+ NS_LOG_V(DEBUG, "%s", __func__);
+ if (NSFindMessageState(msgId))
+ {
+ return false;
+ }
+
+ NSMessageStateLL * insertMsg = (NSMessageStateLL * )OICMalloc(sizeof(NSMessageStateLL));
+ NS_VERIFY_NOT_NULL(insertMsg, false);
+
+ insertMsg->messageId = msgId;
+ insertMsg->state = state;
+ insertMsg->next = NULL;
+
+ NSLockMessageListMutex();
+ if (NSGetMessageStateList()->head == NULL)
+ {
+ NSGetMessageStateList()->head = insertMsg;
+ }
+ else
+ {
+ NSGetMessageStateList()->tail->next = insertMsg;
+ }
+ NSGetMessageStateList()->tail = insertMsg;
+ NSUnlockMessageListMutex();
+
+ return true;
+}
+
+void NSDestroyMessageStateList()
+{
+ NS_LOG_V(DEBUG, "%s", __func__);
+ NSLockMessageListMutex();
+
+ NSMessageStateLL * iter = NSGetMessageStateList()->head;
+ while (iter)
+ {
+ NSMessageStateLL * del = iter;
+ iter = iter->next;
+ NSOICFree(del);
+ }
+
+ NSGetMessageStateList()->head = NULL;
+ NSGetMessageStateList()->tail = NULL;
+
+ NSUnlockMessageListMutex();
+
+ pthread_mutex_t * mu = *NSGetMessageListMutex();
+ pthread_mutex_destroy(mu);
+ NSOICFree(mu);
+ *NSGetMessageListMutex() = NULL;
+
+ NSMessageStateList * list = NSGetMessageStateList();
+ NSOICFree(list);
+ *NSGetMessageStateListAddr() = NULL;
}