Imported Upstream version 0.9.2
[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 /**
41  * @var g_edrDeviceListMutex
42  * @brief Mutex to synchronize the access to Bluetooth device information list.
43  */
44 static ca_mutex g_edrDeviceListMutex = NULL;
45
46 /**
47  * @var g_edrDeviceList
48  * @brief Peer Bluetooth device information list.
49  */
50 static EDRDeviceList *g_edrDeviceList = NULL;
51
52 /**
53  * @var gEDRNetworkChangeCallback
54  * @brief Maintains the callback to be notified when data received from remote Bluetooth device
55  */
56 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
57
58 /**
59  * @var g_edrErrorHandler
60  * @brief Error callback to update error in EDR
61  */
62 static CAEDRErrorHandleCallback g_edrErrorHandler = NULL;
63 /**
64  * @fn CAEDRManagerInitializeMutex
65  * @brief This function creates mutex.
66  */
67 static void CAEDRManagerInitializeMutex(void);
68
69 /**
70  * @fn CAEDRManagerTerminateMutex
71  * @brief This function frees mutex.
72  */
73 static void CAEDRManagerTerminateMutex(void);
74
75 /**
76  * @fn CAEDRDataRecvCallback
77  * @brief This callback is registered to recieve data on any open RFCOMM connection.
78  */
79 static void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData);
80
81 /**
82  * @brief This function starts device discovery.
83  * @return NONE
84  */
85 static CAResult_t CAEDRStartDeviceDiscovery(void);
86
87 /**
88  * @fn CAEDRStopServiceSearch
89  * @brief This function stops any ongoing service sevice search.
90  */
91 static CAResult_t CAEDRStopServiceSearch(void);
92
93 /**
94  * @fn CAEDRStopDeviceDiscovery
95  * @brief This function stops device discovery.
96  */
97 static CAResult_t CAEDRStopDeviceDiscovery(void);
98
99 /**
100  * @fn CAEDRStartServiceSearch
101  * @brief This function searches for OIC service for remote Bluetooth device.
102  */
103 static CAResult_t CAEDRStartServiceSearch(const char *remoteAddress);
104
105 /**
106  * @fn CAEDRDeviceDiscoveryCallback
107  * @brief This callback is registered to recieve all bluetooth nearby devices when device
108  *           scan is initiated.
109  */
110 static void CAEDRDeviceDiscoveryCallback(int result,
111                                          bt_adapter_device_discovery_state_e state,
112                                          bt_adapter_device_discovery_info_s *discoveryInfo,
113                                          void *userData);
114
115 /**
116  * @fn CAEDRServiceSearchedCallback
117  * @brief This callback is registered to recieve all the services remote bluetooth device supports
118  *           when service search initiated.
119  */
120 static void CAEDRServiceSearchedCallback(int result, bt_device_sdp_info_s *sdpInfo,
121                                         void *userData);
122
123 /**
124  * @fn CAEDRSocketConnectionStateCallback
125  * @brief This callback is registered to receive bluetooth RFCOMM connection state changes.
126  */
127 static void CAEDRSocketConnectionStateCallback(int result,
128                                     bt_socket_connection_state_e state,
129                                               bt_socket_connection_s *connection, void *userData);
130
131 /**
132  * @fn CAEDRClientConnect
133  * @brief Establishes RFCOMM connection with remote bluetooth device
134  */
135 static CAResult_t CAEDRClientConnect(const char *remoteAddress, const char *serviceUUID);
136
137 /**
138  * @fn CAEDRClientDisconnect
139  * @brief  Disconnect RFCOMM client socket connection
140  */
141 static CAResult_t CAEDRClientDisconnect(const int32_t clientID);
142
143 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
144 {
145     g_edrPacketReceivedCallback = packetReceivedCallback;
146 }
147
148 void CAEDRSetErrorHandler(CAEDRErrorHandleCallback errorHandleCallback)
149 {
150     g_edrErrorHandler = errorHandleCallback;
151 }
152
153 void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e state,
154                                        bt_socket_connection_s *connection, void *userData)
155 {
156     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
157
158     EDRDevice *device = NULL;
159
160     if (BT_ERROR_NONE != result || NULL == connection)
161     {
162         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Invalid connection state!, error num [%x]",
163                   result);
164         return;
165     }
166
167     switch (state)
168     {
169         case BT_SOCKET_CONNECTED:
170             {
171                 ca_mutex_lock(g_edrDeviceListMutex);
172                 CAResult_t res = CAGetEDRDevice(g_edrDeviceList, connection->remote_address,
173                                                    &device);
174                 if (CA_STATUS_OK != res)
175                 {
176                     // Create the deviceinfo and add to list
177                     res = CACreateAndAddToDeviceList(&g_edrDeviceList,
178                             connection->remote_address, OIC_EDR_SERVICE_ID, &device);
179                     if (CA_STATUS_OK != res)
180                     {
181                         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed add device to list ret[%d]", res);
182                         ca_mutex_unlock(g_edrDeviceListMutex);
183                         return;
184                     }
185
186                     if(!device)
187                     {
188                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
189                         ca_mutex_unlock(g_edrDeviceListMutex);
190                         return;
191                     }
192
193                     device->socketFD = connection->socket_fd;
194                     ca_mutex_unlock(g_edrDeviceListMutex);
195                     return;
196                 }
197
198                 if(!device)
199                 {
200                     OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
201                     ca_mutex_unlock(g_edrDeviceListMutex);
202                     return;
203                 }
204                 device->socketFD = connection->socket_fd;
205                 while (device->pendingDataList)
206                 {
207                     uint32_t sentData = 0;
208                     EDRData *edrData = device->pendingDataList->data;
209                     res = CAEDRSendData(device->socketFD, edrData->data,
210                                                      edrData->dataLength, &sentData);
211                     if (CA_STATUS_OK != res)
212                     {
213                         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send pending data [%s]",
214                                   device->remoteAddress);
215
216                         // Remove all the data from pending list
217                         CADestroyEDRDataList(&device->pendingDataList);
218                         break;
219                     }
220
221                     // Remove the data which send from pending list
222                     CARemoveEDRDataFromList(&device->pendingDataList);
223                 }
224                 ca_mutex_unlock(g_edrDeviceListMutex);
225             }
226             break;
227
228         case BT_SOCKET_DISCONNECTED:
229             {
230                 ca_mutex_lock(g_edrDeviceListMutex);
231                 CARemoveEDRDeviceFromList(&g_edrDeviceList, connection->remote_address);
232                 ca_mutex_unlock(g_edrDeviceListMutex);
233             }
234             break;
235     }
236
237     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
238 }
239
240
241 void CAEDRDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_e state,
242                                  bt_adapter_device_discovery_info_s *discoveryInfo, void *userData)
243 {
244     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
245
246     EDRDevice *device = NULL;
247
248     if (BT_ERROR_NONE != result)
249     {
250         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Received bad state!, error num [%x]",
251                   result);
252         return;
253     }
254
255     switch (state)
256     {
257         case BT_ADAPTER_DEVICE_DISCOVERY_STARTED:
258             {
259                 OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Discovery started!");
260             }
261             break;
262
263         case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED:
264             {
265                 OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Discovery finished!");
266             }
267             break;
268
269         case BT_ADAPTER_DEVICE_DISCOVERY_FOUND:
270             {
271                 OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Device discovered [%s]!",
272                           discoveryInfo->remote_name);
273                 if (true == CAEDRIsServiceSupported((const char **)discoveryInfo->service_uuid,
274                                                         discoveryInfo->service_count,
275                                                         OIC_EDR_SERVICE_ID))
276                 {
277                     // Check if the deivce is already in the list
278                     ca_mutex_lock(g_edrDeviceListMutex);
279                     if (CA_STATUS_OK == CAGetEDRDevice(g_edrDeviceList,
280                                                 discoveryInfo->remote_address, &device))
281                     {
282                         if(!device)
283                         {
284                             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
285                             ca_mutex_unlock(g_edrDeviceListMutex);
286                             return;
287                         }
288                         device->serviceSearched = true;
289                         ca_mutex_unlock(g_edrDeviceListMutex);
290                         return;
291                     }
292
293                     // Create the deviceinfo and add to list
294                     CAResult_t res = CACreateAndAddToDeviceList(&g_edrDeviceList,
295                             discoveryInfo->remote_address, OIC_EDR_SERVICE_ID, &device);
296                     if (CA_STATUS_OK != res)
297                     {
298                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add device to list!");
299                         ca_mutex_unlock(g_edrDeviceListMutex);
300                         return;
301                     }
302
303                     if(!device)
304                     {
305                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
306                         ca_mutex_unlock(g_edrDeviceListMutex);
307                         return;
308                     }
309                     device->serviceSearched = true;
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     // Register for discovery and rfcomm socket connection callbacks
482     bt_adapter_set_device_discovery_state_changed_cb(CAEDRDeviceDiscoveryCallback, NULL);
483     bt_device_set_service_searched_cb(CAEDRServiceSearchedCallback, NULL);
484     bt_socket_set_connection_state_changed_cb(CAEDRSocketConnectionStateCallback, NULL);
485     bt_socket_set_data_received_cb(CAEDRDataRecvCallback, NULL);
486
487     // Start device discovery
488     CAResult_t result = CAEDRStartDeviceDiscovery();
489     if(CA_STATUS_OK != result)
490     {
491         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Failed to Start Device discovery");
492         return CA_STATUS_FAILED;
493     }
494
495     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
496     return CA_STATUS_OK;
497 }
498
499
500 void CAEDRClientUnsetCallbacks(void)
501 {
502     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
503
504     // Stop service search
505     CAEDRStopServiceSearch();
506
507     // Stop the device discovery process
508     CAEDRStopDeviceDiscovery();
509
510     // reset bluetooth adapter callbacks
511     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Resetting the callbacks");
512     bt_adapter_unset_device_discovery_state_changed_cb();
513     bt_device_unset_service_searched_cb();
514     bt_socket_unset_connection_state_changed_cb();
515     bt_socket_unset_data_received_cb();
516
517     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
518 }
519
520 void CAEDRManagerInitializeMutex(void)
521 {
522     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
523
524     if (!g_edrDeviceListMutex)
525     {
526         g_edrDeviceListMutex = ca_mutex_new();
527     }
528
529     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
530 }
531
532 void CAEDRManagerTerminateMutex(void)
533 {
534     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
535
536     if (g_edrDeviceListMutex)
537     {
538         ca_mutex_free(g_edrDeviceListMutex);
539         g_edrDeviceListMutex = NULL;
540     }
541
542     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
543 }
544
545 void CAEDRInitializeClient(ca_thread_pool_t handle)
546 {
547     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
548     CAEDRManagerInitializeMutex();
549     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
550 }
551
552 void CAEDRClientTerminate()
553 {
554     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
555
556     // Free EDRDevices list
557     if (g_edrDeviceListMutex)
558     {
559         ca_mutex_lock(g_edrDeviceListMutex);
560         CADestroyEDRDeviceList(&g_edrDeviceList);
561         ca_mutex_unlock(g_edrDeviceListMutex);
562     }
563
564     // Free the mutex
565     CAEDRManagerTerminateMutex();
566     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
567 }
568
569 void CAEDRClientDisconnectAll(void)
570 {
571     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
572
573     ca_mutex_lock(g_edrDeviceListMutex);
574
575     EDRDeviceList *cur = g_edrDeviceList;
576     while (cur != NULL)
577     {
578         EDRDevice *device = cur->device;
579         cur = cur->next;
580
581         if (device && 0 <= device->socketFD)
582         {
583             CAResult_t result = CAEDRClientDisconnect(device->socketFD);
584             if (CA_STATUS_OK != result)
585             {
586                 OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to disconnect with client :%s",
587                           device->remoteAddress);
588             }
589
590             device->socketFD = -1;
591         }
592     }
593
594     ca_mutex_unlock(g_edrDeviceListMutex);
595
596     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
597 }
598
599
600 CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *serviceUUID,
601                                       const void *data, uint32_t dataLength, uint32_t *sentLength)
602 {
603     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
604
605     EDRDevice *device = NULL;
606
607     // Input validation
608     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
609     VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "service UUID is null");
610     VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
611     VERIFY_NON_NULL(sentLength, EDR_ADAPTER_TAG, "Sent data length holder is null");
612
613     if (0 >= dataLength)
614     {
615         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Negative data length!");
616         return CA_STATUS_INVALID_PARAM;
617     }
618
619     // Check the connection existence with remote device
620     ca_mutex_lock(g_edrDeviceListMutex);
621     CAResult_t result = CAGetEDRDevice(g_edrDeviceList, remoteAddress, &device);
622     if (CA_STATUS_OK != result)
623     {
624         // Create new device and add to list
625         result = CACreateAndAddToDeviceList(&g_edrDeviceList, remoteAddress,
626                                             OIC_EDR_SERVICE_ID, &device);
627         if (CA_STATUS_OK != result)
628         {
629             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed create device and add to list!");
630
631             ca_mutex_unlock(g_edrDeviceListMutex);
632             return CA_STATUS_FAILED;
633         }
634
635         // Start the OIC service search newly created device
636         result = CAEDRStartServiceSearch(remoteAddress);
637         if (CA_STATUS_OK != result)
638         {
639             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to initiate service search!");
640
641             // Remove device from list
642             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
643
644             ca_mutex_unlock(g_edrDeviceListMutex);
645             return CA_STATUS_FAILED;
646         }
647     }
648
649     if(!device)
650     {
651         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
652         // Remove device from list
653         CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
654
655         ca_mutex_unlock(g_edrDeviceListMutex);
656         return CA_STATUS_FAILED;
657     }
658
659     ca_mutex_unlock(g_edrDeviceListMutex);
660
661     if (-1 == device->socketFD)
662     {
663         // Adding to pending list
664         result = CAAddEDRDataToList(&device->pendingDataList, data,
665                                               dataLength);
666         if (CA_STATUS_OK != result)
667         {
668             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add data to pending list!");
669
670             //Remove device from list
671             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
672             return CA_STATUS_FAILED;
673         }
674
675         // Make a rfcomm connection with remote BT Device
676         if (device->serviceSearched &&
677             CA_STATUS_OK != CAEDRClientConnect(remoteAddress, serviceUUID))
678         {
679             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to make RFCOMM connection!");
680
681             //Remove device from list
682             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
683             return CA_STATUS_FAILED;
684         }
685         *sentLength = dataLength;
686     }
687     else
688     {
689         result = CAEDRSendData(device->socketFD, data, dataLength, sentLength);
690         if (CA_STATUS_OK != result)
691         {
692             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to send data!");
693             return CA_STATUS_FAILED;
694         }
695     }
696
697     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
698     return CA_STATUS_OK;
699 }
700
701 CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *data,
702                                         uint32_t dataLength, uint32_t *sentLength)
703 {
704     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
705
706     // Input validation
707     VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "service UUID is null");
708     VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
709     VERIFY_NON_NULL(sentLength, EDR_ADAPTER_TAG, "Sent data length holder is null");
710
711     if (0 >= dataLength)
712     {
713         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Negative data length!");
714         return CA_STATUS_INVALID_PARAM;
715     }
716
717     *sentLength = dataLength;
718
719     // Send the packet to all OIC devices
720     ca_mutex_lock(g_edrDeviceListMutex);
721     EDRDeviceList *curList = g_edrDeviceList;
722     CAResult_t result = CA_STATUS_FAILED;
723     while (curList != NULL)
724     {
725         EDRDevice *device = curList->device;
726         curList = curList->next;
727
728         if (!device)
729         {
730             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "There is no device!");
731             break;
732         }
733
734         if (-1 == device->socketFD)
735         {
736             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN1");
737             // Check if the device service search is finished
738             if (false == device->serviceSearched)
739             {
740                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Device services are still unknown!");
741                 continue;
742             }
743
744             // Adding to pendding list
745             result = CAAddEDRDataToList(&device->pendingDataList, data,
746                                                   dataLength);
747             if (CA_STATUS_OK != result)
748             {
749                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add data to pending list !");
750                 continue;
751             }
752
753             // Make a rfcomm connection with remote BT Device
754             result = CAEDRClientConnect(device->remoteAddress, device->serviceUUID);
755             if (CA_STATUS_OK != result)
756             {
757                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to make RFCOMM connection !");
758
759                 //Remove the data which added to pending list
760                 CARemoveEDRDataFromList(&device->pendingDataList);
761                 continue;
762             }
763             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN2");
764         }
765         else
766         {
767             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN3");
768             result = CAEDRSendData(device->socketFD, data, dataLength, sentLength);
769             if (CA_STATUS_OK != result)
770             {
771                 OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send data to [%s] !",
772                           device->remoteAddress);
773             }
774             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN4");
775         }
776     }
777     ca_mutex_unlock(g_edrDeviceListMutex);
778
779     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
780     return CA_STATUS_OK;
781 }
782
783 CAResult_t CAEDRClientConnect(const char *remoteAddress, const char *serviceUUID)
784 {
785     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
786
787     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
788     VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "Service UUID is null");
789
790     size_t addressLen = strlen(remoteAddress);
791     if (0 == addressLen || CA_MACADDR_SIZE - 1 != addressLen)
792     {
793         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Invalid remote address");
794         return  CA_STATUS_INVALID_PARAM;
795     }
796
797     if (!serviceUUID[0])
798     {
799         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Empty service uuid");
800         return  CA_STATUS_INVALID_PARAM;
801     }
802
803     bt_error_e err = bt_socket_connect_rfcomm(remoteAddress, serviceUUID);
804     if (BT_ERROR_NONE != err)
805     {
806         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
807                   "Failed to connect!, address [%s] error num [%x]",
808                   remoteAddress, err);
809         return CA_STATUS_FAILED;
810     }
811
812     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
813     return CA_STATUS_OK;
814 }
815
816 CAResult_t CAEDRClientDisconnect(const int32_t clientID)
817 {
818     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
819
820     // Input validation
821     if (0 > clientID)
822     {
823         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: negative client id");
824         return CA_STATUS_INVALID_PARAM;
825     }
826
827     bt_error_e err = bt_socket_disconnect_rfcomm(clientID);
828     if (BT_ERROR_NONE != err)
829     {
830         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed close rfcomm client socket!, error num [%x]",
831                   err);
832         return CA_STATUS_FAILED;
833     }
834
835     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
836     return CA_STATUS_OK;
837 }
838
839 void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData)
840 {
841     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
842
843     EDRDevice *device = NULL;
844
845     if (NULL == data || 0 >= data->data_size)
846     {
847         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Data is null!");
848         return;
849     }
850
851     // Get EDR device from list
852     ca_mutex_lock(g_edrDeviceListMutex);
853     CAResult_t result = CAGetEDRDeviceBySocketId(g_edrDeviceList, data->socket_fd, &device);
854     if (CA_STATUS_OK != result)
855     {
856         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Could not find the device!");
857
858         ca_mutex_unlock(g_edrDeviceListMutex);
859         return;
860     }
861     ca_mutex_unlock(g_edrDeviceListMutex);
862
863     if (!device)
864     {
865         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "There is no device!");
866         return;
867     }
868
869     uint32_t sentLength = 0;
870
871     g_edrPacketReceivedCallback(device->remoteAddress, data->data,
872                                 (uint32_t)data->data_size, &sentLength);
873
874     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
875 }
876
877