[Jira IOT-604] Fix error handling from message handler
authorjnashok <jn.ashok@samsung.com>
Fri, 24 Jul 2015 07:41:21 +0000 (16:41 +0900)
committerErich Keane <erich.keane@intel.com>
Fri, 31 Jul 2015 16:15:52 +0000 (16:15 +0000)
This is a specific case where error hadling is not handled
Fixed the error in the send thread

Change-Id: I3f4d1983d379550ee6e72d95b9341da847fce47a
Signed-off-by: jnashok <jn.ashok@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1871
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Erich Keane <erich.keane@intel.com>
resource/csdk/connectivity/common/inc/caremotehandler.h
resource/csdk/connectivity/common/src/caremotehandler.c
resource/csdk/connectivity/src/cainterfacecontroller.c
resource/csdk/connectivity/src/camessagehandler.c
resource/csdk/connectivity/src/ip_adapter/caipadapter.c

index e24db97..ebe8d0e 100644 (file)
@@ -59,9 +59,17 @@ CAEndpoint_t *CACreateEndpointObject(CATransportFlags_t flags, CATransportAdapte
 void CAFreeEndpoint(CAEndpoint_t *rep);
 
 /**
+ * @brief       duplicates the given info.
+ * @param[in]   info    info object to be duplicated.
+ * @param[out]  clone   info object to be modified.
+ * @return      #CA_STATUS_OK or Appropriate error code if fail to clone.
+ */
+CAResult_t CACloneInfo(const CAInfo_t *info, CAInfo_t *clone);
+
+/**
  * @brief   Creates a new request information
  * @param   request       [IN]    request information that needs to be duplicated
- * @return  remote endpoint created
+ * @return  duplicated request info object
  */
 CARequestInfo_t *CACloneRequestInfo(const CARequestInfo_t *request);
 
@@ -75,7 +83,7 @@ void CADestroyRequestInfoInternal(CARequestInfo_t *request);
 /**
  * @brief   Creates a new response information
  * @param   response       [IN]    response information that needs to be duplicated
- * @return  remote endpoint created
+ * @return  duplicated response info object
  */
 CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *response);
 
index decc861..e6ef079 100644 (file)
@@ -314,15 +314,23 @@ static void CADestroyInfoInternal(CAInfo_t *info)
 {
     // free token field
     OICFree(info->token);
+    info->token = NULL;
+    info->tokenLength = 0;
 
     // free options field
     OICFree(info->options);
+    info->options = NULL;
+    info->numOptions = 0;
+
 
     // free payload field
     OICFree((char *) info->payload);
+    info->payload = NULL;
+    info->payloadSize = 0;
 
     // free uri
     OICFree(info->resourceUri);
+    info->resourceUri = NULL;
 }
 
 void CADestroyRequestInfoInternal(CARequestInfo_t *rep)
@@ -361,3 +369,81 @@ void CADestroyErrorInfoInternal(CAErrorInfo_t *errorInfo)
     OICFree(errorInfo);
 }
 
+CAResult_t CACloneInfo(const CAInfo_t *info, CAInfo_t *clone)
+{
+    if (!info || !clone)
+    {
+        OIC_LOG(ERROR, TAG, "input parameter invalid");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    //Do not free clone. we cannot declare it const, as the content is modified
+    if ((info->token) && (0 < info->tokenLength))
+    {
+        char *temp = NULL;
+
+        // allocate token field
+        uint8_t len = info->tokenLength;
+
+        temp = (char *) OICMalloc(len * sizeof(char));
+        if (!temp)
+        {
+            OIC_LOG(ERROR, TAG, "CAClonePayloadInfo Out of memory");
+            return CA_MEMORY_ALLOC_FAILED;
+        }
+
+        memcpy(temp, info->token, len);
+        // save the token
+        clone->token = temp;
+        clone->tokenLength = len;
+    }
+
+    if (info->options && (0 < info->numOptions))
+    {
+        // save the options
+        clone->options =
+            (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * info->numOptions);
+
+        if (!clone->options)
+        {
+            OIC_LOG(ERROR, TAG, "CAClonePayloadInfo Out of memory");
+            CADestroyInfoInternal(clone);
+            return CA_MEMORY_ALLOC_FAILED;
+        }
+        memcpy(clone->options, info->options, sizeof(CAHeaderOption_t) * info->numOptions);
+    }
+
+    if (info->payload)
+    {
+        // allocate payload field
+        uint8_t *temp = OICMalloc(info->payloadSize);
+        if (!temp)
+        {
+            OIC_LOG(ERROR, TAG, "CAClonePayloadInfo Out of memory");
+            CADestroyInfoInternal(clone);
+            return CA_MEMORY_ALLOC_FAILED;
+        }
+        memcpy(temp, info->payload, info->payloadSize);
+
+        // save the payload
+        clone->payload = temp;
+    }
+
+    if (info->resourceUri)
+    {
+        // allocate payload field
+        char *temp = OICStrdup(info->resourceUri);
+        if (!temp)
+        {
+            OIC_LOG(ERROR, TAG, "CAClonePayloadInfo Out of memory");
+            CADestroyInfoInternal(clone);
+            return CA_MEMORY_ALLOC_FAILED;
+        }
+
+        // save the resourceUri
+        clone->resourceUri = temp;
+    }
+
+    return CA_STATUS_OK;
+
+}
index ddf689e..52c2f21 100644 (file)
@@ -352,8 +352,6 @@ CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uin
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    CAResult_t res = CA_STATUS_FAILED;
-
     if (endpoint == NULL)
     {
         OIC_LOG(DEBUG, TAG, "Invalid endpoint");
@@ -377,20 +375,23 @@ CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uin
         sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length);
     }
 
