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