setting received ttl value by consumer.
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerCommon.c
index 1f84137..a790c4b 100644 (file)
 #include "NSThread.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
+#include "ocpayload.h"
 
 #include <pthread.h>
 
-#define NS_QUERY_CONSUMER_ID "consumerid"
+#define NS_QUERY_CONSUMER_ID "consumerId"
 
 pthread_mutex_t ** NSGetStackMutex()
 {
@@ -98,6 +99,16 @@ bool * NSGetBoneIsStartedConsumer()
 void NSSetIsStartedConsumer(bool setValue)
 {
     * NSGetBoneIsStartedConsumer() = setValue;
+
+    if (setValue == false)
+    {
+        pthread_mutex_destroy(*NSGetStackMutex());
+        NSOICFree(*NSGetStackMutex());
+        *NSGetStackMutex() = NULL;
+
+        NSOICFree(*NSGetConsumerId());
+        *NSGetConsumerId() = NULL;
+    }
 }
 
 bool NSIsStartedConsumer()
@@ -105,56 +116,55 @@ bool NSIsStartedConsumer()
     return * NSGetBoneIsStartedConsumer();
 }
 
-NSProviderDiscoveredCallback * NSGetBoneDiscoverCb()
+NSProviderStateCallback * NSGetProviderChangedCb()
 {
-    static NSProviderDiscoveredCallback g_discoverCb = NULL;
+    static NSProviderStateCallback g_changedCb = NULL;
 
-    return & g_discoverCb;
+    return & g_changedCb;
 }
 
-void NSSetDiscoverProviderCb(NSProviderDiscoveredCallback cb)
+void NSSetProviderChangedCb(NSProviderStateCallback cb)
 {
-    * NSGetBoneDiscoverCb() = cb;
+    *(NSGetProviderChangedCb()) = cb;
 }
 
-NSProviderDiscoveredCallback NSGetDiscoverCb()
+typedef struct
 {
-    return * NSGetBoneDiscoverCb();
-}
+    NSProvider * provider;
+    NSProviderState state;
+} NSProviderChangedData;
 
-void * NSDiscoveredProviderFunc(void * provider)
+void * NSProviderChangedFunc(void * obj)
 {
-    NSGetDiscoverCb()((NSProvider *) provider);
-
+    NSProviderChangedData * data = (NSProviderChangedData *) obj;
+    (*(NSGetProviderChangedCb()))(data->provider, data->state);
+    NSOICFree(data);
     return NULL;
 }
 
-void NSDiscoveredProvider(NSProvider * provider)
+void NSProviderChanged(NSProvider * provider, NSProviderState response)
 {
     NS_VERIFY_NOT_NULL_V(provider);
 
-    NSProvider * retProvider = (NSProvider *)NSCopyProvider((NSProvider_internal *)provider);
+    NSProvider * retProvider = NSCopyProvider((NSProvider_internal *) provider);
     NS_VERIFY_NOT_NULL_V(retProvider);
 
-    NSConsumerThread * thread = NSThreadInit(NSDiscoveredProviderFunc, (void *) retProvider);
-    NS_VERIFY_NOT_NULL_V(thread);
-}
+    NSProviderChangedData * data =
+            (NSProviderChangedData *)OICMalloc(sizeof(NSProviderChangedData));
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(data, NSRemoveProvider(retProvider));
 
-NSProviderChangedCallback * NSGetProviderChangedCb()
-{
-    static NSProviderChangedCallback g_changedCb = NULL;
-
-    return & g_changedCb;
-}
+    data->provider = retProvider;
+    data->state = response;
 
-void NSSetProviderChangedCb(NSProviderChangedCallback cb)
-{
-    *(NSGetProviderChangedCb()) = cb;
-}
+    NSConsumerThread * thread = NSThreadInit(NSProviderChangedFunc, (void *) data);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(thread,
+    {
+        NSRemoveProvider(retProvider);
+        NSOICFree(data);
+    });
 
-void NSProviderChanged(NSProvider * provider, NSResponse response)
-{
-    (*(NSGetProviderChangedCb()))(provider, response);
+    NSDestroyThreadHandle(thread);
+    NSOICFree(thread);
 }
 
 NSSyncInfoReceivedCallback * NSGetBoneNotificationSyncCb()
@@ -185,6 +195,9 @@ void NSNotificationSync(NSSyncInfo * sync)
 
     NSConsumerThread * thread = NSThreadInit(NSNotificationSyncFunc, (void *) retSync);
     NS_VERIFY_NOT_NULL_V(thread);
