1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #include "cainterface.h"
27 #include "camessagehandler.h"
28 #include "caremotehandler.h"
29 #include "caprotocolmessage.h"
31 #include "config.h" /* for coap protocol */
32 #include "oic_malloc.h"
33 #include "canetworkconfigurator.h"
34 #include "caadapterutils.h"
35 #include "cainterfacecontroller.h"
36 #include "caretransmission.h"
40 #include "cathreadpool.h" /* for thread pool */
41 #include "caqueueingthread.h"
44 #define MAX_THREAD_POOL_SIZE 20
47 static ca_thread_pool_t g_threadPoolHandle = NULL;
49 // message handler main thread
50 static CAQueueingThread_t g_sendThread;
51 static CAQueueingThread_t g_receiveThread;
54 #define CA_MAX_RT_ARRAY_SIZE 3
55 #endif /* SINGLE_THREAD */
57 #define TAG "CA_MSG_HNDLR"
59 static CARetransmission_t g_retransmissionContext;
62 static CARequestCallback g_requestHandler = NULL;
63 static CAResponseCallback g_responseHandler = NULL;
64 static CAErrorCallback g_errorHandler = NULL;
66 static void CAErrorHandler(const CAEndpoint_t *endpoint,
67 const void *data, uint32_t dataLen,
70 static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, const void *data,
71 CADataType_t dataType);
73 static void CAProcessReceivedData(CAData_t *data);
74 static void CADataDestroyer(void *data, uint32_t size);
75 static void CALogPayloadInfo(CAInfo_t *info);
76 static bool CADropSecondRequest(const CAEndpoint_t *endpoint, uint16_t messageId);
78 static bool CAIsSelectedNetworkAvailable()
80 u_arraylist_t *list = CAGetSelectedNetworkList();
81 if (!list || list->length == 0)
83 OIC_LOG(ERROR, TAG, "No selected network");
90 static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, const void *data, CADataType_t dataType)
92 OIC_LOG(DEBUG, TAG, "CAGenerateHandlerData IN");
93 CAInfo_t *info = NULL;
94 CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
97 OIC_LOG(ERROR, TAG, "memory allocation failed");
101 CAEndpoint_t* ep = CACloneEndpoint(endpoint);
104 OIC_LOG(ERROR, TAG, "endpoint clone failed");
109 OIC_LOG_V(DEBUG, TAG, "address : %s", ep->addr);
112 if(CA_RESPONSE_DATA == dataType)
114 CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(CAResponseInfo_t));
117 OIC_LOG(ERROR, TAG, "memory allocation failed");
123 result = CAGetResponseInfoFromPDU(data, resInfo);
124 if (CA_STATUS_OK != result)
126 OIC_LOG(ERROR, TAG, "CAGetResponseInfoFromPDU Failed");
128 CADestroyResponseInfoInternal(resInfo);
132 cadata->responseInfo = resInfo;
133 info = &resInfo->info;
134 OIC_LOG(DEBUG, TAG, "Response Info :");
135 CALogPayloadInfo(info);
137 else if (CA_REQUEST_DATA == dataType)
139 CARequestInfo_t* reqInfo = (CARequestInfo_t*)OICCalloc(1, sizeof(CARequestInfo_t));
142 OIC_LOG(ERROR, TAG, "memory allocation failed");
148 result = CAGetRequestInfoFromPDU(data, reqInfo);
149 if (CA_STATUS_OK != result)
151 OIC_LOG(ERROR, TAG, "CAGetRequestInfoFromPDU failed");
153 CADestroyRequestInfoInternal(reqInfo);
158 if (CADropSecondRequest(endpoint, reqInfo->info.messageId))
160 OIC_LOG(ERROR, TAG, "Second Request with same Token, Drop it");
162 CADestroyRequestInfoInternal(reqInfo);
167 cadata->requestInfo = reqInfo;
168 info = &reqInfo->info;
169 OIC_LOG(DEBUG, TAG, "Request Info :");
170 CALogPayloadInfo(info);
172 else if (CA_ERROR_DATA == dataType)
174 CAErrorInfo_t *errorInfo = (CAErrorInfo_t *)OICCalloc(1, sizeof (CAErrorInfo_t));
177 OIC_LOG(ERROR, TAG, "Memory allocation failed!");
183 CAResult_t result = CAGetErrorInfoFromPDU(data, errorInfo);
184 if (CA_STATUS_OK != result)
186 OIC_LOG(ERROR, TAG, "CAGetErrorInfoFromPDU failed");
193 cadata->errorInfo = errorInfo;
194 info = &errorInfo->info;
195 OIC_LOG(DEBUG, TAG, "error Info :");
196 CALogPayloadInfo(info);
199 cadata->remoteEndpoint = ep;
200 cadata->dataType = dataType;
204 OIC_LOG(DEBUG, TAG, "CAGenerateHandlerData OUT");
207 static void CATimeoutCallback(const CAEndpoint_t *endpoint, const void *pdu, uint32_t size)
209 OIC_LOG(DEBUG, TAG, "IN");
210 VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint");
211 VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
213 CAEndpoint_t* ep = CACloneEndpoint(endpoint);
216 OIC_LOG(ERROR, TAG, "clone failed");
220 CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(CAResponseInfo_t));
224 OIC_LOG(ERROR, TAG, "calloc failed");
229 resInfo->result = CA_RETRANSMIT_TIMEOUT;
230 resInfo->info.type = CAGetMessageTypeFromPduBinaryData(pdu, size);
231 resInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
233 CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *) pdu, &(resInfo->info));
234 if (CA_STATUS_OK != res)
236 OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
237 CADestroyResponseInfoInternal(resInfo);
242 CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
245 OIC_LOG(ERROR, TAG, "memory allocation failed !");
247 CADestroyResponseInfoInternal(resInfo);
251 cadata->type = SEND_TYPE_UNICAST;
252 cadata->remoteEndpoint = ep;
253 cadata->requestInfo = NULL;
254 cadata->responseInfo = resInfo;
257 CAProcessReceivedData(cadata);
259 CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
262 OIC_LOG(DEBUG, TAG, "OUT");
265 static void CADataDestroyer(void *data, uint32_t size)
267 OIC_LOG(DEBUG, TAG, "CADataDestroyer IN");
268 CAData_t *cadata = (CAData_t *) data;
272 OIC_LOG(ERROR, TAG, "cadata is NULL");
276 if (NULL != cadata->remoteEndpoint)
278 CAFreeEndpoint(cadata->remoteEndpoint);
281 if (NULL != cadata->requestInfo)
283 CADestroyRequestInfoInternal((CARequestInfo_t *) cadata->requestInfo);
286 if (NULL != cadata->responseInfo)
288 CADestroyResponseInfoInternal((CAResponseInfo_t *) cadata->responseInfo);
291 if (NULL != cadata->errorInfo)
293 CADestroyErrorInfoInternal(cadata->errorInfo);
296 OICFree(cadata->options);
298 OIC_LOG(DEBUG, TAG, "CADataDestroyer OUT");
301 static void CAProcessReceivedData(CAData_t *data)
303 OIC_LOG(DEBUG, TAG, "CAProcessReceivedData IN");
306 OIC_LOG(ERROR, TAG, "thread data error!!");
310 // parse the data and call the callbacks.
313 CAEndpoint_t *rep = (CAEndpoint_t *)(data->remoteEndpoint);
316 OIC_LOG(ERROR, TAG, "remoteEndpoint error!!");
320 if (data->requestInfo && g_requestHandler)
322 g_requestHandler(rep, data->requestInfo);
324 else if (data->responseInfo && g_responseHandler)
326 g_responseHandler(rep, data->responseInfo);
328 else if (data->errorInfo && g_errorHandler)
330 g_errorHandler(rep, data->errorInfo);
335 CADataDestroyer(data, sizeof(CAData_t));
338 OIC_LOG(DEBUG, TAG, "CAProcessReceivedData OUT");
341 #ifndef SINGLE_THREAD
343 static void CAReceiveThreadProcess(void *threadData)
345 OIC_LOG(DEBUG, TAG, "IN");
346 #ifndef SINGLE_HANDLE
347 CAData_t *data = (CAData_t *) threadData;
348 CAProcessReceivedData(data);
350 OIC_LOG(DEBUG, TAG, "OUT");
354 static void CAProcessSendData(const CAData_t *data)
356 OIC_LOG(DEBUG, TAG, "IN");
357 VERIFY_NON_NULL_VOID(data, TAG, "data");
358 VERIFY_NON_NULL_VOID(data->remoteEndpoint, TAG, "remoteEndpoint");
360 CAResult_t res = CA_STATUS_FAILED;
362 CASendDataType_t type = data->type;
364 coap_pdu_t *pdu = NULL;
366 if (SEND_TYPE_UNICAST == type)
369 OIC_LOG(DEBUG,TAG,"Unicast message");
370 if (NULL != data->requestInfo)
372 OIC_LOG(DEBUG, TAG, "requestInfo is available..");
374 pdu = CAGeneratePDU(data->requestInfo->method, &data->requestInfo->info);
376 else if (NULL != data->responseInfo)
378 OIC_LOG(DEBUG, TAG, "responseInfo is available..");
380 pdu = CAGeneratePDU(data->responseInfo->result, &data->responseInfo->info);
384 OIC_LOG(DEBUG, TAG, "request info, response info is empty");
388 // interface controller function call.
393 res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length);
394 if (CA_STATUS_OK != res)
396 OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
397 coap_delete_pdu(pdu);
400 // for retransmission
401 res = CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr,
403 if (CA_STATUS_OK != res)
405 OIC_LOG_V(INFO, TAG, "retransmission is not enabled due to error, res : %d", res);
406 coap_delete_pdu(pdu);
410 coap_delete_pdu(pdu);
414 OIC_LOG(ERROR,TAG,"Failed to generate unicast PDU");
418 else if (SEND_TYPE_MULTICAST == type)
420 OIC_LOG(DEBUG,TAG,"Multicast message");
421 if (NULL != data->requestInfo)
423 OIC_LOG(DEBUG, TAG, "requestInfo is available..");
424 CAInfo_t *info = &data->requestInfo->info;
426 pdu = CAGeneratePDU(CA_GET, info);
431 res = CASendMulticastData(data->remoteEndpoint, pdu->hdr, pdu->length);
432 if (CA_STATUS_OK != res)
434 OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
435 coap_delete_pdu(pdu);
439 coap_delete_pdu(pdu);
443 OIC_LOG(ERROR,TAG,"Failed to generate multicast PDU");
448 OIC_LOG(ERROR, TAG, "request info is empty");
452 OIC_LOG(DEBUG, TAG, "OUT");
455 #ifndef SINGLE_THREAD
456 static void CASendThreadProcess(void *threadData)
458 CAData_t *data = (CAData_t *) threadData;
459 CAProcessSendData(data);
465 * If a second message arrives with the same token and the other address
466 * family, drop it. Typically, IPv6 beats IPv4, so the IPv4 message is dropped.
467 * This can be made more robust (for instance, another message could arrive
468 * in between), but it is good enough for now.
470 static bool CADropSecondRequest(const CAEndpoint_t *endpoint, uint16_t messageId)
476 if (endpoint->adapter != CA_ADAPTER_IP)
482 CATransportFlags_t familyFlags = endpoint->flags & CA_IPFAMILY_MASK;
484 if (messageId == caglobals.ca.previousRequestMessageId)
486 if ((familyFlags ^ caglobals.ca.previousRequestFlags) == CA_IPFAMILY_MASK)
488 if (familyFlags & CA_IPV6)
490 OIC_LOG(INFO, TAG, "IPv6 duplicate response ignored");
494 OIC_LOG(INFO, TAG, "IPv4 duplicate response ignored");
499 caglobals.ca.previousRequestFlags = familyFlags;
500 caglobals.ca.previousRequestMessageId = messageId;
504 static void CAReceivedPacketCallback(const CAEndpoint_t *remoteEndpoint, void *data, uint32_t dataLen)
506 OIC_LOG(DEBUG, TAG, "IN");
507 VERIFY_NON_NULL_VOID(remoteEndpoint, TAG, "remoteEndpoint");
508 VERIFY_NON_NULL_VOID(data, TAG, "data");
510 uint32_t code = CA_NOT_FOUND;
511 CAData_t *cadata = NULL;
513 coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code);
516 OIC_LOG(ERROR, TAG, "Parse PDU failed");
520 OIC_LOG_V(DEBUG, TAG, "code = %d", code);
521 if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
523 cadata = CAGenerateHandlerData(remoteEndpoint, pdu, CA_REQUEST_DATA);
526 OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
527 coap_delete_pdu(pdu);
533 cadata = CAGenerateHandlerData(remoteEndpoint, pdu, CA_RESPONSE_DATA);
536 OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
537 coap_delete_pdu(pdu);
541 // for retransmission
542 void *retransmissionPdu = NULL;
543 CARetransmissionReceivedData(&g_retransmissionContext, cadata->remoteEndpoint, pdu->hdr,
544 pdu->length, &retransmissionPdu);
546 // get token from saved data in retransmission list
547 if (retransmissionPdu && CA_EMPTY == code)
549 CAInfo_t *info = &cadata->responseInfo->info;
550 CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *)retransmissionPdu,
552 if (CA_STATUS_OK != res)
554 OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
555 OICFree(info->token);
556 info->tokenLength = 0;
559 OICFree(retransmissionPdu);
562 cadata->type = SEND_TYPE_UNICAST;
565 CAProcessReceivedData(cadata);
567 CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
570 coap_delete_pdu(pdu);
572 OIC_LOG(DEBUG, TAG, "OUT");
575 static void CANetworkChangedCallback(const CAEndpoint_t *info, CANetworkStatus_t status)
577 OIC_LOG(DEBUG, TAG, "IN");
579 OIC_LOG(DEBUG, TAG, "OUT");
582 void CAHandleRequestResponseCallbacks()
584 OIC_LOG(DEBUG, TAG, "CAHandleRequestResponseCallbacks IN");
587 CARetransmissionBaseRoutine((void *)&g_retransmissionContext);
590 // parse the data and call the callbacks.
594 ca_mutex_lock(g_receiveThread.threadMutex);
596 u_queue_message_t *item = u_queue_get_element(g_receiveThread.dataQueue);
598 ca_mutex_unlock(g_receiveThread.threadMutex);
606 void *msg = item->msg;
614 CAData_t *td = (CAData_t *) msg;
616 if (td->requestInfo && g_requestHandler)
618 OIC_LOG_V(DEBUG, TAG, "request callback : %d", td->requestInfo->info.numOptions);
619 g_requestHandler(td->remoteEndpoint, td->requestInfo);
621 else if (td->responseInfo && g_responseHandler)
623 OIC_LOG_V(DEBUG, TAG, "response callback : %d", td->responseInfo->info.numOptions);
624 g_responseHandler(td->remoteEndpoint, td->responseInfo);
626 else if (td->errorInfo && g_errorHandler)
628 OIC_LOG_V(DEBUG, TAG, "error callback error: %d", td->errorInfo->result);
629 g_errorHandler(td->remoteEndpoint, td->errorInfo);
632 CADataDestroyer(msg, sizeof(CAData_t));
635 #endif /* SINGLE_HANDLE */
637 OIC_LOG(DEBUG, TAG, "CAHandleRequestResponseCallbacks OUT");
640 static CAData_t* CAPrepareSendData(const CAEndpoint_t *endpoint, const void *sendData,
641 CADataType_t dataType)
643 OIC_LOG(DEBUG, TAG, "CAPrepareSendData IN");
644 CAInfo_t *info = NULL;
646 CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
649 OIC_LOG(ERROR, TAG, "memory allocation failed");
653 if(CA_REQUEST_DATA == dataType)
655 // clone request info
656 CARequestInfo_t *request = CACloneRequestInfo((CARequestInfo_t *)sendData);
660 OIC_LOG(ERROR, TAG, "CACloneRequestInfo failed");
665 cadata->type = request->isMulticast ? SEND_TYPE_MULTICAST : SEND_TYPE_UNICAST;
666 info = &request->info;
667 cadata->requestInfo = request;
669 else if(CA_RESPONSE_DATA == dataType)
671 // clone response info
672 CAResponseInfo_t *response = CACloneResponseInfo((CAResponseInfo_t *)sendData);
676 OIC_LOG(ERROR, TAG, "CACloneResponseInfo failed");
681 cadata->type = SEND_TYPE_UNICAST;
682 info = &response->info;
683 cadata->responseInfo = response;
686 if (NULL != info->options && 0 < info->numOptions)
688 uint8_t numOptions = info->numOptions;
690 CAHeaderOption_t *headerOption = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t)
694 OIC_LOG(ERROR, TAG, "memory allocation failed");
695 CADataDestroyer(cadata, sizeof(CAData_t));
699 memcpy(headerOption, info->options, sizeof(CAHeaderOption_t) * numOptions);
701 cadata->options = headerOption;
702 cadata->numOptions = numOptions;
705 CAEndpoint_t* ep = CACloneEndpoint(endpoint);
708 OIC_LOG(ERROR, TAG, "endpoint clone failed");
709 CADataDestroyer(cadata, sizeof(CAData_t));
713 cadata->remoteEndpoint = ep;
718 CAResult_t CADetachRequestMessage(const CAEndpoint_t *object, const CARequestInfo_t *request)
720 OIC_LOG(DEBUG, TAG, "IN");
722 VERIFY_NON_NULL(object, TAG, "object");
723 VERIFY_NON_NULL(request, TAG, "request");
725 if (false == CAIsSelectedNetworkAvailable())
727 return CA_STATUS_FAILED;
731 // If max retransmission queue is reached, then don't handle new request
732 if (CA_MAX_RT_ARRAY_SIZE == u_arraylist_length(g_retransmissionContext.dataList))
734 OIC_LOG(ERROR, TAG, "max RT queue size reached!");
735 return CA_SEND_FAILED;
739 CAData_t *data = CAPrepareSendData(object, request, CA_REQUEST_DATA);
742 OIC_LOG(ERROR, TAG, "CAPrepareSendData failed");
743 return CA_MEMORY_ALLOC_FAILED;
747 CAProcessSendData(data);
748 CADataDestroyer(data, sizeof(CAData_t));
750 CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
753 OIC_LOG(DEBUG, TAG, "OUT");
757 CAResult_t CADetachResponseMessage(const CAEndpoint_t *object,
758 const CAResponseInfo_t *response)
760 OIC_LOG(DEBUG, TAG, "IN");
761 VERIFY_NON_NULL(object, TAG, "object");
762 VERIFY_NON_NULL(response, TAG, "response");
764 if (false == CAIsSelectedNetworkAvailable())
766 return CA_STATUS_FAILED;
769 CAData_t *data = CAPrepareSendData(object, response, CA_RESPONSE_DATA);
772 OIC_LOG(ERROR, TAG, "CAPrepareSendData failed");
773 return CA_MEMORY_ALLOC_FAILED;
777 CAProcessSendData(data);
778 CADataDestroyer(data, sizeof(CAData_t));
780 CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
783 OIC_LOG(DEBUG, TAG, "OUT");
787 CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
788 uint8_t tokenLength, const CAHeaderOption_t *options,
791 return CA_NOT_SUPPORTED;
794 void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
795 CAErrorCallback errorHandler)
797 OIC_LOG(DEBUG, TAG, "IN");
798 g_requestHandler = ReqHandler;
799 g_responseHandler = RespHandler;
800 g_errorHandler = errorHandler;
801 OIC_LOG(DEBUG, TAG, "OUT");
804 CAResult_t CAInitializeMessageHandler()
806 OIC_LOG(DEBUG, TAG, "IN");
807 CASetPacketReceivedCallback(CAReceivedPacketCallback);
809 CASetNetworkChangeCallback(CANetworkChangedCallback);
810 CASetErrorHandleCallback(CAErrorHandler);
812 #ifndef SINGLE_THREAD
813 // create thread pool
814 CAResult_t res = ca_thread_pool_init(MAX_THREAD_POOL_SIZE, &g_threadPoolHandle);
816 if (CA_STATUS_OK != res)
818 OIC_LOG(ERROR, TAG, "thread pool initialize error.");
822 // send thread initialize
823 if (CA_STATUS_OK != CAQueueingThreadInitialize(&g_sendThread, g_threadPoolHandle,
824 CASendThreadProcess, CADataDestroyer))
826 OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
827 return CA_STATUS_FAILED;
831 res = CAQueueingThreadStart(&g_sendThread);
833 if (CA_STATUS_OK != res)
835 OIC_LOG(ERROR, TAG, "thread start error(send thread).");
836 ca_thread_pool_free(g_threadPoolHandle);
837 g_threadPoolHandle = NULL;
841 // receive thread initialize
842 if (CA_STATUS_OK != CAQueueingThreadInitialize(&g_receiveThread, g_threadPoolHandle,
843 CAReceiveThreadProcess, CADataDestroyer))
845 OIC_LOG(ERROR, TAG, "Failed to Initialize receive queue thread");
846 return CA_STATUS_FAILED;
849 #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading
850 // start receive thread
851 res = CAQueueingThreadStart(&gReceiveThread);
853 if (res != CA_STATUS_OK)
855 OIC_LOG(ERROR, TAG, "thread start error(receive thread).");
858 #endif /* SINGLE_HANDLE */
860 // retransmission initialize
861 CARetransmissionInitialize(&g_retransmissionContext, g_threadPoolHandle, CASendUnicastData,
862 CATimeoutCallback, NULL);
864 // start retransmission
865 res = CARetransmissionStart(&g_retransmissionContext);
867 if (CA_STATUS_OK != res)
869 OIC_LOG(ERROR, TAG, "thread start error(retransmission thread).");
873 // initialize interface adapters by controller
874 CAInitializeAdapters(g_threadPoolHandle);
876 // retransmission initialize
877 CARetransmissionInitialize(&g_retransmissionContext, NULL, CASendUnicastData,
878 CATimeoutCallback, NULL);
879 CAInitializeAdapters();
882 OIC_LOG(DEBUG, TAG, "OUT");
886 void CATerminateMessageHandler()
888 OIC_LOG(DEBUG, TAG, "IN");
889 #ifndef SINGLE_THREAD
890 CATransportAdapter_t connType;
891 u_arraylist_t *list = CAGetSelectedNetworkList();
892 uint32_t length = u_arraylist_length(list);
895 for (i = 0; i < length; i++)
897 void* ptrType = u_arraylist_get(list, i);
904 connType = *(CATransportAdapter_t *)ptrType;
905 CAStopAdapter(connType);
908 // stop retransmission
909 if (NULL != g_retransmissionContext.threadMutex)
911 CARetransmissionStop(&g_retransmissionContext);
915 // delete thread data
916 if (NULL != g_sendThread.threadMutex)
918 CAQueueingThreadStop(&g_sendThread);
922 // delete thread data
923 if (NULL != g_receiveThread.threadMutex)
925 #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading
926 CAQueueingThreadStop(&gReceiveThread);
927 #endif /* SINGLE_HANDLE */
930 // destroy thread pool
931 if (NULL != g_threadPoolHandle)
933 ca_thread_pool_free(g_threadPoolHandle);
934 g_threadPoolHandle = NULL;
937 CARetransmissionDestroy(&g_retransmissionContext);
938 CAQueueingThreadDestroy(&g_sendThread);
939 CAQueueingThreadDestroy(&g_receiveThread);
941 // terminate interface adapters by controller
942 CATerminateAdapters();
944 // terminate interface adapters by controller
945 CATerminateAdapters();
947 // stop retransmission
948 CARetransmissionStop(&g_retransmissionContext);
949 CARetransmissionDestroy(&g_retransmissionContext);
952 OIC_LOG(DEBUG, TAG, "OUT");
955 void CALogPDUInfo(coap_pdu_t *pdu)
957 VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
959 OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data);
961 OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->type);
963 OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code);
965 OIC_LOG(DEBUG, TAG, "PDU Maker - token :");
967 OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length);
970 static void CALogPayloadInfo(CAInfo_t *info)
976 for (uint32_t i = 0; i < info->numOptions; i++)
978 OIC_LOG_V(DEBUG, TAG, "optionID: %d", info->options[i].optionID);
980 OIC_LOG_V(DEBUG, TAG, "list: %s", info->options[i].optionData);
986 OIC_LOG_V(DEBUG, TAG, "payload: %p(%u)", info->payload,
992 OIC_LOG(DEBUG, TAG, "token:");
993 OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) info->token,
996 OIC_LOG_V(DEBUG, TAG, "msgID: %d", info->messageId);
1000 OIC_LOG(DEBUG, TAG, "info is NULL, cannot output log data");
1004 void CAErrorHandler(const CAEndpoint_t *endpoint,
1005 const void *data, uint32_t dataLen,
1008 OIC_LOG(DEBUG, TAG, "IN");
1010 #ifndef SINGLE_THREAD
1012 VERIFY_NON_NULL_VOID(endpoint, TAG, "remoteEndpoint");
1013 VERIFY_NON_NULL_VOID(data, TAG, "data");
1015 uint32_t code = CA_NOT_FOUND;
1016 //Do not free remoteEndpoint and data. Currently they will be freed in data thread
1018 coap_pdu_t *pdu = (coap_pdu_t *)CAParsePDU((const char *)data, dataLen, &code);
1021 OIC_LOG(ERROR, TAG, "Parse PDU failed");
1025 CAData_t *cadata = CAGenerateHandlerData(endpoint, pdu, CA_ERROR_DATA);
1028 OIC_LOG(ERROR, TAG, "CAErrorHandler, CAGenerateHandlerData failed!");
1029 coap_delete_pdu(pdu);
1033 cadata->errorInfo->result = result;
1035 CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
1036 coap_delete_pdu(pdu);
1039 OIC_LOG(DEBUG, TAG, "OUT");