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