-    if (sentDataLen != -1)
+    if (sentDataLen != length)
     {
-        res = CA_STATUS_OK;
+        OIC_LOG(ERROR, TAG, "error in sending data. Error will be reported in adapter");
+#ifdef SINGLE_THREAD
+        //in case of single thread, no error handler. Report error immediately
+        return CA_SEND_FAILED;
+#endif
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
-    return res;
+    return CA_STATUS_OK;
 }
 
 CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    CAResult_t res = CA_SEND_FAILED;
     u_arraylist_t *list = CAGetSelectedNetworkList();
 
     if (!list)
@@ -434,19 +435,19 @@ CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, u
             OICFree(payload);
         }
 
-        if (sentDataLen == length)
+        if (sentDataLen != length)
         {
-           res = CA_STATUS_OK;
-        }
-        else
-        {
-            OIC_LOG(ERROR, TAG, "sendDataToAll failed!");
+            OIC_LOG(ERROR, TAG, "sendDataToAll failed! Error will be reported from adapter");
+#ifdef SINGLE_THREAD
+            //in case of single thread, no error handler. Report error immediately
+            return CA_SEND_FAILED;
+#endif
         }
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
 
-    return res;
+    return CA_STATUS_OK;
 }
 
 CAResult_t CAStartListeningServerAdapters()
index 78b207c..8371328 100644 (file)
@@ -74,6 +74,9 @@ static void CAErrorHandler(const CAEndpoint_t *endpoint,
 static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, const void *data,
                                        CADataType_t dataType);
 
+static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info,
+                            CAResult_t result);
+
 #ifdef SINGLE_THREAD
 static void CAProcessReceivedData(CAData_t *data);
 #endif
@@ -382,21 +385,21 @@ static void CAReceiveThreadProcess(void *threadData)
 }
 #endif
 
-static void CAProcessSendData(const CAData_t *data)
+static CAResult_t CAProcessSendData(const CAData_t *data)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    VERIFY_NON_NULL_VOID(data, TAG, "data");
-    VERIFY_NON_NULL_VOID(data->remoteEndpoint, TAG, "remoteEndpoint");
+    VERIFY_NON_NULL(data, TAG, "data");
+    VERIFY_NON_NULL(data->remoteEndpoint, TAG, "remoteEndpoint");
 
     CAResult_t res = CA_STATUS_FAILED;
 
     CASendDataType_t type = data->type;
 
     coap_pdu_t *pdu = NULL;
+    CAInfo_t *info = NULL;
 
     if (SEND_TYPE_UNICAST == type)
     {
-        CAInfo_t *info = NULL;
 
         OIC_LOG(DEBUG,TAG,"Unicast message");
         if (NULL != data->requestInfo)
@@ -416,7 +419,7 @@ static void CAProcessSendData(const CAData_t *data)
         else
         {
             OIC_LOG(DEBUG, TAG, "request info, response info is empty");
-            return;
+            return CA_STATUS_INVALID_PARAM;
         }
 
         // interface controller function call.
@@ -435,7 +438,7 @@ static void CAProcessSendData(const CAData_t *data)
                         OIC_LOG(INFO, TAG, "to write block option has failed");
                         CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
                         coap_delete_pdu(pdu);
-                        return;
+                        return res;
                     }
                 }
             }
@@ -446,17 +449,19 @@ static void CAProcessSendData(const CAData_t *data)
             if (CA_STATUS_OK != res)
             {
                 OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
+                CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
                 coap_delete_pdu(pdu);
-                return;
+                return res;
             }
             // for retransmission
             res = CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr,
                                            pdu->length);
-            if (CA_STATUS_OK != res)
+            if ((CA_STATUS_OK != res) && (CA_NOT_SUPPORTED != res))
             {
+                //when retransmission not supported this will return CA_NOT_SUPPORTED, ignore
                 OIC_LOG_V(INFO, TAG, "retransmission is not enabled due to error, res : %d", res);
                 coap_delete_pdu(pdu);
-                return;
+                return res;
             }
 
             coap_delete_pdu(pdu);
@@ -464,7 +469,8 @@ static void CAProcessSendData(const CAData_t *data)
         else
         {
             OIC_LOG(ERROR,TAG,"Failed to generate unicast PDU");
-            return;
+            CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED);
+            return CA_SEND_FAILED;
         }
     }
     else if (SEND_TYPE_MULTICAST == type)
