setting received ttl value by consumer.
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerCommon.c
index 3dddedd..a790c4b 100644 (file)
 #include "NSThread.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
+#include "ocpayload.h"
 
-#define NS_QUERY_CONSUMER_ID "consumerid"
+#include <pthread.h>
+
+#define NS_QUERY_CONSUMER_ID "consumerId"
+
+pthread_mutex_t ** NSGetStackMutex()
+{
+    static pthread_mutex_t * g_stackMutext = NULL;
+    if (g_stackMutext == NULL)
+    {
+        g_stackMutext = (pthread_mutex_t *)OICMalloc(sizeof(pthread_mutex_t));
+        NS_VERIFY_NOT_NULL(g_stackMutext, NULL);
+        pthread_mutex_init(g_stackMutext, NULL);
+    }
+
+    return & g_stackMutext;
+}
 
 char ** NSGetConsumerId()
 {
@@ -83,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()
@@ -90,51 +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)
 {
-    NSConsumerThread * thread = NSThreadInit(NSDiscoveredProviderFunc, (void *) provider);
-    NS_VERIFY_NOT_NULL_V(thread);
-}
+    NS_VERIFY_NOT_NULL_V(provider);
 
-NSSubscriptionAcceptedCallback * NSGetSubscriptionAcceptedCb()
-{
-    static NSSubscriptionAcceptedCallback g_acceptCb = NULL;
+    NSProvider * retProvider = NSCopyProvider((NSProvider_internal *) provider);
+    NS_VERIFY_NOT_NULL_V(retProvider);
 
-    return & g_acceptCb;
-}
+    NSProviderChangedData * data =
+            (NSProviderChangedData *)OICMalloc(sizeof(NSProviderChangedData));
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(data, NSRemoveProvider(retProvider));
 
-void NSSetSubscriptionAcceptedCb(NSSubscriptionAcceptedCallback cb)
-{
-    *(NSGetSubscriptionAcceptedCb()) = cb;
-}
+    data->provider = retProvider;
+    data->state = response;
 
-void NSSubscriptionAccepted(NSProvider * provider)
-{
-    (*(NSGetSubscriptionAcceptedCb()))(provider);
+    NSConsumerThread * thread = NSThreadInit(NSProviderChangedFunc, (void *) data);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(thread,
+    {
+        NSRemoveProvider(retProvider);
+        NSOICFree(data);
+    });
+
+    NSDestroyThreadHandle(thread);
+    NSOICFree(thread);
 }
 
 NSSyncInfoReceivedCallback * NSGetBoneNotificationSyncCb()
@@ -158,8 +188,16 @@ void * NSNotificationSyncFunc(void * obj)
 void NSNotificationSync(NSSyncInfo * sync)
 {
     NS_VERIFY_NOT_NULL_V(sync);
-    NSConsumerThread * thread = NSThreadInit(NSNotificationSyncFunc, (void *) sync);
+
+    NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
+    NS_VERIFY_NOT_NULL_V(retSync);
+    memcpy(retSync, sync, sizeof(NSSyncInfo));
+
+    NSConsumerThread * thread = NSThreadInit(NSNotificationSyncFunc, (void *) retSync);
     NS_VERIFY_NOT_NULL_V(thread);
+
+    NSDestroyThreadHandle(thread);
+    NSOICFree(thread);
 }
 
 NSMessageReceivedCallback  * NSGetBoneMessagePostedCb()
@@ -188,8 +226,15 @@ void * NSMessagePostFunc(void * obj)
 void NSMessagePost(NSMessage * msg)
 {
     NS_VERIFY_NOT_NULL_V(msg);
-    NSConsumerThread * thread = NSThreadInit(NSMessagePostFunc, (void *) msg);
+
+    NSMessage * retMsg = NSCopyMessage(msg);
+    NS_VERIFY_NOT_NULL_V(retMsg);
+
+    NSConsumerThread * thread = NSThreadInit(NSMessagePostFunc, (void *) retMsg);
     NS_VERIFY_NOT_NULL_V(thread);
+
+    NSDestroyThreadHandle(thread);
+    NSOICFree(thread);
 }
 
 NSTask * NSMakeTask(NSTaskType type, void * data)
@@ -204,46 +249,350 @@ NSTask * NSMakeTask(NSTaskType type, void * data)
     return retTask;
 }
 
-NSMessage_consumer * NSCopyMessage(NSMessage_consumer * msg)
+NSMessage * NSCopyMessage(NSMessage * msg)
 {
     NS_VERIFY_NOT_NULL(msg, NULL);
 
-    NSMessage_consumer * newMsg = (NSMessage_consumer *)OICMalloc(sizeof(NSMessage_consumer));
+    NSMessage * newMsg = (NSMessage *)OICMalloc(sizeof(NSMessage));
     NS_VERIFY_NOT_NULL(newMsg, NULL);
 
-    newMsg->addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
-    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newMsg, NULL, OICFree(newMsg));
-    memcpy(newMsg->addr, msg->addr, sizeof(OCDevAddr));
+    OICStrcpy(newMsg->providerId, NS_DEVICE_ID_LENGTH, msg->providerId);
 
     newMsg->messageId = msg->messageId;
     newMsg->title = OICStrdup(msg->title);
     newMsg->contentText = OICStrdup(msg->contentText);
     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);
