a0106eb1f4eff4fba2e7922248c1ef23f58aed1b
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_edr_adapter / tizen / caedrclient.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 provides the APIs to establish RFCOMM connection with remote
25  * bluetooth device.
26  */
27
28 #include <string.h>
29 #include <bluetooth.h>
30
31 #include "caedrinterface.h"
32 #include "camutex.h"
33 #include "caedrendpoint.h"
34 #include "caadapterutils.h"
35 #include "caedrutils.h"
36 #include "logger.h"
37 #include "cacommon.h"
38 #include "caedrdevicelist.h"
39
40 #define MICROSECS_PER_SEC 1000000
41
42 /**
43  * Condition to check if OIC supported device is found.
44  */
45 static ca_cond g_deviceDescCond = NULL;
46
47 /**
48  * Flag that will be set when EDR adapter is stopped.
49  */
50 static bool g_isStopping = false;
51
52 /**
53  * Mutex to synchronize the access to Bluetooth device information list.
54  */
55 static ca_mutex g_edrDeviceListMutex = NULL;
56
57 /**
58  * Peer Bluetooth device information list.
59  */
60 static EDRDeviceList *g_edrDeviceList = NULL;
61
62 /**
63  * Maintains the callback to be notified when data received from remote
64  * Bluetooth device.
65  */
66 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
67
68 /**
69  * Error callback to update error in EDR.
70  */
71 static CAEDRErrorHandleCallback g_edrErrorHandler = NULL;
72
73 /**
74  * This function creates mutex.
75  */
76 static void CAEDRManagerInitializeMutex(void);
77
78 /**
79  * This function frees mutex.
80  */
81 static void CAEDRManagerTerminateMutex(void);
82
83 /**
84  * This callback is registered to recieve data on any open RFCOMM connection.
85  */
86 static void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData);
87
88 /**
89  * This function starts device discovery.
90  */
91 static CAResult_t CAEDRStartDeviceDiscovery(void);
92
93 /**
94  * This function stops any ongoing service sevice search.
95  */
96 static CAResult_t CAEDRStopServiceSearch(void);
97
98 /**
99  * This function stops device discovery.
100  */
101 static CAResult_t CAEDRStopDeviceDiscovery(void);
102
103 /**
104  * This function searches for OIC service for remote Bluetooth device.
105  */
106 static CAResult_t CAEDRStartServiceSearch(const char *remoteAddress);
107
108 /**
109  * This callback is registered to recieve all bluetooth nearby devices
110  * when device scan is initiated.
111  */
112 static void CAEDRDeviceDiscoveryCallback(int result,
113                                          bt_adapter_device_discovery_state_e state,
114                                          bt_adapter_device_discovery_info_s *discoveryInfo,
115                                          void *userData);
116
117 /**
118  * This callback is registered to recieve all the services remote
119  * bluetooth device supports when service search initiated.
120  */
121 static void CAEDRServiceSearchedCallback(int result, bt_device_sdp_info_s *sdpInfo,
122                                         void *userData);
123
124 /**
125  * This callback is registered to receive bluetooth RFCOMM connection
126  * state changes.
127  */
128 static void CAEDRSocketConnectionStateCallback(int result,
129                                     bt_socket_connection_state_e state,
130                                               bt_socket_connection_s *connection, void *userData);
131
132 /**
133  * Establishes RFCOMM connection with remote bluetooth device.
134  */
135 static CAResult_t CAEDRClientConnect(const char *remoteAddress, const char *serviceUUID);
136
137 /**
138  * Disconnect RFCOMM client socket connection.
139  */
140 static CAResult_t CAEDRClientDisconnect(const int32_t clientID);
141
142 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
143 {
144     g_edrPacketReceivedCallback = packetReceivedCallback;
145 }
146
147 void CAEDRSetErrorHandler(CAEDRErrorHandleCallback errorHandleCallback)
148 {
149     g_edrErrorHandler = errorHandleCallback;
150 }
151
152 void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e state,
153                                        bt_socket_connection_s *connection, void *userData)
154 {
155     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
156
157     EDRDevice *device = NULL;
158
159     if (BT_ERROR_NONE != result || NULL == connection)
160     {
161         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid connection state!, error num [%x]",
162                   result);
163         return;
164     }
165
166     switch (state)
167     {
168         case BT_SOCKET_CONNECTED:
169             {
170                 ca_mutex_lock(g_edrDeviceListMutex);
171                 CAResult_t res = CAGetEDRDevice(g_edrDeviceList, connection->remote_address,
172                                                    &device);
173                 if (CA_STATUS_OK != res)
174                 {
175                     // Create the deviceinfo and add to list
176                     res = CACreateAndAddToDeviceList(&g_edrDeviceList,
177                             connection->remote_address, OIC_EDR_SERVICE_ID, &device);
178                     if (CA_STATUS_OK != res)
179                     {
180                         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed add device to list ret[%d]", res);
181                         ca_mutex_unlock(g_edrDeviceListMutex);
182                         return;
183                     }
184
185                     if(!device)
186                     {
187                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
188                         ca_mutex_unlock(g_edrDeviceListMutex);
189                         return;
190                     }
191
192                     device->socketFD = connection->socket_fd;
193                     ca_mutex_unlock(g_edrDeviceListMutex);
194                     return;
195                 }
196
197                 if(!device)
198                 {
199                     OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
200                     ca_mutex_unlock(g_edrDeviceListMutex);
201                     return;
202                 }
203                 device->socketFD = connection->socket_fd;
204                 while (device->pendingDataList)
205                 {
206                     EDRData *edrData = device->pendingDataList->data;
207                     res = CAEDRSendData(device->socketFD, edrData->data,
208                                         edrData->dataLength);
209                     if (CA_STATUS_OK != res)
210                     {
211                         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send pending data [%s]",
212                                   device->remoteAddress);
213
214                         // Remove all the data from pending list
215                         CADestroyEDRDataList(&device->pendingDataList);
216                         break;
217                     }
218
219                     // Remove the data which send from pending list
220                     CARemoveEDRDataFromList(&device->pendingDataList);
221                 }
222                 ca_mutex_unlock(g_edrDeviceListMutex);
223             }
224             break;
225
226         case BT_SOCKET_DISCONNECTED:
227             {
228                 ca_mutex_lock(g_edrDeviceListMutex);
229                 CARemoveEDRDeviceFromList(&g_edrDeviceList, connection->remote_address);
230                 ca_mutex_unlock(g_edrDeviceListMutex);
231             }
232             break;
233     }
234
235     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
236 }
237
238
239 void CAEDRDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_e state,
240                                  bt_adapter_device_discovery_info_s *discoveryInfo, void *userData)
241 {
242     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
243
244     EDRDevice *device = NULL;
245
246     if (BT_ERROR_NONE != result)
247     {
248         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Received bad state!, error num [%x]",
249                   result);
250         return;
251     }
252
253     switch (state)
254     {
255         case BT_ADAPTER_DEVICE_DISCOVERY_STARTED:
256             {
257                 OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Discovery started!");
258             }
259             break;
260
261         case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED:
262             {
263                 OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Discovery finished!");
264             }
265             break;
266
267         case BT_ADAPTER_DEVICE_DISCOVERY_FOUND:
268             {
269                 OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Device discovered [%s]!",
270                           discoveryInfo->remote_name);
271                 if (true == CAEDRIsServiceSupported((const char **)discoveryInfo->service_uuid,
272                                                         discoveryInfo->service_count,
273                                                         OIC_EDR_SERVICE_ID))
274                 {
275                     // Check if the deivce is already in the list
276                     ca_mutex_lock(g_edrDeviceListMutex);
277                     if (CA_STATUS_OK == CAGetEDRDevice(g_edrDeviceList,
278                                                 discoveryInfo->remote_address, &device))
279                     {
280                         if(!device)
281                         {
282                             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
283                             ca_mutex_unlock(g_edrDeviceListMutex);
284                             return;
285                         }
286                         device->serviceSearched = true;
287                         ca_mutex_unlock(g_edrDeviceListMutex);
288                         return;
289                     }
290
291                     // Create the deviceinfo and add to list
292                     CAResult_t res = CACreateAndAddToDeviceList(&g_edrDeviceList,
293                             discoveryInfo->remote_address, OIC_EDR_SERVICE_ID, &device);
294                     if (CA_STATUS_OK != res)
295                     {
296                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add device to list!");
297                         ca_mutex_unlock(g_edrDeviceListMutex);
298                         return;
299                     }
300
301                     if(!device)
302                     {
303                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
304                         ca_mutex_unlock(g_edrDeviceListMutex);
305                         return;
306                     }
307                     device->serviceSearched = true;
308                     // Signal the wait to send the data.
309                     ca_cond_signal(g_deviceDescCond);
310                     ca_mutex_unlock(g_edrDeviceListMutex);
311                 }
312                 else
313                 {
314                     OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Device does not support OIC service!");
315                 }
316             }
317             break;
318     }
319
320     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
321 }
322
323 void CAEDRServiceSearchedCallback(int32_t result,
324                 bt_device_sdp_info_s *sdpInfo,void *userData)
325 {
326     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
327
328     if (NULL == sdpInfo)
329     {
330         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "SDP info is null!");
331         return;
332     }
333
334     ca_mutex_lock(g_edrDeviceListMutex);
335
336     EDRDevice *device = NULL;
337     CAResult_t res = CAGetEDRDevice(g_edrDeviceList, sdpInfo->remote_address, &device);
338     if (CA_STATUS_OK == res && NULL != device)
339     {
340         if (device->serviceSearched)
341         {
342             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Service is already searched for this device!");
343             ca_mutex_unlock(g_edrDeviceListMutex);
344             return;
345         }
346
347         if (true == CAEDRIsServiceSupported((const char **)sdpInfo->service_uuid,
348                                            sdpInfo->service_count, OIC_EDR_SERVICE_ID))
349         {
350             device->serviceSearched = true;
351             res = CAEDRClientConnect(sdpInfo->remote_address, OIC_EDR_SERVICE_ID);
352             if (CA_STATUS_OK != res)
353             {
354                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to make rfcomm connection!");
355
356                 // Remove the device from device list
357                 CARemoveEDRDeviceFromList(&g_edrDeviceList, sdpInfo->remote_address);
358             }
359         }
360         else
361         {
362             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Device does not contain OIC service!");
363
364             // Remove device from list as it does not support OIC service
365             CARemoveEDRDeviceFromList(&g_edrDeviceList, sdpInfo->remote_address);
366         }
367     }
368
369     ca_mutex_unlock(g_edrDeviceListMutex);
370
371     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
372 }
373
374 CAResult_t CAEDRStartDeviceDiscovery(void)
375 {
376     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
377
378
379     bool isDiscoveryStarted = false;
380
381     // Check the device discovery state
382     bt_error_e err = bt_adapter_is_discovering(&isDiscoveryStarted);
383     if (BT_ERROR_NONE != err)
384     {
385         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]",
386                   err);
387         return CA_STATUS_FAILED;
388     }
389
390     //Start device discovery if its not started
391     if (false == isDiscoveryStarted)
392     {
393         err = bt_adapter_start_device_discovery();
394         if (BT_ERROR_NONE != err)
395         {
396             OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Device discovery failed!, error num [%x]",
397                       err);
398             return CA_STATUS_FAILED;
399         }
400     }
401
402     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
403     return CA_STATUS_OK;
404 }
405
406 CAResult_t CAEDRStopServiceSearch(void)
407 {
408     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
409
410     bt_error_e err = bt_device_cancel_service_search();
411     // Stop ongoing service search
412     if (BT_ERROR_NONE != err)
413     {
414         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
415                   err);
416         return CA_STATUS_FAILED;
417     }
418
419     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
420     return CA_STATUS_OK;
421 }
422
423 CAResult_t CAEDRStopDeviceDiscovery(void)
424 {
425     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
426
427     bool isDiscoveryStarted = false;
428     bt_error_e err = bt_adapter_is_discovering(&isDiscoveryStarted);
429     // Check the device discovery state
430     if (BT_ERROR_NONE != err)
431     {
432         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]",
433                   err);
434         return CA_STATUS_FAILED;
435     }
436
437     //stop the device discovery process
438     if (true == isDiscoveryStarted)
439     {
440         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Stopping the device search process");
441         if (BT_ERROR_NONE != (err = bt_adapter_stop_device_discovery()))
442         {
443             OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to stop discovery!, error num [%x]",
444                       err);
445         }
446     }
447
448     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
449     return CA_STATUS_OK;
450 }
451
452 CAResult_t CAEDRStartServiceSearch(const char *remoteAddress)
453 {
454     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
455
456     // Input validation
457     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
458     if (!remoteAddress[0])
459     {
460         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Remote address is empty!");
461         return CA_STATUS_INVALID_PARAM;
462     }
463
464     bt_error_e err = bt_device_start_service_search(remoteAddress);
465     // Start searching for OIC service
466     if (BT_ERROR_NONE != err)
467     {
468         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
469                   err);
470         return CA_STATUS_FAILED;
471     }
472
473     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
474     return CA_STATUS_OK;
475 }
476
477 CAResult_t CAEDRClientSetCallbacks(void)
478 {
479     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
480
481     g_isStopping = false;
482     // Register for discovery and rfcomm socket connection callbacks
483     bt_adapter_set_device_discovery_state_changed_cb(CAEDRDeviceDiscoveryCallback, NULL);
484     bt_device_set_service_searched_cb(CAEDRServiceSearchedCallback, NULL);
485     bt_socket_set_connection_state_changed_cb(CAEDRSocketConnectionStateCallback, NULL);
486     bt_socket_set_data_received_cb(CAEDRDataRecvCallback, NULL);
487
488     // Start device discovery
489     CAResult_t result = CAEDRStartDeviceDiscovery();
490     if(CA_STATUS_OK != result)
491     {
492         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Failed to Start Device discovery");
493         return CA_STATUS_FAILED;
494     }
495
496     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
497     return CA_STATUS_OK;
498 }
499
500
501 void CAEDRClientUnsetCallbacks(void)
502 {
503     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
504
505     // Stop service search
506     CAEDRStopServiceSearch();
507
508     // Stop the device discovery process
509     CAEDRStopDeviceDiscovery();
510
511     // Signal the conditional wait for discovery of devices.
512     g_isStopping = true;
513     ca_cond_signal(g_deviceDescCond);
514
515     // reset bluetooth adapter callbacks
516     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Resetting the callbacks");
517     bt_adapter_unset_device_discovery_state_changed_cb();
518     bt_device_unset_service_searched_cb();
519     bt_socket_unset_connection_state_changed_cb();
520     bt_socket_unset_data_received_cb();
521
522     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
523 }
524
525 void CAEDRManagerInitializeMutex(void)
526 {
527     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
528
529     if (!g_edrDeviceListMutex)
530     {
531         g_edrDeviceListMutex = ca_mutex_new();
532     }
533
534     if (!g_deviceDescCond)
535     {
536         g_deviceDescCond = ca_cond_new();
537     }
538
539     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
540 }
541
542 void CAEDRManagerTerminateMutex(void)
543 {
544     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
545
546     if (g_edrDeviceListMutex)
547     {
548         ca_mutex_free(g_edrDeviceListMutex);
549         g_edrDeviceListMutex = NULL;
550     }
551
552     if (g_deviceDescCond)
553     {
554         ca_cond_free(g_deviceDescCond);
555         g_deviceDescCond = NULL;
556     }
557     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
558 }
559
560 void CAEDRInitializeClient(ca_thread_pool_t handle)
561 {
562     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
563     CAEDRManagerInitializeMutex();
564     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
565 }
566
567 void CAEDRClientTerminate()
568 {
569     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
570
571     // Free EDRDevices list
572     if (g_edrDeviceListMutex)
573     {
574         ca_mutex_lock(g_edrDeviceListMutex);
575         CADestroyEDRDeviceList(&g_edrDeviceList);
576         ca_mutex_unlock(g_edrDeviceListMutex);
577     }
578
579     // Free the mutex
580     CAEDRManagerTerminateMutex();
581     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
582 }
583
584 void CAEDRClientDisconnectAll(void)
585 {
586     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
587
588     ca_mutex_lock(g_edrDeviceListMutex);
589
590     EDRDeviceList *cur = g_edrDeviceList;
591     while (cur != NULL)
592     {
593         EDRDevice *device = cur->device;
594         cur = cur->next;
595
596         if (device && 0 <= device->socketFD)
597         {
598             CAResult_t result = CAEDRClientDisconnect(device->socketFD);
599             if (CA_STATUS_OK != result)
600             {
601                 OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to disconnect with client :%s",
602                           device->remoteAddress);
603             }
604
605             device->socketFD = -1;
606         }
607     }
608
609     ca_mutex_unlock(g_edrDeviceListMutex);
610
611     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
612 }
613
614
615 CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress,
616                                       const uint8_t *data,
617                                       uint32_t dataLength)
618 {
619     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
620
621     EDRDevice *device = NULL;
622
623     // Input validation
624     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
625     VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
626
627     if (0 >= dataLength)
628     {
629         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Negative data length!");
630         return CA_STATUS_INVALID_PARAM;
631     }
632
633     // Check the connection existence with remote device
634     ca_mutex_lock(g_edrDeviceListMutex);
635     CAResult_t result = CAGetEDRDevice(g_edrDeviceList, remoteAddress, &device);
636     if (CA_STATUS_OK != result)
637     {
638         // Create new device and add to list
639         result = CACreateAndAddToDeviceList(&g_edrDeviceList, remoteAddress,
640                                             OIC_EDR_SERVICE_ID, &device);
641         if (CA_STATUS_OK != result)
642         {
643             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed create device and add to list!");
644
645             ca_mutex_unlock(g_edrDeviceListMutex);
646             return CA_STATUS_FAILED;
647         }
648
649         // Start the OIC service search newly created device
650         result = CAEDRStartServiceSearch(remoteAddress);
651         if (CA_STATUS_OK != result)
652         {
653             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to initiate service search!");
654
655             // Remove device from list
656             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
657
658             ca_mutex_unlock(g_edrDeviceListMutex);
659             return CA_STATUS_FAILED;
660         }
661     }
662
663     if(!device)
664     {
665         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
666         // Remove device from list
667         CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
668
669         ca_mutex_unlock(g_edrDeviceListMutex);
670         return CA_STATUS_FAILED;
671     }
672
673     ca_mutex_unlock(g_edrDeviceListMutex);
674
675     if (-1 == device->socketFD)
676     {
677         // Adding to pending list
678         result = CAAddEDRDataToList(&device->pendingDataList, data,
679                                               dataLength);
680         if (CA_STATUS_OK != result)
681         {
682             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add data to pending list!");
683
684             //Remove device from list
685             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
686             return CA_STATUS_FAILED;
687         }
688
689         // Make a rfcomm connection with remote BT Device
690         if (device->serviceSearched &&
691             CA_STATUS_OK != CAEDRClientConnect(remoteAddress, OIC_EDR_SERVICE_ID))
692         {
693             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to make RFCOMM connection!");
694
695             //Remove device from list
696             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
697             return CA_STATUS_FAILED;
698         }
699     }
700     else
701     {
702         result = CAEDRSendData(device->socketFD, data, dataLength);
703         if (CA_STATUS_OK != result)
704         {
705             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to send data!");
706             return CA_STATUS_FAILED;
707         }
708     }
709
710     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
711     return CA_STATUS_OK;
712 }
713
714 CAResult_t CAEDRClientSendMulticastData(const uint8_t *data,
715                                         uint32_t dataLength)
716 {
717     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
718
719     // Input validation
720     VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
721
722     if (0 >= dataLength)
723     {
724         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Negative data length!");
725         return CA_STATUS_INVALID_PARAM;
726     }
727
728     // Send the packet to all OIC devices
729     ca_mutex_lock(g_edrDeviceListMutex);
730
731     // Check if any device is discovered.
732     if (NULL == g_edrDeviceList)
733     {
734         // Wait for BT devices to be discovered.
735
736         // Number of times to wait for discovery to complete.
737         int const RETRIES = 5;
738
739         uint64_t const TIMEOUT = 2 * MICROSECS_PER_SEC;  // Microseconds
740
741         bool devicesDiscovered = false;
742         for (size_t i = 0; NULL == g_edrDeviceList && i < RETRIES && !g_isStopping;
743              ++i)
744         {
745             if (ca_cond_wait_for(g_deviceDescCond, g_edrDeviceListMutex,
746                                  TIMEOUT) == 0)
747             {
748                 devicesDiscovered = true;
749             }
750         }
751         if (!devicesDiscovered || g_isStopping)
752         {
753             goto exit;
754         }
755     }
756
757     EDRDeviceList *curList = g_edrDeviceList;
758     CAResult_t result = CA_STATUS_FAILED;
759     while (curList != NULL)
760     {
761         EDRDevice *device = curList->device;
762         curList = curList->next;
763
764         if (!device)
765         {
766             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "There is no device!");
767             break;
768         }
769
770         if (-1 == device->socketFD)
771         {
772             // Check if the device service search is finished
773             if (false == device->serviceSearched)
774             {
775                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Device services are still unknown!");
776                 continue;
777             }
778
779             // Adding to pendding list
780             result = CAAddEDRDataToList(&device->pendingDataList, data,
781                                                   dataLength);
782             if (CA_STATUS_OK != result)
783             {
784                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add data to pending list !");
785                 continue;
786             }
787
788             // Make a rfcomm connection with remote BT Device
789             result = CAEDRClientConnect(device->remoteAddress, device->serviceUUID);
790             if (CA_STATUS_OK != result)
791             {
792                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to make RFCOMM connection !");
793
794                 //Remove the data which added to pending list
795                 CARemoveEDRDataFromList(&device->pendingDataList);
796                 continue;
797             }
798         }
799         else
800         {
801             result = CAEDRSendData(device->socketFD, data, dataLength);
802             if (CA_STATUS_OK != result)
803             {
804                 OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send data to [%s] !",
805                           device->remoteAddress);
806             }
807         }
808     }
809 exit:
810     ca_mutex_unlock(g_edrDeviceListMutex);
811
812     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
813     return CA_STATUS_OK;
814 }
815
816 CAResult_t CAEDRClientConnect(const char *remoteAddress, const char *serviceUUID)
817 {
818     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
819
820     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
821     VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "Service UUID is null");
822
823     size_t addressLen = strlen(remoteAddress);
824     if (0 == addressLen || CA_MACADDR_SIZE - 1 != addressLen)
825     {
826         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Invalid remote address");
827         return  CA_STATUS_INVALID_PARAM;
828     }
829
830     if (!serviceUUID[0])
831     {
832         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Empty service uuid");
833         return  CA_STATUS_INVALID_PARAM;
834     }
835
836     bt_error_e err = bt_socket_connect_rfcomm(remoteAddress, serviceUUID);
837     if (BT_ERROR_NONE != err)
838     {
839         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
840                   "Failed to connect!, address [%s] error num [%x]",
841                   remoteAddress, err);
842         return CA_STATUS_FAILED;
843     }
844
845     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
846     return CA_STATUS_OK;
847 }
848
849 CAResult_t CAEDRClientDisconnect(const int32_t clientID)
850 {
851     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
852
853     // Input validation
854     if (0 > clientID)
855     {
856         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: negative client id");
857         return CA_STATUS_INVALID_PARAM;
858     }
859
860     bt_error_e err = bt_socket_disconnect_rfcomm(clientID);
861     if (BT_ERROR_NONE != err)
862     {
863         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed close rfcomm client socket!, error num [%x]",
864                   err);
865         return CA_STATUS_FAILED;
866     }
867
868     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
869     return CA_STATUS_OK;
870 }
871
872 void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData)
873 {
874     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
875
876     EDRDevice *device = NULL;
877
878     if (NULL == data || 0 >= data->data_size)
879     {
880         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Data is null!");
881         return;
882     }
883
884     // Get EDR device from list
885     ca_mutex_lock(g_edrDeviceListMutex);
886     CAResult_t result = CAGetEDRDeviceBySocketId(g_edrDeviceList, data->socket_fd, &device);
887     if (CA_STATUS_OK != result)
888     {
889         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Could not find the device!");
890
891         ca_mutex_unlock(g_edrDeviceListMutex);
892         return;
893     }
894     ca_mutex_unlock(g_edrDeviceListMutex);
895
896     if (!device)
897     {
898         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "There is no device!");
899         return;
900     }
901
902     uint32_t sentLength = 0;
903
904     g_edrPacketReceivedCallback(device->remoteAddress,
905                                 (uint8_t *) data->data,
906                                 (uint32_t) data->data_size,
907                                 &sentLength);
908
909     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
910 }