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(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(ERROR, 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(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(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(DEBUG, TAG, "PDU Maker - token :");
250 OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length);
252 res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length);
254 // for retransmission
255 CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr,
258 coap_delete_pdu(pdu);
261 else if (type == SEND_TYPE_MULTICAST)
263 coap_pdu_t *pdu = NULL;
266 info.options = data->options;
267 info.numOptions = data->numOptions;
268 info.token = data->requestInfo->info.token;
269 info.tokenLength = data->requestInfo->info.tokenLength;
270 info.type = data->requestInfo->info.type;
272 pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri, CA_GET, info);
276 OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data);
278 OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->type);
280 OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code);
282 OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", ntohs(pdu->hdr->id));
284 OIC_LOG(DEBUG, TAG, "PDU Maker - token");
286 OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length);
288 res = CASendMulticastData(pdu->hdr, pdu->length);
289 coap_delete_pdu(pdu);
293 OIC_LOG_V(DEBUG, TAG, " Result :%d", res);
296 static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
299 OIC_LOG(DEBUG, TAG, "receivedPacketCallback in message handler!!");
303 OIC_LOG(DEBUG, TAG, "received data is null");
308 uint32_t code = CA_NOT_FOUND;
310 OIC_LOG_V(DEBUG, TAG, "data : %s", data);
311 pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code);
316 OIC_LOG(DEBUG, TAG, "pdu is null");
320 char uri[CA_MAX_URI_LENGTH] = { 0, };
321 uint32_t bufLen = CA_MAX_URI_LENGTH;
323 if (code == CA_GET || code == CA_POST || code == CA_PUT || code == CA_DELETE)
325 CARequestInfo_t *ReqInfo;
326 ReqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t));
329 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
330 coap_delete_pdu(pdu);
331 CAAdapterFreeRemoteEndpoint(endpoint);
334 CAGetRequestInfoFromPdu(pdu, ReqInfo, uri, bufLen);
336 if (NULL != ReqInfo->info.options)
339 for (i = 0; i < ReqInfo->info.numOptions; i++)
341 OIC_LOG_V(DEBUG, TAG, "Request- optionID: %d", ReqInfo->info.options[i].optionID);
343 OIC_LOG_V(DEBUG, TAG, "Request- list: %s", ReqInfo->info.options[i].optionData);
347 if (NULL != ReqInfo->info.payload)
349 OIC_LOG_V(DEBUG, TAG, "Request- payload: %s", ReqInfo->info.payload);
351 OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method);
352 if (NULL != ReqInfo->info.token)
354 OIC_LOG(DEBUG, TAG, "Request- token:");
355 OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) ReqInfo->info.token,
356 ReqInfo->info.tokenLength);
359 if (NULL != endpoint)
361 endpoint->resourceUri = (char *) OICCalloc(bufLen + 1, sizeof(char));
362 if (endpoint->resourceUri == NULL)
364 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
366 coap_delete_pdu(pdu);
367 CAAdapterFreeRemoteEndpoint(endpoint);
370 memcpy(endpoint->resourceUri, uri, bufLen);
371 OIC_LOG_V(DEBUG, TAG, "added resource URI : %s", endpoint->resourceUri);
373 // store the data at queue.
374 CAData_t *cadata = NULL;
375 cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
378 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
379 if (endpoint != NULL && endpoint->resourceUri != NULL)
380 OICFree(endpoint->resourceUri);
382 coap_delete_pdu(pdu);
383 CAAdapterFreeRemoteEndpoint(endpoint);
387 cadata->type = SEND_TYPE_UNICAST;
388 cadata->remoteEndpoint = endpoint;
389 cadata->requestInfo = ReqInfo;
390 cadata->responseInfo = NULL;
391 CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
395 CAResponseInfo_t *ResInfo;
396 ResInfo = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t));
399 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
400 coap_delete_pdu(pdu);
401 CAAdapterFreeRemoteEndpoint(endpoint);
404 CAGetResponseInfoFromPdu(pdu, ResInfo, uri, bufLen);
406 if (NULL != ResInfo->info.options)
409 for (i = 0; i < ResInfo->info.numOptions; i++)
411 OIC_LOG_V(DEBUG, TAG, "Response- optionID: %d", ResInfo->info.options[i].optionID);
413 OIC_LOG_V(DEBUG, TAG, "Response- list: %s", ResInfo->info.options[i].optionData);
415 if (NULL != ResInfo->info.payload)
417 OIC_LOG_V(DEBUG, TAG, "Response- payload: %s", ResInfo->info.payload);
419 OIC_LOG_V(DEBUG, TAG, "Response- code: %d", ResInfo->result);
422 if (NULL != endpoint)
424 endpoint->resourceUri = (char *) OICCalloc(bufLen + 1, sizeof(char));
425 if (endpoint->resourceUri == NULL)
427 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
429 coap_delete_pdu(pdu);
430 CAAdapterFreeRemoteEndpoint(endpoint);
433 memcpy(endpoint->resourceUri, uri, bufLen);
434 OIC_LOG_V(DEBUG, TAG, "added resource URI : %s", endpoint->resourceUri);
437 // store the data at queue.
438 CAData_t *cadata = NULL;
439 cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
442 OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
443 if (endpoint != NULL && endpoint->resourceUri != NULL)
444 OICFree(endpoint->resourceUri);
446 coap_delete_pdu(pdu);
447 CAAdapterFreeRemoteEndpoint(endpoint);
451 cadata->type = SEND_TYPE_UNICAST;
452 cadata->remoteEndpoint = endpoint;
453 cadata->requestInfo = NULL;
454 cadata->responseInfo = ResInfo;
456 CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
458 // for retransmission
459 CARetransmissionReceivedData(&g_retransmissionContext, endpoint, pdu->hdr, pdu->length);
464 coap_delete_pdu(pdu);
468 static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
470 OIC_LOG(DEBUG, TAG, "networkChangeCallback in message handler!!");
472 OIC_LOG_V(DEBUG, TAG, "Changed Network Status: %d", status);
475 void CAHandleRequestResponseCallbacks()
477 OIC_LOG(DEBUG, TAG, "CAHandleRequestResponseCallbacks IN");
479 // parse the data and call the callbacks.
483 u_mutex_lock(g_receiveThread.threadMutex);
485 u_queue_message_t *item = u_queue_get_element(g_receiveThread.dataQueue);
487 u_mutex_unlock(g_receiveThread.threadMutex);
493 void *msg = item->msg;
499 CAData_t *td = (CAData_t *) msg;
500 CARemoteEndpoint_t *rep = td->remoteEndpoint;
505 if (td->requestInfo != NULL)
507 if (g_requestHandler)
509 g_requestHandler(rep, td->requestInfo);
512 OICFree(td->requestInfo->info.options);
513 OICFree(td->requestInfo->info.payload);
514 OICFree(td->requestInfo->info.token);
515 OICFree(td->requestInfo);
518 if (td->responseInfo != NULL)
520 if (g_responseHandler)
522 g_responseHandler(rep, td->responseInfo);
525 OICFree(td->responseInfo->info.options);
526 OICFree(td->responseInfo->info.payload);
527 OICFree(td->responseInfo->info.token);
528 OICFree(td->responseInfo);
531 if (NULL != rep->resourceUri)
533 OICFree(rep->resourceUri);
537 OIC_LOG(DEBUG, TAG, "CAHandleRequestResponseCallbacks OUT");
540 CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object,
541 const CARequestInfo_t *request)
543 OIC_LOG(DEBUG, TAG, "CADetachRequestMessage");
545 if (object == NULL || request == NULL)
547 return CA_STATUS_FAILED;
550 CARemoteEndpoint_t *remoteEndpoint = NULL;
551 CARequestInfo_t *requestInfo = NULL;
553 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
554 CA_MEMORY_ALLOC_CHECK(data);
556 // clone remote endpoint
558 remoteEndpoint = CACloneRemoteEndpoint(object);
559 CA_MEMORY_ALLOC_CHECK(remoteEndpoint);
561 // clone request info
562 requestInfo = CACloneRequestInfo(request);
563 CA_MEMORY_ALLOC_CHECK(requestInfo);
566 data->type = SEND_TYPE_UNICAST;
567 data->remoteEndpoint = remoteEndpoint;
568 data->requestInfo = requestInfo;
569 data->responseInfo = NULL;
572 CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
576 // memory error label.
579 CADestroyRemoteEndpointInternal(remoteEndpoint);
581 CADestroyRequestInfoInternal(requestInfo);
588 return CA_MEMORY_ALLOC_FAILED;
591 CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object,
592 const CARequestInfo_t *request)
595 OIC_LOG(DEBUG, TAG, "CADetachRequestToAllMessage");
598 if (object == NULL || request == NULL)
600 return CA_STATUS_FAILED;
603 CARemoteEndpoint_t *remoteEndpoint = NULL;
604 CARequestInfo_t *requestInfo = NULL;
606 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
607 CA_MEMORY_ALLOC_CHECK(data);
610 memset(&addr, 0, sizeof(CAAddress_t));
611 remoteEndpoint = CACreateRemoteEndpointInternal(object->resourceUri, addr,
612 object->connectivityType);
614 // clone request info
615 requestInfo = CACloneRequestInfo(request);
616 CA_MEMORY_ALLOC_CHECK(requestInfo);
619 data->type = SEND_TYPE_MULTICAST;
620 data->remoteEndpoint = remoteEndpoint;
621 data->requestInfo = requestInfo;
622 data->responseInfo = NULL;
625 CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
629 // memory error label.
632 CADestroyRemoteEndpointInternal(remoteEndpoint);
634 CADestroyRequestInfoInternal(requestInfo);
641 return CA_MEMORY_ALLOC_FAILED;
644 CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
645 const CAResponseInfo_t *response)
647 OIC_LOG(DEBUG, TAG, "CADetachResponseMessage");
649 if (object == NULL || response == NULL)
651 return CA_STATUS_FAILED;
654 CARemoteEndpoint_t *remoteEndpoint = NULL;
655 CAResponseInfo_t *responseInfo = NULL;
657 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
658 CA_MEMORY_ALLOC_CHECK(data);
660 // clone remote endpoint
661 remoteEndpoint = CACloneRemoteEndpoint(object);
662 CA_MEMORY_ALLOC_CHECK(remoteEndpoint);
664 // clone response info
665 responseInfo = CACloneResponseInfo(response);
666 CA_MEMORY_ALLOC_CHECK(responseInfo);
669 data->type = SEND_TYPE_UNICAST;
670 data->remoteEndpoint = remoteEndpoint;
671 data->requestInfo = NULL;
672 data->responseInfo = responseInfo;
675 CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
679 // memory error label.
682 CADestroyRemoteEndpointInternal(remoteEndpoint);
684 CADestroyResponseInfoInternal(responseInfo);
691 return CA_MEMORY_ALLOC_FAILED;
694 CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
695 uint8_t tokenLength, const CAHeaderOption_t *options,
698 OIC_LOG(DEBUG, TAG, "IN");
699 VERIFY_NON_NULL(resourceUri, TAG, "resourceUri is NULL");
700 VERIFY_NON_NULL(token, TAG, "Token is NULL");
702 CARemoteEndpoint_t *remoteEndpoint = NULL;
703 CARequestInfo_t *reqInfo = NULL;
704 char *tempToken = NULL;
706 // allocate & initialize
707 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
708 CA_MEMORY_ALLOC_CHECK(data);
710 CAAddress_t addr = {};
711 remoteEndpoint = CACreateRemoteEndpointInternal(resourceUri, addr,
712 CA_ETHERNET | CA_WIFI | CA_EDR | CA_LE);
714 // create request info
715 reqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t));
716 CA_MEMORY_ALLOC_CHECK(reqInfo);
721 tempToken = (char *) OICMalloc(tokenLength);
722 CA_MEMORY_ALLOC_CHECK(tempToken);
723 memcpy(tempToken, token, tokenLength);
726 // save request info data
727 reqInfo->method = CA_GET;
728 reqInfo->info.type = CA_MSG_NONCONFIRM;
730 reqInfo->info.token = tempToken;
731 reqInfo->info.tokenLength = tokenLength;
734 data->type = SEND_TYPE_MULTICAST;
735 data->remoteEndpoint = remoteEndpoint;
736 data->requestInfo = reqInfo;
738 data->responseInfo = NULL;
739 data->options = NULL;
740 data->numOptions = 0;
742 if (options != NULL && numOptions > 0)
745 CAHeaderOption_t *temp = (CAHeaderOption_t *) OICCalloc(numOptions,
746 sizeof(CAHeaderOption_t));
747 CA_MEMORY_ALLOC_CHECK(temp);
749 memcpy(temp, options, sizeof(CAHeaderOption_t) * numOptions);
751 data->options = temp;
752 data->numOptions = numOptions;
756 CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
760 // memory error label.
763 CADestroyRemoteEndpointInternal(remoteEndpoint);
768 OIC_LOG(DEBUG, TAG, "OUT");
769 return CA_MEMORY_ALLOC_FAILED;
772 void CASetRequestResponseCallbacks(CARequestCallback ReqHandler,
773 CAResponseCallback RespHandler)
775 OIC_LOG(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(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(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(ERROR, 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(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(DEBUG, TAG, "message handler termination is complete!");