Adding Error handling from CA to RI
authorjnashok <jn.ashok@samsung.com>
Wed, 20 May 2015 07:48:12 +0000 (16:48 +0900)
committerErich Keane <erich.keane@intel.com>
Wed, 3 Jun 2015 16:01:38 +0000 (16:01 +0000)
This is the first step to add the error handling
Error handling in adapters will be added incrementally

Change-Id: I6d27133cab49d5945e9eb42ea734d7ad881e89b8
Signed-off-by: jnashok <jn.ashok@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1046
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Erich Keane <erich.keane@intel.com>
21 files changed:
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/api/cainterface.h
resource/csdk/connectivity/inc/caadapterinterface.h
resource/csdk/connectivity/inc/cainterfacecontroller.h
resource/csdk/connectivity/inc/cainterfacecontroller_singlethread.h
resource/csdk/connectivity/inc/camessagehandler.h
resource/csdk/connectivity/inc/camessagehandler_singlethread.h
resource/csdk/connectivity/inc/caprotocolmessage.h
resource/csdk/connectivity/samples/android/sample_service/jni/ResourceModel.c
resource/csdk/connectivity/samples/arduino/casample.cpp
resource/csdk/connectivity/samples/linux/sample_main.c
resource/csdk/connectivity/samples/tizen/casample.c
resource/csdk/connectivity/src/caconnectivitymanager.c
resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c
resource/csdk/connectivity/src/cainterfacecontroller.c
resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c
resource/csdk/connectivity/src/camessagehandler.c
resource/csdk/connectivity/src/camessagehandler_singlethread.c
resource/csdk/connectivity/src/caprotocolmessage.c
resource/csdk/connectivity/test/ca_api_unittest.cpp
resource/csdk/stack/src/ocstack.c

index 2f6dcf9..d503b5a 100644 (file)
@@ -334,6 +334,19 @@ typedef struct
     CAInfo_t info;              /**< Information of the response */
 } CAResponseInfo_t;
 
+/**
+ * @brief Error information from CA
+ *        contains error code and message information
+ *
+ * This structure holds error information
+ */
+typedef struct
+{
+    CAResult_t result;  /**< CA API request result  */
+    CAInfo_t info;      /**< message information such as token and payload data
+                             helpful to identify the error */
+} CAErrorInfo_t;
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 7607bfc..7cb0a4f 100644 (file)
@@ -59,6 +59,14 @@ typedef void (*CARequestCallback)(const CARemoteEndpoint_t *object,
  */
 typedef void (*CAResponseCallback)(const CARemoteEndpoint_t *object,
                                    const CAResponseInfo_t *responseInfo);
+/**
+ * @brief   Callback function type for error
+ * @param   object          [OUT] remote device information
+ * @param   errorInfo       [OUT] CA Error information
+ * @return  NONE
+ */
+typedef void (*CAErrorCallback)(const CARemoteEndpoint_t *object,
+                                const CAErrorInfo_t *errorInfo);
 
 #ifdef __WITH_DTLS__
 
@@ -122,9 +130,11 @@ CAResult_t CAStartDiscoveryServer();
  * @param   RespHandler  [IN] Response Handler Callback
  * @see     CARequestCallback
  * @see     CAResponseCallback
+ * @see     CAErrorCallback
  * @return  NONE
  */
-void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler);
+void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                       CAErrorCallback ErrorHandler);
 
 #ifdef __WITH_DTLS__
 /**
index f45cfce..31b81e0 100644 (file)
@@ -175,6 +175,12 @@ typedef void (*CANetworkPacketReceivedCallback)(CARemoteEndpoint_t *endPoint, vo
  */
 typedef void (*CANetworkChangeCallback)(CALocalConnectivity_t *info, CANetworkStatus_t status);
 
