Merge branch 'master' into notification-service
[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 "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 void CAAdapterRecvData(const char *remoteAddress, const uint8_t *data, uint32_t dataLength,
97                        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)
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
273     if (0 == dataLength)
274     {
275         OIC_LOG(ERROR, TAG, "Invalid input: data length is zero!");
276         return -1;
277     }
278
279     if (0 == strlen(remoteEndpoint->addr))
280     {
281         OIC_LOG(ERROR, TAG, "Invalid input: EDR Address is empty!");
282         return -1;
283     }
284
285     uint32_t sentLength = 0;
286     const char *serviceUUID = OIC_EDR_SERVICE_ID;
287     const char *address = remoteEndpoint->addr;
288     CAResult_t err = CAAdapterSendData(address, serviceUUID, data, dataLength, &sentLength);
289     if (CA_STATUS_OK != err)
290     {
291         OIC_LOG_V(ERROR, TAG, "Send unicast data failed!, error num [%d]", err);
292         g_errorCallback(remoteEndpoint, data, dataLength, err);
293         return -1;
294     }
295
296     return sentLength;
297 }
298
299 int32_t CASendEDRMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
300 {
301     OIC_LOG(DEBUG, TAG, "IN - CASendEDRMulticastData");
302
303     // Input validation
304     VERIFY_NON_NULL_RET(data, TAG, "Data is null", -1);
305
306     if (0 == dataLength)
307     {
308         OIC_LOG(ERROR, TAG, "Invalid input: data length is zero!");
309         return -1;
310     }
311
312     uint32_t sentLen = 0;
313     const char *serviceUUID = OIC_EDR_SERVICE_ID;
314     CAResult_t err = CAAdapterSendData(NULL, serviceUUID, data, dataLength, &sentLen);
315     if (CA_STATUS_OK != err)
316     {
317         OIC_LOG_V(ERROR, TAG, "Send multicast data failed!, error num [%d]", err);
318         g_errorCallback(endpoint, data, dataLength, err);
319         return -1;
320     }
321
322     OIC_LOG(DEBUG, TAG, "OUT - CASendEDRMulticastData");
323     return sentLen;
324 }
325
326 CAResult_t CAGetEDRInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
327 {
328     VERIFY_NON_NULL(info, TAG, "LocalConnectivity info is null");
329
330     CAResult_t err = CA_STATUS_OK;
331     *size = 0;
332     if (CA_STATUS_OK != (err = CAEDRGetInterfaceInformation(info)))
333     {
334         OIC_LOG_V(ERROR, TAG, "Failed to get local interface information!, error num [%d]", err);
335         return err;
336     }
337
338     *size = 1;
339     return err;
340 }
341
342 CAResult_t CAReadEDRData()
343 {
344     return CAEDRManagerReadData();
345 }
346
347 CAResult_t CAStopEDR()
348 {
349     // Stop RFComm server if it is running
350     CAEDRServerStop();
351
352     // Stop network monitor
353     CAEDRStopNetworkMonitor();
354
355     // Stop the adapter
356     CAEDRClientUnsetCallbacks();
357
358     // Disconnect all the client connections
359     CAEDRClientDisconnectAll();
360
361     // Stop Send and receive Queue
362     CAAdapterStopQueue();
363
364     return CA_STATUS_OK;
365 }
366
367 void CATerminateEDR()
368 {
369     // Terminate EDR Network Monitor
370     CAEDRTerminateNetworkMonitor();
371
372     // Terminate Send/Receive data messages queues
373     CAAdapterTerminateQueues();
374
375     g_networkPacketReceivedCallback = NULL;
376     g_adapterChangeCallback = NULL;
377
378     // Terminate thread pool
379     g_edrThreadPool = NULL;
380
381     // Terminate EDR Client
382     CAEDRClientTerminate();
383
384     // Terminate EDR Server
385     CAEDRServerTerminate();
386
387     // Free LocalConnectivity information
388     CAFreeEndpoint(g_localConnectivity);
389     g_localConnectivity = NULL;
390 }
391
392 CAResult_t CAStartServer()
393 {
394     if (false == g_adapterState)
395     {
396         OIC_LOG(DEBUG, TAG, "Bluetooth adapter is disabled!");
397         // Setting g_serverState for starting Rfcommserver when adapter starts
398         g_serverState = true;
399         return CA_STATUS_OK;
400     }
401
402     CAResult_t err = CA_STATUS_OK;
403     if (CA_STATUS_OK != (err = CAEDRServerStart()))
404     {
405         OIC_LOG_V(ERROR, TAG, "Failed to start RFCOMM server!, error num [%d]",
406                   err);
407         return err;
408     }
409
410     return err;
411 }
412
413 CAResult_t CAEDRInitializeQueueHandlers()
414 {
415     if (CA_STATUS_OK == CAEDRInitializeSendHandler()
416         && CA_STATUS_OK == CAEDRInitializeReceiveHandler())
417     {
418         OIC_LOG(DEBUG, TAG, "Queue is initialized!");
419         return CA_STATUS_OK;
420     }
421
422     return CA_STATUS_FAILED;
423 }
424
425 CAResult_t CAEDRInitializeSendHandler()
426 {
427     // Check if the message queue is already initialized
428     if (g_sendQueueHandle)
429     {
430         OIC_LOG(DEBUG, TAG, "Already queue is initialized!");
431         return CA_STATUS_OK;
432     }
433
434     g_sendQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
435     if (!g_sendQueueHandle)
436     {
437         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
438         return CA_MEMORY_ALLOC_FAILED;
439     }
440
441     if (CA_STATUS_OK != CAQueueingThreadInitialize(g_sendQueueHandle, g_edrThreadPool,
442                                                    CAAdapterDataSendHandler, CAEDRDataDestroyer))
443     {
444         OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
445         return CA_STATUS_FAILED;
446     }
447     return CA_STATUS_OK;
448 }
449
450 CAResult_t CAEDRInitializeReceiveHandler()
451 {
452     // Check if the message queue is already initialized
453     if (g_recvQueueHandle)
454     {
455         OIC_LOG(DEBUG, TAG, "Already queue is initialized!");
456         return CA_STATUS_OK;
457     }
458
459     g_recvQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
460     if (!g_recvQueueHandle)
461     {
462         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
463         return CA_MEMORY_ALLOC_FAILED;
464     }
465
466
467     if (CA_STATUS_OK != CAQueueingThreadInitialize(g_recvQueueHandle, g_edrThreadPool,
468                                                    CAAdapterDataReceiverHandler,
469                                                    CAEDRDataDestroyer))
470     {
471         OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
472         OICFree(g_recvQueueHandle);
473         g_recvQueueHandle = NULL;
474         return CA_STATUS_FAILED;
475     }
476
477     return CA_STATUS_OK;
478 }
479
480 void CAAdapterTerminateQueues()
481 {
482     if (g_sendQueueHandle)
483     {
484         CAQueueingThreadDestroy(g_sendQueueHandle);
485         g_sendQueueHandle = NULL;
486     }
487     if (g_recvQueueHandle)
488     {
489         CAQueueingThreadDestroy(g_recvQueueHandle);
490         g_recvQueueHandle = NULL;
491     }
492 }
493
494 void CAAdapterDataSendHandler(void *context)
495 {
496     OIC_LOG(DEBUG, TAG, "IN - CAAdapterDataSendHandler");
497
498     CAEDRData *message = (CAEDRData *) context;
499     if (!message)
500     {
501         OIC_LOG(ERROR, TAG, "Failed to get message!");
502         return;
503     }
504
505     if (!message->remoteEndpoint)
506     {
507         OIC_LOG(DEBUG, TAG, "remoteEndpoint is not available");
508         return;
509     }
510
511     const char *remoteAddress = message->remoteEndpoint->addr;
512     if(!remoteAddress)
513     {
514         OIC_LOG(ERROR, TAG, "EDR Send Message error");
515         //Error cannot be sent if remote address is NULL
516         return;
517     }
518
519     CAResult_t result = CAEDRClientSendData(remoteAddress, message->data, message->dataLen);
520     if(CA_STATUS_OK != result)
521     {
522         OIC_LOG(ERROR, TAG, "CAEDRClientSendData API failed");
523         CAEDRErrorHandler(remoteAddress, message->data, message->dataLen, result);
524         return;
525     }
526
527     OIC_LOG(DEBUG, TAG, "OUT");
528 }
529
530 CAResult_t CAEDRClientSendData(const char *remoteAddress, const uint8_t *data,
531                                uint32_t dataLength)
532 {
533     CAResult_t result = CA_SEND_FAILED;
534
535     // Send the first segment with the header.
536     if ((NULL != remoteAddress) && (0 < strlen(remoteAddress))) //Unicast data
537     {
538         result = CAEDRClientSendUnicastData(remoteAddress, data, dataLength);
539         if (CA_STATUS_OK != result)
540         {
541             OIC_LOG(ERROR, TAG, "Failed to send unicast data !");
542             return result;
543         }
544     }
545     else
546     {
547         OIC_LOG_V(DEBUG, TAG, "sending multicast data : %s", data);
548         result = CAEDRClientSendMulticastData(data, dataLength);
549
550         if (CA_STATUS_OK != result)
551         {
552             OIC_LOG(ERROR, TAG, "Failed to send multicast data !");
553             return result;
554         }
555     }
556     return result;
557 }
558
559 void CAAdapterDataReceiverHandler(void *context)
560 {
561     OIC_LOG(DEBUG, TAG, "IN_CAAdapterDataReceiverHandler");
562
563     if (NULL == g_networkPacketReceivedCallback)
564     {
565         OIC_LOG(ERROR, TAG, "g_networkPacketReceivedCallback is NULL");
566         return;
567     }
568
569     CAEDRData *message = (CAEDRData *) context;
570     if (NULL == message || NULL == message->remoteEndpoint)
571     {
572         OIC_LOG(ERROR, TAG, "Failed to get message!");
573         return;
574     }
575
576     CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
577                                                           CA_ADAPTER_RFCOMM_BTEDR,
578                                                           message->remoteEndpoint->addr,
579                                                           0);
580
581     if (!remoteEndpoint)
582     {
583         OIC_LOG(ERROR, TAG, "remoteEndpoint is NULL");
584         return;
585     }
586
587     OIC_LOG(DEBUG, TAG, "Sending data up !");
588
589     const CASecureEndpoint_t sep = { .endpoint = *remoteEndpoint };
590
591     g_networkPacketReceivedCallback(&sep, message->data, message->dataLen);
592
593     CAFreeEndpoint(remoteEndpoint);
594
595     OIC_LOG(DEBUG, TAG, "OUT_CAAdapterDataReceiverHandler");
596 }
597
598 CAResult_t CAAdapterStartQueue()
599 {
600     // Start send queue thread
601     if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle))
602     {
603         OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread");
604         CAEDRClientUnsetCallbacks();
605         //Disconnect all the client connections
606         CAEDRClientDisconnectAll();
607         return CA_STATUS_FAILED;
608     }
609
610     // Start receive queue thread
611     if (CA_STATUS_OK != CAQueueingThreadStart(g_recvQueueHandle))
612     {
613         OIC_LOG(ERROR, TAG, "Failed to Start Receive Data Thread");
614         CAEDRClientUnsetCallbacks();
615         //Disconnect all the client connections
616         CAEDRClientDisconnectAll();
617         return CA_STATUS_FAILED;
618     }
619
620     return CA_STATUS_OK;
621 }
622
623 CAResult_t CAAdapterStopQueue()
624 {
625     //Stop send queue thread
626     CAQueueingThreadStop(g_sendQueueHandle);
627
628     //Stop receive queue thread
629     CAQueueingThreadStop(g_recvQueueHandle);
630
631     return CA_STATUS_OK;
632 }
633
634 void CAAdapterRecvData(const char *remoteAddress, const uint8_t *data, uint32_t dataLength,
635                        uint32_t *sentLength)
636 {
637     if (false == g_adapterState)
638     {
639         OIC_LOG_V(ERROR, TAG, "Bluetooth adapter is disabled!");
640         *sentLength = 0;
641         return;
642     }
643
644     // Input validation
645     VERIFY_NON_NULL_VOID(data, TAG, "Data is null");
646     VERIFY_NON_NULL_VOID(sentLength, TAG, "Sent data length holder is null");
647
648     // Create remote endpoint
649     CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
650                                                           CA_ADAPTER_RFCOMM_BTEDR,
651                                                           remoteAddress, 0);
652     if (NULL == remoteEndpoint)
653     {
654         OIC_LOG(ERROR, TAG, "Failed to create remote endpoint !");
655         return;
656     }
657
658     // Add message to data queue
659     CAEDRData *edrData =  CACreateEDRData(remoteEndpoint, data, dataLength);
660     CAQueueingThreadAddData(g_recvQueueHandle, edrData, sizeof(CAEDRData));
661     *sentLength = dataLength;
662
663     // Free remote endpoint
664     CAFreeEndpoint(remoteEndpoint);
665 }
666
667 void CAEDRErrorHandler(const char *remoteAddress, const uint8_t *data,
668                        uint32_t dataLength, CAResult_t result)
669 {
670     // Input validation
671     VERIFY_NON_NULL_VOID(data, TAG, "Data is null");
672
673     // Create remote endpoint
674     CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(0, CA_ADAPTER_RFCOMM_BTEDR,
675                                                            remoteAddress, 0);
676     if (!remoteEndpoint)
677     {
678         OIC_LOG(ERROR, TAG, "Failed to create remote endpoint !");
679         return;
680     }
681
682     g_errorCallback(remoteEndpoint, data, dataLength, result);
683
684     // Free remote endpoint
685     CAFreeEndpoint(remoteEndpoint);
686 }
687
688 CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID, const uint8_t *data,
689                              uint32_t dataLength, uint32_t *sentLength)
690 {
691     OIC_LOG(DEBUG, TAG, "IN - CAAdapterSendData");
692
693     if (false == g_adapterState)
694     {
695         OIC_LOG(ERROR, TAG, "Bluetooth adapter is disabled!");
696         *sentLength = 0;
697         return CA_ADAPTER_NOT_ENABLED;
698     }
699     // Input validation
700     VERIFY_NON_NULL(serviceUUID, TAG, "service UUID is null");
701     VERIFY_NON_NULL(data, TAG, "Data is null");
702     VERIFY_NON_NULL(sentLength, TAG, "Sent data length holder is null");
703
704     // Create remote endpoint
705     CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
706                                                           CA_ADAPTER_RFCOMM_BTEDR,
707                                                           remoteAddress, 0);
708     if (NULL == remoteEndpoint)
709     {
710         OIC_LOG(ERROR, TAG, "Failed to create remote endpoint !");
711         return CA_MEMORY_ALLOC_FAILED;
712     }
713
714     // Add message to data queue
715     CAEDRData *edrData =  CACreateEDRData(remoteEndpoint, data, dataLength);
716     CAQueueingThreadAddData(g_sendQueueHandle, edrData, sizeof (CAEDRData));
717     *sentLength = dataLength;
718
719     // Free remote endpoint
720     CAFreeEndpoint(remoteEndpoint);
721
722     OIC_LOG(DEBUG, TAG, "OUT - CAAdapterSendData");
723     return CA_STATUS_OK;
724 }
725
726 void CAEDRNotifyNetworkStatus(CANetworkStatus_t status)
727 {
728     // Create localconnectivity
729     if (NULL == g_localConnectivity)
730     {
731         CAEDRGetInterfaceInformation(&g_localConnectivity);
732     }
733
734     if (CA_INTERFACE_UP == status)
735     {
736         if (false == g_adapterState)
737         {
738             // Get Bluetooth adapter state
739             bool adapterState = false;
740             if (CA_STATUS_OK != CAEDRGetAdapterEnableState(&adapterState))
741             {
742                 OIC_LOG(ERROR, TAG, "Failed to get adapter enable state");
743                 return;
744             }
745
746             if (false == adapterState)
747             {
748                 OIC_LOG(ERROR, TAG, "Bluetooth adapter is disabled!");
749                 g_adapterState = false;
750                 return;
751             }
752             CAEDRClientSetCallbacks();
753             g_adapterState = true;
754             CAAdapterStartQueue();
755             // starting RFCommServer
756             if (true == g_serverState)
757             {
758                 CAStartServer();
759                 g_serverState = false;
760             }
761         }
762     }
763     else
764     {
765         g_adapterState = false;
766     }
767
768     // Notify to upper layer
769     if (g_adapterChangeCallback && g_localConnectivity && g_edrThreadPool)
770     {
771         // Add notification task to thread pool
772         CAEDRNetworkEvent *event = CAEDRCreateNetworkEvent(g_localConnectivity, status);
773         if (NULL != event)
774         {
775             if (CA_STATUS_OK != ca_thread_pool_add_task(g_edrThreadPool,
776                                                         CAEDROnNetworkStatusChanged,event))
777             {
778                 OIC_LOG(ERROR, TAG, "Failed to create threadpool!");
779                 return;
780             }
781         }
782     }
783 }
784
785 void CAEDROnNetworkStatusChanged(void *context)
786 {
787     if (NULL == context)
788     {
789         OIC_LOG(ERROR, TAG, "context is NULL!");
790         return;
791     }
792
793     CAEDRNetworkEvent *networkEvent = (CAEDRNetworkEvent *) context;
794
795     // Notify to upper layer
796     if (g_adapterChangeCallback)
797     {
798         g_adapterChangeCallback(networkEvent->info->adapter, networkEvent->status);
799     }
800
801     // Free the created Network event
802     CAEDRFreeNetworkEvent(networkEvent);
803 }
804
805 CAEDRNetworkEvent *CAEDRCreateNetworkEvent(CAEndpoint_t *connectivity,
806                                            CANetworkStatus_t status)
807 {
808     VERIFY_NON_NULL_RET(connectivity, TAG, "connectivity is NULL", NULL);
809
810     // Create CAEDRNetworkEvent
811     CAEDRNetworkEvent *event = (CAEDRNetworkEvent *) OICMalloc(sizeof(CAEDRNetworkEvent));
812     if (NULL == event)
813     {
814         OIC_LOG(ERROR, TAG, "Failed to allocate memory to network event!");
815         return NULL;
816     }
817
818     // Create duplicate of Local connectivity
819     event->info = CACloneEndpoint(connectivity);
820     event->status = status;
821     return event;
822 }
823
824 void CAEDRFreeNetworkEvent(CAEDRNetworkEvent *event)
825 {
826     if (event)
827     {
828         CAFreeEndpoint(event->info);
829         OICFree(event);
830     }
831 }
832
833 CAEDRData *CACreateEDRData(const CAEndpoint_t *remoteEndpoint,
834                            const uint8_t *data, uint32_t dataLength)
835 {
836     CAEDRData *edrData = (CAEDRData *) OICCalloc(1, sizeof(*edrData));
837     if (!edrData)
838     {
839         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
840         return NULL;
841     }
842
843     edrData->remoteEndpoint = CACloneEndpoint(remoteEndpoint);
844
845     edrData->data = OICMalloc(dataLength);
846     if (NULL == edrData->data)
847     {
848         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
849         CAFreeEDRData(edrData);
850         return NULL;
851     }
852     memcpy(edrData->data, data, dataLength);
853     edrData->dataLen = dataLength;
854
855     return edrData;
856 }
857
858 void CAFreeEDRData(CAEDRData *edrData)
859 {
860     VERIFY_NON_NULL_VOID(edrData, TAG, "edrData is NULL");
861
862     CAFreeEndpoint(edrData->remoteEndpoint);
863     OICFree(edrData->data);
864     OICFree(edrData);
865 }
866
867 void CAEDRDataDestroyer(void *data, uint32_t size)
868 {
869     if ((size_t)size < sizeof(CAEDRData))
870     {
871         OIC_LOG_V(ERROR, TAG, "Destroy data too small %p %d", data, size);
872     }
873     CAEDRData *edrdata = (CAEDRData *) data;
874
875     CAFreeEDRData(edrdata);
876 }