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