+/**
+ * @brief This will be used to notify error result to the connectivity common logic layer
+ */
+typedef void (*CAErrorHandleCallback)(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
+                                      uint32_t dataLen, CAResult_t result);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 8aa5940..6725216 100644 (file)
@@ -50,6 +50,13 @@ void CAInitializeAdapters(ca_thread_pool_t handle);
 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback);
 
 /**
+ * @brief   Set the error handler callback for message handler
+ * @param   errorCallback       [IN]    error handler callback from adapters
+ * @return  none
+ */
+void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback);
+
+/**
  * @brief   Set the network status changed callback for message handler
  * @param   callback       [IN]    message handler network status callback to receive network changes.
  * @return  none
index 70f0759..2c048f8 100644 (file)
@@ -60,6 +60,13 @@ void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback);
 void CASetNetworkChangeCallback(CANetworkChangeCallback callback);
 
 /**
+ * @brief   Set the error handler callback for message handler
+ * @param   errorCallback       [IN]    error handler callback from adapters
+ * @return  none
+ */
+void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback);
+
+/**
  * @brief   Starting different connectivity adapters based on the network selection.
  * @param   transportType    [IN]    network type that want to stop
  * @return  none
index e5ee5cb..76085df 100644 (file)
@@ -101,9 +101,11 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t
  * @brief   Setting the request and response callbacks for network packets
  * @param   ReqHandler     [IN]    callback for receiving the requests
  * @param   RespHandler    [IN]    callback for receiving the response
+ * @param   ErrorHandler   [IN]    callback for receiving error response
  * @return  NONE
  */
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler);
+void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                             CAErrorCallback ErrorHandler);
 
 /**
  * @brief   Initialize the message handler by starting thread pool and initializing the
index 469c6ea..0db6219 100644 (file)
@@ -101,9 +101,11 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t
  * @brief   Setting the request and response callbacks for network packets
  * @param   ReqHandler     [IN]    callback for receiving the requests
  * @param   RespHandler    [IN]    callback for receiving the response
+ * @param   ErrorHandler   [IN]    callback for receiving error response
  * @return  NONE
  */
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler);
+void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                             CAErrorCallback ErrorHandler);
 
 /**
  * @brief   Initialize the message handler by starting thread pool and initializing the
index d96c7a3..a0a2db9 100644 (file)
@@ -76,6 +76,16 @@ CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *out
                                     char *outUri, uint32_t buflen);
 
 /**
+ * @brief   extracts error information from received pdu.
+ * @param   pdu              [IN]     received pdu
+ * @param   errorInfo        [OUT]    error info structure made from received pdu
+ * @param   outUri           [OUT]    uri received in the received pdu
+ * @param   buflen           [IN]     length of outUri
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CAGetErrorInfoFromPDU(const coap_pdu_t *pdu, CAErrorInfo_t *errorInfo,
+                                 char *outUri, uint32_t buflen);
+/**
  * @brief   creates pdu from the request information
  * @param   code             [IN]    request or response code
  * @param   options          [OUT]   options for the request and response
index 31e3abe..cfce9b5 100644 (file)
@@ -34,6 +34,8 @@ uint16_t g_localSecurePort = SECURE_DEFAULT_PORT;
 
 void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo);
 void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo);
+void error_handler(const CARemoteEndpoint_t *object, const CAErrorInfo_t* errorInfo);
+
 void get_resource_uri(const char *URI, char *resourceURI, uint32_t length);
 uint32_t get_secure_information(CAPayload_t payLoad);
 CAResult_t get_network_type(uint32_t selectedNetwork);
@@ -245,7 +247,7 @@ Java_org_iotivity_ca_service_RMInterface_RMRegisterHandler(JNIEnv *env, jobject
 {
     LOGI("RMRegisterHandler");
 
-    CARegisterHandler(request_handler, response_handler);
+    CARegisterHandler(request_handler, response_handler, error_handler);
 }
 
 JNIEXPORT void JNICALL
@@ -1155,6 +1157,55 @@ void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t*
     }
 }
 
+void error_handler(const CARemoteEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
+{
+    printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++");
+
+    if(rep && rep->resourceUri  )
+    {
+        LOGI("Error Handler, RemoteEndpoint Info resourceUri : %s", rep->resourceUri);
+    }
+    else
+    {
+        LOGI("Error Handler, RemoteEndpoint is NULL");
+    }
+
+    if(errorInfo)
+    {
+        const CAInfo_t *info = &errorInfo->info;
+        LOGI("Error Handler, ErrorInfo :");
+        LOGI("Error Handler result    : %d", errorInfo->result);
+        LOGI("Error Handler token     : %s", info->token);
+        LOGI("Error Handler messageId : %d", (uint16_t) info->messageId);
+        LOGI("Error Handler type      : %d", info->type);
+        LOGI("Error Handler payload   : %s", info->payload);
+
+        if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
+        {
+            LOGE("CA_ADAPTER_NOT_ENABLED, enable the adapter");
+        }
+        else if(CA_SEND_FAILED == errorInfo->result)
+        {
+            LOGE("CA_SEND_FAILED, unable to send the message, check parameters");
+        }
+        else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
+        {
+            LOGE("CA_MEMORY_ALLOC_FAILED, insufficient memory");
+        }
+        else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
+        {
+            LOGE("CA_SOCKET_OPERATION_FAILED, socket operation failed");
+        }
+        else if(CA_STATUS_FAILED == errorInfo->result)
+        {
+            LOGE("CA_STATUS_FAILED, message could not be delivered, internal error");
+        }
+    }
+    LOGI("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++");
+
+    return;
+}
+
 void get_resource_uri(const char *URI, char *resourceURI, uint32_t length)
 {
     const char *startPos = URI;
index f22eb1c..4f692d3 100644 (file)
@@ -59,6 +59,7 @@ static void HandleRequestResponse();
 
 static void RequestHandler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo);
 static void ResponseHandler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo);
+static void ErrorHandler(const CARemoteEndpoint_t *object, const CAErrorInfo_t* errorInfo);
 static void Terminate();
 
 void GetData(char *readInput, size_t bufferLength, size_t *dataLength)
@@ -222,7 +223,7 @@ void Initialize()
     }
     SelectNetwork();
     // set handler.
-    CARegisterHandler(RequestHandler, ResponseHandler);
+    CARegisterHandler(RequestHandler, ResponseHandler, ErrorHandler);
 }
 
 void StartListeningServer()
@@ -796,6 +797,55 @@ void ResponseHandler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *r
     }
 }
 
+void ErrorHandler(const CARemoteEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
+{
+    printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++\n");
+
+    if(rep && rep->resourceUri  )
+    {
+        printf("Error Handler, RemoteEndpoint Info resourceUri : %s\n", rep->resourceUri);
+    }
+    else
+    {
+        printf("Error Handler, RemoteEndpoint is NULL");
+    }
+
+    if(errorInfo)
+    {
+        const CAInfo_t *info = &errorInfo->info;
+        printf("Error Handler, ErrorInfo :\n");
+        printf("Error Handler result    : %d\n", errorInfo->result);
+        printf("Error Handler token     : %s\n", info->token);
+        printf("Error Handler messageId : %d\n", (uint16_t) info->messageId);
+        printf("Error Handler type      : %d\n", info->type);
+        printf("Error Handler payload   : %s\n", info->payload);
+
+        if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
+        {
+            printf("CA_ADAPTER_NOT_ENABLED, enable the adapter\n");
+        }
+        else if(CA_SEND_FAILED == errorInfo->result)
+        {
+            printf("CA_SEND_FAILED, unable to send the message, check parameters\n");
+        }
+        else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
+        {
+            printf("CA_MEMORY_ALLOC_FAILED, insufficient memory\n");
+        }
+        else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
+        {
+            printf("CA_SOCKET_OPERATION_FAILED, socket operation failed\n");
+        }
+        else if(CA_STATUS_FAILED == errorInfo->result)
+        {
+            printf("CA_STATUS_FAILED, message could not be delivered, internal error\n");
+        }
+    }
+    printf("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++\n");
+
+    return;
+}
+
 void SendResponse(CARemoteEndpoint_t *endpoint, const CAInfo_t* info)
 {
     char buf[MAX_BUF_LEN] = {0};
index d7c2354..041daed 100644 (file)
@@ -80,6 +80,8 @@ void send_secure_request();
 
 void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo);
 void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo);
+void error_handler(const CARemoteEndpoint_t *object, const CAErrorInfo_t* errorInfo);
+
 void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info);
 void get_resource_uri(char *URI, char *resourceURI, int length);
 int get_secure_information(CAPayload_t payLoad);
@@ -222,7 +224,7 @@ int main()
 #endif
 
     // set handler.
-    CARegisterHandler(request_handler, response_handler);
+    CARegisterHandler(request_handler, response_handler, error_handler);
 
     process();
 
@@ -1209,6 +1211,55 @@ void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *
     }
 }
 
+void error_handler(const CARemoteEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
+{
+    printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++\n");
+
+    if(rep && rep->resourceUri  )
+    {
+        printf("Error Handler, RemoteEndpoint Info resourceUri : %s\n", rep->resourceUri);
+    }
+    else
+    {
+        printf("Error Handler, RemoteEndpoint is NULL");
+    }
+
+    if(errorInfo)
+    {
+        const CAInfo_t *info = &errorInfo->info;
+        printf("Error Handler, ErrorInfo :\n");
+        printf("Error Handler result    : %d\n", errorInfo->result);
+        printf("Error Handler token     : %s\n", info->token);
+        printf("Error Handler messageId : %d\n", (uint16_t) info->messageId);
+        printf("Error Handler type      : %d\n", info->type);
+        printf("Error Handler payload   : %s\n", info->payload);
+
+        if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
+        {
+            printf("CA_ADAPTER_NOT_ENABLED, enable the adapter\n");
+        }
+        else if(CA_SEND_FAILED == errorInfo->result)
+        {
+            printf("CA_SEND_FAILED, unable to send the message, check parameters\n");
+        }
+        else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
+        {
+            printf("CA_MEMORY_ALLOC_FAILED, insufficient memory\n");
+        }
+        else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
+        {
+            printf("CA_SOCKET_OPERATION_FAILED, socket operation failed\n");
+        }
+        else if(CA_STATUS_FAILED == errorInfo->result)
+        {
+            printf("CA_STATUS_FAILED, message could not be delivered, internal error\n");
+        }
+    }
+    printf("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++\n");
+
+    return;
+}
+
 void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info)
 {
     printf("entering send_response\n");
index 3052feb..e0f5b0c 100644 (file)
@@ -95,6 +95,8 @@ void get_network_info();
 
 void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo);
 void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo);
+void error_handler(const CARemoteEndpoint_t *object, const CAErrorInfo_t* errorInfo);
+
 void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info);
 void get_resource_uri(char *URI, char *resourceURI, int length);
 int get_secure_information(CAPayload_t payLoad);
@@ -264,7 +266,7 @@ int main()
 #endif
 
     // set handler.
-    CARegisterHandler(request_handler, response_handler);
+    CARegisterHandler(request_handler, response_handler, error_handler);
 
     process();
 
@@ -1194,6 +1196,55 @@ void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *
     }
 }
 
+void error_handler(const CARemoteEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
+{
+    printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++\n");
+
+    if(rep && rep->resourceUri  )
+    {
+        printf("Error Handler, RemoteEndpoint Info resourceUri : %s\n", rep->resourceUri);
+    }
+    else
+    {
+        printf("Error Handler, RemoteEndpoint is NULL");
+    }
+
+    if(errorInfo)
+    {
+        const CAInfo_t *info = &errorInfo->info;
+        printf("Error Handler, ErrorInfo :\n");
+        printf("Error Handler result    : %d\n", errorInfo->result);
+        printf("Error Handler token     : %s\n", info->token);
+        printf("Error Handler messageId : %d\n", (uint16_t) info->messageId);
+        printf("Error Handler type      : %d\n", info->type);
+        printf("Error Handler payload   : %s\n", info->payload);
+
+        if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
+        {
+            printf("CA_ADAPTER_NOT_ENABLED, enable the adapter\n");
+        }
+        else if(CA_SEND_FAILED == errorInfo->result)
+        {
+            printf("CA_SEND_FAILED, unable to send the message, check parameters\n");
+        }
+        else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
+        {
+            printf("CA_MEMORY_ALLOC_FAILED, insufficient memory\n");
+        }
+        else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
+        {
+            printf("CA_SOCKET_OPERATION_FAILED, socket operation failed\n");
+        }
+        else if(CA_STATUS_FAILED == errorInfo->result)
+        {
+            printf("CA_STATUS_FAILED, message could not be delivered, internal error\n");
+        }
+    }
+    printf("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++\n");
+
+    return;
+}
+
 void send_response(const CARemoteEndpoint_t *endpoint, const CAInfo_t *info)
 {
     printf("entering send_response\n");
index a28fdfe..264b885 100644 (file)
@@ -95,7 +95,8 @@ CAResult_t CAStartDiscoveryServer()
     return CAStartDiscoveryServerAdapters();
 }
 
-void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
+void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                       CAErrorCallback ErrorHandler)
 {
     OIC_LOG(DEBUG, TAG, "CARegisterHandler");
 
@@ -105,7 +106,7 @@ void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHand
         return;
     }
 
-    CASetRequestResponseCallbacks(ReqHandler, RespHandler);
+    CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
 }
 
 #ifdef __WITH_DTLS__
index c797611..bf3e064 100644 (file)
@@ -60,7 +60,7 @@ void CATerminate()
 
     if (g_isInitialized)
     {
-        CASetRequestResponseCallbacks(NULL, NULL);
+        CASetInterfaceCallbacks(NULL, NULL, NULL);
         CATerminateMessageHandler();
         CATerminateNetworkType();
         g_isInitialized = false;
@@ -91,7 +91,8 @@ CAResult_t CAStartDiscoveryServer()
     return CAStartDiscoveryServerAdapters();
 }
 
-void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
+void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                       CAErrorCallback errorHandler)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -101,7 +102,7 @@ void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHand
         return;
     }
 
-    CASetRequestResponseCallbacks(ReqHandler, RespHandler);
+    CASetInterfaceCallbacks(ReqHandler, RespHandler, errorHandler);
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
index 2abc0a8..a5380e1 100644 (file)
@@ -46,6 +46,8 @@ static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
 
 static CANetworkChangeCallback g_networkChangeCallback = NULL;
 
+static CAErrorHandleCallback g_errorHandleCallback = NULL;
+
 static int CAGetAdapterIndex(CATransportType_t cType)
 {
     switch (cType)
@@ -129,6 +131,18 @@ static void CANetworkChangedCallback(CALocalConnectivity_t *info,
     }
 }
 
+static void CAAdapterErrorHandleCallback(const CARemoteEndpoint_t *endpoint, const void *data,
+                                         uint32_t dataLen, CAResult_t result)
+{
+    OIC_LOG(DEBUG, TAG, "received error from adapter in interfacecontroller");
+
+    // Call the callback.
+    if (g_errorHandleCallback != NULL)
+    {
+        g_errorHandleCallback(endpoint, data, dataLen, result);
+    }
+}
+
 void CAInitializeAdapters(ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TAG, "initialize adapters..");
@@ -167,6 +181,12 @@ void CASetNetworkChangeCallback(CANetworkChangeCallback callback)
     g_networkChangeCallback = callback;
 }
 
+void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback)
+{
+    OIC_LOG(DEBUG, TAG, "Set error handle callback");
+    g_errorHandleCallback = errorCallback;
+}
+
 CAResult_t CAStartAdapter(CATransportType_t transportType)
 {
     OIC_LOG_V(DEBUG, TAG, "Start the adapter of CAConnectivityType[%d]", transportType);
@@ -254,7 +274,8 @@ CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size)
     // #3. add data into result
     // memory allocation
 
-    CALocalConnectivity_t * resInfo = OICCalloc(resSize, sizeof(*resInfo));
+    CALocalConnectivity_t *resInfo = (CALocalConnectivity_t *)
+                                     OICCalloc(resSize, sizeof(CALocalConnectivity_t));
     CA_MEMORY_ALLOC_CHECK(resInfo);
 
     // #4. save data
@@ -336,13 +357,13 @@ CAResult_t CASendMulticastData(const void *data, uint32_t length)
 {
     OIC_LOG(DEBUG, TAG, "Send multicast data to enabled interface..");
 
-    CAResult_t res = CA_STATUS_FAILED;
+    CAResult_t res = CA_SEND_FAILED;
     u_arraylist_t *list = CAGetSelectedNetworkList();
 
     if (!list)
     {
         OIC_LOG(DEBUG, TAG, "No selected network");
-        return CA_STATUS_FAILED;
+        return CA_SEND_FAILED;
     }
 
     int i = 0;
index 169ee7e..fc2690e 100644 (file)
@@ -47,6 +47,8 @@ static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
 
 static CANetworkChangeCallback g_networkChangeCallback = NULL;
 
+static CAErrorHandleCallback g_errorHandleCallback = NULL;
+
 static int CAGetAdapterIndex(CATransportType_t cType)
 {
     switch (cType)
@@ -111,6 +113,12 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
+void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback)
+{
+    OIC_LOG(DEBUG, TAG, "Set error handle callback");
+    g_errorHandleCallback = errorCallback;
+}
+
 static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
 {
     OIC_LOG(DEBUG, TAG, "IN");
index 635289c..65bb218 100644 (file)
@@ -49,13 +49,22 @@ typedef enum
     SEND_TYPE_MULTICAST = 0, SEND_TYPE_UNICAST
 } CASendDataType_t;
 
+typedef enum
+{
+    CA_REQUEST_DATA = 1,
+    CA_RESPONSE_DATA = 2,
+    CA_ERROR_DATA = 3,
+} CADataType_t;
+
 typedef struct
 {
     CASendDataType_t type;
     CARemoteEndpoint_t *remoteEndpoint;
     CARequestInfo_t *requestInfo;
     CAResponseInfo_t *responseInfo;
+    CAErrorInfo_t *errorInfo;
     CAHeaderOption_t *options;
+    CADataType_t dataType;
     uint8_t numOptions;
 } CAData_t;
 
@@ -71,6 +80,10 @@ static CARetransmission_t g_retransmissionContext;
 // handler field
 static CARequestCallback g_requestHandler = NULL;
 static CAResponseCallback g_responseHandler = NULL;
+static CAErrorCallback g_errorHandler = NULL;
+
+static void CAErrorHandler(const CARemoteEndpoint_t *remoteEndpoint,
+                           const void *data, uint32_t dataLen, CAResult_t result);
 
 static bool CAIsSelectedNetworkAvailable()
 {
@@ -163,6 +176,15 @@ static void CADataDestroyer(void *data, uint32_t size)
         CADestroyResponseInfoInternal((CAResponseInfo_t *) cadata->responseInfo);
     }
 
+    if (NULL != cadata->errorInfo)
+    {
+       CAInfo_t *info = &cadata->errorInfo->info;
+       OICFree(info->token);
+       OICFree(info->options);
+       OICFree(info->payload);
+       OICFree(cadata->errorInfo);
+    }
+
     OICFree(cadata->options);
     OICFree(cadata);
     OIC_LOG(DEBUG, TAG, "OUT");
@@ -193,22 +215,20 @@ static void CAReceiveThreadProcess(void *threadData)
         return;
     }
 
-    if (NULL != data->requestInfo)
+    if (data->requestInfo && g_requestHandler)
     {
-        if (g_requestHandler)
-        {
-            g_requestHandler(rep, data->requestInfo);
-        }
+        g_requestHandler(rep, data->requestInfo);
     }
-
-    if (NULL != data->responseInfo)
+    else if (data->responseInfo && g_responseHandler)
     {
-        if (g_responseHandler)
-        {
-            g_responseHandler(rep, data->responseInfo);
-        }
+        g_responseHandler(rep, data->responseInfo);
     }
-#endif
+    else if (data->errorInfo && g_errorHandler)
+    {
+        g_errorHandler(rep, data->errorInfo);
+    }
+
+#endif /* SINGLE_HANDLE */
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
@@ -258,6 +278,7 @@ static void CASendThreadProcess(void *threadData)
             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;
             }
