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