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