Updated NSProvider structure for multi connections.
authorKIM JungYong <jyong2.kim@samsung.com>
Mon, 11 Jul 2016 07:08:23 +0000 (16:08 +0900)
committerUze Choi <uzchoi@samsung.com>
Wed, 13 Jul 2016 11:56:54 +0000 (11:56 +0000)
NSProvider can have a only UDP connection information.
But cloud notification service scenraio need to multiple connection informations.
So NSProvider struct is updated for multi connection information.

NSProviderConnectionInfo is added at NSProvider.
NAProviderConnectionInfo is list of Provider connection infomation.
Mutex is added at NSInvokeRequest().

Change-Id: Ie83527e264f93a2f5839417a61997fcdcf541a87
Signed-off-by: KIM JungYong <jyong2.kim@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/9275
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Uze Choi <uzchoi@samsung.com>
Tested-by: Uze Choi <uzchoi@samsung.com>
service/notification/src/consumer/NSConsumerCommon.c
service/notification/src/consumer/NSConsumerCommon.h
service/notification/src/consumer/NSConsumerCommunication.c
service/notification/src/consumer/NSConsumerDiscovery.c
service/notification/src/consumer/NSConsumerInternalTaskController.c
service/notification/src/consumer/cache/linux/NSConsumerMemoryCache.c

index 26a9321..5650f01 100644 (file)
 #include "oic_malloc.h"
 #include "oic_string.h"
 
+#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()
 {
     static char * g_consumerId = NULL;
@@ -234,22 +249,79 @@ void NSRemoveMessage(NSMessage_consumer * msg)
     NSOICFree(msg);
 }
 
+void NSRemoveConnections(NSProviderConnectionInfo * connections)
+{
+    NSProviderConnectionInfo * tmp = connections;
+
+    while(tmp)
+    {
+        tmp->messageHandle = NULL;
+        tmp->syncHandle = NULL;
+        NSOICFree(tmp->addr);
+        tmp = tmp->next;
+    }
+
+    NSOICFree(connections);
+}
+
+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->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);
+    tmp = tmp->next;
+    NSProviderConnectionInfo * copyInfo = retInfo;
+
+    while(tmp)
+    {
+        copyInfo = NSCreateProviderConnections(tmp->addr);
+        NS_VERIFY_NOT_NULL(copyInfo, NULL);
+
+        copyInfo->messageHandle = tmp->messageHandle;
+        copyInfo->syncHandle = tmp->syncHandle;
+        tmp = tmp->next;
+        copyInfo = copyInfo->next;
+    }
+
+    return retInfo;
+}
+
 NSProvider_internal * NSCopyProvider(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(newProv, NULL);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProv, NULL, NSRemoveConnections(connections));
 
+    newProv->connection = connections;
     OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
-    newProv->i_addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
-    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProv, NULL, OICFree(newProv));
-    memcpy(newProv->i_addr, prov->i_addr, sizeof(OCDevAddr));
-
     newProv->messageUri = OICStrdup(prov->messageUri);
     newProv->syncUri = OICStrdup(prov->syncUri);
-    newProv->i_messageHandle = prov->i_messageHandle;
-    newProv->i_syncHandle = prov->i_syncHandle;
     newProv->accessPolicy = prov->accessPolicy;
 
     return newProv;
@@ -258,9 +330,7 @@ void NSRemoveProvider(NSProvider_internal * prov)
 {
     NSOICFree(prov->messageUri);
     NSOICFree(prov->syncUri);
-    NSOICFree(prov->i_messageHandle);
-    NSOICFree(prov->i_syncHandle);
-    NSOICFree(prov->i_addr);
+    NSRemoveConnections(prov->connection);
 
     NSOICFree(prov);
 }