+    }
+
+    newMsg->extraInfo = NULL;
+    if (msg->extraInfo)
+    {
+        newMsg->extraInfo = OCRepPayloadClone(msg->extraInfo);
+    }
 
     return newMsg;
 }
-void NSRemoveMessage(NSMessage_consumer * msg)
+void NSRemoveMessage(NSMessage * msg)
 {
+    NS_VERIFY_NOT_NULL_V(msg);
+
     msg->messageId = 0;
     NSOICFree(msg->title);
     NSOICFree(msg->contentText);
     NSOICFree(msg->sourceName);
-    NSOICFree(msg->addr);
+    NSOICFree(msg->dateTime);
+    NSOICFree(msg->topic);
+
+    if (msg->mediaContents)
+    {
+        NSOICFree(msg->mediaContents->iconImage);
+    }
+    NSOICFree(msg->mediaContents);
+
+    if (msg->extraInfo)
+    {
+        OCRepPayloadDestroy(msg->extraInfo);
+        msg->extraInfo = NULL;
+    }
 
     NSOICFree(msg);
 }
 
+void NSRemoveConnections(NSProviderConnectionInfo * connections)
+{
+    NS_VERIFY_NOT_NULL_V(connections);
+
+    NSProviderConnectionInfo * tmp = connections;
+
+    while(tmp)
+    {
+        tmp->messageHandle = NULL;
+        tmp->syncHandle = NULL;
+        NSOICFree(tmp->addr);
+        NSProviderConnectionInfo * next = tmp->next;
+        NSOICFree(tmp);
+        tmp = next;
+    }
+}
+
+NSProviderConnectionInfo * NSCreateProviderConnections(OCDevAddr * inAddr)
+{
+    NSProviderConnectionInfo * connections
+        = (NSProviderConnectionInfo *)OICMalloc(sizeof(NSProviderConnectionInfo));
+    NS_VERIFY_NOT_NULL(connections, NULL);
+
+    connections->addr = NULL;
+    connections->messageHandle = NULL;
+    connections->syncHandle = NULL;
+    connections->isCloudConnection = false;
+    connections->isSubscribing = false;
+    connections->next = NULL;
+
+    if (inAddr)
+    {
+        connections->addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(connections->addr, NULL, NSRemoveConnections(connections));
+        memcpy(connections->addr, inAddr, sizeof(OCDevAddr));
+    }
+
+    return connections;
+}
+
+NSProviderConnectionInfo * NSCopyProviderConnections(NSProviderConnectionInfo * conn)
+{
+    NS_VERIFY_NOT_NULL(conn, NULL);
+    NSProviderConnectionInfo * tmp = conn;
+
+    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)
+    {
+        NSProviderConnectionInfo * tmpInfo = NSCreateProviderConnections(tmp->addr);
+        NS_VERIFY_NOT_NULL(tmpInfo, NULL);
+
+        tmpInfo->messageHandle = tmp->messageHandle;
+        tmpInfo->syncHandle = tmp->syncHandle;
+        tmpInfo->isCloudConnection = tmp->isCloudConnection;
+        tmpInfo->isSubscribing = tmp->isSubscribing;
+        tmp = tmp->next;
+        copyInfo->next = tmpInfo;
+        copyInfo = tmpInfo;
+    }
+
+    return retInfo;
+}
+
+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));
+    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;
+}
+
+NSProvider * NSCopyProvider(NSProvider_internal * prov)
+{
+    NS_VERIFY_NOT_NULL(prov, NULL);
+
+    NSProvider * newProv = (NSProvider *) OICMalloc(sizeof(NSProvider));
+    NS_VERIFY_NOT_NULL(newProv, NULL);
+
+    OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
+
+    return newProv;
+}
+
+void NSRemoveProvider_internal(void * data)
+{
+    NS_VERIFY_NOT_NULL_V(data);
+
+    NSProvider_internal * prov = (NSProvider_internal *) data;
+
+    NSOICFree(prov->messageUri);
+    NSOICFree(prov->syncUri);
+    NSOICFree(prov->topicUri);
+    NSRemoveConnections(prov->connection);
+    if (prov->topicLL)
+    {
+        NSRemoveTopicLL(prov->topicLL);
+    }
+
+    NSOICFree(prov);
+}
+
+void NSRemoveProvider(NSProvider * prov)
+{
+    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)
+        void * callbackFunc, void * callbackData,
+        OCClientContextDeleter cd, OCConnectivityType type)
 {
-    OCCallbackData cbdata;
+    int mutexRet = pthread_mutex_lock(*(NSGetStackMutex()));
+    NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
+
+    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);
+
+    mutexRet = pthread_mutex_unlock(*(NSGetStackMutex()));
+    NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
 
-    return OCDoResource(handle, method, queryUrl, addr,
-            payload, CT_DEFAULT, NS_QOS, &cbdata, NULL, 0);
+    return ret;
+}
+
+bool NSOCResultToSuccess(OCStackResult ret)
+{
+    switch (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;
+    }
 }