Imported Upstream version 1.1.0
[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  * To Store Adapter Mode information
82  */
83 static bool g_isDiscoveryServer = false;
84
85 /**
86  * This function creates mutex.
87  */
88 static CAResult_t CAEDRManagerInitializeMutex(void);
89
90 /**
91  * This function frees mutex.
92  */
93 static void CAEDRManagerTerminateMutex(void);
94
95 /**
96  * This callback is registered to recieve data on any open RFCOMM connection.
97  */
98 static void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData);
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     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     g_isDiscoveryServer = true;
444
445     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
446     return CA_STATUS_OK;
447 }
448
449 CAResult_t CAEDRStopServiceSearch(void)
450 {
451     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
452
453     bt_error_e err = bt_device_cancel_service_search();
454     // Stop ongoing service search
455     if (BT_ERROR_NONE != err)
456     {
457         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
458                   err);
459         return CA_STATUS_FAILED;
460     }
461
462     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
463     return CA_STATUS_OK;
464 }
465
466 CAResult_t CAEDRStopDeviceDiscovery(void)
467 {
468     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
469
470     bool isDiscoveryStarted = false;
471     bt_error_e err = bt_adapter_is_discovering(&isDiscoveryStarted);
472     // Check the device discovery state
473     if (BT_ERROR_NONE != err)
474     {
475         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]",
476                   err);
477         return CA_STATUS_FAILED;
478     }
479
480     //stop the device discovery process
481     if (true == isDiscoveryStarted)
482     {
483         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Stopping the device search process");
484         if (BT_ERROR_NONE != (err = bt_adapter_stop_device_discovery()))
485         {
486             OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to stop discovery!, error num [%x]",
487                       err);
488         }
489     }
490
491     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
492     return CA_STATUS_OK;
493 }
494
495 CAResult_t CAEDRStartServiceSearch(const char *remoteAddress)
496 {
497     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
498
499     // Input validation
500     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
501     if (!remoteAddress[0])
502     {
503         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Remote address is empty!");
504         return CA_STATUS_INVALID_PARAM;
505     }
506
507     bt_error_e err = bt_device_start_service_search(remoteAddress);
508     // Start searching for OIC service
509     if (BT_ERROR_NONE != err)
510     {
511         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
512                   err);
513         return CA_STATUS_FAILED;
514     }
515
516     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
517     return CA_STATUS_OK;
518 }
519
520 CAResult_t CAEDRClientSetCallbacks(void)
521 {
522     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
523
524     // Register for discovery and rfcomm socket connection callbacks
525     bt_adapter_set_device_discovery_state_changed_cb(CAEDRDeviceDiscoveryCallback, NULL);
526     bt_device_set_service_searched_cb(CAEDRServiceSearchedCallback, NULL);
527     bt_socket_set_connection_state_changed_cb(CAEDRSocketConnectionStateCallback, NULL);
528     bt_socket_set_data_received_cb(CAEDRDataRecvCallback, NULL);
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     if(g_isDiscoveryServer)
835     {
836         // Start the device Discovery.
837         result = CAEDRStartDeviceDiscovery();
838         if (CA_STATUS_OK == result)
839         {
840             OIC_LOG(INFO, EDR_ADAPTER_TAG, "Add the data to the multicast data list");
841
842             EDRData *multicastData = (EDRData *)OICCalloc(1, sizeof(EDRData));
843             if (NULL == multicastData)
844             {
845                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Malloc failed");
846                 goto exit;
847             }
848             multicastData->data = OICCalloc(1, dataLength);
849             if (NULL == multicastData->data)
850             {
851                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Malloc failed");
852                 goto exit;
853             }
854             memcpy(multicastData->data, data, dataLength);
855             multicastData->dataLength = dataLength;
856
857             // Add the data to pending multicast data list.
858             ca_mutex_lock(g_multicastDataListMutex);
859             if (NULL == g_multicastDataList)
860             {
861                 g_multicastDataList = u_arraylist_create();
862             }
863             u_arraylist_add(g_multicastDataList, (void *)multicastData);
864             ca_mutex_unlock(g_multicastDataListMutex);
865         }
866     }
867
868 exit:
869     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
870     return CA_STATUS_OK;
871 }
872
873 CAResult_t CAEDRClientConnect(const char *remoteAddress, const char *serviceUUID)
874 {
875     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
876
877     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
878     VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "Service UUID is null");
879
880     size_t addressLen = strlen(remoteAddress);
881     if (0 == addressLen || CA_MACADDR_SIZE - 1 != addressLen)
882     {
883         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Invalid remote address");
884         return  CA_STATUS_INVALID_PARAM;
885     }
886
887     if (!serviceUUID[0])
888     {
889         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Empty service uuid");
890         return  CA_STATUS_INVALID_PARAM;
891     }
892
893     bt_error_e err = bt_socket_connect_rfcomm(remoteAddress, serviceUUID);
894     if (BT_ERROR_NONE != err)
895     {
896         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
897                   "Failed to connect!, address [%s] error num [%x]",
898                   remoteAddress, err);
899         return CA_STATUS_FAILED;
900     }
901
902     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
903     return CA_STATUS_OK;
904 }
905
906 CAResult_t CAEDRClientDisconnect(const int32_t clientID)
907 {
908     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
909
910     // Input validation
911     if (0 > clientID)
912     {
913         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: negative client id");
914         return CA_STATUS_INVALID_PARAM;
915     }
916
917     bt_error_e err = bt_socket_disconnect_rfcomm(clientID);
918     if (BT_ERROR_NONE != err)
919     {
920         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed close rfcomm client socket!, error num [%x]",
921                   err);
922         return CA_STATUS_FAILED;
923     }
924
925     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
926     return CA_STATUS_OK;
927 }
928
929 void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData)
930 {
931     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
932
933     EDRDevice *device = NULL;
934
935     if (NULL == data || 0 >= data->data_size)
936     {
937         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Data is null!");
938         return;
939     }
940
941     // Get EDR device from list
942     ca_mutex_lock(g_edrDeviceListMutex);
943     CAResult_t result = CAGetEDRDeviceBySocketId(g_edrDeviceList, data->socket_fd, &device);
944     if (CA_STATUS_OK != result)
945     {
946         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Could not find the device!");
947
948         ca_mutex_unlock(g_edrDeviceListMutex);
949         return;
950     }
951     ca_mutex_unlock(g_edrDeviceListMutex);
952
953     //: TODO Need to check if 'check required for socket still connected or not'
954     if (!device)
955     {
956         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "There is no device!");
957         return;
958     }
959
960     CAConnectedDeviceInfo_t *deviceInfo =
961         (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(device->remoteAddress);
962
963     if (!deviceInfo)
964     {
965         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Received Data from new device");
966         deviceInfo = (CAConnectedDeviceInfo_t *) OICCalloc(1, sizeof(*deviceInfo));
967         if (!deviceInfo)
968         {
969             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Out of memory");
970             return;
971         }
972
973         deviceInfo->state = STATE_CONNECTED;
974         deviceInfo->recvData = NULL;
975         deviceInfo->recvDataLen = 0;
976         deviceInfo->totalDataLen = 0;
977         result = CAEDRAddDeviceInfoToList(device->remoteAddress, deviceInfo);
978         if (CA_STATUS_OK != result)
979         {
980             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Could not add device info to list!");
981             OICFree(deviceInfo);
982             return;
983         }
984     }
985
986     if (!deviceInfo->recvData)
987     {
988         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Callocing deviceInfo->recvData");
989         deviceInfo->recvData = OICCalloc(data->data_size, sizeof(uint8_t));
990         if (!deviceInfo->recvData)
991         {
992             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "out of memory");
993             return;
994         }
995     }
996
997     memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*)data->data,
998            data->data_size);
999     deviceInfo->recvDataLen += data->data_size;
1000
1001     if (!deviceInfo->totalDataLen)
1002     {
1003         coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
1004                 ((unsigned char *)deviceInfo->recvData)[0] >> 4);
1005         size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
1006
1007         if (deviceInfo->recvDataLen >= headerLen)
1008         {
1009             // get actual data length from coap over tcp header
1010             deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
1011                                                                      deviceInfo->recvDataLen);
1012             OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "total data length [%d] bytes", deviceInfo->totalDataLen);
1013
1014             uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen);
1015             if (!newBuf)
1016             {
1017                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "out of memory");
1018                 //Memory free
1019                 return;
1020             }
1021             deviceInfo->recvData = newBuf;
1022         }
1023     }
1024
1025     if (deviceInfo->totalDataLen == deviceInfo->recvDataLen)
1026     {
1027         if (g_edrPacketReceivedCallback)
1028         {
1029             OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG,"data will be sent to callback routine: %s, %d",
1030                       deviceInfo->recvData, deviceInfo->recvDataLen);
1031
1032             uint32_t sentLength = 0;
1033             g_edrPacketReceivedCallback(device->remoteAddress, (void*) deviceInfo->recvData,
1034                                         deviceInfo->recvDataLen, &sentLength);
1035
1036             OICFree(deviceInfo->recvData);
1037             deviceInfo->recvData = NULL;
1038             deviceInfo->recvDataLen = 0;
1039             deviceInfo->totalDataLen = 0;
1040         }
1041     }
1042
1043     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
1044 }