@@ -294,6 +315,7 @@ static void CASendThreadProcess(void *threadData)
             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;
             }
@@ -550,23 +572,22 @@ void CAHandleRequestResponseCallbacks()
         return;
     }
 
-    if (NULL != td->requestInfo)
+    if (td->requestInfo && g_requestHandler)
     {
-        if (g_requestHandler)
-        {
-            OIC_LOG_V(DEBUG, TAG, "callback will be sent : %d", td->requestInfo->info.numOptions);
-            g_requestHandler(rep, td->requestInfo);
-        }
+        OIC_LOG_V(DEBUG, TAG, "request callback : %d", td->requestInfo->info.numOptions);
+        g_requestHandler(rep, td->requestInfo);
     }
-
-    if (NULL != td->responseInfo)
+    else if (td->responseInfo && g_responseHandler)
     {
-        if (g_responseHandler)
-        {
-            g_responseHandler(rep, td->responseInfo);
-        }
-
+        OIC_LOG_V(DEBUG, TAG, "response callback : %d", td->responseInfo->info.numOptions);
+        g_responseHandler(rep, td->responseInfo);
     }
+    else if (td->errorInfo && g_errorHandler)
+    {
+        OIC_LOG_V(DEBUG, TAG, "error callback error: %d", td->errorInfo->result);
+        g_errorHandler(rep, td->errorInfo);
+    }
+
     CADataDestroyer(msg, sizeof(CAData_t));
 
 #endif