+
+    NSDestroyThreadHandle(thread);
+    NSOICFree(thread);
 }
 
 NSMessageReceivedCallback  * NSGetBoneMessagePostedCb()
@@ -219,6 +232,9 @@ void NSMessagePost(NSMessage * msg)
 
     NSConsumerThread * thread = NSThreadInit(NSMessagePostFunc, (void *) retMsg);
     NS_VERIFY_NOT_NULL_V(thread);
+
+    NSDestroyThreadHandle(thread);
+    NSOICFree(thread);
 }
 
 NSTask * NSMakeTask(NSTaskType type, void * data)
@@ -248,9 +264,33 @@ NSMessage * NSCopyMessage(NSMessage * msg)
     newMsg->sourceName = OICStrdup(msg->sourceName);
     newMsg->dateTime = OICStrdup(msg->dateTime);
     newMsg->type = msg->type;
+    newMsg->ttl= msg->ttl;
+
+    newMsg->topic = NULL;
+    if (msg->topic && strlen(msg->topic) > 0)
+    {
+        newMsg->topic = OICStrdup(msg->topic);
+    }
+
+    newMsg->mediaContents = NULL;
+    if (msg->mediaContents)
+    {
+        newMsg->mediaContents = (NSMediaContents *)OICMalloc(sizeof(NSMediaContents));
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(
+                newMsg->mediaContents, NULL, NSRemoveMessage(newMsg));
+        newMsg->mediaContents->iconImage =
+                (char *)OICMalloc(sizeof(char)*strlen(msg->mediaContents->iconImage) + 1);
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(
+                newMsg->mediaContents->iconImage, NULL, NSRemoveMessage(newMsg));
+        memcpy(newMsg->mediaContents->iconImage, msg->mediaContents->iconImage,
+               strlen(msg->mediaContents->iconImage) + 1);
+    }
 
-    // TODO change to copy function.
-    newMsg->mediaContents = msg->mediaContents;
+    newMsg->extraInfo = NULL;
+    if (msg->extraInfo)
+    {
+        newMsg->extraInfo = OCRepPayloadClone(msg->extraInfo);
+    }
 
     return newMsg;
 }
@@ -263,10 +303,20 @@ void NSRemoveMessage(NSMessage * msg)
     NSOICFree(msg->contentText);
     NSOICFree(msg->sourceName);
     NSOICFree(msg->dateTime);
+    NSOICFree(msg->topic);
 
-    // TODO change to remove function.
+    if (msg->mediaContents)
+    {
+        NSOICFree(msg->mediaContents->iconImage);
+    }
     NSOICFree(msg->mediaContents);
 
+    if (msg->extraInfo)
+    {
+        OCRepPayloadDestroy(msg->extraInfo);
+        msg->extraInfo = NULL;
+    }
+
     NSOICFree(msg);
 }
 
@@ -281,10 +331,10 @@ void NSRemoveConnections(NSProviderConnectionInfo * connections)
         tmp->messageHandle = NULL;
         tmp->syncHandle = NULL;
         NSOICFree(tmp->addr);
-        tmp = tmp->next;
+        NSProviderConnectionInfo * next = tmp->next;
+        NSOICFree(tmp);
+        tmp = next;
     }
-
-    NSOICFree(connections);
 }
 
 NSProviderConnectionInfo * NSCreateProviderConnections(OCDevAddr * inAddr)
@@ -317,95 +367,209 @@ NSProviderConnectionInfo * NSCopyProviderConnections(NSProviderConnectionInfo *
 
     NSProviderConnectionInfo * retInfo = NSCreateProviderConnections(tmp->addr);
     NS_VERIFY_NOT_NULL(retInfo, NULL);
+    retInfo->messageHandle = tmp->messageHandle;
+    retInfo->syncHandle = tmp->syncHandle;
+    retInfo->isCloudConnection = tmp->isCloudConnection;
+    retInfo->isSubscribing = tmp->isSubscribing;
+
     tmp = tmp->next;
     NSProviderConnectionInfo * copyInfo = retInfo;
 
     while(tmp)
     {
-        copyInfo = NSCreateProviderConnections(tmp->addr);
-        NS_VERIFY_NOT_NULL(copyInfo, NULL);
+        NSProviderConnectionInfo * tmpInfo = NSCreateProviderConnections(tmp->addr);
+        NS_VERIFY_NOT_NULL(tmpInfo, NULL);
 
-        copyInfo->messageHandle = tmp->messageHandle;
-        copyInfo->syncHandle = tmp->syncHandle;
-        copyInfo->isCloudConnection = tmp->isCloudConnection;
-        copyInfo->isSubscribing = tmp->isSubscribing;
+        tmpInfo->messageHandle = tmp->messageHandle;
+        tmpInfo->syncHandle = tmp->syncHandle;
+        tmpInfo->isCloudConnection = tmp->isCloudConnection;
+        tmpInfo->isSubscribing = tmp->isSubscribing;
         tmp = tmp->next;
-        copyInfo = copyInfo->next;
+        copyInfo->next = tmpInfo;
+        copyInfo = tmpInfo;
     }
 
     return retInfo;
 }
 
