replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_edr_adapter / caedradapter.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 /**
22  * @file
23  *
24  * This file contains the APIs for EDR adapter.
25  */
26
27 #include "caedradapter.h"
28
29 #include "caedrinterface.h"
30 #include "caadapterutils.h"
31 #include "logger.h"
32 #include "caqueueingthread.h"
33 #include "oic_malloc.h"
34 #include "caremotehandler.h"
35 #include <coap/pdu.h>
36
37 /**
38  * Logging tag for module name.
39  */
40 #define TAG "OIC_CA_EDR_ADAP"
41
42 /**
43  * Reference to threadpool.
44  */
45 static ca_thread_pool_t g_edrThreadPool = NULL;
46
47 /**
48  * Queue handle for Send Data
49  */
50 static CAQueueingThread_t *g_sendQueueHandle = NULL;
51
52 /**
53  * Queue handle for Receive Data
54  */
55 static CAQueueingThread_t *g_recvQueueHandle = NULL;
56
57 /**
58  * Storing Adapter state information
59  */
60 static bool g_adapterState = true;
61
62 /**
63  * Maintains the callback to be notified on receival of network packets from other
64  * Bluetooth devices.
65  */
66 static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
67
68 /**
69  * Maintains the callback to be notified on local bluetooth adapter status change.
70  */
71 static CAAdapterChangeCallback g_adapterChangeCallback = NULL;
72
73 /**
74  * error Callback to CA adapter
75  */
76 static CAErrorHandleCallback g_errorCallback = NULL;
77
78 /**
79  * Information of local Bluetooth adapter.
80  */
81 static CAEndpoint_t *g_localConnectivity = NULL;
82
83 /**
84  * Storing Rfcommserver state information
85  */
86 static bool g_serverState = false;
87
88 static CAResult_t CAStartServer();
89 static CAResult_t CAEDRInitializeQueueHandlers();
90 CAResult_t CAEDRInitializeSendHandler();
91 CAResult_t CAEDRInitializeReceiveHandler();
92 void CAAdapterTerminateQueues();
93 void CAAdapterDataSendHandler(void *context);
94 void CAAdapterDataReceiverHandler(void *context);
95 CAResult_t CAAdapterStopQueue();
96 CAResult_t CAAdapterRecvData(const char *remoteAddress, const uint8_t *data,
97                              uint32_t dataLength, uint32_t *sentLength);
98 void CAEDRNotifyNetworkStatus(CANetworkStatus_t status);
99 void CAEDROnNetworkStatusChanged(void *context);
100 CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID,
101                              const uint8_t *data, uint32_t dataLength, uint32_t *sentLength);
102 CAEDRNetworkEvent *CAEDRCreateNetworkEvent(CAEndpoint_t *connectivity, CANetworkStatus_t status);
103 CAResult_t CAEDRClientSendData(const char *remoteAddress, const uint8_t *data,
104                                uint32_t dataLength);
105
106 /**
107  * @fn CACreateEDRData
108  * @brief Helper function to create CAEDRData
109  */
110 static CAEDRData *CACreateEDRData(const CAEndpoint_t *remoteEndpoint, const uint8_t *data,
111                                   uint32_t dataLength);
112
113 /**
114  * @fn CAFreeEDRData
115  * @brief Free the Created EDR data
116  */
117 static void CAFreeEDRData(CAEDRData *edrData);
118
119 /**
120  * @fn CAEDRFreeNetworkEvent
121  * @brief Free the memory associated with @event.
122  */
123 void CAEDRFreeNetworkEvent(CAEDRNetworkEvent *event);
124
125 static void CAEDRDataDestroyer(void *data, uint32_t size);
126
127 static void CAEDRErrorHandler(const char *remoteAddress, const uint8_t *data,
128                               uint32_t dataLength, CAResult_t result);
129
130 CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
131                            CANetworkPacketReceivedCallback packetReceivedCallback,
132                            CAAdapterChangeCallback netCallback,
133                            CAConnectionChangeCallback connCallback,
134                            CAErrorHandleCallback errorCallback, ca_thread_pool_t handle)
135 {
136     // Input validation
137     VERIFY_NON_NULL(registerCallback, TAG, "register callback is NULL");
138     VERIFY_NON_NULL(packetReceivedCallback, TAG, "data receive callback is NULL");
139     VERIFY_NON_NULL(netCallback, TAG, "adapter state change callback is NULL");
140     VERIFY_NON_NULL(connCallback, TAG, "connection state change callback is NULL");
141     VERIFY_NON_NULL(handle, TAG, "Thread pool handle is NULL");
142
143     // Register the callbacks
144     g_edrThreadPool = handle;
145     g_networkPacketReceivedCallback = packetReceivedCallback;
146     g_adapterChangeCallback = netCallback;
147     g_errorCallback = errorCallback;
148
149     // Initialize EDR Network Monitor
150     CAResult_t res = CAEDRInitializeNetworkMonitor(handle);
151     if (CA_STATUS_OK != res)
152     {
153         OIC_LOG_V(ERROR, TAG, "EDR N/w Monitor Initialize failed!, error number [%d]", res);
154         return res;
155     }
156
157     CAEDRSetNetworkChangeCallback(CAEDRNotifyNetworkStatus);
158     CAEDRSetPacketReceivedCallback(CAAdapterRecvData);
159     CAEDRSetErrorHandler(CAEDRErrorHandler);
160     res = CAEDRClientInitialize();
161     if (CA_STATUS_OK != res)
162     {
163         OIC_LOG_V(ERROR, TAG, "EDR Client Initialize failed, error number [%d]", res);
164         return res;
165     }
166
167     res = CAEDRServerInitialize(handle);
168     if (CA_STATUS_OK != res)
169     {
170         OIC_LOG_V(ERROR, TAG, "EDR Server Initialize failed, error number [%d]", res);
171         return res;
172     }
173
174     static const CAConnectivityHandler_t handler =
175         {
176             .startAdapter = CAStartEDR,
177             .stopAdapter = CAStopEDR,
178             .startListenServer = CAStartEDRListeningServer,
179             .stopListenServer = CAStopEDRListeningServer,
180             .startDiscoveryServer = CAStartEDRDiscoveryServer,
181             .sendData = CASendEDRUnicastData,
182             .sendDataToAll = CASendEDRMulticastData,
183             .GetnetInfo = CAGetEDRInterfaceInformation,
184             .readData = CAReadEDRData,
185             .terminate = CATerminateEDR,
186             .cType = CA_ADAPTER_RFCOMM_BTEDR
187         };
188     registerCallback(handler);
189
190     OIC_LOG(DEBUG, TAG, "OUT");
191     return CA_STATUS_OK;
192 }
193
194 CAResult_t CAStartEDR()
195 {
196     //Start Monitoring EDR Network
197     CAResult_t ret = CAEDRStartNetworkMonitor();
198     if (CA_STATUS_OK != ret)
199     {
200        OIC_LOG(ERROR, TAG, "Failed to Start n/w monitor");
201     }
202
203     // Get Bluetooth adapter state
204     bool adapterState = false;
205     if (CA_STATUS_OK != CAEDRGetAdapterEnableState(&adapterState))
206     {
207         OIC_LOG(ERROR, TAG, "Failed to get adapter enable state");
208         return CA_STATUS_FAILED;
209     }
210
211     if (false == adapterState)
212     {
213         OIC_LOG(ERROR, TAG, "Bluetooth adapter is disabled!");
214         g_adapterState = false;
215         return CA_ADAPTER_NOT_ENABLED;
216     }
217
218     if (CA_STATUS_OK != (ret = CAEDRClientSetCallbacks()))
219     {
220         OIC_LOG_V(ERROR, TAG, "Start Network Monitor failed!, error number [%d] ",
221                   ret);
222     }
223
224     // Initialize Send/Receive data message queues
225     if (CA_STATUS_OK != (ret = CAEDRInitializeQueueHandlers()))
226     {
227         OIC_LOG_V(ERROR, TAG,
228                   "CAAdapterInitializeQueues failed!, error number [%d] ", ret);
229         CATerminateEDR();
230         return CA_STATUS_FAILED;
231     }
232
233     // Start Send/Receive data message queues
234     if (CA_STATUS_OK != (ret = CAAdapterStartQueue()))
235     {
236         OIC_LOG_V(ERROR, TAG, "CAAdapterStartQueue failed!, error number [%d] ", ret);
237     }
238
239     return ret;
240 }
241
242 CAResult_t CAStartEDRListeningServer()
243 {
244     return CAStartServer();
245 }
246
247 CAResult_t CAStopEDRListeningServer()
248 {
249     return CAEDRServerStop();
250 }
251
252 CAResult_t CAStartEDRDiscoveryServer()
253 {
254 #ifdef __TIZEN__
255     // Start device discovery
256     CAResult_t result = CAEDRStartDeviceDiscovery();
257     if(CA_STATUS_OK != result)
258     {
259         OIC_LOG(DEBUG, TAG, "Failed to Start Device discovery");
260     }
261 #endif
262
263     return CAStartServer();
264 }
265
266 int32_t CASendEDRUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
267                              uint32_t dataLength, CADataType_t dataType)
268 {
269     // Input validation
270     VERIFY_NON_NULL_RET(remoteEndpoint, TAG, "Remote endpoint is null", -1);
271     VERIFY_NON_NULL_RET(data, TAG, "Data is null", -1);
272     (void)dataType;
273
274     if (0 == dataLength)
275     {
276         OIC_LOG(ERROR, TAG, "Invalid input: data length is zero!");
277         return -1;
278     }
279
280     if (0 == strlen(remoteEndpoint->addr))
281     {
282         OIC_LOG(ERROR, TAG, "Invalid input: EDR Address is empty!");
283         return -1;
284     }
285
286     uint32_t sentLength = 0;
287     const char *serviceUUID = OIC_EDR_SERVICE_ID;
288     const char *address = remoteEndpoint->addr;
289     CAResult_t err = CAAdapterSendData(address, serviceUUID, data, dataLength, &sentLength);
290     if (CA_STATUS_OK != err)
291     {
292         OIC_LOG_V(ERROR, TAG, "Send unicast data failed!, error num [%d]", err);
293         g_errorCallback(remoteEndpoint, data, dataLength, err);
294         return -1;
295     }
296
297     return sentLength;
298 }
299
300 int32_t CASendEDRMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength,
301                                CADataType_t dataType)
302 {
303     OIC_LOG(DEBUG, TAG, "IN - CASendEDRMulticastData");
304     (void)dataType;
305
306     // Input validation
307     VERIFY_NON_NULL_RET(data, TAG, "Data is null", -1);
308
309     if (0 == dataLength)
310     {
311         OIC_LOG(ERROR, TAG, "Invalid input: data length is zero!");
312         return -1;
313     }
314
315     uint32_t sentLen = 0;
316     const char *serviceUUID = OIC_EDR_SERVICE_ID;
317     CAResult_t err = CAAdapterSendData(NULL, serviceUUID, data, dataLength, &sentLen);
318     if (CA_STATUS_OK != err)
319     {
320         OIC_LOG_V(ERROR, TAG, "Send multicast data failed!, error num [%d]", err);
321         g_errorCallback(endpoint, data, dataLength, err);
322         return -1;
323     }
324
325     OIC_LOG(DEBUG, TAG, "OUT - CASendEDRMulticastData");
326     return sentLen;
327 }
328
329 CAResult_t CAGetEDRInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
330 {
331     VERIFY_NON_NULL(info, TAG, "LocalConnectivity info is null");
332
333     CAResult_t err = CA_STATUS_OK;
334     *size = 0;
335     if (CA_STATUS_OK != (err = CAEDRGetInterfaceInformation(info)))
336     {
337         OIC_LOG_V(ERROR, TAG, "Failed to get local interface information!, error num [%d]", err);
338         return err;
339     }
340
341     *size = 1;
342     return err;
343 }
344
345 CAResult_t CAReadEDRData()
346 {
347     return CAEDRManagerReadData();
348 }
349
350 CAResult_t CAStopEDR()
351 {
352     // Stop RFComm server if it is running
353     CAEDRServerStop();
354
355     // Stop the adapter
356     CAEDRClientUnsetCallbacks();
357
358     // Disconnect all the client connections
359     CAEDRClientDisconnectAll();
360
361     // Stop network monitor
362     CAEDRStopNetworkMonitor();
363
364     // Stop Send and receive Queue
365     CAAdapterStopQueue();
366
367     return CA_STATUS_OK;
368 }
369
370 void CATerminateEDR()
371 {
372     // Terminate EDR Network Monitor
373     CAEDRTerminateNetworkMonitor();
374
375     // Terminate Send/Receive data messages queues
376     CAAdapterTerminateQueues();
377
378     g_networkPacketReceivedCallback = NULL;
379     g_adapterChangeCallback = NULL;
380
381     // Terminate thread pool
382     g_edrThreadPool = NULL;
383
384     // Terminate EDR Client
385     CAEDRClientTerminate();
386
387     // Terminate EDR Server
388     CAEDRServerTerminate();
389
390     // Free LocalConnectivity information
391     CAFreeEndpoint(g_localConnectivity);
392     g_localConnectivity = NULL;
393 }
394
395 CAResult_t CAStartServer()
396 {
397     if (false == g_adapterState)
398     {
399         OIC_LOG(DEBUG, TAG, "Bluetooth adapter is disabled!");
400         // Setting g_serverState for starting Rfcommserver when adapter starts
401         g_serverState = true;
402         return CA_STATUS_OK;
403     }
404
405     CAResult_t err = CA_STATUS_OK;
406     if (CA_STATUS_OK != (err = CAEDRServerStart()))
407     {
408         OIC_LOG_V(ERROR, TAG, "Failed to start RFCOMM server!, error num [%d]",
409                   err);
410         return err;
411     }
412
413     return err;
414 }
415
416 CAResult_t CAEDRInitializeQueueHandlers()
417 {
418     if (CA_STATUS_OK == CAEDRInitializeSendHandler()
419         && CA_STATUS_OK == CAEDRInitializeReceiveHandler())
420     {
421         OIC_LOG(DEBUG, TAG, "Queue is initialized!");
422         return CA_STATUS_OK;
423     }
424
425     return CA_STATUS_FAILED;
426 }
427
428 CAResult_t CAEDRInitializeSendHandler()
429 {
430     // Check if the message queue is already initialized
431     if (g_sendQueueHandle)
432     {
433         OIC_LOG(DEBUG, TAG, "Already queue is initialized!");
434         return CA_STATUS_OK;
435     }
436
437     g_sendQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
438     if (!g_sendQueueHandle)
439     {
440         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
441         return CA_MEMORY_ALLOC_FAILED;
442     }
443
444     if (CA_STATUS_OK != CAQueueingThreadInitialize(g_sendQueueHandle, g_edrThreadPool,
445                                                    CAAdapterDataSendHandler, CAEDRDataDestroyer))
446     {
447         OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
448         return CA_STATUS_FAILED;
449     }
450     return CA_STATUS_OK;
451 }
452
453 CAResult_t CAEDRInitializeReceiveHandler()
454 {
455     // Check if the message queue is already initialized
456     if (g_recvQueueHandle)
457     {
458         OIC_LOG(DEBUG, TAG, "Already queue is initialized!");
459         return CA_STATUS_OK;
460     }
461
462     g_recvQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
463     if (!g_recvQueueHandle)
464     {
465         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
466         return CA_MEMORY_ALLOC_FAILED;
467     }
468
469
470     if (CA_STATUS_OK != CAQueueingThreadInitialize(g_recvQueueHandle, g_edrThreadPool,
471                                                    CAAdapterDataReceiverHandler,
472                                                    CAEDRDataDestroyer))
473     {
474         OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
475         OICFree(g_recvQueueHandle);
476         g_recvQueueHandle = NULL;
477         return CA_STATUS_FAILED;
478     }
479
480     return CA_STATUS_OK;
481 }
482
483 void CAAdapterTerminateQueues()
484 {
485     if (g_sendQueueHandle)
486     {
487         CAQueueingThreadDestroy(g_sendQueueHandle);
488         g_sendQueueHandle = NULL;
489     }
490     if (g_recvQueueHandle)
491     {
492         CAQueueingThreadDestroy(g_recvQueueHandle);
493         g_recvQueueHandle = NULL;
494     }
495 }
496
497 void CAAdapterDataSendHandler(void *context)
498 {
499     OIC_LOG(DEBUG, TAG, "IN - CAAdapterDataSendHandler");
500
501     CAEDRData *message = (CAEDRData *) context;
502     if (!message)
503     {
504         OIC_LOG(ERROR, TAG, "Failed to get message!");
505         return;
506     }
507
508     if (!message->remoteEndpoint)
509     {
510         OIC_LOG(DEBUG, TAG, "remoteEndpoint is not available");
511         return;
512     }
513
514     const char *remoteAddress = message->remoteEndpoint->addr;
515     if(!remoteAddress)
516     {
517         OIC_LOG(ERROR, TAG, "EDR Send Message error");
518         //Error cannot be sent if remote address is NULL
519         return;
520     }
521
522     CAResult_t result = CAEDRClientSendData(remoteAddress, message->data, message->dataLen);
523     if(CA_STATUS_OK != result)
524     {
525         OIC_LOG(ERROR, TAG, "CAEDRClientSendData API failed");
526         CAEDRErrorHandler(remoteAddress, message->data, message->dataLen, result);
527         return;
528     }
529
530     OIC_LOG(DEBUG, TAG, "OUT");
531 }
532
533 CAResult_t CAEDRClientSendData(const char *remoteAddress, const uint8_t *data,
534                                uint32_t dataLength)
535 {
536     CAResult_t result = CA_SEND_FAILED;
537
538     // Send the first segment with the header.
539     if ((NULL != remoteAddress) && (0 < strlen(remoteAddress))) //Unicast data
540     {
541         result = CAEDRClientSendUnicastData(remoteAddress, data, dataLength);
542         if (CA_STATUS_OK != result)
543         {
544             OIC_LOG(ERROR, TAG, "Failed to send unicast data !");
545             return result;
546         }
547     }
548     else
549     {
550         OIC_LOG_V(DEBUG, TAG, "sending multicast data : %s", data);
551         result = CAEDRClientSendMulticastData(data, dataLength);
552
553         if (CA_STATUS_OK != result)
554         {
555             OIC_LOG(ERROR, TAG, "Failed to send multicast data !");
556             return result;
557         }
558     }
559     return result;
560 }
561
562 void CAAdapterDataReceiverHandler(void *context)
563 {
564     OIC_LOG(DEBUG, TAG, "IN_CAAdapterDataReceiverHandler");
565
566     if (NULL == g_networkPacketReceivedCallback)
567     {
568         OIC_LOG(ERROR, TAG, "g_networkPacketReceivedCallback is NULL");
569         return;
570     }
571
572     CAEDRData *message = (CAEDRData *) context;
573     if (NULL == message || NULL == message->remoteEndpoint)
574     {
575         OIC_LOG(ERROR, TAG, "Failed to get message!");
576         return;
577     }
578
579     CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
580                                                           CA_ADAPTER_RFCOMM_BTEDR,
581                                                           message->remoteEndpoint->addr,
582                                                           0);
583
584     if (!remoteEndpoint)
585     {
586         OIC_LOG(ERROR, TAG, "remoteEndpoint is NULL");
587         return;
588     }
589
590     OIC_LOG(DEBUG, TAG, "Sending data up !");
591
592     const CASecureEndpoint_t sep = { .endpoint = *remoteEndpoint };
593
594     g_networkPacketReceivedCallback(&sep, message->data, message->dataLen);
595
596     CAFreeEndpoint(remoteEndpoint);
597
598     OIC_LOG(DEBUG, TAG, "OUT_CAAdapterDataReceiverHandler");
599 }
600
601 CAResult_t CAAdapterStartQueue()
602 {
603     // Start send queue thread
604     if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle))
605     {
606         OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread");
607         CAEDRClientUnsetCallbacks();
608         //Disconnect all the client connections
609         CAEDRClientDisconnectAll();
610         return CA_STATUS_FAILED;
611     }
612
613     // Start receive queue thread
614     if (CA_STATUS_OK != CAQueueingThreadStart(g_recvQueueHandle))
615     {
616         OIC_LOG(ERROR, TAG, "Failed to Start Receive Data Thread");
617         CAEDRClientUnsetCallbacks();
618         //Disconnect all the client connections
619         CAEDRClientDisconnectAll();
620         return CA_STATUS_FAILED;
621     }
622
623     return CA_STATUS_OK;
624 }
625
626 CAResult_t CAAdapterStopQueue()
627 {
628     //Stop send queue thread
629     CAQueueingThreadStop(g_sendQueueHandle);
630
631     //Stop receive queue thread
632     CAQueueingThreadStop(g_recvQueueHandle);
633
634     return CA_STATUS_OK;
635 }
636
637 CAResult_t CAAdapterRecvData(const char *remoteAddress, const uint8_t *data,
638                              uint32_t dataLength, uint32_t *sentLength)
639 {
640     if (false == g_adapterState)
641     {
642         OIC_LOG_V(ERROR, TAG, "Bluetooth adapter is disabled!");
643         *sentLength = 0;
644         return CA_ADAPTER_NOT_ENABLED;
645     }
646
647     // Input validation
648     VERIFY_NON_NULL(data, TAG, "Data is null");
649     VERIFY_NON_NULL(sentLength, TAG, "Sent data length holder is null");
650
651     // Create remote endpoint
652     CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
653                                                           CA_ADAPTER_RFCOMM_BTEDR,
654                                                           remoteAddress, 0);
655     if (NULL == remoteEndpoint)
656     {
657         OIC_LOG(ERROR, TAG, "Failed to create remote endpoint !");
658         return CA_STATUS_FAILED;
659     }
660
661     // Add message to data queue
662     CAEDRData *edrData =  CACreateEDRData(remoteEndpoint, data, dataLength);
663     CAQueueingThreadAddData(g_recvQueueHandle, edrData, sizeof(CAEDRData));
664     *sentLength = dataLength;
665
666     // Free remote endpoint
667     CAFreeEndpoint(remoteEndpoint);
668
669     return CA_STATUS_OK;
670 }
671
672 void CAEDRErrorHandler(const char *remoteAddress, const uint8_t *data,
673                        uint32_t dataLength, CAResult_t result)
674 {
675     // Input validation
676     VERIFY_NON_NULL_VOID(data, TAG, "Data is null");
677
678     // Create remote endpoint
679     CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(0, CA_ADAPTER_RFCOMM_BTEDR,
680                                                            remoteAddress, 0);
681     if (!remoteEndpoint)
682     {
683         OIC_LOG(ERROR, TAG, "Failed to create remote endpoint !");
684         return;
685     }
686
687     g_errorCallback(remoteEndpoint, data, dataLength, result);
688
689     // Free remote endpoint
690     CAFreeEndpoint(remoteEndpoint);
691 }
692
693 CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID, const uint8_t *data,
694                              uint32_t dataLength, uint32_t *sentLength)
695 {
696     OIC_LOG(DEBUG, TAG, "IN - CAAdapterSendData");
697
698     if (false == g_adapterState)
699     {
700         OIC_LOG(ERROR, TAG, "Bluetooth adapter is disabled!");
701         *sentLength = 0;
702         return CA_ADAPTER_NOT_ENABLED;
703     }
704     // Input validation
705     VERIFY_NON_NULL(serviceUUID, TAG, "service UUID is null");
706     VERIFY_NON_NULL(data, TAG, "Data is null");
707     VERIFY_NON_NULL(sentLength, TAG, "Sent data length holder is null");
708
709     // Create remote endpoint
710     CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
711                                                           CA_ADAPTER_RFCOMM_BTEDR,
712                                                           remoteAddress, 0);
713     if (NULL == remoteEndpoint)
714     {
715         OIC_LOG(ERROR, TAG, "Failed to create remote endpoint !");
716         return CA_MEMORY_ALLOC_FAILED;
717     }
718
719     // Add message to data queue
720     CAEDRData *edrData =  CACreateEDRData(remoteEndpoint, data, dataLength);
721     CAQueueingThreadAddData(g_sendQueueHandle, edrData, sizeof (CAEDRData));
722     *sentLength = dataLength;
723
724     // Free remote endpoint
725     CAFreeEndpoint(remoteEndpoint);
726
727     OIC_LOG(DEBUG, TAG, "OUT - CAAdapterSendData");
728     return CA_STATUS_OK;
729 }
730
731 void CAEDRNotifyNetworkStatus(CANetworkStatus_t status)
732 {
733     // Create localconnectivity
734     if (NULL == g_localConnectivity)
735     {
736         CAEDRGetInterfaceInformation(&g_localConnectivity);
737     }
738
739     if (CA_INTERFACE_UP == status)
740     {
741         if (false == g_adapterState)
742         {
743             // Get Bluetooth adapter state
744             bool adapterState = false;
745             if (CA_STATUS_OK != CAEDRGetAdapterEnableState(&adapterState))
746             {
747                 OIC_LOG(ERROR, TAG, "Failed to get adapter enable state");
748                 return;
749             }
750
751             if (false == adapterState)
752             {
753                 OIC_LOG(ERROR, TAG, "Bluetooth adapter is disabled!");
754                 g_adapterState = false;
755                 return;
756             }
757             CAEDRClientSetCallbacks();
758             g_adapterState = true;
759             CAAdapterStartQueue();
760             // starting RFCommServer
761             if (true == g_serverState)
762             {
763                 CAStartServer();
764                 g_serverState = false;
765             }
766         }
767     }
768     else
769     {
770         g_adapterState = false;
771
772         CAResult_t res = CAQueueingThreadClearData(g_sendQueueHandle);
773         if (res != CA_STATUS_OK)
774         {
775             OIC_LOG_V(ERROR, TAG, "CAQueueingThreadClearData failed[%d]", res);
776         }
777
778         res = CAQueueingThreadClearData(g_recvQueueHandle);
779         if (res != CA_STATUS_OK)
780         {
781             OIC_LOG_V(ERROR, TAG, "CAQueueingThreadClearData failed[%d]", res);
782         }
783     }
784
785     // Notify to upper layer
786     if (g_adapterChangeCallback && g_localConnectivity && g_edrThreadPool)
787     {
788         // Add notification task to thread pool
789         CAEDRNetworkEvent *event = CAEDRCreateNetworkEvent(g_localConnectivity, status);
790         if (NULL != event)
791         {
792             if (CA_STATUS_OK != ca_thread_pool_add_task(g_edrThreadPool,
793                                                         CAEDROnNetworkStatusChanged, event, NULL))
794             {
795                 OIC_LOG(ERROR, TAG, "Failed to create threadpool!");
796                 return;
797             }
798         }
799     }
800 }
801
802 void CAEDROnNetworkStatusChanged(void *context)
803 {
804     if (NULL == context)
805     {
806         OIC_LOG(ERROR, TAG, "context is NULL!");
807         return;
808     }
809
810     CAEDRNetworkEvent *networkEvent = (CAEDRNetworkEvent *) context;
811
812     // Notify to upper layer
813     if (g_adapterChangeCallback)
814     {
815         g_adapterChangeCallback(networkEvent->info->adapter, networkEvent->status);
816     }
817
818     // Free the created Network event
819     CAEDRFreeNetworkEvent(networkEvent);
820 }
821
822 CAEDRNetworkEvent *CAEDRCreateNetworkEvent(CAEndpoint_t *connectivity,
823                                            CANetworkStatus_t status)
824 {
825     VERIFY_NON_NULL_RET(connectivity, TAG, "connectivity is NULL", NULL);
826
827     // Create CAEDRNetworkEvent
828     CAEDRNetworkEvent *event = (CAEDRNetworkEvent *) OICMalloc(sizeof(CAEDRNetworkEvent));
829     if (NULL == event)
830     {
831         OIC_LOG(ERROR, TAG, "Failed to allocate memory to network event!");
832         return NULL;
833     }
834
835     // Create duplicate of Local connectivity
836     event->info = CACloneEndpoint(connectivity);
837     event->status = status;
838     return event;
839 }
840
841 void CAEDRFreeNetworkEvent(CAEDRNetworkEvent *event)
842 {
843     if (event)
844     {
845         CAFreeEndpoint(event->info);
846         OICFree(event);
847     }
848 }
849
850 CAEDRData *CACreateEDRData(const CAEndpoint_t *remoteEndpoint,
851                            const uint8_t *data, uint32_t dataLength)
852 {
853     CAEDRData *edrData = (CAEDRData *) OICCalloc(1, sizeof(*edrData));
854     if (!edrData)
855     {
856         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
857         return NULL;
858     }
859
860     edrData->remoteEndpoint = CACloneEndpoint(remoteEndpoint);
861
862     edrData->data = OICMalloc(dataLength);
863     if (NULL == edrData->data)
864     {
865         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
866         CAFreeEDRData(edrData);
867         return NULL;
868     }
869     memcpy(edrData->data, data, dataLength);
870     edrData->dataLen = dataLength;
871
872     return edrData;
873 }
874
875 void CAFreeEDRData(CAEDRData *edrData)
876 {
877     VERIFY_NON_NULL_VOID(edrData, TAG, "edrData is NULL");
878
879     CAFreeEndpoint(edrData->remoteEndpoint);
880     OICFree(edrData->data);
881     OICFree(edrData);
882 }
883
884 void CAEDRDataDestroyer(void *data, uint32_t size)
885 {
886     if ((size_t)size < sizeof(CAEDRData))
887     {
888         OIC_LOG_V(ERROR, TAG, "Destroy data too small %p %d", data, size);
889     }
890     CAEDRData *edrdata = (CAEDRData *) data;
891
892     CAFreeEDRData(edrdata);
893 }