Add csdk API to send COAP ping messages over TCP
[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 #include <limits.h>
26
27 #include "cainterface.h"
28 #include "camessagehandler.h"
29 #include "caremotehandler.h"
30 #include "caprotocolmessage.h"
31 #include "experimental/logger.h"
32 #include "trace.h"
33 #ifndef WITH_UPSTREAM_LIBCOAP
34 #include "coap/config.h"
35 #endif
36 #include "oic_malloc.h"
37 #include "canetworkconfigurator.h"
38 #include "caadapterutils.h"
39 #include "cainterfacecontroller.h"
40 #include "caretransmission.h"
41 #include "oic_string.h"
42 #include "caping.h"
43
44 #ifdef WITH_BWT
45 #include "cablockwisetransfer.h"
46 #endif
47
48 #ifdef TCP_ADAPTER
49 #include "catcpadapter.h"
50 #endif
51
52 #include "uqueue.h"
53 #include "cathreadpool.h" /* for thread pool */
54 #include "caqueueingthread.h"
55
56 #if defined(TCP_ADAPTER) && defined(WITH_CLOUD)
57 #include "caconnectionmanager.h"
58 #endif
59 #define SINGLE_HANDLE
60 #define MAX_THREAD_POOL_SIZE    20
61
62 // thread pool handle
63 static ca_thread_pool_t g_threadPoolHandle = NULL;
64
65 // message handler main thread
66 static CAQueueingThread_t g_sendThread;
67 static CAQueueingThread_t g_receiveThread;
68
69
70 #define TAG "OIC_CA_MSG_HANDLE"
71
72 static CARetransmission_t g_retransmissionContext;
73
74 // handler field
75 static CARequestCallback g_requestHandler = NULL;
76 static CAResponseCallback g_responseHandler = NULL;
77 static CAErrorCallback g_errorHandler = NULL;
78 static CANetworkMonitorCallback g_nwMonitorHandler = NULL;
79
80 static void CAErrorHandler(const CAEndpoint_t *endpoint,
81                            const void *data, size_t dataLen,
82                            CAResult_t result);
83
84 static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint,
85                                        const CARemoteId_t *identity,
86                                        const void *data, CADataType_t dataType);
87
88 static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info,
89                             CAResult_t result);
90
91 static void CADestroyData(void *data, uint32_t size);
92 static void CALogPayloadInfo(CAInfo_t *info);
93 static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *endpoint, uint16_t id,
94                                 CAToken_t token, uint8_t tokenLength);
95
96 /**
97  * print send / receive message of CoAP.
98  * @param[in] data      CA information which has send/receive message and endpoint.
99  * @param[in] pdu       CoAP pdu low data.
100  */
101 static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu);
102
103 #if defined(WITH_BWT) || defined(TCP_ADAPTER)
104 void CAAddDataToSendThread(CAData_t *data)
105 {
106     VERIFY_NON_NULL_VOID(data, TAG, "data");
107
108     // add thread
109     CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
110 }
111
112 void CAAddDataToReceiveThread(CAData_t *data)
113 {
114     VERIFY_NON_NULL_VOID(data, TAG, "data");
115
116     // add thread
117     CAQueueingThreadAddData(&g_receiveThread, data, sizeof(CAData_t));
118 }
119 #endif
120
121 static bool CAIsSelectedNetworkAvailable(void)
122 {
123     u_arraylist_t *list = CAGetSelectedNetworkList();
124     if (!list || u_arraylist_length(list) == 0)
125     {
126         OIC_LOG(ERROR, TAG, "No selected network");
127         return false;
128     }
129
130     return true;
131 }
132
133 static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint,
134                                        const CARemoteId_t *identity,
135                                        const void *data, CADataType_t dataType)
136 {
137     OIC_LOG(DEBUG, TAG, "CAGenerateHandlerData IN");
138     CAInfo_t *info = NULL;
139     CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
140     if (!cadata)
141     {
142         OIC_LOG(ERROR, TAG, "memory allocation failed");
143         return NULL;
144     }
145     CAEndpoint_t* ep = CACloneEndpoint(endpoint);
146     if (!ep)
147     {
148         OIC_LOG(ERROR, TAG, "endpoint clone failed");
149         goto exit;
150     }
151
152     OIC_LOG_V(DEBUG, TAG, "address : %s", ep->addr);
153
154     if (CA_RESPONSE_DATA == dataType)
155     {
156         CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(CAResponseInfo_t));
157         if (!resInfo)
158         {
159             OIC_LOG(ERROR, TAG, "memory allocation failed");
160             goto exit;
161         }
162
163         CAResult_t result = CAGetResponseInfoFromPDU(data, resInfo, endpoint);
164         if (CA_STATUS_OK != result)
165         {
166             OIC_LOG(ERROR, TAG, "CAGetResponseInfoFromPDU Failed");
167             CADestroyResponseInfoInternal(resInfo);
168             goto exit;
169         }
170         cadata->responseInfo = resInfo;
171         info = &resInfo->info;
172         if (identity)
173         {
174             info->identity = *identity;
175         }
176         else
177         {
178             OIC_LOG_V(INFO, TAG, "%s: No identity information provided", __func__);
179         }
180         OIC_LOG(DEBUG, TAG, "Response Info :");
181         CALogPayloadInfo(info);
182     }
183     else if (CA_REQUEST_DATA == dataType)
184     {
185         CARequestInfo_t* reqInfo = (CARequestInfo_t*)OICCalloc(1, sizeof(CARequestInfo_t));
186         if (!reqInfo)
187         {
188             OIC_LOG(ERROR, TAG, "memory allocation failed");
189             goto exit;
190         }
191
192         CAResult_t result = CAGetRequestInfoFromPDU(data, endpoint, reqInfo);
193         if (CA_STATUS_OK != result)
194         {
195             OIC_LOG(ERROR, TAG, "CAGetRequestInfoFromPDU failed");
196             CADestroyRequestInfoInternal(reqInfo);
197             goto exit;
198         }
199
200         if ((reqInfo->info.type != CA_MSG_CONFIRM) &&
201             CADropSecondMessage(&caglobals.ca.requestHistory, endpoint, reqInfo->info.messageId,
202                                 reqInfo->info.token, reqInfo->info.tokenLength))
203         {
204             OIC_LOG(INFO, TAG, "Second Request with same Token, Drop it");
205             CADestroyRequestInfoInternal(reqInfo);
206             goto exit;
207         }
208
209         cadata->requestInfo = reqInfo;
210         info = &reqInfo->info;
211         if (identity)
212         {
213             info->identity = *identity;
214         }
215         OIC_LOG(DEBUG, TAG, "Request Info :");
216         CALogPayloadInfo(info);
217    }
218     else if (CA_ERROR_DATA == dataType)
219     {
220         CAErrorInfo_t *errorInfo = (CAErrorInfo_t *)OICCalloc(1, sizeof (CAErrorInfo_t));
221         if (!errorInfo)
222         {
223             OIC_LOG(ERROR, TAG, "Memory allocation failed!");
224             goto exit;
225         }
226
227         CAResult_t result = CAGetErrorInfoFromPDU(data, endpoint, errorInfo);
228         if (CA_STATUS_OK != result)
229         {
230             OIC_LOG(ERROR, TAG, "CAGetErrorInfoFromPDU failed");
231             OICFree(errorInfo);
232             goto exit;
233         }
234
235         cadata->errorInfo = errorInfo;
236         info = &errorInfo->info;
237         if (identity)
238         {
239             info->identity = *identity;
240         }
241         OIC_LOG(DEBUG, TAG, "error Info :");
242         CALogPayloadInfo(info);
243     }
244 #ifdef TCP_ADAPTER
245     else if (CA_SIGNALING_DATA == dataType)
246     {
247         CASignalingInfo_t *signalingInfo =
248                 (CASignalingInfo_t *)OICCalloc(1, sizeof (CASignalingInfo_t));
249         if (!signalingInfo)
250         {
251             OIC_LOG(ERROR, TAG, "Memory allocation failed!");
252             goto exit;
253         }
254
255         CAResult_t result = CAGetSignalingInfoFromPDU(data, endpoint, signalingInfo);
256         if (CA_STATUS_OK != result)
257         {
258             OIC_LOG(ERROR, TAG, "CAGetSignalingInfoFromPDU failed");
259             CADestroySignalingInfoInternal(signalingInfo);
260             goto exit;
261         }
262
263         cadata->signalingInfo = signalingInfo;
264         info = &signalingInfo->info;
265         if (identity)
266         {
267             info->identity = *identity;
268         }
269         OIC_LOG(DEBUG, TAG, "Signaling Info :");
270         CALogPayloadInfo(info);
271
272         // Get CA_OPTION_MAX_MESSAGE_SIZE from pdu.
273         unsigned char optionData[CA_MAX_HEADER_OPTION_DATA_LENGTH];
274         size_t optionDataSize = sizeof(optionData);
275         uint16_t receivedDataLength = 0;
276
277         // TODO: We need to decide what options needs to be handled and which needs to be ignored.
278         if(CAGetHeaderOption(info->options, info->numOptions, CA_OPTION_MAX_MESSAGE_SIZE,
279                     optionData, optionDataSize, &receivedDataLength) == CA_STATUS_OK && receivedDataLength) {
280             unsigned int maxMsgSize = (unsigned int) coap_decode_var_bytes(optionData, receivedDataLength);
281             OIC_LOG_V(DEBUG, TAG, "received MAX_MESSAGE_SIZE option data: %u", maxMsgSize);
282             if(maxMsgSize > 1152){
283                 //TODO: Change the TCP sockets parameters for maxMsgSize > 1152
284             }
285         }
286     }
287 #endif
288
289     cadata->remoteEndpoint = ep;
290     cadata->dataType = dataType;
291
292     OIC_LOG(DEBUG, TAG, "CAGenerateHandlerData OUT");
293     return cadata;
294
295 exit:
296     OICFree(cadata);
297     CAFreeEndpoint(ep);
298     return NULL;
299 }
300
301 static void CATimeoutCallback(const CAEndpoint_t *endpoint, const void *pdu, uint32_t size)
302 {
303     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint");
304     VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
305     CAEndpoint_t* ep = CACloneEndpoint(endpoint);
306     if (!ep)
307     {
308         OIC_LOG(ERROR, TAG, "clone failed");
309         return;
310     }
311
312     CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(CAResponseInfo_t));
313
314     if (!resInfo)
315     {
316         OIC_LOG(ERROR, TAG, "calloc failed");
317         CAFreeEndpoint(ep);
318         return;
319     }
320
321     resInfo->result = CA_RETRANSMIT_TIMEOUT;
322     resInfo->info.type = CAGetMessageTypeFromPduBinaryData(pdu, size);
323     resInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
324
325     CAResult_t res = CAGetTokenFromPDU((const coap_hdr_transport_t *) pdu, &(resInfo->info),
326                                        endpoint);
327     if (CA_STATUS_OK != res)
328     {
329         OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
330         CADestroyResponseInfoInternal(resInfo);
331         CAFreeEndpoint(ep);
332         return;
333     }
334
335     CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
336     if (NULL == cadata)
337     {
338         OIC_LOG(ERROR, TAG, "memory allocation failed !");
339         CAFreeEndpoint(ep);
340         CADestroyResponseInfoInternal(resInfo);
341         return;
342     }
343
344     cadata->type = SEND_TYPE_UNICAST;
345     cadata->remoteEndpoint = ep;
346     cadata->requestInfo = NULL;
347     cadata->responseInfo = resInfo;
348
349 #ifdef WITH_BWT
350     if (CAIsSupportedBlockwiseTransfer(endpoint->adapter))
351     {
352         res = CARemoveBlockDataFromListWithSeed(resInfo->info.token, resInfo->info.tokenLength,
353                                                 endpoint->addr, endpoint->port);
354         if (CA_STATUS_OK != res)
355         {
356             OIC_LOG(ERROR, TAG, "CARemoveBlockDataFromListWithSeed failed");
357         }
358     }
359 #endif // WITH_BWT
360
361     CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
362 }
363
364 static void CADestroyData(void *data, uint32_t size)
365 {
366     OIC_LOG(DEBUG, TAG, "CADestroyData IN");
367     if ((size_t)size < sizeof(CAData_t))
368     {
369         OIC_LOG_V(ERROR, TAG, "Destroy data too small %p %d", data, size);
370     }
371     CAData_t *cadata = (CAData_t *) data;
372
373     if (NULL == cadata)
374     {
375         OIC_LOG(ERROR, TAG, "cadata is NULL");
376         return;
377     }
378     if (NULL != cadata->remoteEndpoint)
379     {
380         CAFreeEndpoint(cadata->remoteEndpoint);
381     }
382
383     if (NULL != cadata->requestInfo)
384     {
385         CADestroyRequestInfoInternal((CARequestInfo_t *) cadata->requestInfo);
386     }
387
388     if (NULL != cadata->responseInfo)
389     {
390         CADestroyResponseInfoInternal((CAResponseInfo_t *) cadata->responseInfo);
391     }
392
393     if (NULL != cadata->errorInfo)
394     {
395         CADestroyErrorInfoInternal(cadata->errorInfo);
396     }
397
398 #ifdef TCP_ADAPTER
399     if (NULL != cadata->signalingInfo)
400     {
401         CADestroySignalingInfoInternal(cadata->signalingInfo);
402     }
403 #endif
404
405     OICFree(cadata);
406     OIC_LOG(DEBUG, TAG, "CADestroyData OUT");
407 }
408
409
410 static void CAReceiveThreadProcess(void *threadData)
411 {
412 #ifndef SINGLE_HANDLE
413     CAData_t *data = (CAData_t *) threadData;
414     OIC_TRACE_BEGIN(%s:CAProcessReceivedData, TAG);
415     CAProcessReceivedData(data);
416     OIC_TRACE_END();
417 #else
418     (void)threadData;
419 #endif
420 }
421
422 static CAResult_t CAProcessMulticastData(const CAData_t *data)
423 {
424     VERIFY_NON_NULL(data, TAG, "data");
425     VERIFY_NON_NULL(data->remoteEndpoint, TAG, "remoteEndpoint");
426
427     coap_pdu_t *pdu = NULL;
428     CAInfo_t *info = NULL;
429     coap_list_t *options = NULL;
430     coap_transport_t transport = COAP_UDP;
431     CAResult_t res = CA_SEND_FAILED;
432
433     if (!data->requestInfo && !data->responseInfo)
434     {
435         OIC_LOG(ERROR, TAG, "request or response info is empty");
436         return res;
437     }
438
439     if (data->requestInfo)
440     {
441         OIC_LOG(DEBUG, TAG, "requestInfo is available..");
442
443         info = &data->requestInfo->info;
444         pdu = CAGeneratePDU(CA_GET, info, data->remoteEndpoint, &options, &transport);
445     }
446     else if (data->responseInfo)
447     {
448         OIC_LOG(DEBUG, TAG, "responseInfo is available..");
449
450         info = &data->responseInfo->info;
451         pdu = CAGeneratePDU(data->responseInfo->result, info, data->remoteEndpoint,
452                             &options, &transport);
453     }
454
455     if (!pdu)
456     {
457         OIC_LOG(ERROR,TAG,"Failed to generate multicast PDU");
458         CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED);
459         coap_delete_list(options);
460         return res;
461     }
462
463 #ifdef WITH_BWT
464     if (CAIsSupportedBlockwiseTransfer(data->remoteEndpoint->adapter))
465     {
466         // Blockwise transfer
467         res = CAAddBlockOption(&pdu, info, data->remoteEndpoint, &options);
468         if (CA_STATUS_OK != res)
469         {
470             OIC_LOG(DEBUG, TAG, "CAAddBlockOption has failed");
471             goto exit;
472         }
473     }
474 #endif // WITH_BWT
475
476     CALogPDUInfo(data, pdu);
477
478     res = CASendMulticastData(data->remoteEndpoint, pdu->transport_hdr, pdu->length, data->dataType);
479     if (CA_STATUS_OK != res)
480     {
481         OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
482         goto exit;
483     }
484
485     coap_delete_list(options);
486     coap_delete_pdu(pdu);
487     return res;
488
489 exit:
490     CAErrorHandler(data->remoteEndpoint, pdu->transport_hdr, pdu->length, res);
491     coap_delete_list(options);
492     coap_delete_pdu(pdu);
493     return res;
494 }
495
496 static CAResult_t CAProcessSendData(const CAData_t *data)
497 {
498     VERIFY_NON_NULL(data, TAG, "data");
499     VERIFY_NON_NULL(data->remoteEndpoint, TAG, "remoteEndpoint");
500
501     CAResult_t res = CA_STATUS_FAILED;
502
503     CASendDataType_t type = data->type;
504
505     coap_pdu_t *pdu = NULL;
506     CAInfo_t *info = NULL;
507     coap_list_t *options = NULL;
508     coap_transport_t transport = COAP_UDP;
509
510     if (SEND_TYPE_UNICAST == type)
511     {
512         OIC_LOG(DEBUG,TAG,"Unicast message");
513
514 #ifdef ROUTING_GATEWAY
515         /*
516          * When forwarding a packet, do not attempt retransmission as its the responsibility of
517          * packet originator node
518          */
519         bool skipRetransmission = false;
520 #endif
521
522         if (NULL != data->requestInfo)
523         {
524             OIC_LOG(DEBUG, TAG, "requestInfo is available..");
525
526             info = &data->requestInfo->info;
527 #ifdef ROUTING_GATEWAY
528             skipRetransmission = data->requestInfo->info.skipRetransmission;
529 #endif
530             pdu = CAGeneratePDU(data->requestInfo->method, info, data->remoteEndpoint,
531                                 &options, &transport);
532         }
533         else if (NULL != data->responseInfo)
534         {
535             OIC_LOG(DEBUG, TAG, "responseInfo is available..");
536
537             info = &data->responseInfo->info;
538 #ifdef ROUTING_GATEWAY
539             skipRetransmission = data->responseInfo->info.skipRetransmission;
540 #endif
541             pdu = CAGeneratePDU(data->responseInfo->result, info, data->remoteEndpoint,
542                                 &options, &transport);
543         }
544 #ifdef TCP_ADAPTER
545         else if (NULL != data->signalingInfo)
546         {
547             OIC_LOG(DEBUG, TAG, "signalingInfo is available..");
548             info = &data->signalingInfo->info;
549 #ifdef ROUTING_GATEWAY
550             skipRetransmission = data->signalingInfo->info.skipRetransmission;
551 #endif
552             pdu = CAGeneratePDU(data->signalingInfo->code, info, data->remoteEndpoint,
553                                 &options, &transport);
554         }
555 #endif
556         else
557         {
558             OIC_LOG(DEBUG, TAG, "request info, response info is empty");
559             return CA_STATUS_INVALID_PARAM;
560         }
561
562         // interface controller function call.
563         if (NULL != pdu)
564         {
565 #ifdef WITH_BWT
566             if (CAIsSupportedBlockwiseTransfer(data->remoteEndpoint->adapter))
567             {
568                 // Blockwise transfer
569                 if (NULL != info)
570                 {
571                     res = CAAddBlockOption(&pdu, info, data->remoteEndpoint, &options);
572                     if (CA_STATUS_OK != res)
573                     {
574                         OIC_LOG(INFO, TAG, "to write block option has failed");
575                         CAErrorHandler(data->remoteEndpoint, pdu->transport_hdr, pdu->length, res);
576                         coap_delete_list(options);
577                         coap_delete_pdu(pdu);
578                         return res;
579                     }
580                 }
581             }
582 #endif // WITH_BWT
583             CALogPDUInfo(data, pdu);
584
585             OIC_LOG_V(INFO, TAG, "CASendUnicastData type : %d", data->dataType);
586             res = CASendUnicastData(data->remoteEndpoint, pdu->transport_hdr, pdu->length, data->dataType);
587             if (CA_STATUS_OK != res)
588             {
589                 OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
590                 CAErrorHandler(data->remoteEndpoint, pdu->transport_hdr, pdu->length, res);
591                 coap_delete_list(options);
592                 coap_delete_pdu(pdu);
593                 return res;
594             }
595
596 #ifdef WITH_TCP
597             if (CAIsSupportedCoAPOverTCP(data->remoteEndpoint->adapter))
598             {
599                 OIC_LOG(INFO, TAG, "retransmission will be not worked");
600             }
601             else
602 #endif
603 #ifdef ROUTING_GATEWAY
604             if (!skipRetransmission)
605 #endif
606             {
607                 // for retransmission
608                 res = CARetransmissionSentData(&g_retransmissionContext,
609                                                data->remoteEndpoint,
610                                                data->dataType,
611                                                pdu->transport_hdr, pdu->length);
612                 if ((CA_STATUS_OK != res) && (CA_NOT_SUPPORTED != res))
613                 {
614                     //when retransmission not supported this will return CA_NOT_SUPPORTED, ignore
615                     OIC_LOG_V(INFO, TAG, "retransmission is not enabled due to error, res : %d", res);
616                     coap_delete_list(options);
617                     coap_delete_pdu(pdu);
618                     return res;
619                 }
620             }
621
622             coap_delete_list(options);
623             coap_delete_pdu(pdu);
624         }
625         else
626         {
627             OIC_LOG(ERROR,TAG,"Failed to generate unicast PDU");
628             CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED);
629             return CA_SEND_FAILED;
630         }
631     }
632     else if (SEND_TYPE_MULTICAST == type)
633     {
634         OIC_LOG(DEBUG,TAG,"Multicast message");
635 #ifdef WITH_TCP
636         /*
637          * If CoAP over TCP is enabled, the CoAP pdu wont be same for IP and other adapters.
638          * That's why we need to generate two pdu's, one for IP and second for other transports.
639          * Two possible cases we might have to split: a) when adapter is CA_DEFAULT_ADAPTER
640          * b) when one of the adapter is IP adapter(ex: CA_ADAPTER_IP | CA_ADAPTER_GATT_BTLE)
641          */
642         if (data->remoteEndpoint->adapter == CA_DEFAULT_ADAPTER ||
643                 (CA_ADAPTER_IP & data->remoteEndpoint->adapter &&
644                     CA_ADAPTER_IP != data->remoteEndpoint->adapter))
645         {
646             if (data->remoteEndpoint->adapter == CA_DEFAULT_ADAPTER)
647             {
648                 data->remoteEndpoint->adapter = CA_ALL_ADAPTERS ^ CA_ADAPTER_IP;
649             }
650             else
651             {
652                 data->remoteEndpoint->adapter = data->remoteEndpoint->adapter ^ CA_ADAPTER_IP;
653             }
654             CAProcessMulticastData(data);
655             data->remoteEndpoint->adapter = CA_ADAPTER_IP;
656             CAProcessMulticastData(data);
657         }
658         else
659         {
660             CAProcessMulticastData(data);
661         }
662 #else
663         CAProcessMulticastData(data);
664 #endif
665     }
666
667     return CA_STATUS_OK;
668 }
669
670 static void CASendThreadProcess(void *threadData)
671 {
672     CAData_t *data = (CAData_t *) threadData;
673     OIC_TRACE_BEGIN(%s:CAProcessSendData, TAG);
674     CAProcessSendData(data);
675     OIC_TRACE_END();
676 }
677
678 /*
679  * If a second message arrives with the same message ID, token and the other address
680  * family, drop it.  Typically, IPv6 beats IPv4, so the IPv4 message is dropped.
681  */
682 static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *ep, uint16_t id,
683                                 CAToken_t token, uint8_t tokenLength)
684 {
685     if (!ep)
686     {
687         return true;
688     }
689     if (ep->adapter != CA_ADAPTER_IP)
690     {
691         return false;
692     }
693
694     if (tokenLength > CA_MAX_TOKEN_LEN)
695     {
696         /*
697          * If token length is more than CA_MAX_TOKEN_LEN,
698          * we compare the first CA_MAX_TOKEN_LEN bytes only.
699          */
700         tokenLength = CA_MAX_TOKEN_LEN;
701     }
702
703     bool ret = false;
704     CATransportFlags_t familyFlags = ep->flags & CA_IPFAMILY_MASK;
705
706     for (size_t i = 0; i < sizeof(history->items) / sizeof(history->items[0]); i++)
707     {
708         CAHistoryItem_t *item = &(history->items[i]);
709         if (id == item->messageId && tokenLength == item->tokenLength
710             && ep->ifindex == item->ifindex && memcmp(item->token, token, tokenLength) == 0)
711         {
712             OIC_LOG_V(INFO, TAG, "IPv%c duplicate message ignored",
713                       familyFlags & CA_IPV6 ? '6' : '4');
714             ret = true;
715             break;
716         }
717     }
718
719     history->items[history->nextIndex].flags = familyFlags;
720     history->items[history->nextIndex].messageId = id;
721     history->items[history->nextIndex].ifindex = ep->ifindex;
722     if (token && tokenLength)
723     {
724         memcpy(history->items[history->nextIndex].token, token, tokenLength);
725         history->items[history->nextIndex].tokenLength = tokenLength;
726     }
727
728     if (++history->nextIndex >= HISTORYSIZE)
729     {
730         history->nextIndex = 0;
731     }
732
733     return ret;
734 }
735
736 static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
737                                      const void *data, size_t dataLen)
738 {
739     VERIFY_NON_NULL_VOID(sep, TAG, "remoteEndpoint");
740     VERIFY_NON_NULL_VOID(data, TAG, "data");
741     OIC_TRACE_BEGIN(%s:CAReceivedPacketCallback, TAG);
742
743     if (0 == dataLen)
744     {
745         OIC_LOG(ERROR, TAG, "dataLen is zero");
746         OIC_TRACE_END();
747         return;
748     }
749
750     uint32_t code = CA_NOT_FOUND;
751     CAData_t *cadata = NULL;
752
753     coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code,
754                                                 &(sep->endpoint));
755     if (NULL == pdu)
756     {
757         OIC_LOG(ERROR, TAG, "Parse PDU failed");
758         goto exit;
759     }
760
761     OIC_LOG_V(DEBUG, TAG, "code = %d", code);
762
763 #ifdef TCP_ADAPTER
764     if (CA_ADAPTER_TCP == sep->endpoint.adapter && CA_CSM != code)
765     {
766         CACSMExchangeState_t csmState = CAGetCSMState(&sep->endpoint);
767         if (csmState != RECEIVED && csmState != SENT_RECEIVED)
768         {
769             CATCPDisconnectSession(&sep->endpoint);
770             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, first message is not a CSM!!");
771         }
772     }
773 #endif
774
775     if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
776     {
777         cadata = CAGenerateHandlerData(&(sep->endpoint), &(sep->identity), pdu, CA_REQUEST_DATA);
778         if (!cadata)
779         {
780             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
781             coap_delete_pdu(pdu);
782             goto exit;
783         }
784     }
785     else
786     {
787 #ifdef TCP_ADAPTER
788         // This is signaling message.
789         if (CA_ADAPTER_TCP == sep->endpoint.adapter &&
790                 (CA_CSM == code || CA_PING == code || CA_PONG == code
791                         || CA_RELEASE == code || CA_ABORT == code))
792         {
793             cadata = CAGenerateHandlerData(&(sep->endpoint), &(sep->identity),
794                                            pdu, CA_SIGNALING_DATA);
795             if (!cadata)
796             {
797                 OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
798                 coap_delete_pdu(pdu);
799                 return;
800             }
801
802             // Received signaling message is CSM.
803             if (CA_CSM == code)
804             {
805                 OIC_LOG_V(DEBUG, TAG, "CAReceivedPacketCallback, CSM received");
806                 // update session info of tcp_adapter.
807                 // TODO check if it is a valid CSM, if it is not valid message disconnect the session.
808                 CACSMExchangeState_t csmState = CAGetCSMState(&sep->endpoint);
809                 if (csmState == NONE)
810                 {
811                     CAUpdateCSMState(&sep->endpoint,RECEIVED);
812                 }
813                 else if (csmState == SENT)
814                 {
815                     CAUpdateCSMState(&sep->endpoint,SENT_RECEIVED);
816                 }
817             }
818             else if (CA_PING == code)
819             {
820                 CASendPongMessage(cadata->remoteEndpoint, false, cadata->signalingInfo->info.token,
821                                   cadata->signalingInfo->info.tokenLength);
822             }
823             else if(CA_PONG == code)
824             {
825                 CAPongReceivedCallback(cadata->remoteEndpoint, cadata->signalingInfo->info.token,
826                                        cadata->signalingInfo->info.tokenLength);
827             }
828             return;
829         }
830 #endif
831
832         cadata = CAGenerateHandlerData(&(sep->endpoint), &(sep->identity), pdu, CA_RESPONSE_DATA);
833         if (!cadata)
834         {
835             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
836             coap_delete_pdu(pdu);
837             goto exit;
838         }
839
840 #ifdef WITH_TCP
841         if (CAIsSupportedCoAPOverTCP(sep->endpoint.adapter))
842         {
843             OIC_LOG(INFO, TAG, "retransmission is not supported");
844         }
845         else
846 #endif
847         {
848             // for retransmission
849             void *retransmissionPdu = NULL;
850             CARetransmissionReceivedData(&g_retransmissionContext, cadata->remoteEndpoint, pdu->transport_hdr,
851                                          pdu->length, &retransmissionPdu);
852
853             // get token from saved data in retransmission list
854             if (retransmissionPdu && CA_EMPTY == code)
855             {
856                 if (cadata->responseInfo)
857                 {
858                     CAInfo_t *info = &cadata->responseInfo->info;
859                     CAResult_t res = CAGetTokenFromPDU((const coap_hdr_transport_t *)retransmissionPdu,
860                                                        info, &(sep->endpoint));
861                     if (CA_STATUS_OK != res)
862                     {
863                         OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
864                         OICFree(info->token);
865                         info->tokenLength = 0;
866                     }
867                 }
868             }
869             OICFree(retransmissionPdu);
870         }
871     }
872
873     cadata->type = SEND_TYPE_UNICAST;
874
875     CALogPDUInfo(cadata, pdu);
876
877 #ifdef WITH_BWT
878     if (CAIsSupportedBlockwiseTransfer(sep->endpoint.adapter))
879     {
880         CAResult_t res = CAReceiveBlockWiseData(pdu, &(sep->endpoint), cadata, dataLen);
881         if (CA_NOT_SUPPORTED == res || CA_REQUEST_TIMEOUT == res)
882         {
883             OIC_LOG(DEBUG, TAG, "this message does not have block option");
884             CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
885         }
886         else
887         {
888             CADestroyData(cadata, sizeof(CAData_t));
889         }
890     }
891     else
892 #endif
893     {
894         CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
895     }
896
897     coap_delete_pdu(pdu);
898
899 exit:
900     OIC_LOG(DEBUG, TAG, "received pdu data :");
901     OIC_LOG_BUFFER(DEBUG, TAG,  data, dataLen);
902
903     OIC_TRACE_END();
904 }
905
906 void CAHandleRequestResponseCallbacks(void)
907 {
908 #ifdef SINGLE_HANDLE
909     // parse the data and call the callbacks.
910     // #1 parse the data
911     // #2 get endpoint
912
913     oc_mutex_lock(g_receiveThread.threadMutex);
914
915     u_queue_message_t *item = u_queue_get_element(g_receiveThread.dataQueue);
916
917     oc_mutex_unlock(g_receiveThread.threadMutex);
918
919     if (NULL == item || NULL == item->msg)
920     {
921         return;
922     }
923
924     // get endpoint
925     CAData_t *td = (CAData_t *) item->msg;
926
927     if (td->requestInfo && g_requestHandler)
928     {
929         OIC_LOG_V(DEBUG, TAG, "request callback : %d", td->requestInfo->info.numOptions);
930         g_requestHandler(td->remoteEndpoint, td->requestInfo);
931     }
932     else if (td->responseInfo && g_responseHandler)
933     {
934         OIC_LOG_V(DEBUG, TAG, "response callback : %d", td->responseInfo->info.numOptions);
935         g_responseHandler(td->remoteEndpoint, td->responseInfo);
936     }
937     else if (td->errorInfo && g_errorHandler)
938     {
939         OIC_LOG_V(DEBUG, TAG, "error callback error: %d", td->errorInfo->result);
940         g_errorHandler(td->remoteEndpoint, td->errorInfo);
941     }
942
943     CADestroyData(item->msg, sizeof(CAData_t));
944     OICFree(item);
945
946 #endif // SINGLE_HANDLE
947 }
948
949 static CAData_t* CAPrepareSendData(const CAEndpoint_t *endpoint, const void *sendData,
950                                    CADataType_t dataType)
951 {
952     OIC_LOG(DEBUG, TAG, "CAPrepareSendData IN");
953
954     CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
955     if (!cadata)
956     {
957         OIC_LOG(ERROR, TAG, "memory allocation failed");
958         return NULL;
959     }
960
961     if (CA_REQUEST_DATA == dataType)
962     {
963         // clone request info
964         CARequestInfo_t *request = CACloneRequestInfo((CARequestInfo_t *)sendData);
965         if (!request)
966         {
967             OIC_LOG(ERROR, TAG, "CACloneRequestInfo failed");
968             goto exit;
969         }
970         cadata->type = request->isMulticast ? SEND_TYPE_MULTICAST : SEND_TYPE_UNICAST;
971         cadata->requestInfo =  request;
972     }
973     else if (CA_RESPONSE_DATA == dataType || CA_RESPONSE_FOR_RES == dataType)
974     {
975         // clone response info
976         CAResponseInfo_t *response = CACloneResponseInfo((CAResponseInfo_t *)sendData);
977         if(!response)
978         {
979             OIC_LOG(ERROR, TAG, "CACloneResponseInfo failed");
980             goto exit;
981         }
982         cadata->type = response->isMulticast ? SEND_TYPE_MULTICAST : SEND_TYPE_UNICAST;
983         cadata->responseInfo = response;
984     }
985 #ifdef TCP_ADAPTER
986     else if (CA_SIGNALING_DATA == dataType)
987     {
988         // clone signaling info
989         CASignalingInfo_t *signaling = CACloneSignalingInfo((CASignalingInfo_t *) sendData);
990         if (!signaling)
991         {
992             OIC_LOG(ERROR, TAG, "CACloneSignalingInfo failed");
993             goto exit;
994         }
995         cadata->type = SEND_TYPE_UNICAST;
996         cadata->signalingInfo = signaling;
997     }
998 #endif
999     else
1000     {
1001         OIC_LOG(ERROR, TAG, "CAPrepareSendData unknown data type");
1002         goto exit;
1003     }
1004
1005     CAEndpoint_t* ep = CACloneEndpoint(endpoint);
1006     if (!ep)
1007     {
1008         OIC_LOG(ERROR, TAG, "endpoint clone failed");
1009         goto exit;
1010     }
1011     cadata->remoteEndpoint = ep;
1012     cadata->dataType = dataType;
1013     return cadata;
1014
1015 exit:
1016     CADestroyData(cadata, sizeof(CAData_t));
1017     return NULL;
1018 }
1019
1020 CAResult_t CADetachSendMessage(const CAEndpoint_t *endpoint, const void *sendMsg,
1021                                CADataType_t dataType)
1022 {
1023     VERIFY_NON_NULL(endpoint, TAG, "endpoint");
1024     VERIFY_NON_NULL(sendMsg, TAG, "sendMsg");
1025
1026     if (false == CAIsSelectedNetworkAvailable())
1027     {
1028         return CA_STATUS_FAILED;
1029     }
1030
1031     CAData_t *data = NULL;
1032 #ifdef TCP_ADAPTER
1033     if (CA_ADAPTER_TCP == endpoint->adapter)
1034     {
1035         // #1. Try to find session info from tcp_adapter.
1036         CACSMExchangeState_t CSMstate = CAGetCSMState(endpoint);
1037         if (CSMstate != SENT && CSMstate != SENT_RECEIVED)
1038         {
1039             // #2. Generate CSM message
1040             OIC_LOG_V(DEBUG, TAG, "Generate CSM message for [%s:%d]",
1041                       endpoint->addr, endpoint->port);
1042
1043             // TODO: We need to decide what options needs to be sent Initially?
1044             //       Right now we're sending CA_OPTION_MAX_MESSAGE_SIZE as 1152,
1045             //       which is default according to the RFC.
1046             uint8_t numOptions = 0;
1047             CAHeaderOption_t *csmOpts = NULL;
1048             unsigned int maxMsgSize = 1152;
1049             unsigned char optionData[CA_MAX_HEADER_OPTION_DATA_LENGTH] = { 0 };
1050             size_t optionDataLength = coap_encode_var_bytes(optionData, maxMsgSize);
1051             CAAddHeaderOption(&csmOpts, &numOptions, CA_OPTION_MAX_MESSAGE_SIZE,
1052                               optionData, optionDataLength);
1053
1054             data = CAGenerateSignalingMessage(endpoint, CA_CSM, csmOpts, numOptions);
1055             if (!data)
1056             {
1057                 OIC_LOG(ERROR, TAG, "GenerateSignalingMessage failed");
1058                 return CA_STATUS_FAILED;
1059             }
1060             OICFree(csmOpts);
1061
1062             // #3. Add pdu to send queue.
1063             CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
1064         }
1065     }
1066 #endif
1067
1068     data = CAPrepareSendData(endpoint, sendMsg, dataType);
1069     if(!data)
1070     {
1071         OIC_LOG(ERROR, TAG, "CAPrepareSendData failed");
1072         return CA_MEMORY_ALLOC_FAILED;
1073     }
1074
1075     OIC_LOG_V(DEBUG, TAG, "device ID of endpoint of this message is %s", endpoint->remoteId);
1076
1077 #if defined(TCP_ADAPTER) && defined(WITH_CLOUD)
1078     CAResult_t ret = CACMGetMessageData(data);
1079     if (CA_STATUS_OK != ret)
1080     {
1081         OIC_LOG(DEBUG, TAG, "Ignore ConnectionManager");
1082     }
1083 #endif
1084
1085     if (SEND_TYPE_UNICAST == data->type && CAIsLocalEndpoint(data->remoteEndpoint))
1086     {
1087         OIC_LOG(DEBUG, TAG,
1088                 "This is a loopback message. Transfer it to the receive queue directly");
1089         CAQueueingThreadAddData(&g_receiveThread, data, sizeof(CAData_t));
1090         return CA_STATUS_OK;
1091     }
1092 #ifdef WITH_BWT
1093     if (CAIsSupportedBlockwiseTransfer(endpoint->adapter))
1094     {
1095         // send block data
1096         CAResult_t res = CASendBlockWiseData(data);
1097         if (CA_NOT_SUPPORTED == res)
1098         {
1099             OIC_LOG(DEBUG, TAG, "normal msg will be sent");
1100             CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
1101             return CA_STATUS_OK;
1102         }
1103         else
1104         {
1105             CADestroyData(data, sizeof(CAData_t));
1106         }
1107         return res;
1108     }
1109     else
1110 #endif // WITH_BWT
1111     {
1112         CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t));
1113     }
1114
1115     return CA_STATUS_OK;
1116 }
1117
1118 void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
1119                              CAErrorCallback errorHandler)
1120 {
1121     g_requestHandler = ReqHandler;
1122     g_responseHandler = RespHandler;
1123     g_errorHandler = errorHandler;
1124 }
1125
1126 void CASetNetworkMonitorCallback(CANetworkMonitorCallback nwMonitorHandler)
1127 {
1128     g_nwMonitorHandler = nwMonitorHandler;
1129 }
1130
1131 CAResult_t CAInitializeMessageHandler(CATransportAdapter_t transportType)
1132 {
1133     CASetPacketReceivedCallback(CAReceivedPacketCallback);
1134     CASetErrorHandleCallback(CAErrorHandler);
1135
1136     // create thread pool
1137     CAResult_t res = ca_thread_pool_init(MAX_THREAD_POOL_SIZE, &g_threadPoolHandle);
1138     if (CA_STATUS_OK != res)
1139     {
1140         OIC_LOG(ERROR, TAG, "thread pool initialize error.");
1141         return res;
1142     }
1143
1144     // send thread initialize
1145     res = CAQueueingThreadInitialize(&g_sendThread, g_threadPoolHandle,
1146                                      CASendThreadProcess, CADestroyData);
1147     if (CA_STATUS_OK != res)
1148     {
1149         OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
1150         return res;
1151     }
1152
1153     // start send thread
1154     res = CAQueueingThreadStart(&g_sendThread);
1155     if (CA_STATUS_OK != res)
1156     {
1157         OIC_LOG(ERROR, TAG, "thread start error(send thread).");
1158         return res;
1159     }
1160
1161     // receive thread initialize
1162     res = CAQueueingThreadInitialize(&g_receiveThread, g_threadPoolHandle,
1163                                      CAReceiveThreadProcess, CADestroyData);
1164     if (CA_STATUS_OK != res)
1165     {
1166         OIC_LOG(ERROR, TAG, "Failed to Initialize receive queue thread");
1167         return res;
1168     }
1169
1170 #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading
1171     // start receive thread
1172     res = CAQueueingThreadStart(&g_receiveThread);
1173     if (CA_STATUS_OK != res)
1174     {
1175         OIC_LOG(ERROR, TAG, "thread start error(receive thread).");
1176         return res;
1177     }
1178 #endif // SINGLE_HANDLE
1179
1180     // retransmission initialize
1181     res = CARetransmissionInitialize(&g_retransmissionContext, g_threadPoolHandle,
1182                                      CASendUnicastData, CATimeoutCallback, NULL);
1183     if (CA_STATUS_OK != res)
1184     {
1185         OIC_LOG(ERROR, TAG, "Failed to Initialize Retransmission.");
1186         return res;
1187     }
1188
1189 #ifdef WITH_BWT
1190     // block-wise transfer initialize
1191     res = CAInitializeBlockWiseTransfer(CAAddDataToSendThread, CAAddDataToReceiveThread);
1192     if (CA_STATUS_OK != res)
1193     {
1194         OIC_LOG(ERROR, TAG, "Failed to Initialize BlockWiseTransfer.");
1195         return res;
1196     }
1197 #endif
1198
1199     // start retransmission
1200     res = CARetransmissionStart(&g_retransmissionContext);
1201     if (CA_STATUS_OK != res)
1202     {
1203         OIC_LOG(ERROR, TAG, "thread start error(retransmission thread).");
1204         return res;
1205     }
1206
1207     // initialize interface adapters by controller
1208     res = CAInitializeAdapters(g_threadPoolHandle, transportType);
1209     if (CA_STATUS_OK != res)
1210     {
1211         OIC_LOG(ERROR, TAG, "Failed to Initialize Adapters.");
1212         return res;
1213     }
1214
1215     return CA_STATUS_OK;
1216 }
1217
1218 void CATerminateMessageHandler(void)
1219 {
1220     // stop adapters
1221     CAStopAdapters();
1222
1223     // stop retransmission
1224     if (NULL != g_retransmissionContext.threadMutex)
1225     {
1226         CARetransmissionStop(&g_retransmissionContext);
1227     }
1228
1229     // stop thread
1230     // delete thread data
1231     if (NULL != g_sendThread.threadMutex)
1232     {
1233         CAQueueingThreadStop(&g_sendThread);
1234     }
1235
1236     // stop thread
1237     // delete thread data
1238     if (NULL != g_receiveThread.threadMutex)
1239     {
1240 #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading
1241         CAQueueingThreadStop(&g_receiveThread);
1242 #endif
1243     }
1244
1245     // destroy thread pool
1246     if (NULL != g_threadPoolHandle)
1247     {
1248         ca_thread_pool_free(g_threadPoolHandle);
1249         g_threadPoolHandle = NULL;
1250     }
1251
1252 #ifdef WITH_BWT
1253     CATerminateBlockWiseTransfer();
1254 #endif
1255     CARetransmissionDestroy(&g_retransmissionContext);
1256     CAQueueingThreadDestroy(&g_sendThread);
1257     CAQueueingThreadDestroy(&g_receiveThread);
1258
1259     // terminate interface adapters by controller
1260     CATerminateAdapters();
1261 }
1262
1263 static void CALogPayloadInfo(CAInfo_t *info)
1264 {
1265     if (info)
1266     {
1267         if (info->options)
1268         {
1269             for (uint32_t i = 0; i < info->numOptions; i++)
1270             {
1271                 OIC_LOG_V(DEBUG, TAG, "optionID: %u", info->options[i].optionID);
1272
1273                 OIC_LOG_V(DEBUG, TAG, "list: %s", info->options[i].optionData);
1274             }
1275         }
1276
1277         if (info->payload)
1278         {
1279             OIC_LOG_V(DEBUG, TAG, "payload: %p(%" PRIuPTR ")", info->payload,
1280                       info->payloadSize);
1281         }
1282
1283         if (info->token)
1284         {
1285             OIC_LOG(DEBUG, TAG, "token:");
1286             OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) info->token,
1287                            info->tokenLength);
1288         }
1289         OIC_LOG_V(DEBUG, TAG, "msgID: %u", info->messageId);
1290     }
1291     else
1292     {
1293         OIC_LOG(DEBUG, TAG, "info is NULL, cannot output log data");
1294     }
1295 }
1296
1297 void CAErrorHandler(const CAEndpoint_t *endpoint,
1298                     const void *data, size_t dataLen,
1299                     CAResult_t result)
1300 {
1301     OIC_LOG(DEBUG, TAG, "CAErrorHandler IN");
1302     VERIFY_NON_NULL_VOID(endpoint, TAG, "remoteEndpoint");
1303     VERIFY_NON_NULL_VOID(data, TAG, "data");
1304
1305     if (0 == dataLen)
1306     {
1307         OIC_LOG(ERROR, TAG, "dataLen is zero");
1308         return;
1309     }
1310
1311     uint32_t code = CA_NOT_FOUND;
1312     //Do not free remoteEndpoint and data. Currently they will be freed in data thread
1313     //Get PDU data
1314     coap_pdu_t *pdu = (coap_pdu_t *)CAParsePDU((const char *)data, dataLen, &code, endpoint);
1315     if (NULL == pdu)
1316     {
1317         OIC_LOG(ERROR, TAG, "Parse PDU failed");
1318         return;
1319     }
1320
1321     CAData_t *cadata = CAGenerateHandlerData(endpoint, NULL, pdu, CA_ERROR_DATA);
1322     if (!cadata)
1323     {
1324         OIC_LOG(ERROR, TAG, "CAErrorHandler, CAGenerateHandlerData failed!");
1325         coap_delete_pdu(pdu);
1326         return;
1327     }
1328
1329 #ifdef WITH_TCP
1330     if (CAIsSupportedCoAPOverTCP(endpoint->adapter))
1331     {
1332         OIC_LOG(INFO, TAG, "retransmission is not supported");
1333     }
1334     else
1335 #endif
1336     {
1337         //Fix up CoAP message to adjust it to current retransmission implementation
1338         coap_hdr_t *hdr = (coap_hdr_t *)(pdu->transport_hdr);
1339         hdr->type = CA_MSG_RESET;
1340         hdr->code = CA_EMPTY;
1341
1342         // for retransmission
1343         void *retransmissionPdu = NULL;
1344         CARetransmissionReceivedData(&g_retransmissionContext, cadata->remoteEndpoint,
1345                                      pdu->transport_hdr, pdu->length, &retransmissionPdu);
1346
1347         // get token from saved data in retransmission list
1348         if (retransmissionPdu && cadata->errorInfo)
1349         {
1350             CAInfo_t *info = &cadata->errorInfo->info;
1351             CAResult_t res = CAGetTokenFromPDU((const coap_hdr_transport_t *)retransmissionPdu,
1352                                                info, endpoint);
1353             if (CA_STATUS_OK != res)
1354             {
1355                 OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
1356                 OICFree(info->token);
1357                 info->tokenLength = 0;
1358             }
1359         }
1360         OICFree(retransmissionPdu);
1361     }
1362
1363     cadata->errorInfo->result = result;
1364
1365     CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
1366     coap_delete_pdu(pdu);
1367
1368     OIC_LOG(DEBUG, TAG, "CAErrorHandler OUT");
1369     return;
1370 }
1371
1372 static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info, CAResult_t result)
1373 {
1374     OIC_LOG(DEBUG, TAG, "CASendErrorInfo IN");
1375     CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
1376     if (!cadata)
1377     {
1378         OIC_LOG(ERROR, TAG, "cadata memory allocation failed");
1379         return;
1380     }
1381
1382     CAEndpoint_t* ep = CACloneEndpoint(endpoint);
1383     if (!ep)
1384     {
1385         OIC_LOG(ERROR, TAG, "endpoint clone failed");
1386         OICFree(cadata);
1387         return;
1388     }
1389
1390     CAErrorInfo_t *errorInfo = (CAErrorInfo_t *)OICCalloc(1, sizeof (CAErrorInfo_t));
1391     if (!errorInfo)
1392     {
1393         OIC_LOG(ERROR, TAG, "errorInfo memory allocation failed");
1394         OICFree(cadata);
1395         CAFreeEndpoint(ep);
1396         return;
1397     }
1398
1399     CAResult_t res = CACloneInfo(info, &errorInfo->info);
1400     if (CA_STATUS_OK != res)
1401     {
1402         OIC_LOG(ERROR, TAG, "info clone failed");
1403         OICFree(cadata);
1404         OICFree(errorInfo);
1405         CAFreeEndpoint(ep);
1406         return;
1407     }
1408
1409     errorInfo->result = result;
1410     cadata->remoteEndpoint = ep;
1411     cadata->errorInfo = errorInfo;
1412     cadata->dataType = CA_ERROR_DATA;
1413
1414     CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
1415     OIC_LOG(DEBUG, TAG, "CASendErrorInfo OUT");
1416 }
1417
1418 static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu)
1419 {
1420     OIC_LOG(DEBUG, TAG, "CALogPDUInfo");
1421
1422     VERIFY_NON_NULL_VOID(data, TAG, "data");
1423     VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
1424     OIC_TRACE_BEGIN(%s:CALogPDUInfo, TAG);
1425
1426     OIC_LOG(DEBUG, ANALYZER_TAG, "=================================================");
1427     if(SEND_TYPE_MULTICAST == data->type)
1428     {
1429         OIC_LOG(DEBUG, ANALYZER_TAG, "Is Multicast = true");
1430     }
1431     else
1432     {
1433         OIC_LOG(DEBUG, ANALYZER_TAG, "Is Multicast = false");
1434     }
1435
1436     if (NULL != data->remoteEndpoint)
1437     {
1438         CALogAdapterTypeInfo(data->remoteEndpoint->adapter);
1439         OIC_LOG_V(DEBUG, ANALYZER_TAG, "Address = [%s]:[%d]", data->remoteEndpoint->addr,
1440                   data->remoteEndpoint->port);
1441     }
1442
1443     switch(data->dataType)
1444     {
1445         case CA_REQUEST_DATA:
1446             OIC_LOG(DEBUG, ANALYZER_TAG, "Data Type = [CA_REQUEST_DATA]");
1447             break;
1448         case CA_RESPONSE_DATA:
1449             OIC_LOG(DEBUG, ANALYZER_TAG, "Data Type = [CA_RESPONSE_DATA]");
1450             break;
1451         case CA_ERROR_DATA:
1452             OIC_LOG(DEBUG, ANALYZER_TAG, "Data Type = [CA_ERROR_DATA]");
1453             break;
1454         case CA_RESPONSE_FOR_RES:
1455             OIC_LOG(DEBUG, ANALYZER_TAG, "Data Type = [CA_RESPONSE_FOR_RES]");
1456             break;
1457         default:
1458             OIC_LOG_V(DEBUG, ANALYZER_TAG, "Data Type = [%d]", data->dataType);
1459             break;
1460     }
1461     OIC_LOG(DEBUG, ANALYZER_TAG, "-------------------------------------------------");
1462
1463     const CAInfo_t *info = NULL;
1464     if (NULL != data->requestInfo)
1465     {
1466         switch(data->requestInfo->method)
1467         {
1468             case CA_GET:
1469                 OIC_LOG(DEBUG, ANALYZER_TAG, "Method = [GET]");
1470                 break;
1471             case CA_POST:
1472                 OIC_LOG(DEBUG, ANALYZER_TAG, "Method = [POST]");
1473                 break;
1474             case CA_PUT:
1475                 OIC_LOG(DEBUG, ANALYZER_TAG, "Method = [PUT]");
1476                 break;
1477             case CA_DELETE:
1478                 OIC_LOG(DEBUG, ANALYZER_TAG, "Method = [DELETE]");
1479                 break;
1480             default:
1481                 OIC_LOG_V(DEBUG, ANALYZER_TAG, "Method = [%d]", data->requestInfo->method);
1482                 break;
1483         }
1484         info = &data->requestInfo->info;
1485     }
1486
1487     if (NULL != data->responseInfo)
1488     {
1489         OIC_LOG_V(DEBUG, ANALYZER_TAG, "result code = [%d]", data->responseInfo->result);
1490         info = &data->responseInfo->info;
1491     }
1492
1493     if (pdu->transport_hdr)
1494     {
1495         OIC_LOG_V(DEBUG, ANALYZER_TAG, "Msg ID = [%u]",
1496             (uint32_t)ntohs(pdu->transport_hdr->udp.id));
1497     }
1498
1499     if (info)
1500     {
1501         OIC_LOG(DEBUG, ANALYZER_TAG, "Coap Token");
1502         OIC_LOG_BUFFER(DEBUG, ANALYZER_TAG, (const uint8_t *) info->token, info->tokenLength);
1503         OIC_TRACE_BUFFER("OIC_CA_MSG_HANDLE:CALogPDUInfo:token:", (const uint8_t *) info->token,
1504                          info->tokenLength);
1505         OIC_LOG_V(DEBUG, ANALYZER_TAG, "Res URI = [%s]", info->resourceUri);
1506         OIC_TRACE_MARK(%s:CALogPDUInfo:uri:%s, TAG, info->resourceUri);
1507
1508         if (CA_FORMAT_APPLICATION_CBOR == info->payloadFormat)
1509         {
1510             OIC_LOG(DEBUG, ANALYZER_TAG, "Payload Format = [CA_FORMAT_APPLICATION_CBOR]");
1511         }
1512         else if (CA_FORMAT_APPLICATION_VND_OCF_CBOR == info->payloadFormat)
1513         {
1514             OIC_LOG(DEBUG, ANALYZER_TAG, "Payload Format = [CA_FORMAT_APPLICATION_VND_OCF_CBOR]");
1515         }
1516         else
1517         {
1518             OIC_LOG_V(DEBUG, ANALYZER_TAG, "Payload Format = [%d]", info->payloadFormat);
1519         }
1520     }
1521
1522 #ifdef TB_LOG
1523     size_t payloadLen = (pdu->data) ? (unsigned char *)pdu->hdr + pdu->length - pdu->data : 0;
1524 #endif
1525     OIC_LOG_V(DEBUG, ANALYZER_TAG, "CoAP Message Full Size = [%u]", pdu->length);
1526     OIC_LOG(DEBUG, ANALYZER_TAG, "CoAP Header (+ 0xFF)");
1527     OIC_LOG_BUFFER(DEBUG, ANALYZER_TAG,  (const uint8_t *) pdu->transport_hdr,
1528                    pdu->length - payloadLen);
1529     OIC_LOG_V(DEBUG, ANALYZER_TAG, "CoAP Header size = [%" PRIuPTR "]", (size_t) pdu->length - payloadLen);
1530
1531     OIC_LOG_V(DEBUG, ANALYZER_TAG, "CoAP Payload");
1532     //OIC_LOG_BUFFER(DEBUG, ANALYZER_TAG, pdu->data, payloadLen);
1533     OIC_LOG_V(DEBUG, ANALYZER_TAG, "CoAP Payload Size = [%" PRIuPTR "]", payloadLen);
1534     OIC_LOG(DEBUG, ANALYZER_TAG, "=================================================");
1535     OIC_TRACE_END();
1536 }
1537
1538 #ifdef TCP_ADAPTER
1539 CAResult_t CAAddHeaderOption(CAHeaderOption_t **hdrOpt, uint8_t *numOptions,
1540                              uint16_t optionID, void *optionData, size_t optionDataLength)
1541 {
1542     OIC_LOG_V(DEBUG, TAG, "Entering CAAddHeaderOption with optionID: %d", optionID);
1543
1544     VERIFY_NON_NULL(hdrOpt, TAG, "hdrOpt");
1545     VERIFY_NON_NULL(numOptions, TAG, "numOptions");
1546     VERIFY_NON_NULL(optionData, TAG, "optionData");
1547
1548     CAHeaderOption_t *tmpOpt = OICRealloc(*hdrOpt, (*numOptions + 1) * sizeof(CAHeaderOption_t));
1549     if (!tmpOpt)
1550     {
1551         OIC_LOG(ERROR, TAG, "out of memory");
1552         return CA_MEMORY_ALLOC_FAILED;
1553     }
1554
1555     tmpOpt[*numOptions].protocolID = CA_COAP_ID;
1556     tmpOpt[*numOptions].optionID = optionID;
1557     tmpOpt[*numOptions].optionLength = (uint16_t)optionDataLength;
1558
1559     if (optionData)
1560     {
1561         memcpy(tmpOpt[*numOptions].optionData, optionData,
1562                sizeof(tmpOpt[*numOptions].optionData));
1563     }
1564
1565     // increase the number of options.
1566     *numOptions += 1;
1567     *hdrOpt = tmpOpt;
1568
1569     OIC_LOG(DEBUG, TAG, "Added option successfully");
1570     return CA_STATUS_OK;
1571 }
1572
1573 CAResult_t CAGetHeaderOption(CAHeaderOption_t *hdrOpt, size_t numOptions, uint16_t optionID,
1574                              void *optionData, size_t optionDataLength, uint16_t *receivedDataLen)
1575 {
1576     OIC_LOG_V(DEBUG, TAG, "Entering CAGetHeaderOption with optionID: %d", optionID);
1577
1578     VERIFY_NON_NULL(hdrOpt, TAG, "hdrOpt");
1579     VERIFY_NON_NULL(optionData, TAG, "optionData");
1580     VERIFY_NON_NULL(receivedDataLen, TAG, "receivedDataLen");
1581
1582     for (size_t i = 0; i < numOptions; i++)
1583     {
1584         if (hdrOpt[i].optionID == optionID)
1585         {
1586             if (optionDataLength >= hdrOpt[i].optionLength)
1587             {
1588                 memcpy(optionData, hdrOpt[i].optionData, hdrOpt[i].optionLength);
1589                 *receivedDataLen = hdrOpt[i].optionLength;
1590                 return CA_STATUS_OK;
1591             }
1592         }
1593     }
1594
1595     return CA_STATUS_NOT_FOUND;
1596 }
1597
1598 CAData_t *CAGenerateSignalingMessage(const CAEndpoint_t *endpoint, CASignalingCode_t code,
1599                                      CAHeaderOption_t *headerOpt, uint8_t numOptions)
1600 {
1601     OIC_LOG(DEBUG, TAG, "GenerateSignalingMessage - IN");
1602
1603     // create token for signaling message.
1604     CAToken_t token = NULL;
1605     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
1606     if (CA_STATUS_OK != CAGenerateTokenInternal(&token, tokenLength))
1607     {
1608         OIC_LOG(ERROR, TAG, "CAGenerateTokenInternal failed");
1609         return NULL;
1610     }
1611
1612     CAInfo_t signalingData = { .type = CA_MSG_NONCONFIRM,
1613                                .token = token,
1614                                .tokenLength = tokenLength,
1615                                .numOptions = numOptions,
1616                                .options = headerOpt };
1617
1618     CASignalingInfo_t sigMsg = { .code = code,
1619                                  .info = signalingData };
1620
1621     return CAPrepareSendData(endpoint, &sigMsg, CA_SIGNALING_DATA);
1622 }
1623
1624 CAData_t *CAGenerateSignalingMessageUsingToken(const CAEndpoint_t *endpoint, CASignalingCode_t code,
1625                                                CAHeaderOption_t *headerOpt, uint8_t numOptions,
1626                                                const CAToken_t pingToken, uint8_t pingTokenLength)
1627 {
1628     OIC_LOG(DEBUG, TAG, "GenerateSignalingMessage - IN");
1629
1630     // create token for signaling message.
1631     CAToken_t token = (char *)OICCalloc(pingTokenLength + 1, sizeof(char));
1632     OICStrcpy(token, pingTokenLength, pingToken);
1633
1634     CAInfo_t signalingData = { .type = CA_MSG_NONCONFIRM,
1635                                .token = token,
1636                                .tokenLength = pingTokenLength,
1637                                .numOptions = numOptions,
1638                                .options = headerOpt };
1639
1640     CASignalingInfo_t sigMsg = { .code = code,
1641                                  .info = signalingData };
1642
1643     return CAPrepareSendData(endpoint, &sigMsg, CA_SIGNALING_DATA);
1644 }
1645 #endif //TCP_ADAPTER