@@ -270,12 +340,20 @@ OCStackResult NSInvokeRequest(OCDoHandle * handle,
         const char * queryUrl, OCPayload * payload,
         void * callbackFunc, void * callbackData, OCConnectivityType type)
 {
-    OCCallbackData cbdata;
+    int mutexRet = pthread_mutex_lock(*(NSGetStackMutex()));
+    NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
+
+    OCCallbackData cbdata = { 0, };
 
     cbdata.cb = callbackFunc;
     cbdata.context = callbackData;
     cbdata.cd = NULL;
 
-    return OCDoResource(handle, method, queryUrl, addr,
-            payload, type, NS_QOS, &cbdata, NULL, 0);
+    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 ret;
 }
index 85f9b69..e3f1047 100644 (file)
@@ -123,6 +123,17 @@ extern "C" {
         } \
     }
 
+typedef struct NSProviderConnectionInfo
+{
+    OCDevAddr * addr;
+
+    OCDoHandle messageHandle;
+    OCDoHandle syncHandle;
+
+    struct NSProviderConnectionInfo * next;
+
+} NSProviderConnectionInfo;
+
 typedef struct
 {
     char providerId[NS_DEVICE_ID_LENGTH];
@@ -130,11 +141,10 @@ typedef struct
     char * messageUri;
     char * syncUri;
 
-    OCDoHandle i_messageHandle;
-    OCDoHandle i_syncHandle;
-    OCDevAddr * i_addr;
     NSAccessPolicy accessPolicy;
 
+    NSProviderConnectionInfo * connection;
+
 } NSProvider_internal;
 
 typedef struct
@@ -143,7 +153,8 @@ typedef struct
     char providerId[NS_DEVICE_ID_LENGTH];
     NSSyncType state;
 
-    OCDevAddr * i_addr;
+    NSProviderConnectionInfo * connection;
+
 } NSSyncInfo_internal;
 
 typedef struct
@@ -192,6 +203,10 @@ NSResult NSConsumerPushEvent(NSTask *);
 NSMessage_consumer * NSCopyMessage(NSMessage_consumer *);
 void NSRemoveMessage(NSMessage_consumer *);
 
+NSProviderConnectionInfo * NSCreateProviderConnections(OCDevAddr * inAddr);
+NSProviderConnectionInfo * NSCopyProviderConnections(NSProviderConnectionInfo * conn);
+void NSRemoveConnections(NSProviderConnectionInfo * connections);
+
 NSProvider_internal * NSCopyProvider(NSProvider_internal *);
 void NSRemoveProvider(NSProvider_internal *);
 
index 9ec8e0b..cd968c5 100644 (file)
@@ -35,34 +35,61 @@ NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId,
 NSMessage_consumer * NSGetMessage(OCClientResponse * clientResponse);
 NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse);
 
