replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / notification / src / provider / NSProviderListener.c
index c295645..ea371cc 100644 (file)
 \r
 #include "NSProviderListener.h"\r
 \r
+bool NSProviderIsSyncAttributes(OCRepPayload * payload);\r
+bool NSProviderIsTopicAttributes(OCRepPayload * payload);\r
+OCStackResult NSProviderSendResponse(OCEntityHandlerRequest * entityHandlerRequest,\r
+        OCRepPayload * payload, char * reqInterface, OCEntityHandlerResult ehResult,\r
+        NSInterfaceType interfaceType, NSResourceType resourceType);\r
+\r
 OCEntityHandlerResult NSEntityHandlerNotificationCb(OCEntityHandlerFlag flag,\r
         OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
 {\r
     NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - IN");\r
 \r
-    OCEntityHandlerResult ehResult = OC_EH_OK;\r
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;\r
 \r
     (void)callback;\r
 \r
     if (!entityHandlerRequest)\r
     {\r
         NS_LOG(ERROR, "Invalid request pointer");\r
-        return OC_EH_ERROR;\r
+        return ehResult;\r
     }\r
 \r
     if (flag & OC_REQUEST_FLAG)\r
@@ -43,9 +49,22 @@ OCEntityHandlerResult NSEntityHandlerNotificationCb(OCEntityHandlerFlag flag,
         {\r
             NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OC_REST_GET");\r
 \r
+            char * copyQuery = OICStrdup(entityHandlerRequest->query);\r
+            char * reqInterface = NSGetValueFromQuery(copyQuery, NS_QUERY_INTERFACE);\r
+\r
+            if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) != 0\r
+                    && strcmp(reqInterface, NS_INTERFACE_READ) != 0)\r
+            {\r
+                NS_LOG(ERROR, "Invalid interface");\r
+                NSOICFree(copyQuery);\r
+                return ehResult;\r
+            }\r
+\r
+            NSOICFree(copyQuery);\r
             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_POLICY,\r
                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
 \r
+            ehResult = OC_EH_OK;\r
         }\r
         else\r
         {\r
@@ -62,20 +81,43 @@ OCEntityHandlerResult NSEntityHandlerMessageCb(OCEntityHandlerFlag flag,
 {\r
     NS_LOG(DEBUG, "NSEntityHandlerMessageCb - IN");\r
 \r
-    OCEntityHandlerResult ehResult = OC_EH_OK;\r
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;\r
+    char * reqInterface = NULL;\r
+    OCRepPayload * payload = NULL;\r
 \r
     (void)callback;\r
 \r
     if (!entityHandlerRequest)\r
     {\r
         NS_LOG (ERROR,"Invalid request pointer");\r
-        return OC_EH_ERROR;\r
+        return ehResult;\r
     }\r
 \r
     if (flag & OC_REQUEST_FLAG)\r
     {\r
         NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
         NS_LOG_V(DEBUG, "Received method %d from client", entityHandlerRequest->method);\r
+\r
+        if (OC_REST_GET == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_REST_GET");\r
+\r
+            char * copyQuery = OICStrdup(entityHandlerRequest->query);\r
+            reqInterface = OICStrdup(NSGetValueFromQuery(copyQuery, NS_QUERY_INTERFACE));\r
+            NSOICFree(copyQuery);\r
+\r
+            if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) != 0\r
+                    && strcmp(reqInterface, NS_INTERFACE_READ) != 0)\r
+            {\r
+                NS_LOG(ERROR, "Invalid interface");\r
+                return ehResult;\r
+            }\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else\r
+        {\r
+            NS_LOG_V (DEBUG, "Received method %d from client", entityHandlerRequest->method);\r
+        }\r
     }\r
 \r
     if (flag & OC_OBSERVE_FLAG)\r
@@ -89,19 +131,25 @@ OCEntityHandlerResult NSEntityHandlerMessageCb(OCEntityHandlerFlag flag,
             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_OBSERVE_REGISTER");\r
             NS_LOG_V(DEBUG, "NSEntityHandlerMessageCb\n"\r
                     "Register message observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
+\r
             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_RECV_SUBSCRIPTION,\r
                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
+            ehResult = OC_EH_OK;\r
         }\r
-        else if(ocObAction == OC_OBSERVE_DEREGISTER)\r
+        else if (ocObAction == OC_OBSERVE_DEREGISTER)\r
         {\r
             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_OBSERVE_DEREGISTER");\r
             NS_LOG_V(DEBUG, "NSEntityHandlerMessageCb\n - "\r
                     "Deregister Message observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_RECV_UNSUBSCRIPTION,\r
                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
+            ehResult = OC_EH_OK;\r
         }\r
     }\r
 \r
+    ehResult = NSProviderSendResponse(entityHandlerRequest, payload, reqInterface, ehResult,\r
+            NS_INTERFACE_TYPE_READ, NS_RESOURCE_MESSAGE);\r
+    NSOICFree(reqInterface);\r
     NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OUT");\r
     return ehResult;\r
 }\r
@@ -110,21 +158,39 @@ OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,
         OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
 {\r
     NS_LOG(DEBUG, "NSEntityHandlerSyncCb - IN");\r
-    OCEntityHandlerResult ehResult = OC_EH_OK;\r
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;\r
+    char * reqInterface = NULL;\r
+    OCRepPayload * payload = NULL;\r
 \r
     (void)callback;\r
 \r
     if (!entityHandlerRequest)\r
     {\r
         NS_LOG(ERROR, "Invalid request pointer");\r
-        return OC_EH_ERROR;\r
+        return ehResult;\r
     }\r
 \r
     if (flag & OC_REQUEST_FLAG)\r
     {\r
         NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
 \r
-        if (OC_REST_POST == entityHandlerRequest->method)\r
+        if (OC_REST_GET == entityHandlerRequest->method)\r
+        {\r
+\r
+            char * copyQuery = OICStrdup(entityHandlerRequest->query);\r
+            reqInterface = OICStrdup(NSGetValueFromQuery(copyQuery, NS_QUERY_INTERFACE));\r
+            NSOICFree(copyQuery);\r
+\r
+            if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) != 0\r
+                    && strcmp(reqInterface, NS_INTERFACE_READWRITE) != 0)\r
+            {\r
+                NS_LOG(ERROR, "Invalid interface");\r
+                return ehResult;\r
+            }\r
+\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else if (OC_REST_POST == entityHandlerRequest->method)\r
         {\r
             /** Receive sync data from consumer which read or dismiss notification message.\r
                 And broadcast the sync data to all subscribers including provider app\r
@@ -132,12 +198,17 @@ OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,
 \r
             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_REST_POST");\r
 \r
-            NSPushQueue(NOTIFICATION_SCHEDULER, TASK_RECV_READ,\r
-                    NSGetSyncInfo(entityHandlerRequest->payload));\r
-\r
+            if (NSProviderIsSyncAttributes((OCRepPayload *)entityHandlerRequest->payload))\r
+            {\r
+                NSPushQueue(NOTIFICATION_SCHEDULER, TASK_RECV_READ,\r
+                                    NSGetSyncInfo(entityHandlerRequest->payload));\r
+                ehResult = OC_EH_OK;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            NS_LOG_V(DEBUG, "Received method %d from client", entityHandlerRequest->method);\r
         }\r
-\r
-        NS_LOG_V(DEBUG, "Received method %d from client", entityHandlerRequest->method);\r
     }\r
 \r
     if (flag & OC_OBSERVE_FLAG)\r
@@ -157,7 +228,7 @@ OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,
             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SYNC_SUBSCRIPTION,\r
                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
         }\r
-        else if(ocObAction == OC_OBSERVE_DEREGISTER)\r
+        else if (ocObAction == OC_OBSERVE_DEREGISTER)\r
         {\r
             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_OBSERVE_DEREGISTER");\r
             NS_LOG_V(DEBUG, "NSEntityHandlerSyncCb\n - "\r
@@ -168,6 +239,11 @@ OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,
     }\r
 \r
     NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OUT");\r
+\r
+    ehResult = NSProviderSendResponse(entityHandlerRequest, payload, reqInterface, ehResult,\r
+            NS_INTERFACE_TYPE_READ, NS_RESOURCE_MESSAGE);\r
+    NSOICFree(reqInterface);\r
+\r
     return ehResult;\r
 }\r
 \r
@@ -175,15 +251,16 @@ OCEntityHandlerResult NSEntityHandlerTopicCb(OCEntityHandlerFlag flag,
         OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
 {\r
     NS_LOG(DEBUG, "NSEntityHandlerTopicCb - IN");\r
-    OCEntityHandlerResult ehResult = OC_EH_OK;\r
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;\r
+    char * reqInterface = NULL;\r
+    OCRepPayload * payload = NULL;\r
 \r
     (void)callback;\r
 \r
-    // Validate pointer\r
     if (!entityHandlerRequest)\r
     {\r
         NS_LOG(ERROR, "Invalid request pointer");\r
-        return OC_EH_ERROR;\r
+        return ehResult;\r
     }\r
 \r
     if (flag & OC_REQUEST_FLAG)\r
@@ -194,6 +271,16 @@ OCEntityHandlerResult NSEntityHandlerTopicCb(OCEntityHandlerFlag flag,
         {\r
             NS_LOG(DEBUG, "NSEntityHandlerTopicCb - OC_REST_GET");\r
 \r
+            char * copyReq = OICStrdup(entityHandlerRequest->query);\r
+            reqInterface = OICStrdup(NSGetValueFromQuery(copyReq, NS_QUERY_INTERFACE));\r
+            NSOICFree(copyReq);\r
+\r
+            if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) != 0\r
+                    && strcmp(reqInterface, NS_INTERFACE_READWRITE) != 0)\r
+            {\r
+                NS_LOG(ERROR, "Invalid interface");\r
+                return ehResult;\r
+            }\r
             // send consumer's interesting topic list if consumer id exists\r
             // otherwise send  registered topic list\r
             NSPushQueue(TOPIC_SCHEDULER, TASK_SEND_TOPICS,\r
@@ -204,30 +291,194 @@ OCEntityHandlerResult NSEntityHandlerTopicCb(OCEntityHandlerFlag flag,
         else if (OC_REST_POST == entityHandlerRequest->method)\r
         {\r
             // Receive interesting topic list from consumers\r
-            NS_LOG(DEBUG, "NSEntityHandlerTopicCb - OC_REST_POST");\r
-\r
-            // Send topic notice message(id = TOPIC) to the consumer \r
+            // Send topic notice message(id = TOPIC) to the consumer\r
             // which requests to post.\r
-            NSPushQueue(TOPIC_SCHEDULER, TASK_POST_TOPIC,\r
-                    NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
-\r
-            ehResult = OC_EH_OK;\r
+            NS_LOG(DEBUG, "NSEntityHandlerTopicCb - OC_REST_POST");\r
+            // Accepter is provider. our service is not support sendtopiclist from OC_REST_POST\r
+            // Accepter is consumer. our service is support sendtopiclist from OC_REST_POST\r
+            if (NSGetPolicy() == false &&\r
+                    NSProviderIsTopicAttributes(OCRepPayloadClone((OCRepPayload *)\r
+                            entityHandlerRequest->payload)))\r
+            {\r
+                NSPushQueue(TOPIC_SCHEDULER, TASK_POST_TOPIC,\r
+                        NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
+                ehResult = OC_EH_OK;\r
+            }\r
         }\r
         else\r
         {\r
             NS_LOG_V(DEBUG, "Received unsupported method %d from client",\r
                     entityHandlerRequest->method);\r
-            ehResult = OC_EH_OK;\r
+            ehResult = OC_EH_ERROR;\r
         }\r
     }\r
 \r
     NS_LOG(DEBUG, "NSEntityHandlerTopicCb - OUT");\r
+    ehResult = NSProviderSendResponse(entityHandlerRequest, payload, reqInterface, ehResult,\r
+            NS_INTERFACE_TYPE_READWRITE, NS_RESOURCE_TOPIC);\r
+    NSOICFree(reqInterface);\r
     return ehResult;\r
 }\r
 \r
-void NSProviderConnectionStateListener(const CAEndpoint_t * info, bool connected)\r
+#ifdef WITH_MQ\r
+OCStackApplicationResult NSProviderMQListener(void * ctx, OCDoHandle handle,\r
+        OCClientResponse * clientResponse)\r
 {\r
+    (void) ctx;\r
+    (void) handle;\r
+\r
+    NS_LOG_V(DEBUG, "clientResponse->sequenceNumber = %d", clientResponse->sequenceNumber);\r
+\r
+    if (clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)\r
+    {\r
+        NS_LOG(DEBUG, "MQ OC_OBSERVE_RIGSTER");\r
+        NSSetMQServerInfo(clientResponse->resourceUri, &(clientResponse->devAddr));\r
+    }\r
+\r
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);\r
+    NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);\r
+    NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);\r
+\r
+    NS_LOG(DEBUG, "income observe response of MQ notification");\r
+    NS_LOG_V(INFO_PRIVATE, "MQ OBS response income : %s:%d",\r
+            clientResponse->devAddr.addr, clientResponse->devAddr.port);\r
+    NS_LOG_V(DEBUG, "MQ OBS response result : %d",\r
+            clientResponse->result);\r
+    NS_LOG_V(DEBUG, "MQ OBS response sequenceNum : %d",\r
+            clientResponse->sequenceNumber);\r
+    NS_LOG_V(DEBUG, "MQ OBS response resource uri : %s",\r
+            clientResponse->resourceUri);\r
+    NS_LOG_V(DEBUG, "MQ OBS response Transport Type : %d",\r
+                    clientResponse->devAddr.adapter);\r
+\r
+    OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;\r
+    NS_VERIFY_NOT_NULL(payload, OC_STACK_KEEP_TRANSACTION);\r
+\r
+    NSMessageType type = -1;\r
+    bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TYPE, (int64_t *) &type);\r
+    NS_LOG_V (DEBUG, "message sync type : %d", (int) type);\r
+\r
+    if (!getResult && (type == NS_MESSAGE_READ || type == NS_MESSAGE_DELETED))\r
+    {\r
+        char * pId = NULL;\r
+        getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);\r
+        NS_LOG_V (INFO_PRIVATE, "provider id: %s", pId);\r
+\r
+        if (getResult && strcmp(pId, NSGetProviderInfo()->providerId) == 0)\r
+        {\r
+            NSSyncInfo * syncInfo = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));\r
+            syncInfo->state = (type == NS_MESSAGE_READ) ? NS_SYNC_READ : NS_SYNC_DELETED;\r
+            OICStrcpy(syncInfo->providerId, NS_UUID_STRING_SIZE, pId);\r
+            NSOICFree(pId);\r
+            NSPushQueue(NOTIFICATION_SCHEDULER, TASK_RECV_READ, (void*) syncInfo);\r
+        }\r
+    }\r
+\r
+    return OC_STACK_KEEP_TRANSACTION;\r
+}\r
+\r
+OCStackApplicationResult NSProviderGetMQResponseCB(void * ctx, OCDoHandle handle,\r
+        OCClientResponse * clientResponse)\r
+{\r
+    NS_LOG(DEBUG, "NSProviderGetMQResponseCB - IN");\r
+\r
+    (void) handle;\r
+\r
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);\r
+    NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);\r
+    NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);\r
+\r
+    NS_LOG(DEBUG, "income get response of MQ broker");\r
+    NS_LOG_V(INFO_PRIVATE, "MQ GET response income : %s:%d",\r
+            clientResponse->devAddr.addr, clientResponse->devAddr.port);\r
+    NS_LOG_V(DEBUG, "MQ GET response result : %d",\r
+            clientResponse->result);\r
+    NS_LOG_V(DEBUG, "MQ GET response sequenceNum : %d",\r
+            clientResponse->sequenceNumber);\r
+    NS_LOG_V(DEBUG, "MQ GET response resource uri : %s",\r
+            clientResponse->resourceUri);\r
+    NS_LOG_V(DEBUG, "MQ GET response Transport Type : %d",\r
+                    clientResponse->devAddr.adapter);\r
+\r
+    char ** topicList = NULL;\r
+    size_t dimensions[MAX_REP_ARRAY_DEPTH] = {0};\r
+    OCRepPayloadGetStringArray((OCRepPayload *) clientResponse->payload,\r
+                               NS_ATTIRBUTE_MQ_TOPICLIST, & topicList, dimensions);\r
+\r
+    char * interestTopicName = (char *) ctx;\r
+\r
+    NS_LOG_V(DEBUG, "interestTopicName = %s", interestTopicName);\r
+    for (size_t i = 0; i < dimensions[0]; ++i)\r
+    {\r
+        NS_LOG_V(DEBUG, "found MQ topic : %s", topicList[i]);\r
+        if (!strcmp(topicList[i], interestTopicName))\r
+        {\r
+            NS_LOG(DEBUG, "subscribe to MQ notification");\r
+\r
+            OCCallbackData cbdata = { NULL, NULL, NULL };\r
+            cbdata.cb = NSProviderMQListener;\r
+            cbdata.context = NULL;\r
+            cbdata.cd = NULL;\r
+\r
+            OCStackResult ret = OCDoResource(NULL, OC_REST_OBSERVE, topicList[i],\r
+                    clientResponse->addr, NULL, CT_DEFAULT, OC_HIGH_QOS, &cbdata, NULL, 0);\r
+\r
+            if (!NSOCResultToSuccess(ret))\r
+            {\r
+                NS_LOG(DEBUG, "fail to subscribe to MQ notification");\r
+                continue;\r
+            }\r
+        }\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSProviderGetMQResponseCB - OUT");\r
+    return OC_STACK_KEEP_TRANSACTION;\r
+}\r
+\r
+OCStackApplicationResult NSProviderPublishMQResponseCB(void *ctx, OCDoHandle handle,\r
+        OCClientResponse *clientResponse)\r
+{\r
+    (void) ctx;\r
+    (void) handle;\r
+    NS_LOG(DEBUG, "Publish Topic callback received");\r
+\r
+    OCStackApplicationResult res = OC_STACK_ERROR;\r
+\r
+    NS_LOG_V(DEBUG, "Publish Topic response received code: (%d)", clientResponse->result);\r
+\r
+    if (clientResponse->payload != NULL &&\r
+        clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)\r
+    {\r
+        NS_LOG(DEBUG, "PAYLOAD_TYPE_REPRESENTATION received");\r
+\r
+        OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values;\r
+        while (val)\r
+        {\r
+            if( val->type == OCREP_PROP_INT)\r
+            {\r
+                NS_LOG_V(DEBUG, "Key: %s, Value: %lld, int", val->name, val->i);\r
+            }\r
+            else if( val->type == OCREP_PROP_STRING)\r
+            {\r
+                NS_LOG_V(DEBUG, "Key: %s, Value: %s, string", val->name, val->str);\r
+            }\r
+            else\r
+            {\r
+                NS_LOG_V(DEBUG, "Un supported val Type.(0x%d)", val->type);\r
+            }\r
+\r
+            val = val->next;\r
+        }\r
 \r
+        res = OC_STACK_KEEP_TRANSACTION;\r
+    }\r
+\r
+    return res;\r
+}\r
+#endif\r
+\r
+void NSProviderConnectionStateListener(const CAEndpoint_t * info, bool connected)\r
+{\r
     NS_LOG(DEBUG, "NSProviderConnectionStateListener - IN");\r
 \r
     if (connected)\r
@@ -240,22 +491,21 @@ void NSProviderConnectionStateListener(const CAEndpoint_t * info, bool connected
         // Start Presence\r
         NSPushQueue(DISCOVERY_SCHEDULER, TASK_START_PRESENCE, NULL);\r
 \r
-        if(info->adapter == CA_ADAPTER_TCP)\r
+        if (info->adapter == CA_ADAPTER_TCP)\r
         {\r
-            NS_LOG_V(DEBUG, "TCP Connected remote address: %s:%d", info->addr, info->port);\r
+            NS_LOG_V(INFO_PRIVATE, "TCP Connected remote address: %s:%d", info->addr, info->port);\r
         }\r
     }\r
     else\r
     {\r
-\r
         NS_LOG(DEBUG, "DISCONNECTED");\r
 \r
         // Set Connection State\r
         NSSetProviderConnectionState(DISCONNECTED);\r
 \r
-        if(info->adapter == CA_ADAPTER_TCP)\r
+        if (info->adapter == CA_ADAPTER_TCP)\r
         {\r
-            NS_LOG_V(DEBUG, "TCP Disconnected remote address: %s:%d", info->addr, info->port);\r
+            NS_LOG_V(INFO_PRIVATE, "TCP Disconnected remote address: %s:%d", info->addr, info->port);\r
         }\r
     }\r
 \r
@@ -290,3 +540,181 @@ void NSProviderAdapterStateListener(CATransportAdapter_t adapter, bool enabled)
     NS_LOG(DEBUG, "NSProviderAdapterStateListener - OUT");\r
 }\r
 \r
+bool NSProviderCompareSyncAttributes(const char * name)\r
+{\r
+    if (!strcmp(name, NS_ATTRIBUTE_MESSAGE_ID) ||\r
+        !strcmp(name, NS_ATTRIBUTE_PROVIDER_ID) ||\r
+        !strcmp(name, NS_ATTRIBUTE_STATE))\r
+    {\r
+        return true;\r
+    }\r
+\r
+    return false;\r
+}\r
+\r
+bool NSProviderIsSyncAttributes(OCRepPayload * payload)\r
+{\r
+    NS_LOG(DEBUG, "get extra info");\r
+    OCRepPayloadValue * curr = payload->values;\r
+\r
+    while (curr)\r
+    {\r
+        if (!NSProviderCompareSyncAttributes(curr->name))\r
+        {\r
+            return false;\r
+        }\r
+\r
+        curr = curr->next;\r
+    }\r
+\r
+    return true;\r
+}\r
+\r
+bool NSProviderCompareTopicAttributes(const char * name)\r
+{\r
+    if (!strcmp(name, NS_ATTRIBUTE_TOPIC_LIST) ||\r
+        !strcmp(name, NS_ATTRIBUTE_CONSUMER_ID))\r
+    {\r
+        return true;\r
+    }\r
+\r
+    return false;\r
+}\r
+\r
+bool NSProviderCompareSubTopicAttributes(const char * name)\r
+{\r
+    if (!strcmp(name, NS_ATTRIBUTE_TOPIC_NAME) ||\r
+        !strcmp(name, NS_ATTRIBUTE_TOPIC_SELECTION))\r
+    {\r
+        return true;\r
+    }\r
+\r
+    return false;\r
+}\r
+\r
+bool NSProviderIsTopicAttributes(OCRepPayload * payload)\r
+{\r
+    NS_LOG(DEBUG, "get extra info");\r
+    OCRepPayloadValue * curr = payload->values;\r
+\r
+    while (curr)\r
+    {\r
+        if (!NSProviderCompareTopicAttributes(curr->name))\r
+        {\r
+            OCRepPayloadDestroy(payload);\r
+            return false;\r
+        }\r
+\r
+        if (!strcmp(curr->name, NS_ATTRIBUTE_TOPIC_LIST))\r
+        {\r
+            OCRepPayload ** topicListPayload = NULL;\r
+            OCRepPayloadValue * payloadValue = NULL;\r
+            payloadValue = NSPayloadFindValue(payload, NS_ATTRIBUTE_TOPIC_LIST);\r
+            size_t dimensionSize = calcDimTotal(payloadValue->arr.dimensions);\r
+            size_t dimensions[3] = { dimensionSize, 0, 0 };\r
+\r
+            if (!dimensionSize)\r
+            {\r
+                OCRepPayloadDestroy(payload);\r
+                return false;\r
+            }\r
+\r
+            OCRepPayloadGetPropObjectArray(payload, NS_ATTRIBUTE_TOPIC_LIST, &topicListPayload,\r
+                    dimensions);\r
+\r
+            for (int i = 0; i < (int) dimensionSize; i++)\r
+            {\r
+                OCRepPayloadValue * subCurr = topicListPayload[i]->values;\r
+\r
+                while (subCurr)\r
+                {\r
+                    if (!NSProviderCompareSubTopicAttributes(subCurr->name))\r
+                    {\r
+                        for(int j = i; j < (int) dimensionSize; ++j)\r
+                        {\r
+                            OCRepPayloadDestroy(topicListPayload[j]);\r
+                        }\r
+\r
+                        NSOICFree(topicListPayload);\r
+                        OCRepPayloadDestroy(payload);\r
+                        return false;\r
+                    }\r
+                    subCurr = subCurr->next;\r
+                }\r
+                OCRepPayloadDestroy(topicListPayload[i]);\r
+            }\r
+            NSOICFree(topicListPayload);\r
+        }\r
+        curr = curr->next;\r
+    }\r
+\r
+    OCRepPayloadDestroy(payload);\r
+    return true;\r
+}\r
+\r
+OCStackResult NSProviderSendResponse(OCEntityHandlerRequest * entityHandlerRequest,\r
+        OCRepPayload * payload, char * reqInterface, OCEntityHandlerResult ehResult,\r
+        NSInterfaceType interfaceType, NSResourceType resourceType)\r
+{\r
+    if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) == 0)\r
+    {\r
+        payload = OCRepPayloadCreate();\r
+\r
+        if (!payload)\r
+        {\r
+            NS_LOG(ERROR, "payload is NULL");\r
+            return ehResult;\r
+        }\r
+\r
+        OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_BASELINE);\r
+        interfaceType == NS_INTERFACE_TYPE_READ ?\r
+                OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_READ)\r
+                : OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_READWRITE);\r
+\r
+        char * rtStr = NULL;\r
+        switch (resourceType)\r
+        {\r
+            case NS_RESOURCE_MESSAGE:\r
+                rtStr = NS_COLLECTION_MESSAGE_TYPE;\r
+                break;\r
+            case NS_RESOURCE_SYNC:\r
+                rtStr = NS_COLLECTION_SYNC_TYPE;\r
+                break;\r
+            case NS_RESOURCE_TOPIC:\r
+                rtStr = NS_COLLECTION_TOPIC_TYPE;\r
+                break;\r
+            default:\r
+                NS_LOG(ERROR, "sendResponseError");\r
+                return ehResult;\r
+        }\r
+\r
+        OCResourcePayloadAddStringLL(&payload->types, rtStr);\r
+    }\r
+\r
+    if (resourceType == NS_RESOURCE_TOPIC && entityHandlerRequest->method == OC_REST_GET)\r
+    {\r
+        OCRepPayloadDestroy(payload);\r
+        return ehResult;\r
+    }\r
+\r
+    OCEntityHandlerResponse response;\r
+    response.numSendVendorSpecificHeaderOptions = 0;\r
+    memset(response.sendVendorSpecificHeaderOptions, 0,\r
+            sizeof response.sendVendorSpecificHeaderOptions);\r
+    memset(response.resourceUri, 0, sizeof response.resourceUri);\r
+\r
+    response.requestHandle = entityHandlerRequest->requestHandle;\r
+    response.resourceHandle = entityHandlerRequest->resource;\r
+    response.persistentBufferFlag = 0;\r
+    response.ehResult = ehResult;\r
+    response.payload = (OCPayload *) payload;\r
+\r
+    if (OCDoResponse(&response) != OC_STACK_OK)\r
+    {\r
+        NS_LOG(ERROR, "Fail to AccessPolicy send response");\r
+        ehResult = OC_STACK_ERROR;\r
+    }\r
+\r
+    OCRepPayloadDestroy(payload);\r
+    return ehResult;\r
+}\r