-NSProvider_internal * NSCopyProvider(NSProvider_internal * prov)
+void NSRemoveTopicNode(NSTopicLL * topicNode)
+{
+    NS_VERIFY_NOT_NULL_V(topicNode);
+
+    NSOICFree(topicNode->topicName);
+    topicNode->next = NULL;
+
+    NSOICFree(topicNode);
+}
+
+NSTopicLL * NSCopyTopicNode(NSTopicLL * topicNode)
+{
+    NS_VERIFY_NOT_NULL(topicNode, NULL);
+
+    NSTopicLL * newTopicNode = (NSTopicLL *)OICMalloc(sizeof(NSTopicLL));
+    NS_VERIFY_NOT_NULL(newTopicNode, NULL);
+
+    newTopicNode->topicName = OICStrdup(topicNode->topicName);
+    newTopicNode->state = topicNode->state;
+    newTopicNode->next = NULL;
+
+    return newTopicNode;
+}
+
+NSResult NSInsertTopicNode(NSTopicLL * topicHead, NSTopicLL * topicNode)
+{
+    NS_VERIFY_NOT_NULL(topicHead, NS_ERROR);
+    NS_VERIFY_NOT_NULL(topicNode, NS_ERROR);
+
+    NSTopicLL * iter = topicHead;
+    NSTopicLL * prev = NULL;
+
+    while (iter)
+    {
+        prev = iter;
+        iter = (NSTopicLL *) iter->next;
+    }
+
+    prev->next = topicNode;
+    topicNode->next = NULL;
+
+    return NS_OK;
+}
+
+void NSRemoveTopicLL(NSTopicLL * topicHead)
+{
+    NS_VERIFY_NOT_NULL_V(topicHead);
+
+    NSTopicLL * iter = topicHead;
+    NSTopicLL * following = NULL;
+
+    while (iter)
+    {
+        following = iter->next;
+
+        NSRemoveTopicNode(iter);
+
+        iter = following;
+    }
+}
+
+NSTopicLL * NSCopyTopicLL(NSTopicLL * topicHead)
+{
+    NS_VERIFY_NOT_NULL(topicHead, NULL);
+
+    NSTopicLL * iter = topicHead;
+
+    NS_LOG_V(DEBUG, "[NSCopyTopicLL] Name:%s\t State:%d", iter->topicName, iter->state);
+    NSTopicLL * newTopicHead = NSCopyTopicNode(iter);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicHead, NULL, NSRemoveTopicLL(newTopicHead));
+
+    iter = (NSTopicLL *) iter->next;
+
+    while (iter)
+    {
+        NS_LOG_V(DEBUG, "[NSCopyTopicLL] Name:%s\t State:%d", iter->topicName, iter->state);
+        NSTopicLL * newTopicNode = NSCopyTopicNode(iter);
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicNode, NULL, NSRemoveTopicLL(newTopicHead));
+
+        NSResult ret = NSInsertTopicNode(newTopicHead, newTopicNode);
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == NS_OK ? (void *)1 : NULL,
+                                                    NULL, NSRemoveTopicLL(newTopicHead));
+
+        iter = (NSTopicLL *) iter->next;
+    }
+
+    return newTopicHead;
+}
+
+void NSCopyProviderPostClean(
+        NSProviderConnectionInfo * connections, NSProvider_internal * provider)
+{
+    NSRemoveConnections(connections);
+    NSOICFree(provider);
+}
+
+NSProvider_internal * NSCopyProvider_internal(NSProvider_internal * prov)
 {
     NS_VERIFY_NOT_NULL(prov, NULL);
 
     NSProviderConnectionInfo * connections = NSCopyProviderConnections(prov->connection);
     NS_VERIFY_NOT_NULL(connections, NULL);
 
-    NSProvider_internal * newProv = (NSProvider_internal *)OICMalloc(sizeof(NSProvider_internal));
+    NSProvider_internal * newProv = (NSProvider_internal *) OICMalloc(sizeof(NSProvider_internal));
     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProv, NULL, NSRemoveConnections(connections));
 