+char * NSGetCloudUri(const char * providerId, char * uri);
+
 NSResult NSConsumerSubscribeProvider(NSProvider * provider)
 {
     NSProvider_internal * provider_internal = (NSProvider_internal *) provider;
     NS_VERIFY_NOT_NULL(provider_internal, NS_ERROR);
 
-    NS_LOG(DEBUG, "get subscribe message query");
-    char * query = NSMakeRequestUriWithConsumerId(provider_internal->messageUri);
-    NS_VERIFY_NOT_NULL(query, NS_ERROR);
-
-    NS_LOG(DEBUG, "subscribe message");
-    NS_LOG_V(DEBUG, "subscribe query : %s", query);
-    OCStackResult ret = NSInvokeRequest(&(provider_internal->i_messageHandle),
-                          OC_REST_OBSERVE, provider_internal->i_addr,
-                          query, NULL, NSConsumerMessageListener, NULL, CT_DEFAULT);
-    NS_VERIFY_STACK_OK(ret, NS_ERROR);
-    NSOICFree(query);
-
-    NS_LOG(DEBUG, "get subscribe sync query");
-    query = NSMakeRequestUriWithConsumerId(provider_internal->syncUri);
-    NS_VERIFY_NOT_NULL(query, NS_ERROR);
-
-    NS_LOG(DEBUG, "subscribe sync");
-    NS_LOG_V(DEBUG, "subscribe query : %s", query);
-    ret = NSInvokeRequest(&(provider_internal->i_syncHandle),
-                          OC_REST_OBSERVE, provider_internal->i_addr,
-                          query, NULL, NSConsumerSyncInfoListener, NULL, CT_DEFAULT);
-    NS_VERIFY_STACK_OK(ret, NS_ERROR);
-    NSOICFree(query);
+    NSProviderConnectionInfo * connections = provider_internal->connection;
+    while(connections)
+    {
+        if (connections->messageHandle)
+        {
+            continue;
+        }
+
+        char * msgUri = OICStrdup(provider_internal->messageUri);
+        char * syncUri = OICStrdup(provider_internal->syncUri);
+
+        OCConnectivityType type = CT_DEFAULT;
+        if (connections->addr->adapter == OC_ADAPTER_TCP)
+        {
+            type = CT_ADAPTER_TCP;
+            msgUri = NSGetCloudUri(provider_internal->providerId, msgUri);
+            syncUri = NSGetCloudUri(provider_internal->providerId, syncUri);
+        }
+
+        NS_LOG(DEBUG, "get subscribe message query");
+        char * query = NULL;
+        query = NSMakeRequestUriWithConsumerId(msgUri);
+        NS_VERIFY_NOT_NULL(query, NS_ERROR);
+
+        NS_LOG(DEBUG, "subscribe message");
+        NS_LOG_V(DEBUG, "subscribe query : %s", query);
+        OCStackResult ret = NSInvokeRequest(&(connections->messageHandle),
+                              OC_REST_OBSERVE, connections->addr, query, NULL,
+                              NSConsumerMessageListener, NULL, type);
+        NS_VERIFY_STACK_OK_WITH_POST_CLEANING(ret, NS_ERROR, NSOICFree(query));
+        NSOICFree(query);
+        NSOICFree(msgUri);
+
+        NS_LOG(DEBUG, "get subscribe sync query");
+        query = NSMakeRequestUriWithConsumerId(syncUri);
+        NS_VERIFY_NOT_NULL(query, NS_ERROR);
+
+        NS_LOG(DEBUG, "subscribe sync");
+        NS_LOG_V(DEBUG, "subscribe query : %s", query);
+        ret = NSInvokeRequest(&(connections->syncHandle),
+                              OC_REST_OBSERVE, connections->addr, query, NULL,
+                              NSConsumerSyncInfoListener, NULL, type);
+        NS_VERIFY_STACK_OK_WITH_POST_CLEANING(ret, NS_ERROR, NSOICFree(query));
+        NSOICFree(query);
+        NSOICFree(syncUri);
+
+        connections = connections->next;
+    }
 
     return NS_OK;
 }
@@ -270,9 +297,31 @@ OCStackResult NSSendSyncInfo(NSSyncInfo * syncInfo, OCDevAddr * addr)
     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_STATE, syncInfo->state);
     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, syncInfo->providerId);
 
-    return NSInvokeRequest(NULL, OC_REST_POST, addr,
-                           NS_SYNC_URI, (OCPayload*)payload,
-                           NSConsumerCheckPostResult, NULL, addr->adapter);
+    char * uri = (char*)OICStrdup(NS_SYNC_URI);
+    OCConnectivityType type = CT_DEFAULT;
+    if(addr->adapter == OC_ADAPTER_TCP)
+    {
+        type = CT_ADAPTER_TCP;
+        uri = NSGetCloudUri(syncInfo->providerId, uri);
+    }
+
+    OCStackResult ret = NSInvokeRequest(NULL, OC_REST_POST, addr,
+                            uri, (OCPayload*)payload,
+                            NSConsumerCheckPostResult, NULL, type);
+    NSOICFree(uri);
+
+    return ret;
+}
+
+char * NSGetCloudUri(const char * providerId, char * uri)
+{
+    size_t uriLen = NS_DEVICE_ID_LENGTH + 1 + strlen(uri) + 1;
+    char * retUri = (char *)OICMalloc(uriLen);
+    snprintf(retUri, uriLen, "/%s%s", providerId, uri);
+    NSOICFree(uri);
+    NS_LOG_V(DEBUG, "TCP uri : %s", retUri);
+
+    return retUri;
 }
 
 void NSConsumerCommunicationTaskProcessing(NSTask * task)
