replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / routing / src / routingmanager.c
index bf82153..9f87d2f 100644 (file)
@@ -46,7 +46,7 @@
 /**
  * Unique gateway ID generated before hosting a gateway resource.
  */
-uint32_t g_GatewayID = 0;
+static uint32_t g_GatewayID = 0;
 
 /**
  * Used for assigning unique ID.to endpoint's connected to this gateway
@@ -906,13 +906,14 @@ uint16_t RMGetMcastSeqNumber()
  */
 
 OCStackResult RMHandlePacket(bool isRequest, void *message, const CAEndpoint_t *sender,
-                             bool *selfDestination)
+                             bool *selfDestination, bool *isEmptyMsg)
 {
     RM_NULL_CHECK_WITH_RET(message, RM_TAG, "message");
     RM_NULL_CHECK_WITH_RET(sender, RM_TAG, "sender");
     RM_NULL_CHECK_WITH_RET(selfDestination, RM_TAG, "selfDestination");
 
     bool forward = false;
+    bool isEMPTYPacket = false;
     CAEndpoint_t nextHop = {.adapter = CA_DEFAULT_ADAPTER};
     CAInfo_t *info = NULL;
     if (isRequest)
@@ -1048,6 +1049,13 @@ OCStackResult RMHandlePacket(bool isRequest, void *message, const CAEndpoint_t *
     else if (g_GatewayID == routeOption.destGw)
     {
         OIC_LOG(INFO, RM_TAG, "GatewayId found in destination");
+
+        // Check the MSGType of RouteOption to find if the packet is EMPTY packet.
+        if (ACK == routeOption.msgType || RST == routeOption.msgType)
+        {
+            isEMPTYPacket = true;
+        }
+
         /*
          * This unicast packet either belongs to us or any of our connected end devices
          * check if packet belongs to end device.
@@ -1111,7 +1119,8 @@ rewriteandexit:
     if (forward)
     {
         // Don't forward any packet meant for gateway resource.
-        if (info->resourceUri && (0 == strcmp(info->resourceUri, OC_RSRVD_GATEWAY_URI)))
+        if (info->resourceUri && (0 == strcmp(info->resourceUri, OC_RSRVD_GATEWAY_URI)) &&
+            (ACK != routeOption.msgType))
         {
             OIC_LOG(ERROR, RM_TAG, "Not forwarding gateway resource packet");
         }
@@ -1120,6 +1129,31 @@ rewriteandexit:
             OIC_LOG(ERROR, RM_TAG, "This is secured request. Not supported by routing manager");
             return OC_STACK_ERROR;
         }
+        else if (isEMPTYPacket)
+        {
+            OIC_LOG(DEBUG, TAG, "The message to be Forwarded is a EMPTY message");
+            CAResponseInfo_t responseMessage = {.result = CA_EMPTY};
+            if (ACK == routeOption.msgType)
+            {
+                responseMessage.info.type = CA_MSG_ACKNOWLEDGE;
+            }
+            else
+            {
+                responseMessage.info.type = CA_MSG_RESET;
+            }
+
+            responseMessage.info.messageId = info->messageId;
+            responseMessage.info.dataType = CA_RESPONSE_DATA;
+
+            CAResult_t caRes = CASendResponse(&nextHop, &responseMessage);
+            if (CA_STATUS_OK != caRes)
+            {
+                OIC_LOG_V(ERROR, RM_TAG, "Failed to forward response to next hop [%d][%s]",
+                         caRes, nextHop.addr);
+                // Since a response is always unicast, return error here.
+                return OC_STACK_ERROR;
+            }
+        }
         else
         {
             // rewrite any changes in routing option.
@@ -1137,6 +1171,7 @@ rewriteandexit:
             if(isRequest)
             {
                 CARequestInfo_t *msg = message;
+                msg->info.dataType = CA_REQUEST_DATA;
                 CAResult_t caRes = CASendRequest(&nextHop, msg);
                 if (CA_STATUS_OK != caRes)
                 {
@@ -1156,6 +1191,7 @@ rewriteandexit:
             else
             {
                 CAResponseInfo_t *msg = message;
+                msg->info.dataType = CA_RESPONSE_DATA;
                 CAResult_t caRes = CASendResponse(&nextHop, msg);
                 if (CA_STATUS_OK != caRes)
                 {
@@ -1167,21 +1203,52 @@ rewriteandexit:
             }
         }
     }
+    else
+    {
+        if (isEMPTYPacket)
+        {
+            if (isRequest)
+            {
+                OIC_LOG(DEBUG, TAG, "POST message with type ACK in Route Option");
+                if (NULL != isEmptyMsg)
+                {
+                    *isEmptyMsg = true;
+                }
+            }
+            else
+            {
+                OIC_LOG(DEBUG, TAG, "Response for EMPTY message is received");
+                CAResponseInfo_t *msg = message;
+                if (ACK == (MSGType)routeOption.msgType)
+                {
+                    msg->info.type = CA_MSG_ACKNOWLEDGE;
+                }
+                else
+                {
+                    msg->info.type = CA_MSG_RESET;
+                }
+                msg->result = CA_EMPTY;
+                OICFree(msg->info.token);
+                msg->info.token = NULL;
+                msg->info.tokenLength = 0;
+            }
+        }
+    }
 
     OIC_LOG_V(INFO, RM_TAG, "Sender: [%u] Destination: [%u]", routeOption.srcGw, routeOption.destGw);
     return OC_STACK_OK;
 }
 
 OCStackResult RMHandleRequest(CARequestInfo_t *message, const CAEndpoint_t *sender,
-                              bool *selfDestination)
+                              bool *selfDestination, bool *isEmptyMsg)
 {
     if (!g_isRMInitialized)
     {
-        OIC_LOG(ERROR, TAG, "RM not initialized");
+        OIC_LOG(INFO, TAG, "RM not initialized");
         *selfDestination = true;
         return OC_STACK_OK;
     }
-    OCStackResult res = RMHandlePacket(true, message, sender, selfDestination);
+    OCStackResult res = RMHandlePacket(true, message, sender, selfDestination, isEmptyMsg);
     return res;
 }
 
@@ -1190,10 +1257,10 @@ OCStackResult RMHandleResponse(CAResponseInfo_t *message, const CAEndpoint_t *se
 {
     if (!g_isRMInitialized)
     {
-        OIC_LOG(ERROR, TAG, "RM not initialized");
+        OIC_LOG(INFO, TAG, "RM not initialized");
         *selfDestination = true;
         return OC_STACK_OK;
     }
-    OCStackResult res = RMHandlePacket(false, message, sender, selfDestination);
+    OCStackResult res = RMHandlePacket(false, message, sender, selfDestination, NULL);
     return res;
 }