@@ -810,11 +831,13 @@ memory_error_exit:
     return CA_MEMORY_ALLOC_FAILED;
 }
 
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
+void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                             CAErrorCallback errroHandler)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     g_requestHandler = ReqHandler;
     g_responseHandler = RespHandler;
+    g_errorHandler = errroHandler;
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
@@ -824,6 +847,7 @@ CAResult_t CAInitializeMessageHandler()
     CASetPacketReceivedCallback(CAReceivedPacketCallback);
 
     CASetNetworkChangeCallback(CANetworkChangedCallback);
+    CASetErrorHandleCallback(CAErrorHandler);
 
     // create thread pool
     CAResult_t res = ca_thread_pool_init(MAX_THREAD_POOL_SIZE, &g_threadPoolHandle);
@@ -967,3 +991,104 @@ void CALogPDUInfo(coap_pdu_t *pdu)
 
     OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length);
 }
+
+void CAErrorHandler(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
+                    uint32_t dataLen, CAResult_t result)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    VERIFY_NON_NULL_VOID(remoteEndpoint, TAG, "remoteEndpoint");
+    VERIFY_NON_NULL_VOID(data, TAG, "data");
+
+    uint32_t code = CA_NOT_FOUND;
+    //Do not free remoteEndpoint and data. Currently they will be freed in data thread
+    //Get PDU data
+    coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code);
+    if (NULL == pdu)
+    {
+        OIC_LOG(ERROR, TAG, "Parse PDU failed");
+        return;
+    }
+
+    char uri[CA_MAX_URI_LENGTH] = { 0, };
+
+    CAErrorInfo_t *errorInfo = (CAErrorInfo_t *) OICCalloc(1, sizeof(CAErrorInfo_t));
+    if (NULL == errorInfo)
+    {
+        OIC_LOG(ERROR, TAG, "CAErrorHandler, Memory allocation failed!");
+        coap_delete_pdu(pdu);
+        return;
+    }
+
+    CAResult_t res = CAGetErrorInfoFromPDU(pdu, errorInfo, uri, CA_MAX_URI_LENGTH);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "CAGetErrorInfoFromPDU failed : %d", res);
+        OICFree(errorInfo);
+        coap_delete_pdu(pdu);
+       return;
+    }
+
+    errorInfo->result = result;
+    OIC_LOG_V(DEBUG, TAG, "error : %d", result);
+    if (NULL != errorInfo->info.payload)
+    {
+        OIC_LOG_V(DEBUG, TAG, "error, payload: %s", errorInfo->info.payload);
+    }
+
+    OIC_LOG(DEBUG, TAG, "error, token");
+    OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) errorInfo->info.token,
+                   errorInfo->info.tokenLength);
+    OIC_LOG_V(DEBUG, TAG, "CAErrorHandler, msgID : %d", errorInfo->info.messageId);
+
+    CARemoteEndpoint_t *rep = NULL;
+    rep = CACloneRemoteEndpoint(remoteEndpoint);
+    if(!rep)
+    {
+        OIC_LOG(ERROR, TAG, "CAErrorHandler, CloneRemoteEndpoint Failed");
+        OICFree(errorInfo);
+        coap_delete_pdu(pdu);
+        return;
+    }
+
+    if(NULL == rep->resourceUri)
+    {
+        uint32_t bufLen = sizeof(uri);
+
+        CAURI_t resourceUri = (CAURI_t) OICMalloc(bufLen + 1);
+        if (NULL == resourceUri)
+        {
+            OIC_LOG(ERROR, TAG, "CAErrorHandler, Memory allocation failed!");
+            OICFree(errorInfo);
+            coap_delete_pdu(pdu);
+            return;
+        }
+
+        memcpy(resourceUri, uri, bufLen);
+        resourceUri[bufLen] = '\0';
+        OIC_LOG_V(DEBUG, TAG, "URI : %s", resourceUri);
+        rep->resourceUri = resourceUri;
+    }
+
+    // store the data at queue.
+    CAData_t *cadata = NULL;
+    cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
+    if (NULL == cadata)
+    {
+        OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
+        CADestroyRemoteEndpointInternal(rep);
+        OICFree(errorInfo);
+        coap_delete_pdu(pdu);
+        return;
+    }
+
+    cadata->remoteEndpoint = rep;
+    cadata->requestInfo = NULL;
+    cadata->responseInfo = NULL;
+    cadata->errorInfo = errorInfo;
+    cadata->dataType = CA_ERROR_DATA;
+    CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
+    coap_delete_pdu(pdu);
+
+    return;
+}
+
index 6bad8a3..0ce2c40 100644 (file)
@@ -58,6 +58,7 @@ static CARetransmission_t g_retransmissionContext;
 // handler field
 static CARequestCallback g_requestHandler = NULL;
 static CAResponseCallback g_responseHandler = NULL;