@@ -282,27 +331,42 @@ void NSConsumerCommunicationTaskProcessing(NSTask * task)
     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
     if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE)
     {
+        NS_VERIFY_NOT_NULL_V(task->taskData);
         NS_LOG(DEBUG, "Request Subscribe");
         NSResult ret = NSConsumerSubscribeProvider((NSProvider *)task->taskData);
         NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
     }
     else if (task->taskType == TASK_SEND_SYNCINFO)
     {
-        // TODO find target OCDevAddr using provider Id.
+        NS_VERIFY_NOT_NULL_V(task->taskData);
         NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)task->taskData;
-        OCDevAddr * addr = syncInfo->i_addr;
-        OCStackResult ret = NSSendSyncInfo((NSSyncInfo *)(task->taskData), addr);
-        NS_VERIFY_STACK_OK_V(ret);
+        NSProviderConnectionInfo * info = syncInfo->connection;
+
+        while(info)
+        {
+            OCStackResult ret = NSSendSyncInfo((NSSyncInfo *)(task->taskData), info->addr);
+            if (ret != OC_STACK_OK)
+            {
+                NS_LOG_V(ERROR, "send sync info fail : %d", info->addr->adapter);
+            }
+
+            info = info->next;
+        }
 
-        NSOICFree(syncInfo->i_addr);
+        NSRemoveConnections(syncInfo->connection);
         NSOICFree(syncInfo);
     }
     else if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL)
     {
         NSProvider_internal * provider = (NSProvider_internal *)task->taskData;
 
-        OCCancel(provider->i_messageHandle, NS_QOS, NULL, 0);
-        OCCancel(provider->i_syncHandle, NS_QOS, NULL, 0);
+        NSProviderConnectionInfo * connections = provider->connection;
+        while(connections)
+        {
+            OCCancel(connections->messageHandle, NS_QOS, NULL, 0);
+            OCCancel(connections->syncHandle, NS_QOS, NULL, 0);
+            connections = connections->next;
+        }
     }
     else
     {
index a87fb0b..8e66d04 100644 (file)
@@ -50,6 +50,8 @@ OCStackApplicationResult NSConsumerPresenceListener(
             clientResponse->result);
     NS_LOG_V(DEBUG, "Presence sequenceNum : %d",
             clientResponse->sequenceNumber);
+    NS_LOG_V(DEBUG, "Presence Transport Type : %d",
+                clientResponse->devAddr.adapter);
 
     if (!NSIsStartedConsumer())
     {
@@ -92,6 +94,8 @@ OCStackApplicationResult NSProviderDiscoverListener(
             clientResponse->result);
     NS_LOG_V(DEBUG, "Discover sequenceNum : %d",
             clientResponse->sequenceNumber);
+    NS_LOG_V(DEBUG, "Discover Transport Type : %d",
+                    clientResponse->devAddr.adapter);
 
     if (!NSIsStartedConsumer())
     {
@@ -103,9 +107,15 @@ OCStackApplicationResult NSProviderDiscoverListener(
     {
         if (strstr(resource->uri, NS_RESOURCE_URI))
         {
+            OCConnectivityType type = CT_DEFAULT;
+            if (clientResponse->addr->adapter == OC_ADAPTER_TCP)
+            {
+                type = CT_ADAPTER_TCP;
+            }
+
             NSInvokeRequest(NULL, OC_REST_GET, clientResponse->addr,
                     resource->uri, NULL, NSIntrospectProvider, NULL,
-                    clientResponse->addr->adapter);
+                    type);
         }
         resource = resource->next;
     }
@@ -118,10 +128,7 @@ void NSRemoveProviderObj(NSProvider_internal * provider)
     NSOICFree(provider->messageUri);
     NSOICFree(provider->syncUri);
 
-    provider->i_messageHandle = NULL;
-    provider->i_syncHandle = NULL;
-    NSOICFree(provider->i_addr);
-
+    NSRemoveConnections(provider->connection);
     NSOICFree(provider);
 }
 
@@ -142,6 +149,8 @@ OCStackApplicationResult NSIntrospectProvider(
             clientResponse->sequenceNumber);
     NS_LOG_V(DEBUG, "GET response resource uri : %s",
             clientResponse->resourceUri);
+    NS_LOG_V(DEBUG, "GET response Transport Type : %d",
+                    clientResponse->devAddr.adapter);
 
     if (!NSIsStartedConsumer())
     {
@@ -160,12 +169,13 @@ OCStackApplicationResult NSIntrospectProvider(
     return OC_STACK_KEEP_TRANSACTION;
 }
 
-void NSGetProviderPostClean(char * pId, char * mUri, char * sUri, OCDevAddr * addr)
+void NSGetProviderPostClean(
+        char * pId, char * mUri, char * sUri, NSProviderConnectionInfo * connection)
 {
     NSOICFree(pId);
     NSOICFree(mUri);
     NSOICFree(sUri);
-    NSOICFree(addr);
+    NSRemoveConnections(connection);
 }
 
 NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse)
@@ -186,7 +196,7 @@ NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse)
     char * messageUri = NULL;
     char * syncUri = NULL;
     int64_t accepter = 0;
-    OCDevAddr * addr = NULL;
+    NSProviderConnectionInfo * connection = NULL;
 
     NS_LOG(DEBUG, "get information of accepter");
     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_POLICY, & accepter);
