Revert "[CONPRO-1568] Ignoring duplicate IPv6/Ipv4 messages"
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / camessagehandler.c
1 /* *****************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  ******************************************************************/
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdint.h>
25
26 #include "cainterface.h"
27 #include "camessagehandler.h"
28 #include "caremotehandler.h"
29 #include "caprotocolmessage.h"
30 #include "logger.h"
31 #include "trace.h"
32 #ifndef WITH_UPSTREAM_LIBCOAP
33 #include "coap/config.h"
34 #endif
35 #include "oic_malloc.h"
36 #include "canetworkconfigurator.h"
37 #include "caadapterutils.h"
38 #include "cainterfacecontroller.h"
39 #include "caretransmission.h"
40 #include "oic_string.h"
41
42 #ifdef WITH_BWT
43 #include "cablockwisetransfer.h"
44 #endif
45
46 #ifndef  SINGLE_THREAD
47 #include "uqueue.h"
48 #include "cathreadpool.h" /* for thread pool */
49 #include "caqueueingthread.h"
50
51 #define SINGLE_HANDLE
52 #define MAX_THREAD_POOL_SIZE    20
53
54 #define UNUSED(x) (void)(x)
55
56 // thread pool handle
57 static ca_thread_pool_t g_threadPoolHandle = NULL;
58
59 // message handler main thread
60 static CAQueueingThread_t g_sendThread;
61 static CAQueueingThread_t g_receiveThread;
62
63 #ifdef WITH_PROCESS_EVENT
64 static oc_event g_processEvent = NULL;
65 #endif // WITH_PROCESS_EVENT
66
67 #else
68 #define CA_MAX_RT_ARRAY_SIZE    3
69 #endif  // SINGLE_THREAD
70
71 #define TAG "OIC_CA_MSG_HANDLE"
72
73 static CARetransmission_t g_retransmissionContext;
74
75 // handler field
76 static CARequestCallback g_requestHandler = NULL;
77 static CAResponseCallback g_responseHandler = NULL;
78 static CAErrorCallback g_errorHandler = NULL;
79 static CANetworkMonitorCallback g_nwMonitorHandler = NULL;
80
81 static void CAErrorHandler(const CAEndpoint_t *endpoint,
82                            const void *data, uint32_t dataLen,
83                            CAResult_t result);
84
85 static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint,
86                                        const CARemoteId_t *identity,
87                                        const void *data, CADataType_t dataType);
88
89 static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info,
90                             CAResult_t result);
91
92 #ifdef SINGLE_THREAD
93 static void CAProcessReceivedData(CAData_t *data);
94 #endif
95 static void CADestroyData(void *data, uint32_t size);
96 static void CALogPayloadInfo(CAInfo_t *info);
97 static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *endpoint, uint16_t id,
98                                 CAToken_t token, uint8_t tokenLength);
99
100 /**
101  * print send / receive message of CoAP.
102  * @param[in] data      CA information which has send/receive message and endpoint.
103  * @param[in] pdu       CoAP pdu low data.
104  */
105 static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu);
106
107 #ifndef ARDUINO
108 static char g_headerBuffer[MAX_LOG_BUFFER_SIZE] = {0};
109 static size_t g_headerIndex = 0;
110 static void CASamsungLogMessage(const CAData_t *data, const coap_pdu_t *pdu);
111 #endif
112
113 #ifdef WITH_BWT
114 void CAAddDataToSendThread(CAData_t *data)
115 {
116     VERIFY_NON_NULL_VOID(data, TAG, "data");
117
118     // add thread
119     CAResult_t result = CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t), true);
120     if (result != CA_STATUS_OK)
121     {
122         OIC_LOG(ERROR, TAG, "Failed to add message to data queue!");
123         CADestroyData(data, sizeof(CAData_t));
124     }
125 }
126
127 void CAAddDataToReceiveThread(CAData_t *data)
128 {
129     VERIFY_NON_NULL_VOID(data, TAG, "data");
130
131     // add thread
132     CAResult_t result = CAQueueingThreadAddData(&g_receiveThread, data, sizeof(CAData_t), false);
133     if (result != CA_STATUS_OK)
134     {
135         OIC_LOG(ERROR, TAG, "Failed to add message to data queue!");
136         CADestroyData(data, sizeof(CAData_t));
137         return;
138     }
139
140 #ifdef WITH_PROCESS_EVENT
141     if (g_processEvent)
142     {
143         oc_event_signal(g_processEvent);
144     }
145 #endif
146 }
147 #endif
148
149 static bool CAIsSelectedNetworkAvailable()
150 {
151     u_arraylist_t *list = CAGetSelectedNetworkList();
152     if (!list || u_arraylist_length(list) == 0)
153     {
154         OIC_LOG(ERROR, TAG, "No selected network");
155         return false;
156     }
157
158     return true;
159 }
160
161 static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint,
162                                        const CARemoteId_t *identity,
163                                        const void *data, CADataType_t dataType)
164 {
165     OIC_LOG(DEBUG, TAG, "CAGenerateHandlerData IN");
166     CAInfo_t *info = NULL;
167     CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
168     if (!cadata)
169     {
170         OIC_LOG(ERROR, TAG, "memory allocation failed");
171         return NULL;
172     }
173 #ifdef SINGLE_THREAD
174     CAEndpoint_t* ep = endpoint;
175 #else
176     CAEndpoint_t* ep = CACloneEndpoint(endpoint);
177     if (!ep)
178     {
179         OIC_LOG(ERROR, TAG, "endpoint clone failed");
180         goto exit;
181     }
182 #endif
183
184     OIC_LOG_V(DEBUG, TAG, "address : %s", ep->addr);
185
186     if (CA_RESPONSE_DATA == dataType)
187     {
188         CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(CAResponseInfo_t));
189         if (!resInfo)
190         {
191             OIC_LOG(ERROR, TAG, "memory allocation failed");
192             goto exit;
193         }
194
195         CAResult_t result = CAGetResponseInfoFromPDU(data, resInfo, endpoint);
196         if (CA_STATUS_OK != result)
197         {
198             OIC_LOG(ERROR, TAG, "CAGetResponseInfoFromPDU Failed");
199             CADestroyResponseInfoInternal(resInfo);
200             goto exit;
201         }
202         cadata->responseInfo = resInfo;
203         info = &resInfo->info;
204         if (identity)
205         {
206             info->identity = *identity;
207         }
208         OIC_LOG(DEBUG, TAG, "Response Info :");
209         CALogPayloadInfo(info);
210     }
211     else if (CA_REQUEST_DATA == dataType)
212     {
213         CARequestInfo_t* reqInfo = (CARequestInfo_t*)OICCalloc(1, sizeof(CARequestInfo_t));
214         if (!reqInfo)
215         {
216             OIC_LOG(ERROR, TAG, "memory allocation failed");
217             goto exit;
218         }
219
220         CAResult_t result = CAGetRequestInfoFromPDU(data, endpoint, reqInfo);
221         if (CA_STATUS_OK != result)
222         {
223             OIC_LOG(ERROR, TAG, "CAGetRequestInfoFromPDU failed");
224             CADestroyRequestInfoInternal(reqInfo);
225             goto exit;
226         }
227
228         if ((reqInfo->info.type != CA_MSG_CONFIRM) &&
229             CADropSecondMessage(&caglobals.ca.requestHistory, endpoint, reqInfo->info.messageId,
230                                 reqInfo->info.token, reqInfo->info.tokenLength))
231         {
232             OIC_LOG(INFO, TAG, "Second Request with same Token, Drop it");
233             CADestroyRequestInfoInternal(reqInfo);
234             goto exit;
235         }
236
237         cadata->requestInfo = reqInfo;
238         info = &reqInfo->info;
239         if (identity)
240         {
241             info->identity = *identity;
242         }
243         OIC_LOG(DEBUG, TAG, "Request Info :");
244         CALogPayloadInfo(info);
245    }
246     else if (CA_ERROR_DATA == dataType)
247     {
248         CAErrorInfo_t *errorInfo = (CAErrorInfo_t *)OICCalloc(1, sizeof (CAErrorInfo_t));
249         if (!errorInfo)
250         {
251             OIC_LOG(ERROR, TAG, "Memory allocation failed!");
252             goto exit;
253         }
254
255         CAResult_t result = CAGetErrorInfoFromPDU(data, endpoint, errorInfo);
256         if (CA_STATUS_OK != result)
257         {
258             OIC_LOG(ERROR, TAG, "CAGetErrorInfoFromPDU failed");
259             OICFree(errorInfo);
260             goto exit;
261         }
262
263         cadata->errorInfo = errorInfo;
264         info = &errorInfo->info;
265         if (identity)
266         {
267             info->identity = *identity;
268         }
269         OIC_LOG(DEBUG, TAG, "error Info :");
270         CALogPayloadInfo(info);
271     }
272
273     cadata->remoteEndpoint = ep;
274     cadata->dataType = dataType;
275
276     OIC_LOG(DEBUG, TAG, "CAGenerateHandlerData OUT");
277     return cadata;
278
279 exit:
280     OICFree(cadata);
281 #ifndef SINGLE_THREAD
282     CAFreeEndpoint(ep);
283 #endif
284     return NULL;
285 }
286
287 static void CATimeoutCallback(const CAEndpoint_t *endpoint, const void *pdu, uint32_t size)
288 {
289     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint");
290     VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
291 #ifdef SINGLE_THREAD
292     CAEndpoint_t* ep = endpoint;
293 #else
294     CAEndpoint_t* ep = CACloneEndpoint(endpoint);
295     if (!ep)
296     {
297         OIC_LOG(ERROR, TAG, "clone failed");
298         return;
299     }
300 #endif
301
302     CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(CAResponseInfo_t));
303
304     if (!resInfo)
305     {
306         OIC_LOG(ERROR, TAG, "calloc failed");
307 #ifndef SINGLE_THREAD
308         CAFreeEndpoint(ep);
309 #endif
310         return;
311     }
312
313     resInfo->result = CA_RETRANSMIT_TIMEOUT;
314     resInfo->info.type = CAGetMessageTypeFromPduBinaryData(pdu, size);
315     resInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
316
317     CAResult_t res = CAGetTokenFromPDU((const coap_hdr_transport_t *) pdu, &(resInfo->info),
318                                        endpoint);
319     if (CA_STATUS_OK != res)
320     {
321         OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
322         CADestroyResponseInfoInternal(resInfo);
323 #ifndef SINGLE_THREAD
324         CAFreeEndpoint(ep);
325 #endif
326         return;
327     }
328
329     CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
330     if (NULL == cadata)
331     {
332         OIC_LOG(ERROR, TAG, "memory allocation failed !");
333 #ifndef SINGLE_THREAD
334         CAFreeEndpoint(ep);
335 #endif
336         CADestroyResponseInfoInternal(resInfo);
337         return;
338     }
339
340     cadata->type = SEND_TYPE_UNICAST;
341     cadata->remoteEndpoint = ep;
342     cadata->requestInfo = NULL;
343     cadata->responseInfo = resInfo;
344
345 #ifdef WITH_BWT
346     if (CAIsSupportedBlockwiseTransfer(endpoint->adapter))
347     {
348         res = CARemoveBlockDataFromListWithSeed(resInfo->info.token, resInfo->info.tokenLength,
349                                                 endpoint->port);
350         if (CA_STATUS_OK != res)
351         {
352             OIC_LOG(ERROR, TAG, "CARemoveBlockDataFromListWithSeed failed");
353         }
354     }
355 #endif // WITH_BWT
356
357 #ifdef SINGLE_THREAD
358     CAProcessReceivedData(cadata);
359 #else
360     CAResult_t result = CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t), false);
361     if (result != CA_STATUS_OK)
362     {
363         OIC_LOG(ERROR, TAG, "Failed to add message to data queue!");
364         CADestroyData(cadata, sizeof(CAData_t));
365         return;
366     }
367
368 #ifdef WITH_PROCESS_EVENT
369     if (g_processEvent)
370     {
371         oc_event_signal(g_processEvent);
372     }
373 #endif//WITH_PROCESS_EVENT
374 #endif// SINGLE_THREAD
375 }
376
377 static void CADestroyData(void *data, uint32_t size)
378 {
379     OIC_LOG(DEBUG, TAG, "CADestroyData IN");
380     if ((size_t)size < sizeof(CAData_t))
381     {
382         OIC_LOG_V(ERROR, TAG, "Destroy data too small %p %d", data, size);
383     }
384     CAData_t *cadata = (CAData_t *) data;
385
386     if (NULL == cadata)
387     {
388         OIC_LOG(ERROR, TAG, "cadata is NULL");
389         return;
390     }
391 #ifndef SINGLE_THREAD
392     if (NULL != cadata->remoteEndpoint)
393     {
394         CAFreeEndpoint(cadata->remoteEndpoint);
395     }
396 #endif
397
398     if (NULL != cadata->requestInfo)
399     {
400         CADestroyRequestInfoInternal((CARequestInfo_t *) cadata->requestInfo);
401     }
402
403     if (NULL != cadata->responseInfo)
404     {
405         CADestroyResponseInfoInternal((CAResponseInfo_t *) cadata->responseInfo);
406     }
407
408     if (NULL != cadata->errorInfo)
409     {
410         CADestroyErrorInfoInternal(cadata->errorInfo);
411     }
412
413     OICFree(cadata);
414     OIC_LOG(DEBUG, TAG, "CADestroyData OUT");
415 }
416
417 #ifdef SINGLE_THREAD
418 static void CAProcessReceivedData(CAData_t *data)
419 {
420     OIC_LOG(DEBUG, TAG, "CAProcessReceivedData IN");
421     if (!data)
422     {
423         OIC_LOG(ERROR, TAG, "thread data error!!");
424         return;
425     }
426
427     // parse the data and call the callbacks.
428     // #1 parse the data
429     // #2 get endpoint
430     CAEndpoint_t *rep = (CAEndpoint_t *)(data->remoteEndpoint);
431     if (!rep)
432     {
433         OIC_LOG(ERROR, TAG, "remoteEndpoint error!!");
434         return;
435     }
436
437     if (data->requestInfo && g_requestHandler)
438     {
439         g_requestHandler(rep, data->requestInfo);
440     }
441     else if (data->responseInfo && g_responseHandler)
442     {
443         g_responseHandler(rep, data->responseInfo);
444     }
445     else if (data->errorInfo && g_errorHandler)
446     {
447         g_errorHandler(rep, data->errorInfo);
448     }
449
450     CADestroyData(data, sizeof(CAData_t));
451
452     OIC_LOG(DEBUG, TAG, "CAProcessReceivedData OUT");
453 }
454 #endif
455
456 #ifndef SINGLE_THREAD
457 static void CAReceiveThreadProcess(void *threadData)
458 {
459 #ifndef SINGLE_HANDLE
460     CAData_t *data = (CAData_t *) threadData;
461     OIC_TRACE_BEGIN(%s:CAProcessReceivedData, TAG);
462     CAProcessReceivedData(data);
463     OIC_TRACE_END();
464 #else
465     (void)threadData;
466 #endif
467 }
468 #endif // SINGLE_THREAD
469
470 static CAResult_t CAProcessMulticastData(const CAData_t *data)
471 {
472     VERIFY_NON_NULL(data, TAG, "data");
473     VERIFY_NON_NULL(data->remoteEndpoint, TAG, "remoteEndpoint");
474
475     coap_pdu_t *pdu = NULL;
476     CAInfo_t *info = NULL;
477     coap_list_t *options = NULL;
478     coap_transport_t transport = COAP_UDP;
479     CAResult_t res = CA_SEND_FAILED;
480
481     if (!data->requestInfo && !data->responseInfo)
482     {
483         OIC_LOG(ERROR, TAG, "request or response info is empty");
484         return res;
485     }
486
487     if (data->requestInfo)
488     {
489         OIC_LOG(DEBUG, TAG, "requestInfo is available..");
490
491         info = &data->requestInfo->info;
492         pdu = CAGeneratePDU(CA_GET, info, data->remoteEndpoint, &options, &transport);
493     }
494     else if (data->responseInfo)
495     {
496         OIC_LOG(DEBUG, TAG, "responseInfo is available..");
497
498         info = &data->responseInfo->info;
499         pdu = CAGeneratePDU(data->responseInfo->result, info, data->remoteEndpoint,
500                             &options, &transport);
501     }
502
503     if (!pdu)
504     {
505         OIC_LOG(ERROR,TAG,"Failed to generate multicast PDU");
506         CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED);
507         coap_delete_list(options);
508         return res;
509     }
510
511 #ifdef WITH_BWT
512     if (CAIsSupportedBlockwiseTransfer(data->remoteEndpoint->adapter))
513     {
514         // Blockwise transfer
515         res = CAAddBlockOption(&pdu, info, data->remoteEndpoint, &options);
516         if (CA_STATUS_OK != res)
517         {
518             OIC_LOG(DEBUG, TAG, "CAAddBlockOption has failed");
519             goto exit;
520         }
521     }
522 #endif // WITH_BWT
523
524     CALogPDUInfo(data, pdu);
525
526     res = CASendMulticastData(data->remoteEndpoint, pdu->transport_hdr, pdu->length, data->dataType);
527     if (CA_STATUS_OK != res)
528     {
529         OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
530         goto exit;
531     }
532
533     coap_delete_list(options);
534     coap_delete_pdu(pdu);
535     return res;
536
537 exit:
538     CAErrorHandler(data->remoteEndpoint, pdu->transport_hdr, pdu->length, res);
539     coap_delete_list(options);
540     coap_delete_pdu(pdu);
541     return res;
542 }
543
544 static CAResult_t CAProcessSendData(const CAData_t *data)
545 {
546     VERIFY_NON_NULL(data, TAG, "data");
547     VERIFY_NON_NULL(data->remoteEndpoint, TAG, "remoteEndpoint");
548
549     CAResult_t res = CA_STATUS_FAILED;
550
551     if (CA_NETWORK_COMMAND == data->dataType)
552     {
553         if (CA_REQ_DISCONNECT == data->eventInfo)
554         {
555 #ifdef TCP_ADAPTER
556             // request TCP disconnect
557             if (CA_ADAPTER_TCP == data->remoteEndpoint->adapter)
558             {
559                 OIC_LOG(INFO, TAG, "request TCP disconnect");
560                 return CADisconnectSession(data->remoteEndpoint);
561             }
562 #endif
563         }
564     }
565
566     CASendDataType_t type = data->type;
567
568     coap_pdu_t *pdu = NULL;
569     CAInfo_t *info = NULL;
570     coap_list_t *options = NULL;
571     coap_transport_t transport = COAP_UDP;
572
573     if (SEND_TYPE_UNICAST == type)
574     {
575         OIC_LOG(DEBUG,TAG,"Unicast message");
576
577 #ifdef ROUTING_GATEWAY
578         /*
579          * When forwarding a packet, do not attempt retransmission as its the responsibility of
580          * packet originator node
581          */
582         bool skipRetransmission = false;
583 #endif
584
585         if (NULL != data->requestInfo)
586         {
587             OIC_LOG(DEBUG, TAG, "requestInfo is available..");
588
589             info = &data->requestInfo->info;
590 #ifdef ROUTING_GATEWAY
591             skipRetransmission = data->requestInfo->info.skipRetransmission;
592 #endif
593             pdu = CAGeneratePDU(data->requestInfo->method, info, data->remoteEndpoint,
594                                 &options, &transport);
595         }
596         else if (NULL != data->responseInfo)
597         {
598             OIC_LOG(DEBUG, TAG, "responseInfo is available..");
599
600             info = &data->responseInfo->info;
601 #ifdef ROUTING_GATEWAY
602             skipRetransmission = data->responseInfo->info.skipRetransmission;
603 #endif
604             pdu = CAGeneratePDU(data->responseInfo->result, info, data->remoteEndpoint,
605                                 &options, &transport);
606         }
607         else
608         {
609             OIC_LOG(DEBUG, TAG, "request info, response info is empty");
610             return CA_STATUS_INVALID_PARAM;
611         }
612
613         // interface controller function call.
614         if (NULL != pdu)
615         {
616 #ifdef WITH_BWT
617             if (CAIsSupportedBlockwiseTransfer(data->remoteEndpoint->adapter))
618             {
619                 // Blockwise transfer
620                 if (NULL != info)
621                 {
622                     CAResult_t res = CAAddBlockOption(&pdu, info,
623                                                       data->remoteEndpoint,
624                                                       &options);
625                     if (CA_STATUS_OK != res)
626                     {
627                         OIC_LOG(INFO, TAG, "to write block option has failed");
628                         CAErrorHandler(data->remoteEndpoint, pdu->transport_hdr, pdu->length, res);
629                         coap_delete_list(options);
630                         coap_delete_pdu(pdu);
631                         return res;
632                     }
633                 }
634             }
635 #endif // WITH_BWT
636             CALogPDUInfo(data, pdu);
637
638             OIC_LOG_V(INFO, TAG, "CASendUnicastData type : %d", data->dataType);
639             res = CASendUnicastData(data->remoteEndpoint, pdu->transport_hdr, pdu->length, data->dataType);
640             if (CA_STATUS_OK != res)
641             {
642                 OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
643                 CAErrorHandler(data->remoteEndpoint, pdu->transport_hdr, pdu->length, res);
644                 coap_delete_list(options);
645                 coap_delete_pdu(pdu);
646                 return res;
647             }
648
649 #ifdef WITH_TCP
650             if (CAIsSupportedCoAPOverTCP(data->remoteEndpoint->adapter))
651             {
652                 OIC_LOG(INFO, TAG, "retransmission will be not worked");
653             }
654             else
655 #endif
656 #ifdef ROUTING_GATEWAY
657             if (!skipRetransmission)
658 #endif
659             {
660                 // for retransmission
661                 res = CARetransmissionSentData(&g_retransmissionContext,
662                                                data->remoteEndpoint,
663                                                data->dataType,
664                                                pdu->transport_hdr, pdu->length);
665                 if ((CA_STATUS_OK != res) && (CA_NOT_SUPPORTED != res))
666                 {
667                     //when retransmission not supported this will return CA_NOT_SUPPORTED, ignore
668                     OIC_LOG_V(INFO, TAG, "retransmission is not enabled due to error, res : %d", res);
669                     coap_delete_list(options);
670                     coap_delete_pdu(pdu);
671                     return res;
672                 }
673             }
674
675             coap_delete_list(options);
676             coap_delete_pdu(pdu);
677         }
678         else
679         {
680             OIC_LOG(ERROR,TAG,"Failed to generate unicast PDU");
681             CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED);
682             return CA_SEND_FAILED;
683         }
684     }
685     else if (SEND_TYPE_MULTICAST == type)
686     {
687         OIC_LOG(DEBUG,TAG,"Multicast message");
688 #ifdef WITH_TCP
689         /*
690          * If CoAP over TCP is enabled, the CoAP pdu wont be same for IP and other adapters.
691          * That's why we need to generate two pdu's, one for IP and second for other transports.
692          * Two possible cases we might have to split: a) when adapter is CA_DEFAULT_ADAPTER
693          * b) when one of the adapter is IP adapter(ex: CA_ADAPTER_IP | CA_ADAPTER_GATT_BTLE)
694          */
695         if (data->remoteEndpoint->adapter == CA_DEFAULT_ADAPTER ||
696                 (CA_ADAPTER_IP & data->remoteEndpoint->adapter &&
697                     CA_ADAPTER_IP != data->remoteEndpoint->adapter))
698         {
699             if (data->remoteEndpoint->adapter == CA_DEFAULT_ADAPTER)
700             {
701                 data->remoteEndpoint->adapter = CA_ALL_ADAPTERS ^ CA_ADAPTER_IP;
702             }
703             else
704             {
705                 data->remoteEndpoint->adapter = data->remoteEndpoint->adapter ^ CA_ADAPTER_IP;
706             }
707             CAProcessMulticastData(data);
708             data->remoteEndpoint->adapter = CA_ADAPTER_IP;
709             CAProcessMulticastData(data);
710         }
711         else
712         {
713             CAProcessMulticastData(data);
714         }
715 #else
716         CAProcessMulticastData(data);
717 #endif
718     }
719     return CA_STATUS_OK;
720 }
721
722 #ifndef SINGLE_THREAD
723 static void CASendThreadProcess(void *threadData)
724 {
725     CAData_t *data = (CAData_t *) threadData;
726     OIC_TRACE_BEGIN(%s:CAProcessSendData, TAG);
727     CAProcessSendData(data);
728     OIC_TRACE_END();
729 }
730 #endif
731
732 /*
733  * If a second message arrives with the same message ID, token and the other address
734  * family, drop it.  Typically, IPv6 beats IPv4, so the IPv4 message is dropped.
735  */
736 static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *ep, uint16_t id,
737                                 CAToken_t token, uint8_t tokenLength)
738 {
739     if (!ep)
740     {
741         return true;
742     }
743     if (ep->adapter != CA_ADAPTER_IP)
744     {
745         return false;
746     }
747     if (!caglobals.ip.dualstack)
748     {
749         return false;
750     }
751     if (!history)
752     {
753         return false;
754     }
755     if (tokenLength > CA_MAX_TOKEN_LEN)
756     {
757         /*
758          * If token length is more than CA_MAX_TOKEN_LEN,
759          * we compare the first CA_MAX_TOKEN_LEN bytes only.
760          */
761         tokenLength = CA_MAX_TOKEN_LEN;
762     }
763
764     bool ret = false;
765     CATransportFlags_t familyFlags = ep->flags & CA_IPFAMILY_MASK;
766
767     for (size_t i = 0; i < sizeof(history->items) / sizeof(history->items[0]); i++)
768     {
769         CAHistoryItem_t *item = &(history->items[i]);
770         if (id == item->messageId && tokenLength == item->tokenLength
771             && memcmp(item->token, token, tokenLength) == 0)
772         {
773             if ((familyFlags ^ item->flags) == CA_IPFAMILY_MASK)
774             {
775                 OIC_LOG_V(INFO, TAG, "IPv%c duplicate message ignored",
776                           familyFlags & CA_IPV6 ? '6' : '4');
777                 ret = true;
778                 break;
779             }
780         }
781     }
782
783     history->items[history->nextIndex].flags = familyFlags;
784     history->items[history->nextIndex].messageId = id;
785     if (token && tokenLength)
786     {
787         memcpy(history->items[history->nextIndex].token, token, tokenLength);
788         history->items[history->nextIndex].tokenLength = tokenLength;
789     }
790
791     if (++history->nextIndex >= HISTORYSIZE)
792     {
793         history->nextIndex = 0;
794     }
795
796     return ret;
797 }
798
799 static CAResult_t CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
800                                            const void *data, uint32_t dataLen)
801 {
802     VERIFY_NON_NULL(sep, TAG, "remoteEndpoint");
803     VERIFY_NON_NULL(data, TAG, "data");
804     OIC_TRACE_BEGIN(%s:CAReceivedPacketCallback, TAG);
805
806     if (0 == dataLen)
807     {
808         OIC_LOG(ERROR, TAG, "dataLen is zero");
809         OIC_TRACE_END();
810
811         return CA_STATUS_FAILED;
812     }
813
814     // samsung log
815     OIC_LOG(DEBUG, TAG, "received pdu data :");
816     if (dataLen < 32)
817     {
818         OIC_LOG_BUFFER(DEBUG, TAG,  data, dataLen);
819     }
820     else
821     {
822         OIC_LOG_BUFFER(DEBUG, TAG,  data, 32);
823     }
824
825     CAResult_t res = CA_STATUS_OK;
826     uint32_t code = CA_NOT_FOUND;
827     CAData_t *cadata = NULL;
828
829     coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code,
830                                                 &(sep->endpoint));
831     if (NULL == pdu)
832     {
833         OIC_LOG(ERROR, TAG, "Parse PDU failed");
834         res = CA_STATUS_FAILED;
835         goto exit;
836     }
837
838     OIC_LOG_V(DEBUG, TAG, "code = %d", code);
839     if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
840     {
841         cadata = CAGenerateHandlerData(&(sep->endpoint), &(sep->identity), pdu, CA_REQUEST_DATA);
842         if (!cadata)
843         {
844             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
845             coap_delete_pdu(pdu);
846             goto exit;
847         }
848     }
849     else
850     {
851         cadata = CAGenerateHandlerData(&(sep->endpoint), &(sep->identity), pdu, CA_RESPONSE_DATA);
852         if (!cadata)
853         {
854             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
855             coap_delete_pdu(pdu);
856             goto exit;
857         }
858
859 #ifdef WITH_TCP
860         if (CAIsSupportedCoAPOverTCP(sep->endpoint.adapter))
861         {
862             OIC_LOG(INFO, TAG, "retransmission is not supported");
863         }
864         else
865 #endif
866         {
867             // for retransmission
868             void *retransmissionPdu = NULL;
869             CARetransmissionReceivedData(&g_retransmissionContext, cadata->remoteEndpoint, pdu->transport_hdr,
870                                          pdu->length, &retransmissionPdu);
871
872             // get token from saved data in retransmission list
873             if (retransmissionPdu && CA_EMPTY == code)
874             {
875                 if (cadata->responseInfo)
876                 {
877                     CAInfo_t *info = &cadata->responseInfo->info;
878                     CAResult_t res = CAGetTokenFromPDU((const coap_hdr_transport_t *)retransmissionPdu,
879                                                        info, &(sep->endpoint));
880                     if (CA_STATUS_OK != res)
881                     {
882                         OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
883                         OICFree(info->token);
884                         info->token = NULL;
885                         info->tokenLength = 0;
886                     }
887                 }
888             }
889             OICFree(retransmissionPdu);
890         }
891     }
892
893     cadata->type = SEND_TYPE_UNICAST;
894
895     CALogPDUInfo(cadata, pdu);
896
897 #ifdef SINGLE_THREAD
898     CAProcessReceivedData(cadata);
899 #else
900 #ifdef WITH_BWT
901     if (CAIsSupportedBlockwiseTransfer(sep->endpoint.adapter))
902     {
903         CAResult_t res = CAReceiveBlockWiseData(pdu, &(sep->endpoint), cadata, dataLen);
904         if (CA_NOT_SUPPORTED == res || CA_REQUEST_TIMEOUT == res)
905         {
906             OIC_LOG(DEBUG, TAG, "this message does not have block option");
907             CAAddDataToReceiveThread(cadata);
908         }
909         else
910         {
911             CADestroyData(cadata, sizeof(CAData_t));
912         }
913     }
914     else
915 #endif
916     {
917         CAResult_t result = CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t), false);
918         if (result != CA_STATUS_OK)
919         {
920             OIC_LOG(ERROR, TAG, "Failed to add message to data queue!");
921             CADestroyData(cadata, sizeof(CAData_t));
922             coap_delete_pdu(pdu);
923             goto exit;
924         }
925
926 #ifdef WITH_PROCESS_EVENT
927         if (g_processEvent)
928         {
929             oc_event_signal(g_processEvent);
930         }
931 #endif
932     }
933 #endif // SINGLE_THREAD
934
935     coap_delete_pdu(pdu);
936
937 exit:
938     OIC_LOG(DEBUG, TAG, "OUT - Recv Thread");
939     OIC_TRACE_END();
940     return res;
941 }
942
943 static void CAAdapterStateChangedCallback(CATransportAdapter_t transportType, bool enabled)
944 {
945     if (!enabled)
946     {
947         CAClearMessageHandler(transportType);
948     }
949 }
950
951 static bool CAClearQueueEndpointDataContext(void *data, uint32_t size, void *ctx)
952 {
953     UNUSED(size);
954     if (NULL == data || NULL == ctx)
955     {
956         return false;
957     }
958
959     CAData_t *caData = (CAData_t *)data;
960     const CAEndpoint_t *endpoint = (const CAEndpoint_t *)ctx;
961
962     if (NULL != caData && NULL != caData->remoteEndpoint)
963     {
964         if (strcmp(caData->remoteEndpoint->addr, endpoint->addr) == 0
965             && caData->remoteEndpoint->port == endpoint->port
966             && caData->remoteEndpoint->adapter == endpoint->adapter)
967         {
968             return true;
969         }
970     }
971     return false;
972 }
973
974 static void CAConnectionStateChangedCallback(const CAEndpoint_t *info, bool isConnected)
975 {
976     if (!isConnected)
977     {
978         CAResult_t res = CAQueueingThreadClearContextData(&g_sendThread,
979                                                           CAClearQueueEndpointDataContext,
980                                                           (void *)info);
981         if (CA_STATUS_OK != res)
982         {
983             OIC_LOG(ERROR, TAG, "Could not clear the send queue");
984         }
985     }
986 }
987
988 static u_queue_message_t *get_receive_queue_item(void)
989 {
990     u_queue_message_t *item = NULL;
991
992     oc_mutex_lock(g_receiveThread.threadMutex);
993     item = u_queue_get_element(g_receiveThread.dataQueue);
994     oc_mutex_unlock(g_receiveThread.threadMutex);
995
996     return item;
997 }
998
999
1000 void CAHandleRequestResponseCallbacks()
1001 {
1002 #ifdef SINGLE_THREAD
1003     CAReadData();
1004     CARetransmissionBaseRoutine((void *)&g_retransmissionContext);
1005 #else
1006 #ifdef SINGLE_HANDLE
1007     // parse the data and call the callbacks.
1008     // #1 parse the data
1009     // #2 get endpoint
1010
1011     u_queue_message_t *item = NULL;
1012 #ifdef WITH_PROCESS_EVENT
1013     while ((item = get_receive_queue_item()) != NULL)
1014 #else
1015     if ((item = get_receive_queue_item()) != NULL)
1016 #endif
1017     {        if (NULL == item->msg)
1018         {
1019             OICFree(item);
1020 #ifdef WITH_PROCESS_EVENT
1021             continue;
1022 #else
1023             return;
1024 #endif
1025         }
1026
1027         // get endpoint
1028         CAData_t *td = (CAData_t *) item->msg;
1029
1030         if (td->requestInfo && g_requestHandler)
1031         {
1032             OIC_LOG_V(DEBUG, TAG, "request callback : %d", td->requestInfo->info.numOptions);
1033             g_requestHandler(td->remoteEndpoint, td->requestInfo);
1034         }
1035         else if (td->responseInfo && g_responseHandler)
1036         {
1037             OIC_LOG_V(DEBUG, TAG, "response callback : %d", td->responseInfo->info.numOptions);
1038             g_responseHandler(td->remoteEndpoint, td->responseInfo);
1039         }
1040         else if (td->errorInfo && g_errorHandler)
1041         {
1042             OIC_LOG_V(DEBUG, TAG, "error callback error: %d", td->errorInfo->result);
1043             g_errorHandler(td->remoteEndpoint, td->errorInfo);
1044         }
1045
1046         CADestroyData(item->msg, sizeof(CAData_t));
1047         OICFree(item);
1048     }
1049 #endif // SINGLE_HANDLE
1050 #endif // SINGLE_THREAD
1051 }
1052
1053 static CAData_t* CAPrepareSendData(const CAEndpoint_t *endpoint, const void *sendData,
1054                                    CADataType_t dataType)
1055 {
1056     OIC_LOG(DEBUG, TAG, "CAPrepareSendData IN");
1057
1058     CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
1059     if (!cadata)
1060     {
1061         OIC_LOG(ERROR, TAG, "memory allocation failed");
1062         return NULL;
1063     }
1064
1065     if (CA_REQUEST_DATA == dataType)
1066     {
1067 #ifdef SINGLE_THREAD
1068         CARequestInfo_t *request = (CARequestInfo_t *)sendData;
1069 #else
1070         // clone request info
1071         CARequestInfo_t *request = CACloneRequestInfo((CARequestInfo_t *)sendData);
1072         if (!request)
1073         {
1074             OIC_LOG(ERROR, TAG, "CACloneRequestInfo failed");
1075             goto exit;
1076         }
1077 #endif
1078         cadata->type = request->isMulticast ? SEND_TYPE_MULTICAST : SEND_TYPE_UNICAST;
1079         cadata->requestInfo =  request;
1080     }
1081     else if (CA_RESPONSE_DATA == dataType || CA_RESPONSE_FOR_RES == dataType)
1082     {
1083 #ifdef SINGLE_THREAD
1084         CAResponseInfo_t *response = (CAResponseInfo_t *)sendData;
1085 #else
1086         // clone response info
1087         CAResponseInfo_t *response = CACloneResponseInfo((CAResponseInfo_t *)sendData);
1088         if (!response)
1089         {
1090             OIC_LOG(ERROR, TAG, "CACloneResponseInfo failed");
1091             goto exit;
1092         }
1093 #endif
1094         cadata->type = response->isMulticast ? SEND_TYPE_MULTICAST : SEND_TYPE_UNICAST;
1095         cadata->responseInfo = response;
1096     }
1097     else
1098     {
1099         OIC_LOG(ERROR, TAG, "CAPrepareSendData unknown data type");
1100         goto exit;
1101     }
1102
1103 #ifdef SINGLE_THREAD
1104     CAEndpoint_t* ep = endpoint;
1105 #else
1106     CAEndpoint_t* ep = CACloneEndpoint(endpoint);
1107     if (!ep)
1108     {
1109         OIC_LOG(ERROR, TAG, "endpoint clone failed");
1110         goto exit;
1111     }
1112 #endif
1113     cadata->remoteEndpoint = ep;
1114     cadata->dataType = dataType;
1115     return cadata;
1116
1117 exit:
1118 #ifndef SINGLE_THREAD
1119     CADestroyData(cadata, sizeof(CAData_t));
1120 #else
1121     OICFree(cadata);
1122 #endif
1123     return NULL;
1124 }
1125
1126 CAResult_t CADetachSendNetworkReqMessage(const CAEndpoint_t *endpoint,
1127                                          CAConnectEvent_t event,
1128                                          CADataType_t dataType)
1129 {
1130     VERIFY_NON_NULL(endpoint, TAG, "endpoint");
1131
1132     if (false == CAIsSelectedNetworkAvailable())
1133     {
1134         return CA_STATUS_FAILED;
1135     }
1136
1137 #ifndef SINGLE_THREAD
1138     CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
1139     if (!cadata)
1140     {
1141         OIC_LOG(ERROR, TAG, "cadata memory allocation failed");
1142         return CA_MEMORY_ALLOC_FAILED;
1143     }
1144
1145     CAEndpoint_t* ep = CACloneEndpoint(endpoint);
1146     if (!ep)
1147     {
1148         OIC_LOG(ERROR, TAG, "endpoint clone failed");
1149         OICFree(cadata);
1150         return CA_MEMORY_ALLOC_FAILED;
1151     }
1152
1153     cadata->remoteEndpoint = ep;
1154     cadata->eventInfo = event;
1155     cadata->dataType = dataType;
1156
1157     CAResult_t result = CAQueueingThreadAddData(&g_sendThread, cadata, sizeof(CAData_t), true);
1158     if (result != CA_STATUS_OK)
1159     {
1160         OIC_LOG(ERROR, TAG, "Failed to add message to data queue!");
1161         CADestroyData(cadata, sizeof(CAData_t));
1162         return result;
1163     }
1164 #endif
1165
1166     return CA_STATUS_OK;
1167 }
1168
1169 CAResult_t CADetachSendMessage(const CAEndpoint_t *endpoint, const void *sendMsg,
1170                                CADataType_t dataType)
1171 {
1172     VERIFY_NON_NULL(endpoint, TAG, "endpoint");
1173     VERIFY_NON_NULL(sendMsg, TAG, "sendMsg");
1174
1175     if (false == CAIsSelectedNetworkAvailable())
1176     {
1177         return CA_STATUS_FAILED;
1178     }
1179
1180 #ifdef ARDUINO
1181     // If max retransmission queue is reached, then don't handle new request
1182     if (CA_MAX_RT_ARRAY_SIZE == u_arraylist_length(g_retransmissionContext.dataList))
1183     {
1184         OIC_LOG(ERROR, TAG, "max RT queue size reached!");
1185         return CA_SEND_FAILED;
1186     }
1187 #endif // ARDUINO
1188
1189     CAData_t *data = CAPrepareSendData(endpoint, sendMsg, dataType);
1190     if(!data)
1191     {
1192         OIC_LOG(ERROR, TAG, "CAPrepareSendData failed");
1193         return CA_MEMORY_ALLOC_FAILED;
1194     }
1195
1196     OIC_LOG_V(INFO_PRIVATE, TAG, "DID of endpoint of this message is %s", endpoint->remoteId);
1197
1198 #ifdef SINGLE_THREAD
1199     CAResult_t result = CAProcessSendData(data);
1200     if (CA_STATUS_OK != result)
1201     {
1202         OIC_LOG(ERROR, TAG, "CAProcessSendData failed");
1203         OICFree(data);
1204         return result;
1205     }
1206
1207     OICFree(data);
1208
1209 #else
1210 #ifdef WITH_BWT
1211     if (CAIsSupportedBlockwiseTransfer(endpoint->adapter))
1212     {
1213         CACheckAndDeleteTimedOutBlockData();
1214         // send block data
1215         CAResult_t res = CASendBlockWiseData(data);
1216         if (CA_NOT_SUPPORTED == res)
1217         {
1218             OIC_LOG(DEBUG, TAG, "normal msg will be sent");
1219             CAResult_t result = CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t), true);
1220             if (result != CA_STATUS_OK)
1221             {
1222                 OIC_LOG(ERROR, TAG, "Failed to add message to data queue!");
1223                 CADestroyData(data, sizeof(CAData_t));
1224                 return result;
1225             }
1226             return CA_STATUS_OK;
1227         }
1228         else
1229         {
1230             CADestroyData(data, sizeof(CAData_t));
1231         }
1232
1233         return res;
1234     }
1235     else
1236 #endif // WITH_BWT
1237     {
1238         CAResult_t result = CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t), true);
1239         if (result != CA_STATUS_OK)
1240         {
1241             OIC_LOG(ERROR, TAG, "Failed to add message to data queue!");
1242             CADestroyData(data, sizeof(CAData_t));
1243             return result;
1244         }
1245     }
1246 #endif // SINGLE_THREAD
1247
1248     return CA_STATUS_OK;
1249 }
1250
1251 void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
1252                              CAErrorCallback errorHandler)
1253 {
1254     g_requestHandler = ReqHandler;
1255     g_responseHandler = RespHandler;
1256     g_errorHandler = errorHandler;
1257 }
1258
1259 void CASetNetworkMonitorCallback(CANetworkMonitorCallback nwMonitorHandler)
1260 {
1261     g_nwMonitorHandler = nwMonitorHandler;
1262 }
1263
1264 CAResult_t CAInitializeMessageHandler(CATransportAdapter_t transportType)
1265 {
1266     CASetPacketReceivedCallback((CANetworkPacketReceivedCallback)CAReceivedPacketCallback);
1267     CASetErrorHandleCallback((CAErrorHandleCallback)CAErrorHandler);
1268
1269 #ifndef SINGLE_THREAD
1270     // create thread pool
1271     CAResult_t res = ca_thread_pool_init(MAX_THREAD_POOL_SIZE, &g_threadPoolHandle);
1272     if (CA_STATUS_OK != res)
1273     {
1274         OIC_LOG(ERROR, TAG, "thread pool initialize error.");
1275         return res;
1276     }
1277
1278     // send thread initialize
1279     res = CAQueueingThreadInitialize(&g_sendThread, g_threadPoolHandle,
1280                                      CASendThreadProcess, CADestroyData);
1281     if (CA_STATUS_OK != res)
1282     {
1283         OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
1284         return res;
1285     }
1286
1287     // start send thread
1288 #ifndef __TIZENRT__
1289     res = CAQueueingThreadStart(&g_sendThread);
1290 #else
1291     res = CAQueueingThreadStart(&g_sendThread, "IoT_MessageHandlerQueue");
1292 #endif
1293     if (CA_STATUS_OK != res)
1294     {
1295         OIC_LOG(ERROR, TAG, "thread start error(send thread).");
1296         return res;
1297     }
1298
1299     // receive thread initialize
1300     res = CAQueueingThreadInitialize(&g_receiveThread, g_threadPoolHandle,
1301                                      CAReceiveThreadProcess, CADestroyData);
1302     if (CA_STATUS_OK != res)
1303     {
1304         OIC_LOG(ERROR, TAG, "Failed to Initialize receive queue thread");
1305         return res;
1306     }
1307
1308 #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading
1309     // start receive thread
1310     res = CAQueueingThreadStart(&g_receiveThread);
1311     if (CA_STATUS_OK != res)
1312     {
1313         OIC_LOG(ERROR, TAG, "thread start error(receive thread).");
1314         return res;
1315     }
1316 #endif // SINGLE_HANDLE
1317
1318     // retransmission initialize
1319     res = CARetransmissionInitialize(&g_retransmissionContext, g_threadPoolHandle,
1320                                      CASendUnicastData, CATimeoutCallback, NULL);
1321     if (CA_STATUS_OK != res)
1322     {
1323         OIC_LOG(ERROR, TAG, "Failed to Initialize Retransmission.");
1324         return res;
1325     }
1326
1327 #ifdef WITH_BWT
1328     // block-wise transfer initialize
1329     res = CAInitializeBlockWiseTransfer(CAAddDataToSendThread, CAAddDataToReceiveThread);
1330     if (CA_STATUS_OK != res)
1331     {
1332         OIC_LOG(ERROR, TAG, "Failed to Initialize BlockWiseTransfer.");
1333         return res;
1334     }
1335 #endif
1336
1337     // start retransmission
1338     res = CARetransmissionStart(&g_retransmissionContext);
1339     if (CA_STATUS_OK != res)
1340     {
1341         OIC_LOG(ERROR, TAG, "thread start error(retransmission thread).");
1342         return res;
1343     }
1344
1345     // initialize interface adapters by controller
1346     CAInitializeAdapters(g_threadPoolHandle, transportType);
1347     CASetNetworkMonitorCallbacks(CAAdapterStateChangedCallback, CAConnectionStateChangedCallback);
1348 #else
1349     // retransmission initialize
1350     CAResult_t res = CARetransmissionInitialize(&g_retransmissionContext, NULL, CASendUnicastData,
1351                                                 CATimeoutCallback, NULL);
1352     if (CA_STATUS_OK != res)
1353     {
1354         OIC_LOG(ERROR, TAG, "Failed to Initialize Retransmission.");
1355         return res;
1356     }
1357
1358     CAInitializeAdapters();
1359 #endif // SINGLE_THREAD
1360
1361     return CA_STATUS_OK;
1362 }
1363
1364 static bool CAClearQueueAdapterDataContext(void *data, uint32_t size, void *ctx)
1365 {
1366     (void)size;
1367
1368     if (NULL == data || NULL == ctx)
1369     {
1370         return false;
1371     }
1372
1373     CAData_t *caData = (CAData_t *)data;
1374     CATransportAdapter_t *type = (CATransportAdapter_t *)ctx;
1375
1376     if (NULL != caData && NULL != caData->remoteEndpoint
1377         && caData->remoteEndpoint->adapter == *type)
1378     {
1379         return true;
1380     }
1381     return false;
1382 }
1383
1384 void CAClearMessageHandler(CATransportAdapter_t transportType)
1385 {
1386     CATransportAdapter_t *typeCtx = &transportType;
1387
1388     CAResult_t res = CAQueueingThreadClearContextData(&g_sendThread,
1389                                                       CAClearQueueAdapterDataContext,
1390                                                       typeCtx);
1391
1392     if (res != CA_STATUS_OK)
1393     {
1394         OIC_LOG_V(ERROR, TAG, "Clear send data failed[%d]", res);
1395     }
1396
1397     if (transportType & DEFAULT_RETRANSMISSION_TYPE)
1398     {
1399         res = CARetransmissionClearAdapterData(&g_retransmissionContext, transportType);
1400         if (res != CA_STATUS_OK)
1401         {
1402             OIC_LOG_V(ERROR, TAG, "Clear retransmission data failed[%d]", res);
1403         }
1404     }
1405 }
1406
1407 void CATerminateMessageHandler()
1408 {
1409 #ifndef SINGLE_THREAD
1410     CATransportAdapter_t connType;
1411     u_arraylist_t *list = CAGetSelectedNetworkList();
1412     uint32_t length = u_arraylist_length(list);
1413
1414  #ifdef WITH_PROCESS_EVENT
1415     g_processEvent = NULL;
1416 #endif
1417
1418     uint32_t i = 0;
1419     for (i = 0; i < length; i++)
1420     {
1421         void* ptrType = u_arraylist_get(list, i);
1422
1423         if (NULL == ptrType)
1424         {
1425             continue;
1426         }
1427
1428         connType = *(CATransportAdapter_t *)ptrType;
1429         CAStopAdapter(connType);
1430     }
1431
1432     // stop retransmission
1433     if (NULL != g_retransmissionContext.threadMutex)
1434     {
1435         CARetransmissionStop(&g_retransmissionContext);
1436     }
1437
1438     // stop thread
1439     // delete thread data
1440     if (NULL != g_sendThread.threadMutex)
1441     {
1442         CAQueueingThreadStop(&g_sendThread);
1443     }
1444
1445     // stop thread
1446     // delete thread data
1447     if (NULL != g_receiveThread.threadMutex)
1448     {
1449 #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading
1450         CAQueueingThreadStop(&g_receiveThread);
1451 #endif
1452     }
1453
1454     // destroy thread pool
1455     if (NULL != g_threadPoolHandle)
1456     {
1457         ca_thread_pool_free(g_threadPoolHandle);
1458         g_threadPoolHandle = NULL;
1459     }
1460
1461 #ifdef WITH_BWT
1462     CATerminateBlockWiseTransfer();
1463 #endif
1464     CARetransmissionDestroy(&g_retransmissionContext);
1465     CAQueueingThreadDestroy(&g_sendThread);
1466     CAQueueingThreadDestroy(&g_receiveThread);
1467
1468     // terminate interface adapters by controller
1469     CATerminateAdapters();
1470 #else
1471     // terminate interface adapters by controller
1472     CATerminateAdapters();
1473
1474     // stop retransmission
1475     CARetransmissionStop(&g_retransmissionContext);
1476     CARetransmissionDestroy(&g_retransmissionContext);
1477 #endif // SINGLE_THREAD
1478 }
1479
1480 static void CALogPayloadInfo(CAInfo_t *info)
1481 {
1482     if (info)
1483     {
1484         if (info->options)
1485         {
1486             for (uint32_t i = 0; i < info->numOptions; i++)
1487             {
1488                 OIC_LOG_V(DEBUG, TAG, "optionID: %u", info->options[i].optionID);
1489
1490                 OIC_LOG_V(DEBUG, TAG, "list: %s", info->options[i].optionData);
1491             }
1492         }
1493
1494         if (info->payload)
1495         {
1496             OIC_LOG_V(DEBUG, TAG, "payload: %p(%zu)", info->payload,
1497                       info->payloadSize);
1498         }
1499
1500         if (info->token)
1501         {
1502             OIC_LOG(DEBUG, TAG, "token:");
1503             OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) info->token,
1504                            info->tokenLength);
1505         }
1506         OIC_LOG_V(DEBUG, TAG, "msgID: %u", info->messageId);
1507     }
1508     else
1509     {
1510         OIC_LOG(DEBUG, TAG, "info is NULL, cannot output log data");
1511     }
1512 }
1513
1514 void CAErrorHandler(const CAEndpoint_t *endpoint,
1515                     const void *data, uint32_t dataLen,
1516                     CAResult_t result)
1517 {
1518     OIC_LOG(DEBUG, TAG, "CAErrorHandler IN");
1519     VERIFY_NON_NULL_VOID(endpoint, TAG, "remoteEndpoint");
1520     VERIFY_NON_NULL_VOID(data, TAG, "data");
1521
1522     if (0 == dataLen)
1523     {
1524         OIC_LOG(ERROR, TAG, "dataLen is zero");
1525         return;
1526     }
1527
1528 #ifndef SINGLE_THREAD
1529     uint32_t code = CA_NOT_FOUND;
1530     //Do not free remoteEndpoint and data. Currently they will be freed in data thread
1531     //Get PDU data
1532     coap_pdu_t *pdu = (coap_pdu_t *)CAParsePDU((const char *)data, dataLen, &code, endpoint);
1533     if (NULL == pdu)
1534     {
1535         OIC_LOG(ERROR, TAG, "Parse PDU failed");
1536         return;
1537     }
1538
1539     CAData_t *cadata = CAGenerateHandlerData(endpoint, NULL, pdu, CA_ERROR_DATA);
1540     if (!cadata)
1541     {
1542         OIC_LOG(ERROR, TAG, "CAErrorHandler, CAGenerateHandlerData failed!");
1543         coap_delete_pdu(pdu);
1544         return;
1545     }
1546
1547     cadata->errorInfo->result = result;
1548
1549     CAResult_t res = CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t), false);
1550     if (res != CA_STATUS_OK)
1551     {
1552         OIC_LOG(ERROR, TAG, "Failed to add message to data queue!");
1553         CADestroyData(cadata, sizeof(CAData_t));
1554         coap_delete_pdu(pdu);
1555         return;
1556     }
1557
1558 #ifdef WITH_PROCESS_EVENT
1559     if (g_processEvent)
1560     {
1561         oc_event_signal(g_processEvent);
1562     }
1563 #endif
1564     coap_delete_pdu(pdu);
1565 #else
1566     (void)result;
1567 #endif
1568
1569     OIC_LOG(DEBUG, TAG, "CAErrorHandler OUT");
1570     return;
1571 }
1572
1573 static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info, CAResult_t result)
1574 {
1575     OIC_LOG(DEBUG, TAG, "CASendErrorInfo IN");
1576 #ifndef SINGLE_THREAD
1577     CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
1578     if (!cadata)
1579     {
1580         OIC_LOG(ERROR, TAG, "cadata memory allocation failed");
1581         return;
1582     }
1583
1584     CAEndpoint_t* ep = CACloneEndpoint(endpoint);
1585     if (!ep)
1586     {
1587         OIC_LOG(ERROR, TAG, "endpoint clone failed");
1588         OICFree(cadata);
1589         return;
1590     }
1591
1592     CAErrorInfo_t *errorInfo = (CAErrorInfo_t *)OICCalloc(1, sizeof (CAErrorInfo_t));
1593     if (!errorInfo)
1594     {
1595         OIC_LOG(ERROR, TAG, "errorInfo memory allocation failed");
1596         OICFree(cadata);
1597         CAFreeEndpoint(ep);
1598         return;
1599     }
1600
1601     CAResult_t res = CACloneInfo(info, &errorInfo->info);
1602     if (CA_STATUS_OK != res)
1603     {
1604         OIC_LOG(ERROR, TAG, "info clone failed");
1605         OICFree(cadata);
1606         OICFree(errorInfo);
1607         CAFreeEndpoint(ep);
1608         return;
1609     }
1610
1611     errorInfo->result = result;
1612     cadata->remoteEndpoint = ep;
1613     cadata->errorInfo = errorInfo;
1614     cadata->dataType = CA_ERROR_DATA;
1615
1616     res = CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t), false);
1617     if (res != CA_STATUS_OK)
1618     {
1619         OIC_LOG(ERROR, TAG, "Failed to add message to data queue!");
1620         CADestroyData(cadata, sizeof(CAData_t));
1621         return;
1622     }
1623
1624 #ifdef WITH_PROCESS_EVENT
1625     if (g_processEvent)
1626     {
1627         oc_event_signal(g_processEvent);
1628     }
1629 #endif//WITH_PROCESS_EVENT
1630 #endif
1631     OIC_LOG(DEBUG, TAG, "CASendErrorInfo OUT");
1632 }
1633
1634
1635
1636 #ifndef ARDUINO
1637 #ifdef __TIZENRT__
1638 static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu)
1639 {
1640
1641         if(data == NULL || pdu == NULL)
1642         {
1643                 printf("INVALID INPUT, CALogPDUInfo FAIL\n");
1644         }
1645
1646         char type[30] = "";
1647
1648         switch(data->dataType)
1649         {
1650                 case CA_REQUEST_DATA:
1651                         strncpy(type, "\e[32mREQUEST  <<<<\e[m", 30);
1652                         break;
1653                 case CA_RESPONSE_DATA:
1654                         strncpy(type, "\e[36mRESPONSE >>>>\e[m", 30);
1655                         break;
1656                 case CA_ERROR_DATA:
1657                         strncpy(type, "ERROR", 30);
1658                         break;
1659                 case CA_RESPONSE_FOR_RES:
1660                         strncpy(type, "RESP_RES >>>>", 30);
1661                         break;
1662                 default:
1663                         snprintf(type, 30, "Type : %d", data->dataType);
1664                         break;
1665         }
1666
1667
1668         char method[20] = "";
1669         const CAInfo_t *info = NULL;
1670         if (NULL != data->requestInfo)
1671         {
1672                 switch(data->requestInfo->method)
1673                 {
1674                         case CA_GET:
1675                                 strncpy(method, "GET", 20);
1676                                 break;
1677                         case CA_POST:
1678                                 strncpy(method, "POST", 20);
1679                                 break;
1680                         case CA_PUT:
1681                                 strncpy(method, "PUT", 20);
1682                                 break;
1683                         case CA_DELETE:
1684                                 strncpy(method, "DEL", 20);
1685                                 break;
1686                         default:
1687                                 sprintf(method, "Method : %d", data->requestInfo->method);
1688                                 break;
1689                 }
1690                 info = &data->requestInfo->info;
1691         }
1692
1693         if(NULL != data->responseInfo)
1694         {
1695
1696                 sprintf(method, "result : %d", data->responseInfo->result);
1697                 info = &data->responseInfo->info;
1698         }
1699
1700
1701         char log_buffer[1024] = "";
1702         sprintf(log_buffer, "CA_LOG [%5d] | %-13s | %-12s | msg size : %4d | %s", pdu->transport_hdr->udp.id , type, method, pdu->length, info->resourceUri);
1703
1704         if(NULL != info)
1705         {
1706                 sprintf(log_buffer, "CA_LOG [%5d] | %-13s | %-12s | msg size : %4d | %s", pdu->transport_hdr->udp.id , type, method, pdu->length, info->resourceUri);
1707         }
1708
1709         puts(log_buffer);
1710 }
1711
1712
1713 #else
1714
1715 static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu)
1716 {
1717     OIC_LOG(DEBUG, TAG, "CALogPDUInfo");
1718
1719     VERIFY_NON_NULL_VOID(data, TAG, "data");
1720     VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
1721     OIC_TRACE_BEGIN(%s:CALogPDUInfo, TAG);
1722
1723     OIC_LOG(INFO, ANALYZER_TAG, "=================================================");
1724     if(SEND_TYPE_MULTICAST == data->type)
1725     {
1726         OIC_LOG(INFO, ANALYZER_TAG, "Is Multicast = true");
1727     }
1728     else
1729     {
1730         OIC_LOG(INFO, ANALYZER_TAG, "Is Multicast = false");
1731     }
1732
1733     if (NULL != data->remoteEndpoint)
1734     {
1735         CALogAdapterTypeInfo(data->remoteEndpoint->adapter);
1736         OIC_LOG_V(DEBUG, ANALYZER_TAG, "Address = [%s]:[%d]", data->remoteEndpoint->addr,
1737                   data->remoteEndpoint->port);
1738     }
1739
1740     switch(data->dataType)
1741     {
1742         case CA_REQUEST_DATA:
1743             OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_REQUEST_DATA]");
1744             break;
1745         case CA_RESPONSE_DATA:
1746             OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_RESPONSE_DATA]");
1747             break;
1748         case CA_ERROR_DATA:
1749             OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_ERROR_DATA]");
1750             break;
1751         case CA_RESPONSE_FOR_RES:
1752             OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_RESPONSE_FOR_RES]");
1753             break;
1754         default:
1755             OIC_LOG_V(INFO, ANALYZER_TAG, "Data Type = [%d]", data->dataType);
1756             break;
1757     }
1758
1759     const CAInfo_t *info = NULL;
1760     if (NULL != data->requestInfo)
1761     {
1762         switch(data->requestInfo->method)
1763         {
1764             case CA_GET:
1765                 OIC_LOG(INFO, ANALYZER_TAG, "Method = [GET]");
1766                 break;
1767             case CA_POST:
1768                 OIC_LOG(INFO, ANALYZER_TAG, "Method = [POST]");
1769                 break;
1770             case CA_PUT:
1771                 OIC_LOG(INFO, ANALYZER_TAG, "Method = [PUT]");
1772                 break;
1773             case CA_DELETE:
1774                 OIC_LOG(INFO, ANALYZER_TAG, "Method = [DELETE]");
1775                 break;
1776             default:
1777                 OIC_LOG_V(INFO, ANALYZER_TAG, "Method = [%d]", data->requestInfo->method);
1778                 break;
1779         }
1780         info = &data->requestInfo->info;
1781     }
1782
1783     if (NULL != data->responseInfo)
1784     {
1785         OIC_LOG_V(INFO, ANALYZER_TAG, "result code = [%d]", data->responseInfo->result);
1786         info = &data->responseInfo->info;
1787     }
1788
1789     if (pdu->transport_hdr)
1790     {
1791         OIC_LOG_V(INFO, ANALYZER_TAG, "Msg ID = [%d]", pdu->transport_hdr->udp.id);
1792     }
1793
1794     if (info)
1795     {
1796         OIC_LOG(INFO, ANALYZER_TAG, "Coap Token");
1797         OIC_LOG_BUFFER(INFO, ANALYZER_TAG, (const uint8_t *) info->token, info->tokenLength);
1798         OIC_TRACE_BUFFER("OIC_CA_MSG_HANDLE:CALogPDUInfo:token",
1799                          (const uint8_t *) info->token, info->tokenLength);
1800         OIC_LOG_V(INFO_PRIVATE, ANALYZER_TAG, "Res URI = [%s]", info->resourceUri);
1801         OIC_TRACE_MARK(%s:CALogPDUInfo:uri:%s, TAG, info->resourceUri);
1802
1803         if (CA_FORMAT_APPLICATION_CBOR == info->payloadFormat)
1804         {
1805             OIC_LOG(INFO, ANALYZER_TAG, "Payload Format = [CA_FORMAT_APPLICATION_CBOR]");
1806         }
1807         else
1808         {
1809             OIC_LOG_V(INFO, ANALYZER_TAG, "Payload Format = [%d]", info->payloadFormat);
1810         }
1811     }
1812
1813     size_t payloadLen = (pdu->data) ? (unsigned char *) pdu->hdr + pdu->length - pdu->data : 0;
1814     OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Message Full Size = [%u]", pdu->length);
1815     OIC_LOG(INFO, ANALYZER_TAG, "CoAP Header (+ 0xFF)");
1816     OIC_LOG_BUFFER(INFO, ANALYZER_TAG,  (const uint8_t *) pdu->transport_hdr,
1817                    pdu->length - payloadLen);
1818     OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Header size = [%" PRIuPTR "]", (size_t) pdu->length - payloadLen);
1819
1820     OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Payload");
1821     OIC_LOG_BUFFER(INFO_PRIVATE, ANALYZER_TAG, pdu->data, payloadLen);
1822     OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Payload Size = [%" PRIuPTR "]", payloadLen);
1823     OIC_LOG(INFO, ANALYZER_TAG, "=================================================");
1824
1825     // samsung log
1826     CASamsungLogMessage(data, pdu);
1827     OIC_TRACE_END();
1828 }
1829
1830 static void CASamsungLogMessage(const CAData_t *data, const coap_pdu_t *pdu)
1831 {
1832     OIC_LOG(INFO, TAG, "CASamsungLogMessage");
1833     VERIFY_NON_NULL_VOID(data, TAG, "data");
1834     VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
1835     VERIFY_NON_NULL_VOID(data->remoteEndpoint, TAG, "data->remoteEndpoint");
1836
1837     const CAInfo_t *info = NULL;
1838     if (NULL != data->requestInfo)
1839     {
1840         info = &data->requestInfo->info;
1841     }
1842
1843     if (NULL != data->responseInfo)
1844     {
1845         info = &data->responseInfo->info;
1846     }
1847
1848     VERIFY_NON_NULL_VOID(info, TAG, "info");
1849
1850     memset(g_headerBuffer, 0, MAX_LOG_BUFFER_SIZE);
1851     g_headerIndex = 0;
1852
1853     g_headerBuffer[g_headerIndex++] = data->dataType;
1854     g_headerBuffer[g_headerIndex++] = '|';
1855     g_headerBuffer[g_headerIndex++] = data->remoteEndpoint->adapter;
1856     g_headerBuffer[g_headerIndex++] = '|';
1857     g_headerBuffer[g_headerIndex++] = data->type;
1858     g_headerBuffer[g_headerIndex++] = '|';
1859
1860     if (NULL != data->remoteEndpoint)
1861     {
1862         int i = 0;
1863         while (data->remoteEndpoint->addr[i])
1864         {
1865             g_headerBuffer[g_headerIndex++] = data->remoteEndpoint->addr[i];
1866             i++;
1867         }
1868         g_headerBuffer[g_headerIndex++] = ':';
1869         g_headerBuffer[g_headerIndex++] = (data->remoteEndpoint->port >> 8) & 0x0000ff;
1870         g_headerBuffer[g_headerIndex++] = data->remoteEndpoint->port & 0x000000ff;
1871     }
1872
1873     g_headerBuffer[g_headerIndex++] = '|';
1874     if (data->requestInfo)
1875     {
1876         g_headerBuffer[g_headerIndex++] = data->requestInfo->method;
1877     }
1878     else
1879     {
1880         g_headerBuffer[g_headerIndex++] = 0;
1881     }
1882
1883     g_headerBuffer[g_headerIndex++] = '|';
1884     if (data->responseInfo)
1885     {
1886         g_headerBuffer[g_headerIndex++] = data->responseInfo->result;
1887     }
1888     else
1889     {
1890         g_headerBuffer[g_headerIndex++] = 0;
1891     }
1892     g_headerBuffer[g_headerIndex++] = '|';
1893
1894     if (pdu->transport_hdr)
1895     {
1896         g_headerBuffer[g_headerIndex++] = (pdu->transport_hdr->udp.id >> 8) & 0x0000ff;
1897         g_headerBuffer[g_headerIndex++] = pdu->transport_hdr->udp.id & 0x000000ff;
1898     }
1899     else
1900     {
1901         g_headerBuffer[g_headerIndex++] = 0;
1902         g_headerBuffer[g_headerIndex++] = 0;
1903     }
1904     g_headerBuffer[g_headerIndex++] = '|';
1905
1906     if (info->token && info->tokenLength > 0)
1907     {
1908         for (size_t i = 0; i < info->tokenLength; i++)
1909         {
1910             g_headerBuffer[g_headerIndex++] = info->token[i];
1911         }
1912         g_headerBuffer[g_headerIndex++] = '|';
1913     }
1914
1915     if (info->resourceUri)
1916     {
1917         size_t i = 0;
1918         while (info->resourceUri[i])
1919         {
1920             g_headerBuffer[g_headerIndex++] = info->resourceUri[i];
1921             i++;
1922         }
1923         g_headerBuffer[g_headerIndex++] = '|';
1924     }
1925
1926     OIC_LOG_CA_BUFFER(INFO, TAG, (uint8_t *) g_headerBuffer, g_headerIndex, 1);
1927     size_t payloadLen = (unsigned char *) pdu->hdr + pdu->length - pdu->data;
1928     OIC_LOG_CA_BUFFER(INFO_PRIVATE, TAG, pdu->data, payloadLen, 0);
1929 }
1930 #endif
1931
1932 #else
1933 static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu)
1934 {
1935     VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
1936     (void)data;
1937
1938     OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data);
1939     OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->transport_hdr->udp.type);
1940     OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->transport_hdr->udp.code);
1941     OIC_LOG(DEBUG, TAG, "PDU Maker - token :");
1942     OIC_LOG_BUFFER(DEBUG, TAG, pdu->transport_hdr->udp.token,
1943                    pdu->transport_hdr->udp.token_length);
1944 }
1945 #endif
1946
1947 #ifdef WITH_PROCESS_EVENT
1948 void CARegisterMessageProcessEvent(oc_event event)
1949 {
1950     g_processEvent = event;
1951 }
1952 #endif // WITH_PROCESS_EVENT