+    newProv->topicLL = NULL;
+
+    if (prov->topicLL)
+    {
+        NSTopicLL * newTopicLL = NSCopyTopicLL(prov->topicLL);
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicLL, NULL,
+                    NSCopyProviderPostClean(connections, newProv));
+
+        newProv->topicLL = newTopicLL;
+    }
+
     newProv->connection = connections;
     OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
     newProv->messageUri = OICStrdup(prov->messageUri);
     newProv->syncUri = OICStrdup(prov->syncUri);
+    newProv->topicUri = OICStrdup(prov->topicUri);
     newProv->accessPolicy = prov->accessPolicy;
+    newProv->state = prov->state;
 
     return newProv;
 }
 
-void NSRemoveProvider(NSProvider_internal * prov)
+NSProvider * NSCopyProvider(NSProvider_internal * prov)
 {
-    NS_VERIFY_NOT_NULL_V(prov);
+    NS_VERIFY_NOT_NULL(prov, NULL);
 
-    NSOICFree(prov->messageUri);
-    NSOICFree(prov->syncUri);
-    NSRemoveConnections(prov->connection);
+    NSProvider * newProv = (NSProvider *) OICMalloc(sizeof(NSProvider));
+    NS_VERIFY_NOT_NULL(newProv, NULL);
 
-    NSOICFree(prov);
+    OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
+
+    return newProv;
 }
 
-NSSyncInfo_internal * NSCopySyncInfo(NSSyncInfo_internal * syncInfo)
+void NSRemoveProvider_internal(void * data)
 {
-    NS_VERIFY_NOT_NULL(syncInfo, NULL);
-
-    NSProviderConnectionInfo * connections = NSCopyProviderConnections(syncInfo->connection);
-    NS_VERIFY_NOT_NULL(connections, NULL);
+    NS_VERIFY_NOT_NULL_V(data);
 
-    NSSyncInfo_internal * newSyncInfo = (NSSyncInfo_internal *)OICMalloc(sizeof(NSSyncInfo_internal));
-    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newSyncInfo, NULL, NSRemoveConnections(connections));
+    NSProvider_internal * prov = (NSProvider_internal *) data;
 
-    OICStrcpy(newSyncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, syncInfo->providerId);
-    newSyncInfo->messageId = syncInfo->messageId;
-    newSyncInfo->state = syncInfo->state;
-    newSyncInfo->connection = connections;
+    NSOICFree(prov->messageUri);
+    NSOICFree(prov->syncUri);
+    NSOICFree(prov->topicUri);
+    NSRemoveConnections(prov->connection);
+    if (prov->topicLL)
+    {
+        NSRemoveTopicLL(prov->topicLL);
+    }
 
-    return newSyncInfo;
+    NSOICFree(prov);
 }
 
-void NSRemoveSyncInfo(NSSyncInfo_internal * syncInfo)
+void NSRemoveProvider(NSProvider * prov)
 {
-    NS_VERIFY_NOT_NULL_V(syncInfo);
-
-    NSRemoveConnections(syncInfo->connection);
-
-    NSOICFree(syncInfo);
+    NS_VERIFY_NOT_NULL_V(prov);
+    NSOICFree(prov);
 }
 
 OCStackResult NSInvokeRequest(OCDoHandle * handle,
         OCMethod method, const OCDevAddr * addr,
         const char * queryUrl, OCPayload * payload,
-        void * callbackFunc, void * callbackData, OCConnectivityType type)
+        void * callbackFunc, void * callbackData,
+        OCClientContextDeleter cd, OCConnectivityType type)
 {
     int mutexRet = pthread_mutex_lock(*(NSGetStackMutex()));
     NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
 
-    OCCallbackData cbdata = { 0, };
+    OCCallbackData cbdata = { NULL, NULL, NULL };
 
     cbdata.cb = callbackFunc;
     cbdata.context = callbackData;
-    cbdata.cd = NULL;
+    cbdata.cd = cd;
 
     OCStackResult ret = OCDoResource(handle, method, queryUrl, addr,
                                      payload, type, NS_QOS, &cbdata, NULL, 0);
@@ -423,10 +587,12 @@ bool NSOCResultToSuccess(OCStackResult ret)
         case OC_STACK_OK:
         case OC_STACK_RESOURCE_CREATED:
         case OC_STACK_RESOURCE_DELETED:
+        case OC_STACK_PRESENCE_STOPPED:
         case OC_STACK_CONTINUE:
         case OC_STACK_RESOURCE_CHANGED:
             return true;
         default:
+            NS_LOG_V(DEBUG, "OCStackResult : %d", (int)ret);
             return false;
     }
 }