@@ -199,33 +209,29 @@ NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse)
     NS_LOG(DEBUG, "get message URI");
     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_MESSAGE, & messageUri);
     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
-            NSGetProviderPostClean(providerId, messageUri, syncUri, addr));
+            NSGetProviderPostClean(providerId, messageUri, syncUri, connection));
 
     NS_LOG(DEBUG, "get sync URI");
     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SYNC, & syncUri);
     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
-            NSGetProviderPostClean(providerId, messageUri, syncUri, addr));
+            NSGetProviderPostClean(providerId, messageUri, syncUri, connection));
 
-    NS_LOG(DEBUG, "get provider address");
-    addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
-    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(addr, NULL,
-           NSGetProviderPostClean(providerId, messageUri, syncUri, addr));
-
-    memcpy(addr, clientResponse->addr, sizeof(OCDevAddr));
+    NS_LOG(DEBUG, "get provider connection information");
+    NS_VERIFY_NOT_NULL(clientResponse->addr, NULL);
+    connection = NSCreateProviderConnections(clientResponse->addr);
+    NS_VERIFY_NOT_NULL(connection, NULL);
 
     NSProvider_internal * newProvider
         = (NSProvider_internal *)OICMalloc(sizeof(NSProvider_internal));
     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProvider, NULL,
-          NSGetProviderPostClean(providerId, messageUri, syncUri, addr));
+          NSGetProviderPostClean(providerId, messageUri, syncUri, connection));
 
     OICStrcpy(newProvider->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
     NSOICFree(providerId);
     newProvider->messageUri = messageUri;
     newProvider->syncUri = syncUri;
     newProvider->accessPolicy = (NSAccessPolicy)accepter;
-    newProvider->i_addr = addr;
-    newProvider->i_messageHandle = NULL;
-    newProvider->i_syncHandle = NULL;
+    newProvider->connection = connection;
 
     return newProvider;
 }
