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 "cainterfacecontroller.h"
30 #include "caprotocolmessage.h"
33 #include "config.h" /* for coap protocol */
35 #include "uthreadpool.h" /* for thread pool */
36 #include "caqueueingthread.h"
37 #include "caretransmission.h"
39 #include "oic_malloc.h"
40 #include "caadapterutils.h"
41 #include "canetworkconfigurator.h"
46 #define CA_MEMORY_ALLOC_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(ERROR, TAG, "Out of memory"); \
47 goto memory_error_exit;} }
49 #define MAX_THREAD_POOL_SIZE 20
53 SEND_TYPE_MULTICAST = 0, SEND_TYPE_UNICAST
58 CASendDataType_t type;
59 CARemoteEndpoint_t *remoteEndpoint;
60 CARequestInfo_t *requestInfo;
61 CAResponseInfo_t *responseInfo;
62 CAHeaderOption_t *options;
67 static u_thread_pool_t g_threadPoolHandle = NULL;
69 // message handler main thread
70 static CAQueueingThread_t g_sendThread;
71 static CAQueueingThread_t g_receiveThread;
73 static CARetransmission_t g_retransmissionContext;
76 static CARequestCallback g_requestHandler = NULL;
77 static CAResponseCallback g_responseHandler = NULL;
79 static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pdu, uint32_t size)
81 CARemoteEndpoint_t* ep = CACloneRemoteEndpoint(endpoint);
84 OIC_LOG(DEBUG, TAG, "memory allocation failed !");
88 CAResponseInfo_t* resInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t));
92 OIC_LOG(DEBUG, TAG, "memory allocation failed !");
93 CADestroyRemoteEndpointInternal(ep);
97 CAMessageType_t type = CAGetMessageTypeFromPduBinaryData(pdu, size);
98 uint16_t messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
100 resInfo->result = CA_RETRANSMIT_TIMEOUT;
101 resInfo->info.type = type;
102 resInfo->info.messageId = messageId;
104 CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
107 OIC_LOG(DEBUG, TAG, "memory allocation failed !");
108 CADestroyRemoteEndpointInternal(ep);
113 cadata->type = SEND_TYPE_UNICAST;
114 cadata->remoteEndpoint = ep;
115 cadata->requestInfo = NULL;
116 cadata->responseInfo = resInfo;
118 CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
121 static void CADataDestroyer(void *data, uint32_t size)
123 CAData_t *cadata = (CAData_t *) data;
130 if (cadata->remoteEndpoint != NULL)
132 CADestroyRemoteEndpointInternal((CARemoteEndpoint_t *)cadata->remoteEndpoint);
135 if (cadata->requestInfo != NULL)
137 CADestroyRequestInfoInternal((CARequestInfo_t *)cadata->requestInfo);
140 if (cadata->responseInfo != NULL)
142 CADestroyResponseInfoInternal((CAResponseInfo_t *)cadata->responseInfo);
145 if (cadata->options != NULL)
147 OICFree(cadata->options);
153 static void CAReceiveThreadProcess(void *threadData)
155 // Currently not supported
156 // This will be enabled when RI supports multi threading
157 #ifndef SINGLE_HANDLE
158 CAData_t *data = (CAData_t *) threadData;
162 OIC_LOG(DEBUG, TAG, "thread data error!!");
166 // parse the data and call the callbacks.
169 CARemoteEndpoint_t *rep = (CARemoteEndpoint_t *)(data->remoteEndpoint);
174 if (data->requestInfo != NULL)
176 if (g_requestHandler)
178 g_requestHandler(rep, data->requestInfo);
182 if (data->responseInfo != NULL)
184 if (g_responseHandler)
186 g_responseHandler(rep, data->responseInfo);
192 static void CASendThreadProcess(void *threadData)
194 CAData_t *data = (CAData_t *) threadData;
198 OIC_LOG(ERROR, TAG, "thread data error!!");
202 if (NULL == data->remoteEndpoint)
204 OIC_LOG(DEBUG, TAG, "remoteEndpoint is null");
208 CAResult_t res = CA_STATUS_FAILED;
210 CASendDataType_t type = data->type;
212 if (type == SEND_TYPE_UNICAST)
214 coap_pdu_t *pdu = NULL;
216 if (data->requestInfo != NULL)
218 OIC_LOG_V(DEBUG, TAG, "requestInfo is available..");
220 pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri,
221 data->requestInfo->method,
222 data->requestInfo->info);
224 else if (data->responseInfo != NULL)
226 OIC_LOG_V(DEBUG, TAG, "responseInfo is available..");
228 pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri,
229 data->responseInfo->result,
230 data->responseInfo->info);
234 OIC_LOG(DEBUG, TAG, "request info, response info is empty");
237 // interface controller function call.
240 OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data);
242 OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->type);
244 OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code);
246 OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", ntohs(pdu->hdr->id));
248 OIC_LOG_V(DEBUG, TAG, "PDU Maker - token : %s", pdu->hdr->token);
250 res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length);
252 // for retransmission
253 CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr,
256 coap_delete_pdu(pdu);
259 else if (type == SEND_TYPE_MULTICAST)
261 coap_pdu_t *pdu = NULL;
264 info.options = data->options;
265 info.numOptions = data->numOptions;
266 info.token = data->requestInfo->info.token;
267 info.type = data->requestInfo->info.type;
269 pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri, CA_GET, info);
273 OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data);
275 OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->type);
277 OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code);
279 OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", ntohs(pdu->hdr->id));
281 OIC_LOG_V(DEBUG, TAG, "PDU Maker - token : %s", pdu->hdr->token);
283 res = CASendMulticastData(pdu->hdr, pdu->length);
284 coap_delete_pdu(pdu);
288 OIC_LOG_V(DEBUG, TAG, " Result :%d", res);
291 static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
294 OIC_LOG(DEBUG, TAG, "receivedPacketCallback in message handler!!");
298 OIC_LOG(DEBUG, TAG, "received data is null");
303 uint32_t code = CA_NOT_FOUND;
305 OIC_LOG_V(DEBUG, TAG, "data : %s", data);
306 pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code);
311 OIC_LOG(DEBUG, TAG, "pdu is null");
315 char uri[CA_MAX_URI_LENGTH] = { 0, };
316 uint32_t bufLen = CA_MAX_URI_LENGTH;
318 if (code == CA_GET || code == CA_POST || code == CA_PUT || code == CA_DELETE)
320 CARequestInfo_t *ReqInfo;
321 ReqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t));
324 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
325 coap_delete_pdu(pdu);
326 CAAdapterFreeRemoteEndpoint(endpoint);
329 CAGetRequestInfoFromPdu(pdu, ReqInfo, uri, bufLen);
331 if (NULL != ReqInfo->info.options)
334 for (i = 0; i < ReqInfo->info.numOptions; i++)
336 OIC_LOG_V(DEBUG, TAG, "Request- optionID: %d", ReqInfo->info.options[i].optionID);
338 OIC_LOG_V(DEBUG, TAG, "Request- list: %s", ReqInfo->info.options[i].optionData);
342 if (NULL != ReqInfo->info.payload)
344 OIC_LOG_V(DEBUG, TAG, "Request- payload: %s", ReqInfo->info.payload);
346 OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method);
347 if (NULL != ReqInfo->info.token)
349 OIC_LOG_V(DEBUG, TAG, "Request- token : %s", ReqInfo->info.token);
352 if (NULL != endpoint)
354 endpoint->resourceUri = (char *) OICCalloc(bufLen + 1, sizeof(char));
355 if (endpoint->resourceUri == NULL)
357 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
359 coap_delete_pdu(pdu);
360 CAAdapterFreeRemoteEndpoint(endpoint);
363 memcpy(endpoint->resourceUri, uri, bufLen);
364 OIC_LOG_V(DEBUG, TAG, "added resource URI : %s", endpoint->resourceUri);
366 // store the data at queue.
367 CAData_t *cadata = NULL;
368 cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
371 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
372 if (endpoint != NULL && endpoint->resourceUri != NULL)
373 OICFree(endpoint->resourceUri);
375 coap_delete_pdu(pdu);
376 CAAdapterFreeRemoteEndpoint(endpoint);
380 cadata->type = SEND_TYPE_UNICAST;
381 cadata->remoteEndpoint = endpoint;
382 cadata->requestInfo = ReqInfo;
383 cadata->responseInfo = NULL;
384 CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
388 CAResponseInfo_t *ResInfo;
389 ResInfo = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t));
392 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
393 coap_delete_pdu(pdu);
394 CAAdapterFreeRemoteEndpoint(endpoint);
397 CAGetResponseInfoFromPdu(pdu, ResInfo, uri, bufLen);
399 if (NULL != ResInfo->info.options)
402 for (i = 0; i < ResInfo->info.numOptions; i++)
404 OIC_LOG_V(DEBUG, TAG, "Response- optionID: %d", ResInfo->info.options[i].optionID);
406 OIC_LOG_V(DEBUG, TAG, "Response- list: %s", ResInfo->info.options[i].optionData);
408 if (NULL != ResInfo->info.payload)
410 OIC_LOG_V(DEBUG, TAG, "Response- payload: %s", ResInfo->info.payload);
412 OIC_LOG_V(DEBUG, TAG, "Response- code: %d", ResInfo->result);
415 if (NULL != endpoint)
417 endpoint->resourceUri = (char *) OICCalloc(bufLen + 1, sizeof(char));
418 if (endpoint->resourceUri == NULL)
420 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
422 coap_delete_pdu(pdu);
423 CAAdapterFreeRemoteEndpoint(endpoint);
426 memcpy(endpoint->resourceUri, uri, bufLen);
427 OIC_LOG_V(DEBUG, TAG, "added resource URI : %s", endpoint->resourceUri);
430 // store the data at queue.
431 CAData_t *cadata = NULL;
432 cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
435 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
436 if (endpoint != NULL && endpoint->resourceUri != NULL)
437 OICFree(endpoint->resourceUri);
439 coap_delete_pdu(pdu);
440 CAAdapterFreeRemoteEndpoint(endpoint);
444 cadata->type = SEND_TYPE_UNICAST;
445 cadata->remoteEndpoint = endpoint;
446 cadata->requestInfo = NULL;
447 cadata->responseInfo = ResInfo;
449 CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
451 // for retransmission
452 CARetransmissionReceivedData(&g_retransmissionContext, endpoint, pdu->hdr, pdu->length);
457 coap_delete_pdu(pdu);
461 static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
463 OIC_LOG(DEBUG, TAG, "networkChangeCallback in message handler!!");
465 OIC_LOG_V(DEBUG, TAG, "Changed Network Status: %d", status);
468 void CAHandleRequestResponseCallbacks()
470 OIC_LOG_V(DEBUG, TAG, "CAHandleRequestResponseCallbacks IN");
472 // parse the data and call the callbacks.
476 u_mutex_lock(g_receiveThread.threadMutex);
478 u_queue_message_t *item = u_queue_get_element(g_receiveThread.dataQueue);
480 u_mutex_unlock(g_receiveThread.threadMutex);
486 void *msg = item->msg;
492 CAData_t *td = (CAData_t *) msg;
493 CARemoteEndpoint_t *rep = td->remoteEndpoint;
498 if (td->requestInfo != NULL)
500 if (g_requestHandler)
502 g_requestHandler(rep, td->requestInfo);
505 OICFree(td->requestInfo->info.options);
506 OICFree(td->requestInfo->info.payload);
507 OICFree(td->requestInfo->info.token);
508 OICFree(td->requestInfo);
511 if (td->responseInfo != NULL)
513 if (g_responseHandler)
515 g_responseHandler(rep, td->responseInfo);
518 OICFree(td->responseInfo->info.options);
519 OICFree(td->responseInfo->info.payload);
520 OICFree(td->responseInfo->info.token);
521 OICFree(td->responseInfo);
524 if (NULL != rep->resourceUri)
526 OICFree(rep->resourceUri);
530 OIC_LOG_V(DEBUG, TAG, "CAHandleRequestResponseCallbacks OUT");
533 CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object,
534 const CARequestInfo_t *request)
536 OIC_LOG_V(DEBUG, TAG, "CADetachRequestMessage");
538 if (object == NULL || request == NULL)
540 return CA_STATUS_FAILED;
543 CARemoteEndpoint_t *remoteEndpoint = NULL;
544 CARequestInfo_t *requestInfo = NULL;
546 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
547 CA_MEMORY_ALLOC_CHECK(data);
549 // clone remote endpoint
551 remoteEndpoint = CACloneRemoteEndpoint(object);
552 CA_MEMORY_ALLOC_CHECK(remoteEndpoint);
554 // clone request info
555 requestInfo = CACloneRequestInfo(request);
556 CA_MEMORY_ALLOC_CHECK(requestInfo);
559 data->type = SEND_TYPE_UNICAST;
560 data->remoteEndpoint = remoteEndpoint;
561 data->requestInfo = requestInfo;
562 data->responseInfo = NULL;
565 CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
569 // memory error label.
572 CADestroyRemoteEndpointInternal(remoteEndpoint);
574 CADestroyRequestInfoInternal(requestInfo);
581 return CA_MEMORY_ALLOC_FAILED;
584 CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object,
585 const CARequestInfo_t *request)
588 OIC_LOG_V(DEBUG, TAG, "CADetachRequestToAllMessage");
591 if (object == NULL || request == NULL)
593 return CA_STATUS_FAILED;
596 CARemoteEndpoint_t *remoteEndpoint = NULL;
597 CARequestInfo_t *requestInfo = NULL;
599 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
600 CA_MEMORY_ALLOC_CHECK(data);
603 memset(&addr, 0, sizeof(CAAddress_t));
604 remoteEndpoint = CACreateRemoteEndpointInternal(object->resourceUri, addr,
605 object->connectivityType);
607 // clone request info
608 requestInfo = CACloneRequestInfo(request);
609 CA_MEMORY_ALLOC_CHECK(requestInfo);
612 data->type = SEND_TYPE_MULTICAST;
613 data->remoteEndpoint = remoteEndpoint;
614 data->requestInfo = requestInfo;
615 data->responseInfo = NULL;
618 CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
622 // memory error label.
625 CADestroyRemoteEndpointInternal(remoteEndpoint);
627 CADestroyRequestInfoInternal(requestInfo);
634 return CA_MEMORY_ALLOC_FAILED;
637 CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
638 const CAResponseInfo_t *response)
640 OIC_LOG_V(DEBUG, TAG, "CADetachResponseMessage");
642 if (object == NULL || response == NULL)
644 return CA_STATUS_FAILED;
647 CARemoteEndpoint_t *remoteEndpoint = NULL;
648 CAResponseInfo_t *responseInfo = NULL;
650 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
651 CA_MEMORY_ALLOC_CHECK(data);
653 // clone remote endpoint
654 remoteEndpoint = CACloneRemoteEndpoint(object);
655 CA_MEMORY_ALLOC_CHECK(remoteEndpoint);
657 // clone response info
658 responseInfo = CACloneResponseInfo(response);
659 CA_MEMORY_ALLOC_CHECK(responseInfo);
662 data->type = SEND_TYPE_UNICAST;
663 data->remoteEndpoint = remoteEndpoint;
664 data->requestInfo = NULL;
665 data->responseInfo = responseInfo;
668 CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
672 // memory error label.
675 CADestroyRemoteEndpointInternal(remoteEndpoint);
677 CADestroyResponseInfoInternal(responseInfo);
684 return CA_MEMORY_ALLOC_FAILED;
687 CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
688 const CAHeaderOption_t *options,const uint8_t numOptions)
690 if (resourceUri == NULL)
692 return CA_STATUS_FAILED;
694 CARequestInfo_t *ReqInfo = NULL;
695 CAToken_t tempToken = NULL;
696 CARemoteEndpoint_t *remoteEndpoint = NULL;
698 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
699 CA_MEMORY_ALLOC_CHECK(data);
701 CAAddress_t addr = {};
702 remoteEndpoint = CACreateRemoteEndpointInternal(resourceUri, addr,
703 CA_ETHERNET | CA_WIFI | CA_EDR | CA_LE);
705 // create request info
706 ReqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t));
707 CA_MEMORY_ALLOC_CHECK(ReqInfo);
712 int32_t len = strlen(token);
713 tempToken = (char *) OICCalloc((len + 1), sizeof(char));
714 CA_MEMORY_ALLOC_CHECK(tempToken);
715 strncpy(tempToken, token, len);
718 // save request info data
719 ReqInfo->method = CA_GET;
720 ReqInfo->info.token = tempToken;
721 ReqInfo->info.type = CA_MSG_NONCONFIRM;
723 data->type = SEND_TYPE_MULTICAST;
724 data->remoteEndpoint = remoteEndpoint;
725 data->requestInfo = ReqInfo;
727 data->responseInfo = NULL;
728 data->options = NULL;
729 data->numOptions = 0;
731 if (options != NULL && numOptions > 0)
734 CAHeaderOption_t *temp = (CAHeaderOption_t *) OICCalloc(numOptions,
735 sizeof(CAHeaderOption_t));
736 CA_MEMORY_ALLOC_CHECK(temp);
738 memcpy(temp, options, sizeof(CAHeaderOption_t) * numOptions);
740 data->options = temp;
741 data->numOptions = numOptions;
745 CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
749 // memory error label.
752 CADestroyRemoteEndpointInternal(remoteEndpoint);
754 if (tempToken != NULL)
769 return CA_MEMORY_ALLOC_FAILED;
772 void CASetRequestResponseCallbacks(CARequestCallback ReqHandler,
773 CAResponseCallback RespHandler)
775 OIC_LOG_V(DEBUG, TAG, "set request, response handler callback.");
777 g_requestHandler = ReqHandler;
778 g_responseHandler = RespHandler;
781 CAResult_t CAInitializeMessageHandler()
783 OIC_LOG(DEBUG, TAG, "CAInitializeMessageHandler - Entry");
784 CASetPacketReceivedCallback(CAReceivedPacketCallback);
786 CASetNetworkChangeCallback(CANetworkChangedCallback);
788 // create thread pool
790 res = u_thread_pool_init(MAX_THREAD_POOL_SIZE, &g_threadPoolHandle);
792 if (res != CA_STATUS_OK)
794 OIC_LOG_V(ERROR, TAG, "thread pool initialize error.");
798 // send thread initialize
799 CAQueueingThreadInitialize(&g_sendThread, g_threadPoolHandle, CASendThreadProcess,
803 res = CAQueueingThreadStart(&g_sendThread);
805 if (res != CA_STATUS_OK)
807 OIC_LOG_V(ERROR, TAG, "thread start error(send thread).");
808 u_thread_pool_free(g_threadPoolHandle);
809 g_threadPoolHandle = NULL;
813 // receive thread initialize
814 CAQueueingThreadInitialize(&g_receiveThread, g_threadPoolHandle, CAReceiveThreadProcess,
817 #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading
818 // start receive thread
819 res = CAQueueingThreadStart(&gReceiveThread);
821 if (res != CA_STATUS_OK)
823 OIC_LOG_V(DEBUG, TAG, "thread start error(receive thread).");
828 // retransmission initialize
829 CARetransmissionInitialize(&g_retransmissionContext, g_threadPoolHandle, CASendUnicastData,
830 CATimeoutCallback, NULL);
832 // start retransmission
833 res = CARetransmissionStart(&g_retransmissionContext);
835 if (res != CA_STATUS_OK)
837 OIC_LOG_V(ERROR, TAG, "thread start error(retransmission thread).");
841 // initialize interface adapters by controller
842 CAInitializeAdapters(g_threadPoolHandle);
847 void CATerminateMessageHandler()
850 CAConnectivityType_t connType;
851 u_arraylist_t *list = CAGetSelectedNetworkList();
852 uint32_t length = u_arraylist_length(list);
854 for (i = 0; i < length; i++)
856 void* ptrType = u_arraylist_get(list, i);
863 connType = *(CAConnectivityType_t *) ptrType;
864 CAStopAdapter(connType);
867 // stop retransmission
868 if (g_retransmissionContext.threadMutex != NULL)
870 CARetransmissionStop(&g_retransmissionContext);
874 // delete thread data
875 if (g_sendThread.threadMutex != NULL)
877 CAQueueingThreadStop(&g_sendThread);
881 // delete thread data
882 if (g_receiveThread.threadMutex != NULL)
884 #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading
885 CAQueueingThreadStop(&gReceiveThread);
889 // destroy thread pool
890 if (g_threadPoolHandle != NULL)
892 u_thread_pool_free(g_threadPoolHandle);
893 g_threadPoolHandle = NULL;
896 CARetransmissionDestroy(&g_retransmissionContext);
897 CAQueueingThreadDestroy(&g_sendThread);
898 CAQueueingThreadDestroy(&g_receiveThread);
900 // terminate interface adapters by controller
901 CATerminateAdapters();
903 OIC_LOG_V(DEBUG, TAG, "message handler termination is complete!");