@@ -473,8 +479,8 @@ static void CAProcessSendData(const CAData_t *data)
         if (NULL != data->requestInfo)
         {
             OIC_LOG(DEBUG, TAG, "requestInfo is available..");
-            CAInfo_t *info = &data->requestInfo->info;
 
+            info = &data->requestInfo->info;
             pdu = CAGeneratePDU(CA_GET, info);
             if (NULL != pdu)
             {
@@ -489,7 +495,7 @@ static void CAProcessSendData(const CAData_t *data)
                         OIC_LOG(DEBUG, TAG, "CAAddBlockOption has failed");
                         CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
                         coap_delete_pdu(pdu);
-                        return;
+                        return res;
                     }
                 }
 #endif
@@ -499,8 +505,9 @@ static void CAProcessSendData(const CAData_t *data)
                 if (CA_STATUS_OK != res)
                 {
                     OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
+                    CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
                     coap_delete_pdu(pdu);
-                    return;
+                    return res;
                 }
 
                 coap_delete_pdu(pdu);
@@ -508,15 +515,19 @@ static void CAProcessSendData(const CAData_t *data)
             else
             {
                 OIC_LOG(ERROR,TAG,"Failed to generate multicast PDU");
+                CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED);
+                return CA_SEND_FAILED;
             }
         }
         else
         {
             OIC_LOG(ERROR, TAG, "request info is empty");
+            return CA_SEND_FAILED;
         }
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
 #ifndef SINGLE_THREAD
@@ -797,6 +808,7 @@ static CAData_t* CAPrepareSendData(const CAEndpoint_t *endpoint, const void *sen
     }
 
     cadata->remoteEndpoint = ep;
+    cadata->dataType = dataType;
     return cadata;
 }
 
@@ -829,7 +841,13 @@ CAResult_t CADetachRequestMessage(const CAEndpoint_t *object, const CARequestInf
     }
 
 #ifdef SINGLE_THREAD
-    CAProcessSendData(data);
+    CAResult_t result = CAProcessSendData(data);
+    if(CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, TAG, "CAProcessSendData failed");
+        return result;
+    }
+
     CADestroyData(data, sizeof(CAData_t));
 #else
 #ifdef WITH_BWT
@@ -880,7 +898,13 @@ CAResult_t CADetachResponseMessage(const CAEndpoint_t *object,
     }
 
 #ifdef SINGLE_THREAD
-    CAProcessSendData(data);
+    CAResult_t result = CAProcessSendData(data);
+    if(result != CA_STATUS_OK)
+    {
+        OIC_LOG(ERROR, TAG, "CAProcessSendData failed");
+        return result;
+    }
+
     CADestroyData(data, sizeof(CAData_t));
 #else
 #ifdef WITH_BWT
@@ -1140,7 +1164,7 @@ void CAErrorHandler(const CAEndpoint_t *endpoint,
                     const void *data, uint32_t dataLen,
                     CAResult_t result)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "CAErrorHandler IN");
 
 #ifndef SINGLE_THREAD
 
@@ -1171,6 +1195,51 @@ void CAErrorHandler(const CAEndpoint_t *endpoint,
     coap_delete_pdu(pdu);
 #endif
 
-    OIC_LOG(DEBUG, TAG, "OUT");
+    OIC_LOG(DEBUG, TAG, "CAErrorHandler OUT");
     return;
 }
+
+static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info, CAResult_t result)
+{
+    OIC_LOG(DEBUG, TAG, "CASendErrorInfo IN");
+#ifndef SINGLE_THREAD
+    CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
+    if (!cadata)
+    {
+        OIC_LOG(ERROR, TAG, "memory allocation failed");
+        return;
+    }
+
+    CAEndpoint_t* ep = CACloneEndpoint(endpoint);
+    if (!ep)
+    {
+        OIC_LOG(ERROR, TAG, "endpoint clone failed");
+        OICFree(cadata);
+        return;
+    }
+
+    CAErrorInfo_t *errorInfo = (CAErrorInfo_t *)OICCalloc(1, sizeof (CAErrorInfo_t));
+    if (!errorInfo)
+    {
+        OICFree(cadata);
+        CAFreeEndpoint(ep);
+        return;
+    }
+
+    CAResult_t res = CACloneInfo(info, &errorInfo->info);
+    if (CA_STATUS_OK != res)
+    {
+        OICFree(cadata);
+        CAFreeEndpoint(ep);
+        return;
+    }
+
+    errorInfo->result = result;
+    cadata->remoteEndpoint = ep;
+    cadata->errorInfo = errorInfo;
+    cadata->dataType = CA_ERROR_DATA;
+
+    CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
+#endif
+    OIC_LOG(DEBUG, TAG, "CASendErrorInfo OUT");
+}
index c2dea29..bba9e25 100644 (file)
@@ -369,10 +369,10 @@ static int32_t CAQueueIPData(bool isMulticast, const CAEndpoint_t *endpoint,
     // Add message to send queue
     CAQueueingThreadAddData(g_sendQueueHandle, ipData, sizeof(CAIPData));
 
+#endif // SINGLE_THREAD
+
     OIC_LOG(DEBUG, TAG, "OUT");
     return dataLength;
-
-#endif // SINGLE_THREAD
 }
 
 int32_t CASendIPUnicastData(const CAEndpoint_t *endpoint,