@@ -238,23 +244,33 @@ void NSConsumerDiscoveryTaskProcessing(NSTask * task)
     if (task->taskType == TASK_EVENT_CONNECTED || task->taskType == TASK_CONSUMER_REQ_DISCOVER)
     {
         OCDevAddr * addr = (OCDevAddr *) task->taskData;
+        OCConnectivityType type = CT_DEFAULT;
+        if (addr)
+        {
+            type = addr->adapter;
+        }
 
         NS_LOG(DEBUG, "Request discover [UDP]");
         NSInvokeRequest(NULL, OC_REST_DISCOVER, addr, NS_DISCOVER_QUERY,
-                NULL, NSProviderDiscoverListener, NULL, addr->adapter);
+                NULL, NSProviderDiscoverListener, NULL, type);
     }
     else if (task->taskType == TASK_EVENT_CONNECTED_TCP)
     {
         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(task->taskData, NSOICFree(task));
         OCDevAddr * addr = (OCDevAddr *) task->taskData;
+        OCConnectivityType type = CT_ADAPTER_TCP;
+        if (addr)
+        {
+            type = addr->adapter;
+        }
 
         NS_LOG(DEBUG, "Request discover [TCP]");
         NSInvokeRequest(NULL, OC_REST_DISCOVER, addr, NS_DISCOVER_QUERY,
-                NULL, NSProviderDiscoverListener, NULL, addr->adapter);
+                NULL, NSProviderDiscoverListener, NULL, type);
 
         NS_LOG(DEBUG, "Subscribe presence [TCP]");
         NSInvokeRequest(NULL, OC_REST_PRESENCE, addr, NS_PRESENCE_SUBSCRIBE_QUERY_TCP,
-                NULL, NSConsumerPresenceListener, NULL, addr->adapter);
+                NULL, NSConsumerPresenceListener, NULL, type);
 
         NSOICFree(task->taskData);
     }
index 828c946..bb9479f 100644 (file)
@@ -98,10 +98,11 @@ NSProvider_internal * NSProviderCacheFind(const char * providerId)
         NS_VERIFY_NOT_NULL(ProviderCache, NULL);
 
         ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
-        NSSetMessageCacheList(ProviderCache);
+        NSSetProviderCacheList(ProviderCache);
     }
 
     NSCacheElement * cacheElement = NSStorageRead(ProviderCache, providerId);
+    NS_VERIFY_NOT_NULL(cacheElement, NULL);
 
     return (NSProvider_internal *) cacheElement->data;
 }
@@ -175,15 +176,43 @@ void NSConsumerHandleProviderDiscovered(NSProvider_internal * provider)
 {
     NS_VERIFY_NOT_NULL_V(provider);
 
+    bool isAdded = true;
     NSProvider_internal * providerCacheData = NSProviderCacheFind(provider->providerId);
-    NS_VERIFY_NOT_NULL_V(providerCacheData == NULL ? (void *)1 : NULL);
+    //NS_VERIFY_NOT_NULL_V(providerCacheData == NULL ? (void *)1 : NULL);
+    if (providerCacheData == NULL)
+    {
+        isAdded = false;
+    }
+    else
+    {
+        NSProviderConnectionInfo * infos = providerCacheData->connection;
+        OCTransportAdapter newAdapter = provider->connection->addr->adapter;
+        while(infos)
+        {
+            if (infos->addr->adapter == newAdapter)
+            {
+                NS_LOG(DEBUG, "This provider already discovered.");
+                return;
+            }
+            infos = infos->next;
+        }
+    }
 
-    NS_LOG (ERROR, "New provider is discovered");
     NSResult ret = NSProviderCacheUpdate(provider);
     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
 
+    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_ACCESS_DENY)
+
+    if (provider->accessPolicy == NS_ACCESS_DENY && isAdded == false)
     {
         NS_LOG(DEBUG, "accepter is NS_ACCEPTER_CONSUMER, Callback to user");
         NSDiscoveredProvider((NSProvider *) provider);
@@ -205,7 +234,10 @@ void NSConsumerHandleRecvSubscriptionConfirmed(NSMessage_consumer * msg)
     NSProvider_internal * provider = NSProviderCacheFind(msg->providerId);
     NS_VERIFY_NOT_NULL_V(provider);
 
-    NSSubscriptionAccepted((NSProvider *) provider);
+    if (provider->connection->next == NULL)
+    {
+        NSSubscriptionAccepted((NSProvider *) provider);
+    }
 }
 
 void NSConsumerHandleRecvMessage(NSMessage_consumer * msg)