+static CAErrorCallback g_errorHandler = NULL;
 
 static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pdu, uint32_t size)
 {
@@ -543,11 +544,13 @@ memory_error_exit:
     return CA_MEMORY_ALLOC_FAILED;
 }
 
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
+void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+                             CAErrorCallback errorHandler)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     g_requestHandler = ReqHandler;
     g_responseHandler = RespHandler;
+    g_errorHandler = errorHandler;
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
index e0ddd30..f434bd7 100644 (file)
@@ -103,6 +103,23 @@ CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *out
     return ret;
 }
 
+CAResult_t CAGetErrorInfoFromPDU(const coap_pdu_t *pdu, CAErrorInfo_t *errorInfo,
+                                 char *uri, uint32_t buflen)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    if (!pdu || !errorInfo || !uri)
+    {
+        OIC_LOG(ERROR, TAG, "parameter is null");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    uint32_t code = 0;
+    CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &errorInfo->info, uri, buflen);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return ret;
+}
+
 coap_pdu_t *CAGeneratePDU(const char *uri, uint32_t code, const CAInfo_t info)
 {
     OIC_LOG(DEBUG, TAG, "IN");
index e684abd..bfc8bbd 100644 (file)
@@ -37,6 +37,8 @@ class CATests : public testing::Test {
 
 void request_handler(CARemoteEndpoint_t* object, CARequestInfo_t* requestInfo);
 void response_handler(CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo);
+void error_handler(const CARemoteEndpoint_t *object, const CAErrorInfo_t* errorInfo);
+
 CAResult_t checkGetNetworkInfo();
 CAResult_t checkSelectNetwork();
 
@@ -52,6 +54,17 @@ void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *
 
 }
 
+void error_handler(const CARemoteEndpoint_t *object, const CAErrorInfo_t* errorInfo)
+{
+    if(!object || !errorInfo)
+    {
+        return;
+    }
+
+    //error handling shall be added
+    return;
+}
+
 static char* uri = NULL;
 static CARemoteEndpoint_t* tempRep = NULL;
 static CARequestInfo_t requestInfo;
@@ -176,7 +189,7 @@ TEST(StartDiscoveryServerTest, DISABLED_TC_04_Positive_01)
 // check return value
 TEST_F(CATests, RegisterHandlerTest)
 {
-    CARegisterHandler(request_handler, response_handler);
+    CARegisterHandler(request_handler, response_handler, error_handler);
     char* check = (char *) "registerHandler success";
     EXPECT_STREQ(check, "registerHandler success");
 }
index 8bec995..8206bb6 100644 (file)
@@ -1420,6 +1420,28 @@ void HandleCAResponses(const CARemoteEndpoint_t* endPoint, const CAResponseInfo_
 }
 
 /*
+ * This function handles error response from CA
+ * code shall be added to handle the errors
+ */
+void HandleCAErrorResponse(const CARemoteEndpoint_t* endPoint, const CAErrorInfo_t* errrorInfo)
+{
+    OC_LOG(INFO, TAG, PCF("Enter HandleCAErrorResponse"));
+
+    if(NULL == endPoint)
+    {
+        OC_LOG(ERROR, TAG, PCF("endPoint is NULL"));
+        return;
+    }
+
+    if(NULL == errrorInfo)
+    {
+        OC_LOG(ERROR, TAG, PCF("errrorInfo is NULL"));
+        return;
+    }
+    OC_LOG(INFO, TAG, PCF("Exit HandleCAErrorResponse"));
+}
+
+/*
  * This function sends out Direct Stack Responses. These are responses that are not coming
  * from the application entity handler. These responses have no payload and are usually ACKs,
  * RESETs or some error conditions that were caught by the stack.
@@ -1843,7 +1865,7 @@ OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode)
     result = CAResultToOCResult(OCSelectNetwork());
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
-    CARegisterHandler(HandleCARequests, HandleCAResponses);
+    CARegisterHandler(HandleCARequests, HandleCAResponses, HandleCAErrorResponse);
     switch (myStackMode)
     {
         case OC_CLIENT: