fcd1db96dad081f2ac14be4256a000da469e2825
[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  * Mutex to synchronize the access to Bluetooth device information list.
44  */
45 static ca_mutex g_edrDeviceListMutex = NULL;
46
47 /**
48  * Peer Bluetooth device information list.
49  */
50 static EDRDeviceList *g_edrDeviceList = NULL;
51
52 /**
53  * Maintains the callback to be notified when data received from remote
54  * Bluetooth device.
55  */
56 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
57
58 /**
59  * Error callback to update error in EDR.
60  */
61 static CAEDRErrorHandleCallback g_edrErrorHandler = NULL;
62
63 /**
64  * Pending multicast data list to be sent.
65  */
66 static u_arraylist_t *g_multicastDataList = NULL;
67
68 /**
69  * Mutex to synchronize the access to Pending multicast data list.
70  */
71 static ca_mutex g_multicastDataListMutex = NULL;
72
73 /**
74  * This function creates mutex.
75  */
76 static CAResult_t 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                 ca_mutex_lock(g_multicastDataListMutex);
265                 u_arraylist_destroy(g_multicastDataList);
266                 g_multicastDataList = NULL;
267                 ca_mutex_unlock(g_multicastDataListMutex);
268             }
269             break;
270
271         case BT_ADAPTER_DEVICE_DISCOVERY_FOUND:
272             {
273                 OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Device discovered [%s]!",
274                           discoveryInfo->remote_name);
275                 if (true == CAEDRIsServiceSupported((const char **)discoveryInfo->service_uuid,
276                                                         discoveryInfo->service_count,
277                                                         OIC_EDR_SERVICE_ID))
278                 {
279                     // Check if the deivce is already in the list
280                     ca_mutex_lock(g_edrDeviceListMutex);
281                     if (CA_STATUS_OK == CAGetEDRDevice(g_edrDeviceList,
282                                                 discoveryInfo->remote_address, &device))
283                     {
284                         if(!device)
285                         {
286                             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
287                             ca_mutex_unlock(g_edrDeviceListMutex);
288                             return;
289                         }
290                         device->serviceSearched = true;
291                         ca_mutex_unlock(g_edrDeviceListMutex);
292                         return;
293                     }
294
295                     // Create the deviceinfo and add to list
296                     CAResult_t res = CACreateAndAddToDeviceList(&g_edrDeviceList,
297                             discoveryInfo->remote_address, OIC_EDR_SERVICE_ID, &device);
298                     if (CA_STATUS_OK != res)
299                     {
300                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add device to list!");
301                         ca_mutex_unlock(g_edrDeviceListMutex);
302                         return;
303                     }
304
305                     if(!device)
306                     {
307                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
308                         ca_mutex_unlock(g_edrDeviceListMutex);
309                         return;
310                     }
311
312                     int lengthData = u_arraylist_length(g_multicastDataList);
313                     for(int len = 0; len < lengthData; len++)
314                     {
315                         // Adding to pending list
316                         EDRData *multicastData =
317                             (EDRData *)u_arraylist_get(g_multicastDataList, len);
318                         if (NULL == multicastData)
319                         {
320                             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "multicastData is NULL");
321                             continue;
322                         }
323                         result = CAAddEDRDataToList(&device->pendingDataList, multicastData->data,
324                                                     multicastData->dataLength);
325                         if (CA_STATUS_OK != result)
326                         {
327                             OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
328                                       "Failed to add data to pending list[%d]", result);
329                             continue;
330                         }
331                     }
332                     if (lengthData)
333                     {
334                         result = CAEDRClientConnect(device->remoteAddress, device->serviceUUID);
335                         if (CA_STATUS_OK != result)
336                         {
337                             OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
338                                       "Failed to make RFCOMM connection[%d]", result);
339
340                             //Remove the data which added to pending list
341                             CARemoveEDRDataFromList(&device->pendingDataList);
342                         }
343                     }
344                     device->serviceSearched = true;
345                     ca_mutex_unlock(g_edrDeviceListMutex);
346                 }
347                 else
348                 {
349                     OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Device does not support OIC service!");
350                 }
351             }
352             break;
353     }
354
355     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
356 }
357
358 void CAEDRServiceSearchedCallback(int32_t result,
359                 bt_device_sdp_info_s *sdpInfo,void *userData)
360 {
361     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
362
363     if (NULL == sdpInfo)
364     {
365         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "SDP info is null!");
366         return;
367     }
368
369     ca_mutex_lock(g_edrDeviceListMutex);
370
371     EDRDevice *device = NULL;
372     CAResult_t res = CAGetEDRDevice(g_edrDeviceList, sdpInfo->remote_address, &device);
373     if (CA_STATUS_OK == res && NULL != device)
374     {
375         if (device->serviceSearched)
376         {
377             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Service is already searched for this device!");
378             ca_mutex_unlock(g_edrDeviceListMutex);
379             return;
380         }
381
382         if (true == CAEDRIsServiceSupported((const char **)sdpInfo->service_uuid,
383                                            sdpInfo->service_count, OIC_EDR_SERVICE_ID))
384         {
385             device->serviceSearched = true;
386             res = CAEDRClientConnect(sdpInfo->remote_address, OIC_EDR_SERVICE_ID);
387             if (CA_STATUS_OK != res)
388             {
389                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to make rfcomm connection!");
390
391                 // Remove the device from device list
392                 CARemoveEDRDeviceFromList(&g_edrDeviceList, sdpInfo->remote_address);
393             }
394         }
395         else
396         {
397             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Device does not contain OIC service!");
398
399             // Remove device from list as it does not support OIC service
400             CARemoveEDRDeviceFromList(&g_edrDeviceList, sdpInfo->remote_address);
401         }
402     }
403
404     ca_mutex_unlock(g_edrDeviceListMutex);
405
406     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
407 }
408
409 CAResult_t CAEDRStartDeviceDiscovery(void)
410 {
411     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
412
413
414     bool isDiscoveryStarted = false;
415
416     // Check the device discovery state
417     bt_error_e err = bt_adapter_is_discovering(&isDiscoveryStarted);
418     if (BT_ERROR_NONE != err)
419     {
420         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]",
421                   err);
422         return CA_STATUS_FAILED;
423     }
424
425     //Start device discovery if its not started
426     if (false == isDiscoveryStarted)
427     {
428         err = bt_adapter_start_device_discovery();
429         if (BT_ERROR_NONE != err)
430         {
431             OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Device discovery failed!, error num [%x]",
432                       err);
433             return CA_STATUS_FAILED;
434         }
435     }
436
437     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
438     return CA_STATUS_OK;
439 }
440
441 CAResult_t CAEDRStopServiceSearch(void)
442 {
443     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
444
445     bt_error_e err = bt_device_cancel_service_search();
446     // Stop ongoing service search
447     if (BT_ERROR_NONE != err)
448     {
449         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
450                   err);
451         return CA_STATUS_FAILED;
452     }
453
454     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
455     return CA_STATUS_OK;
456 }
457
458 CAResult_t CAEDRStopDeviceDiscovery(void)
459 {
460     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
461
462     bool isDiscoveryStarted = false;
463     bt_error_e err = bt_adapter_is_discovering(&isDiscoveryStarted);
464     // Check the device discovery state
465     if (BT_ERROR_NONE != err)
466     {
467         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]",
468                   err);
469         return CA_STATUS_FAILED;
470     }
471
472     //stop the device discovery process
473     if (true == isDiscoveryStarted)
474     {
475         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Stopping the device search process");
476         if (BT_ERROR_NONE != (err = bt_adapter_stop_device_discovery()))
477         {
478             OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to stop discovery!, error num [%x]",
479                       err);
480         }
481     }
482
483     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
484     return CA_STATUS_OK;
485 }
486
487 CAResult_t CAEDRStartServiceSearch(const char *remoteAddress)
488 {
489     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
490
491     // Input validation
492     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
493     if (!remoteAddress[0])
494     {
495         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Remote address is empty!");
496         return CA_STATUS_INVALID_PARAM;
497     }
498
499     bt_error_e err = bt_device_start_service_search(remoteAddress);
500     // Start searching for OIC service
501     if (BT_ERROR_NONE != err)
502     {
503         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
504                   err);
505         return CA_STATUS_FAILED;
506     }
507
508     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
509     return CA_STATUS_OK;
510 }
511
512 CAResult_t CAEDRClientSetCallbacks(void)
513 {
514     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
515
516     // Register for discovery and rfcomm socket connection callbacks
517     bt_adapter_set_device_discovery_state_changed_cb(CAEDRDeviceDiscoveryCallback, NULL);
518     bt_device_set_service_searched_cb(CAEDRServiceSearchedCallback, NULL);
519     bt_socket_set_connection_state_changed_cb(CAEDRSocketConnectionStateCallback, NULL);
520     bt_socket_set_data_received_cb(CAEDRDataRecvCallback, NULL);
521
522     // Start device discovery
523     CAResult_t result = CAEDRStartDeviceDiscovery();
524     if(CA_STATUS_OK != result)
525     {
526         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Failed to Start Device discovery");
527         return CA_STATUS_FAILED;
528     }
529
530     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
531     return CA_STATUS_OK;
532 }
533
534
535 void CAEDRClientUnsetCallbacks(void)
536 {
537     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
538
539     // Stop service search
540     CAEDRStopServiceSearch();
541
542     // Stop the device discovery process
543     CAEDRStopDeviceDiscovery();
544
545     // reset bluetooth adapter callbacks
546     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Resetting the callbacks");
547     bt_adapter_unset_device_discovery_state_changed_cb();
548     bt_device_unset_service_searched_cb();
549     bt_socket_unset_connection_state_changed_cb();
550     bt_socket_unset_data_received_cb();
551
552     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
553 }
554
555 CAResult_t CAEDRManagerInitializeMutex(void)
556 {
557     CAResult_t result = CA_STATUS_OK;
558     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
559
560     if (!g_edrDeviceListMutex)
561     {
562         g_edrDeviceListMutex = ca_mutex_new();
563     }
564
565     if (!g_multicastDataListMutex)
566     {
567         g_multicastDataListMutex = ca_mutex_new();
568     }
569
570     if (!g_edrDeviceListMutex || !g_multicastDataListMutex)
571     {
572         result = CA_STATUS_NOT_INITIALIZED;
573     }
574
575     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
576
577     return result;
578 }
579
580 void CAEDRManagerTerminateMutex(void)
581 {
582     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
583
584     if (g_edrDeviceListMutex)
585     {
586         ca_mutex_free(g_edrDeviceListMutex);
587         g_edrDeviceListMutex = NULL;
588     }
589
590     if (g_multicastDataListMutex)
591     {
592         ca_mutex_free(g_multicastDataListMutex);
593         g_multicastDataListMutex = NULL;
594     }
595
596     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
597 }
598
599 CAResult_t CAEDRClientInitialize()
600 {
601     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
602     CAResult_t result = CAEDRManagerInitializeMutex();
603     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
604     return result;
605 }
606
607 void CAEDRClientTerminate()
608 {
609     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
610
611     // Free EDRDevices list
612     if (g_edrDeviceListMutex)
613     {
614         ca_mutex_lock(g_edrDeviceListMutex);
615         CADestroyEDRDeviceList(&g_edrDeviceList);
616         ca_mutex_unlock(g_edrDeviceListMutex);
617     }
618
619     if (g_multicastDataListMutex)
620     {
621         ca_mutex_lock(g_multicastDataListMutex);
622         u_arraylist_destroy(g_multicastDataList);
623         g_multicastDataList = NULL;
624         ca_mutex_unlock(g_multicastDataListMutex);
625     }
626
627     // Free the mutex
628     CAEDRManagerTerminateMutex();
629     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
630 }
631
632 void CAEDRClientDisconnectAll(void)
633 {
634     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
635
636     ca_mutex_lock(g_edrDeviceListMutex);
637
638     EDRDeviceList *cur = g_edrDeviceList;
639     while (cur != NULL)
640     {
641         EDRDevice *device = cur->device;
642         cur = cur->next;
643
644         if (device && 0 <= device->socketFD)
645         {
646             CAResult_t result = CAEDRClientDisconnect(device->socketFD);
647             if (CA_STATUS_OK != result)
648             {
649                 OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to disconnect with client :%s",
650                           device->remoteAddress);
651             }
652
653             device->socketFD = -1;
654         }
655     }
656
657     ca_mutex_unlock(g_edrDeviceListMutex);
658
659     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
660 }
661
662
663 CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress,
664                                       const uint8_t *data,
665                                       uint32_t dataLength)
666 {
667     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
668
669     EDRDevice *device = NULL;
670
671     // Input validation
672     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
673     VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
674
675     if (0 >= dataLength)
676     {
677         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Negative data length!");
678         return CA_STATUS_INVALID_PARAM;
679     }
680
681     // Check the connection existence with remote device
682     ca_mutex_lock(g_edrDeviceListMutex);
683     CAResult_t result = CAGetEDRDevice(g_edrDeviceList, remoteAddress, &device);
684     if (CA_STATUS_OK != result)
685     {
686         // Create new device and add to list
687         result = CACreateAndAddToDeviceList(&g_edrDeviceList, remoteAddress,
688                                             OIC_EDR_SERVICE_ID, &device);
689         if (CA_STATUS_OK != result)
690         {
691             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed create device and add to list!");
692
693             ca_mutex_unlock(g_edrDeviceListMutex);
694             return CA_STATUS_FAILED;
695         }
696
697         // Start the OIC service search newly created device
698         result = CAEDRStartServiceSearch(remoteAddress);
699         if (CA_STATUS_OK != result)
700         {
701             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to initiate service search!");
702
703             // Remove device from list
704             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
705
706             ca_mutex_unlock(g_edrDeviceListMutex);
707             return CA_STATUS_FAILED;
708         }
709     }
710
711     if(!device)
712     {
713         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
714         // Remove device from list
715         CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
716
717         ca_mutex_unlock(g_edrDeviceListMutex);
718         return CA_STATUS_FAILED;
719     }
720
721     ca_mutex_unlock(g_edrDeviceListMutex);
722
723     if (-1 == device->socketFD)
724     {
725         // Adding to pending list
726         result = CAAddEDRDataToList(&device->pendingDataList, data,
727                                               dataLength);
728         if (CA_STATUS_OK != result)
729         {
730             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add data to pending list!");
731
732             //Remove device from list
733             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
734             return CA_STATUS_FAILED;
735         }
736
737         // Make a rfcomm connection with remote BT Device
738         if (device->serviceSearched &&
739             CA_STATUS_OK != CAEDRClientConnect(remoteAddress, OIC_EDR_SERVICE_ID))
740         {
741             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to make RFCOMM connection!");
742
743             //Remove device from list
744             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
745             return CA_STATUS_FAILED;
746         }
747     }
748     else
749     {
750         result = CAEDRSendData(device->socketFD, data, dataLength);
751         if (CA_STATUS_OK != result)
752         {
753             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to send data!");
754             return CA_STATUS_FAILED;
755         }
756     }
757
758     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
759     return CA_STATUS_OK;
760 }
761
762 CAResult_t CAEDRClientSendMulticastData(const uint8_t *data,
763                                         uint32_t dataLength)
764 {
765     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
766
767     // Input validation
768     VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
769
770     if (0 >= dataLength)
771     {
772         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Negative data length!");
773         return CA_STATUS_INVALID_PARAM;
774     }
775
776     // Send the packet to all OIC devices
777     ca_mutex_lock(g_edrDeviceListMutex);
778
779     EDRDeviceList *curList = g_edrDeviceList;
780     CAResult_t result = CA_STATUS_FAILED;
781     while (curList != NULL)
782     {
783         EDRDevice *device = curList->device;
784         curList = curList->next;
785
786         if (!device)
787         {
788             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "There is no device!");
789             break;
790         }
791
792         if (-1 == device->socketFD)
793         {
794             // Check if the device service search is finished
795             if (false == device->serviceSearched)
796             {
797                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Device services are still unknown!");
798                 continue;
799             }
800
801             // Adding to pendding list
802             result = CAAddEDRDataToList(&device->pendingDataList, data,
803                                                   dataLength);
804             if (CA_STATUS_OK != result)
805             {
806                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add data to pending list !");
807                 continue;
808             }
809
810             // Make a rfcomm connection with remote BT Device
811             result = CAEDRClientConnect(device->remoteAddress, device->serviceUUID);
812             if (CA_STATUS_OK != result)
813             {
814                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to make RFCOMM connection !");
815
816                 //Remove the data which added to pending list
817                 CARemoveEDRDataFromList(&device->pendingDataList);
818                 continue;
819             }
820         }
821         else
822         {
823             result = CAEDRSendData(device->socketFD, data, dataLength);
824             if (CA_STATUS_OK != result)
825             {
826                 OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send data to [%s] !",
827                           device->remoteAddress);
828             }
829         }
830     }
831
832     ca_mutex_unlock(g_edrDeviceListMutex);
833
834     // Start the device Discovery.
835     result = CAEDRStartDeviceDiscovery();
836     if (CA_STATUS_OK == result)
837     {
838         OIC_LOG(INFO, EDR_ADAPTER_TAG, "Add the data to the multicast data list");
839
840         EDRData *multicastData = (EDRData *)OICCalloc(1, sizeof(EDRData));
841         if (NULL == multicastData)
842         {
843             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Malloc failed");
844             goto exit;
845         }
846         multicastData->data = OICCalloc(1, dataLength);
847         if (NULL == multicastData->data)
848         {
849             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Malloc failed");
850             goto exit;
851         }
852         memcpy(multicastData->data, data, dataLength);
853         multicastData->dataLength = dataLength;
854
855         // Add the data to pending multicast data list.
856         ca_mutex_lock(g_multicastDataListMutex);
857         if (NULL == g_multicastDataList)
858         {
859             g_multicastDataList = u_arraylist_create();
860         }
861         u_arraylist_add(g_multicastDataList, (void *)multicastData);
862         ca_mutex_unlock(g_multicastDataListMutex);
863     }
864
865 exit:
866     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
867     return CA_STATUS_OK;
868 }
869
870 CAResult_t CAEDRClientConnect(const char *remoteAddress, const char *serviceUUID)
871 {
872     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
873
874     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
875     VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "Service UUID is null");
876
877     size_t addressLen = strlen(remoteAddress);
878     if (0 == addressLen || CA_MACADDR_SIZE - 1 != addressLen)
879     {
880         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Invalid remote address");
881         return  CA_STATUS_INVALID_PARAM;
882     }
883
884     if (!serviceUUID[0])
885     {
886         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Empty service uuid");
887         return  CA_STATUS_INVALID_PARAM;
888     }
889
890     bt_error_e err = bt_socket_connect_rfcomm(remoteAddress, serviceUUID);
891     if (BT_ERROR_NONE != err)
892     {
893         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
894                   "Failed to connect!, address [%s] error num [%x]",
895                   remoteAddress, err);
896         return CA_STATUS_FAILED;
897     }
898
899     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
900     return CA_STATUS_OK;
901 }
902
903 CAResult_t CAEDRClientDisconnect(const int32_t clientID)
904 {
905     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
906
907     // Input validation
908     if (0 > clientID)
909     {
910         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: negative client id");
911         return CA_STATUS_INVALID_PARAM;
912     }
913
914     bt_error_e err = bt_socket_disconnect_rfcomm(clientID);
915     if (BT_ERROR_NONE != err)
916     {
917         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed close rfcomm client socket!, error num [%x]",
918                   err);
919         return CA_STATUS_FAILED;
920     }
921
922     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
923     return CA_STATUS_OK;
924 }
925
926 void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData)
927 {
928     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
929
930     EDRDevice *device = NULL;
931
932     if (NULL == data || 0 >= data->data_size)
933     {
934         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Data is null!");
935         return;
936     }
937
938     // Get EDR device from list
939     ca_mutex_lock(g_edrDeviceListMutex);
940     CAResult_t result = CAGetEDRDeviceBySocketId(g_edrDeviceList, data->socket_fd, &device);
941     if (CA_STATUS_OK != result)
942     {
943         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Could not find the device!");
944
945         ca_mutex_unlock(g_edrDeviceListMutex);
946         return;
947     }
948     ca_mutex_unlock(g_edrDeviceListMutex);
949
950     if (!device)
951     {
952         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "There is no device!");
953         return;
954     }
955
956     uint32_t sentLength = 0;
957
958     g_edrPacketReceivedCallback(device->remoteAddress,
959                                 (uint8_t *) data->data,
960                                 (uint32_t) data->data_size,
961                                 &sentLength);
962
963     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
964 }