@@ -244,15 +276,16 @@ void NSConsumerHandleMakeSyncInfo(NSSyncInfo * sync)
     NSProvider_internal * provider = NSProviderCacheFind(sync->providerId);
     NS_VERIFY_NOT_NULL_V (provider);
 
+    NSProviderConnectionInfo * connections = NSCopyProviderConnections(provider->connection);
+    NS_VERIFY_NOT_NULL_V (connections);
+
     NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)OICMalloc(sizeof(NSSyncInfo_internal));
-    NS_VERIFY_NOT_NULL_V(syncInfo);
+    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->i_addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
-    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncInfo->i_addr, NSOICFree(syncInfo));
-    memcpy(syncInfo->i_addr, provider->i_addr, sizeof(OCDevAddr));
+    syncInfo->connection = connections;
 
     NSTask * syncTask = NSMakeTask(TASK_SEND_SYNCINFO, (void *) syncInfo);
     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncTask, NSOICFree(syncInfo));
index b031faf..75b26bb 100644 (file)
@@ -103,6 +103,7 @@ NSResult NSStorageWrite(NSCacheList * list, NSCacheElement * newObj)
         return NS_ERROR;
     }
 
+    NS_LOG_V(DEBUG, "cache type : %d", type);
     if (type == NS_CONSUMER_CACHE_MESSAGE)
     {
         pthread_mutex_unlock(mutex);
@@ -293,16 +294,17 @@ NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newOb
     if (it)
     {
         NSProvider_internal * provObj = (NSProvider_internal *) it->data;
-        it->data = (void *) NSCopyProvider(newProvObj);
-        if (!it->data)
-        {
-            NS_LOG (ERROR, "Failed to CopyProvider");
-            it->data = (void *) provObj;
-            pthread_mutex_unlock(mutex);
 
-            return NS_ERROR;
+        NSProviderConnectionInfo * infos = provObj->connection;
+        NSProviderConnectionInfo * lastConn = infos->next;
+        while(lastConn)
+        {
+            infos = lastConn;
+            lastConn = lastConn->next;
         }
-        NSRemoveProvider(provObj);
+        infos->next = NSCopyProviderConnections(newProvObj->connection);
+
+        NSRemoveProvider(newProvObj);
         pthread_mutex_unlock(mutex);
 
         return NS_OK;
@@ -316,6 +318,7 @@ NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newOb
 
         return NS_ERROR;
     }
+    NS_LOG_V(DEBUG, "New Object address : %s:%d", newProvObj->connection->addr->addr, newProvObj->connection->addr->port);
     obj->data = (void *) NSCopyProvider(newProvObj);
 
     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2");
@@ -336,13 +339,14 @@ NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newOb
     {
         list->head = obj;
         list->tail = obj;
-        pthread_mutex_unlock(mutex);
 
         NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3");
         prov = (NSProvider_internal *)list->tail->data;
         NS_LOG_V (DEBUG, "%s", prov->providerId);
         NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3");
 
+        pthread_mutex_unlock(mutex);
+
         return NS_OK;
     }