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