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