017319096a43f28713895c25b2d0fefcd70bb0d6
[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 "octhread.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 oc_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 oc_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                 oc_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                         oc_mutex_unlock(g_edrDeviceListMutex);
189                         return;
190                     }
191
192                     if(!device)
193                     {
194                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
195                         oc_mutex_unlock(g_edrDeviceListMutex);
196                         return;
197                     }
198
199                     device->socketFD = connection->socket_fd;
200                     oc_mutex_unlock(g_edrDeviceListMutex);
201                     return;
202                 }
203
204                 if(!device)
205                 {
206                     OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
207                     oc_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, device->remoteAddress,
215                                         edrData->data, 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                 oc_mutex_unlock(g_edrDeviceListMutex);
230             }
231             break;
232
233         case BT_SOCKET_DISCONNECTED:
234             {
235                 oc_mutex_lock(g_edrDeviceListMutex);
236                 CARemoveEDRDeviceFromList(&g_edrDeviceList, connection->remote_address);
237                 oc_mutex_unlock(g_edrDeviceListMutex);
238             }
239             break;
240
241         default:
242             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Unknown Bluetooth Socket connection state");
243     }
244
245     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
246 }
247
248
249 void CAEDRDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_e state,
250                                  bt_adapter_device_discovery_info_s *discoveryInfo, void *userData)
251 {
252     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
253
254     EDRDevice *device = NULL;
255
256     if (BT_ERROR_NONE != result)
257     {
258         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Received bad state!, error num [%x]",
259                   result);
260         return;
261     }
262
263     switch (state)
264     {
265         case BT_ADAPTER_DEVICE_DISCOVERY_STARTED:
266             {
267                 OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Discovery started!");
268             }
269             break;
270
271         case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED:
272             {
273                 OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Discovery finished!");
274                 oc_mutex_lock(g_multicastDataListMutex);
275                 u_arraylist_destroy(g_multicastDataList);
276                 g_multicastDataList = NULL;
277                 oc_mutex_unlock(g_multicastDataListMutex);
278             }
279             break;
280
281         case BT_ADAPTER_DEVICE_DISCOVERY_FOUND:
282             {
283                 OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Device discovered [%s]!",
284                           discoveryInfo->remote_name);
285                 if (true == CAEDRIsServiceSupported((const char **)discoveryInfo->service_uuid,
286                                                         discoveryInfo->service_count,
287                                                         OIC_EDR_SERVICE_ID))
288                 {
289                     // Check if the deivce is already in the list
290                     oc_mutex_lock(g_edrDeviceListMutex);
291                     if (CA_STATUS_OK == CAGetEDRDevice(g_edrDeviceList,
292                                                 discoveryInfo->remote_address, &device))
293                     {
294                         if(!device)
295                         {
296                             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
297                             oc_mutex_unlock(g_edrDeviceListMutex);
298                             return;
299                         }
300                         device->serviceSearched = true;
301                         oc_mutex_unlock(g_edrDeviceListMutex);
302                         return;
303                     }
304
305                     // Create the deviceinfo and add to list
306                     CAResult_t res = CACreateAndAddToDeviceList(&g_edrDeviceList,
307                             discoveryInfo->remote_address, OIC_EDR_SERVICE_ID, &device);
308                     if (CA_STATUS_OK != res)
309                     {
310                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add device to list!");
311                         oc_mutex_unlock(g_edrDeviceListMutex);
312                         return;
313                     }
314
315                     if(!device)
316                     {
317                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
318                         oc_mutex_unlock(g_edrDeviceListMutex);
319                         return;
320                     }
321
322                     int lengthData = u_arraylist_length(g_multicastDataList);
323                     for(int len = 0; len < lengthData; len++)
324                     {
325                         // Adding to pending list
326                         EDRData *multicastData =
327                             (EDRData *)u_arraylist_get(g_multicastDataList, len);
328                         if (NULL == multicastData)
329                         {
330                             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "multicastData is NULL");
331                             continue;
332                         }
333                         result = CAAddEDRDataToList(&device->pendingDataList, multicastData->data,
334                                                     multicastData->dataLength);
335                         if (CA_STATUS_OK != result)
336                         {
337                             OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
338                                       "Failed to add data to pending list[%d]", result);
339                             continue;
340                         }
341                     }
342                     if (lengthData)
343                     {
344                         result = CAEDRClientConnect(device->remoteAddress, device->serviceUUID);
345                         if (CA_STATUS_OK != result)
346                         {
347                             OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
348                                       "Failed to make RFCOMM connection[%d]", result);
349
350                             //Remove the data which added to pending list
351                             CARemoveEDRDataFromList(&device->pendingDataList);
352                         }
353                     }
354                     device->serviceSearched = true;
355                     oc_mutex_unlock(g_edrDeviceListMutex);
356                 }
357                 else
358                 {
359                     OIC_LOG(INFO, EDR_ADAPTER_TAG, "Device does not support OIC service!");
360                 }
361             }
362             break;
363
364         default:
365             OIC_LOG(INFO, EDR_ADAPTER_TAG, "Unknown Bluetooth Adapter device discovery state");
366     }
367
368     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
369 }
370
371 void CAEDRServiceSearchedCallback(int32_t result,
372                 bt_device_sdp_info_s *sdpInfo,void *userData)
373 {
374     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
375
376     if (NULL == sdpInfo)
377     {
378         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "SDP info is null!");
379         return;
380     }
381
382     oc_mutex_lock(g_edrDeviceListMutex);
383
384     EDRDevice *device = NULL;
385     CAResult_t res = CAGetEDRDevice(g_edrDeviceList, sdpInfo->remote_address, &device);
386     if (CA_STATUS_OK == res && NULL != device)
387     {
388         if (device->serviceSearched)
389         {
390             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Service is already searched for this device!");
391             oc_mutex_unlock(g_edrDeviceListMutex);
392             return;
393         }
394
395         if (true == CAEDRIsServiceSupported((const char **)sdpInfo->service_uuid,
396                                            sdpInfo->service_count, OIC_EDR_SERVICE_ID))
397         {
398             device->serviceSearched = true;
399             res = CAEDRClientConnect(sdpInfo->remote_address, OIC_EDR_SERVICE_ID);
400             if (CA_STATUS_OK != res)
401             {
402                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to make rfcomm connection!");
403
404                 // Remove the device from device list
405                 CARemoveEDRDeviceFromList(&g_edrDeviceList, sdpInfo->remote_address);
406             }
407         }
408         else
409         {
410             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Device does not contain OIC service!");
411
412             // Remove device from list as it does not support OIC service
413             CARemoveEDRDeviceFromList(&g_edrDeviceList, sdpInfo->remote_address);
414         }
415     }
416
417     oc_mutex_unlock(g_edrDeviceListMutex);
418
419     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
420 }
421
422 CAResult_t CAEDRStartDeviceDiscovery(void)
423 {
424     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
425
426     bool isDiscoveryStarted = false;
427
428     // Check the device discovery state
429     bt_error_e err = bt_adapter_is_discovering(&isDiscoveryStarted);
430     if (BT_ERROR_NONE != err)
431     {
432         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]",
433                   err);
434         return CA_STATUS_FAILED;
435     }
436
437     //Start device discovery if its not started
438     if (false == isDiscoveryStarted)
439     {
440         err = bt_adapter_start_device_discovery();
441         if (BT_ERROR_NONE != err)
442         {
443             OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Device discovery failed!, error num [%x]",
444                       err);
445             return CA_STATUS_FAILED;
446         }
447     }
448
449     g_isDiscoveryServer = true;
450
451     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
452     return CA_STATUS_OK;
453 }
454
455 CAResult_t CAEDRStopServiceSearch(void)
456 {
457     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
458
459     bt_error_e err = bt_device_cancel_service_search();
460     // Stop ongoing service search
461     if (BT_ERROR_NONE != err)
462     {
463         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
464                   err);
465         return CA_STATUS_FAILED;
466     }
467
468     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
469     return CA_STATUS_OK;
470 }
471
472 CAResult_t CAEDRStopDeviceDiscovery(void)
473 {
474     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
475
476     bool isDiscoveryStarted = false;
477     bt_error_e err = bt_adapter_is_discovering(&isDiscoveryStarted);
478     // Check the device discovery state
479     if (BT_ERROR_NONE != err)
480     {
481         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]",
482                   err);
483         return CA_STATUS_FAILED;
484     }
485
486     //stop the device discovery process
487     if (true == isDiscoveryStarted)
488     {
489         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Stopping the device search process");
490         if (BT_ERROR_NONE != (err = bt_adapter_stop_device_discovery()))
491         {
492             OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to stop discovery!, error num [%x]",
493                       err);
494         }
495     }
496
497     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
498     return CA_STATUS_OK;
499 }
500
501 CAResult_t CAEDRStartServiceSearch(const char *remoteAddress)
502 {
503     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
504
505     // Input validation
506     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
507     if (!remoteAddress[0])
508     {
509         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Remote address is empty!");
510         return CA_STATUS_INVALID_PARAM;
511     }
512
513     bt_error_e err = bt_device_start_service_search(remoteAddress);
514     // Start searching for OIC service
515     if (BT_ERROR_NONE != err)
516     {
517         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Get bonded device failed!, error num [%x]",
518                   err);
519         return CA_STATUS_FAILED;
520     }
521
522     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
523     return CA_STATUS_OK;
524 }
525
526 CAResult_t CAEDRClientSetCallbacks(void)
527 {
528     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
529
530     // Register for discovery and rfcomm socket connection callbacks
531     bt_adapter_set_device_discovery_state_changed_cb(CAEDRDeviceDiscoveryCallback, NULL);
532     bt_device_set_service_searched_cb(CAEDRServiceSearchedCallback, NULL);
533     bt_socket_set_connection_state_changed_cb(CAEDRSocketConnectionStateCallback, NULL);
534     bt_socket_set_data_received_cb(CAEDRDataRecvCallback, NULL);
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 = oc_mutex_new();
569     }
570
571     if (!g_multicastDataListMutex)
572     {
573         g_multicastDataListMutex = oc_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         oc_mutex_free(g_edrDeviceListMutex);
593         g_edrDeviceListMutex = NULL;
594     }
595
596     if (g_multicastDataListMutex)
597     {
598         oc_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         oc_mutex_lock(g_edrDeviceListMutex);
621         CADestroyEDRDeviceList(&g_edrDeviceList);
622         oc_mutex_unlock(g_edrDeviceListMutex);
623     }
624
625     if (g_multicastDataListMutex)
626     {
627         oc_mutex_lock(g_multicastDataListMutex);
628         u_arraylist_destroy(g_multicastDataList);
629         g_multicastDataList = NULL;
630         oc_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     oc_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     oc_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     oc_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             oc_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             oc_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         oc_mutex_unlock(g_edrDeviceListMutex);
724         return CA_STATUS_FAILED;
725     }
726
727     oc_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, device->remoteAddress, 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     oc_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, device->remoteAddress ,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     oc_mutex_unlock(g_edrDeviceListMutex);
839
840     if(g_isDiscoveryServer)
841     {
842         // Start the device Discovery.
843         result = CAEDRStartDeviceDiscovery();
844         if (CA_STATUS_OK == result)
845         {
846             OIC_LOG(INFO, EDR_ADAPTER_TAG, "Add the data to the multicast data list");
847
848             EDRData *multicastData = (EDRData *)OICCalloc(1, sizeof(EDRData));
849             if (NULL == multicastData)
850             {
851                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Malloc failed");
852                 goto exit;
853             }
854             multicastData->data = OICCalloc(1, dataLength);
855             if (NULL == multicastData->data)
856             {
857                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Malloc failed");
858                 goto exit;
859             }
860             memcpy(multicastData->data, data, dataLength);
861             multicastData->dataLength = dataLength;
862
863             // Add the data to pending multicast data list.
864             oc_mutex_lock(g_multicastDataListMutex);
865             if (NULL == g_multicastDataList)
866             {
867                 g_multicastDataList = u_arraylist_create();
868             }
869             u_arraylist_add(g_multicastDataList, (void *)multicastData);
870             oc_mutex_unlock(g_multicastDataListMutex);
871         }
872     }
873
874 exit:
875     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
876     return CA_STATUS_OK;
877 }
878
879 CAResult_t CAEDRClientConnect(const char *remoteAddress, const char *serviceUUID)
880 {
881     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
882
883     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
884     VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "Service UUID is null");
885
886     size_t addressLen = strlen(remoteAddress);
887     if (0 == addressLen || CA_MACADDR_SIZE - 1 != addressLen)
888     {
889         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Invalid remote address");
890         return  CA_STATUS_INVALID_PARAM;
891     }
892
893     if (!serviceUUID[0])
894     {
895         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: Empty service uuid");
896         return  CA_STATUS_INVALID_PARAM;
897     }
898
899     bt_error_e err = bt_socket_connect_rfcomm(remoteAddress, serviceUUID);
900     if (BT_ERROR_NONE != err)
901     {
902         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
903                   "Failed to connect!, address [%s] error num [%x]",
904                   remoteAddress, err);
905         return CA_STATUS_FAILED;
906     }
907
908     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
909     return CA_STATUS_OK;
910 }
911
912 CAResult_t CAEDRClientDisconnect(const int32_t clientID)
913 {
914     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
915
916     // Input validation
917     if (0 > clientID)
918     {
919         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Invalid input: negative client id");
920         return CA_STATUS_INVALID_PARAM;
921     }
922
923     bt_error_e err = bt_socket_disconnect_rfcomm(clientID);
924     if (BT_ERROR_NONE != err)
925     {
926         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed close rfcomm client socket!, error num [%x]",
927                   err);
928         return CA_STATUS_FAILED;
929     }
930
931     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
932     return CA_STATUS_OK;
933 }
934
935 void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData)
936 {
937     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
938
939     EDRDevice *device = NULL;
940
941     if (NULL == data || 0 >= data->data_size)
942     {
943         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Data is null!");
944         return;
945     }
946
947     // Get EDR device from list
948     oc_mutex_lock(g_edrDeviceListMutex);
949     CAResult_t result = CAGetEDRDeviceBySocketId(g_edrDeviceList, data->socket_fd, &device);
950     if (CA_STATUS_OK != result)
951     {
952         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Could not find the device!");
953
954         oc_mutex_unlock(g_edrDeviceListMutex);
955         return;
956     }
957     oc_mutex_unlock(g_edrDeviceListMutex);
958
959     //: TODO Need to check if 'check required for socket still connected or not'
960     if (!device)
961     {
962         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "There is no device!");
963         return;
964     }
965
966     CAConnectedDeviceInfo_t *deviceInfo =
967         (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(device->remoteAddress);
968
969     if (!deviceInfo)
970     {
971         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Received Data from new device");
972         deviceInfo = (CAConnectedDeviceInfo_t *) OICCalloc(1, sizeof(*deviceInfo));
973         if (!deviceInfo)
974         {
975             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Out of memory");
976             return;
977         }
978
979         deviceInfo->state = STATE_CONNECTED;
980         deviceInfo->recvData = NULL;
981         deviceInfo->recvDataLen = 0;
982         deviceInfo->totalDataLen = 0;
983         result = CAEDRAddDeviceInfoToList(device->remoteAddress, deviceInfo);
984         if (CA_STATUS_OK != result)
985         {
986             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Could not add device info to list!");
987             OICFree(deviceInfo);
988             return;
989         }
990     }
991
992     if (!deviceInfo->recvData)
993     {
994         OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Callocing deviceInfo->recvData");
995         deviceInfo->recvData = OICCalloc(data->data_size, sizeof(uint8_t));
996         if (!deviceInfo->recvData)
997         {
998             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "out of memory");
999             return;
1000         }
1001     }
1002
1003     memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*)data->data,
1004            data->data_size);
1005     deviceInfo->recvDataLen += data->data_size;
1006
1007     if (!deviceInfo->totalDataLen)
1008     {
1009         coap_transport_t transport = coap_get_tcp_header_type_from_initbyte(
1010                 ((unsigned char *)deviceInfo->recvData)[0] >> 4);
1011         size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
1012
1013         if (deviceInfo->recvDataLen >= headerLen)
1014         {
1015             // get actual data length from coap over tcp header
1016             deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
1017                                                                      deviceInfo->recvDataLen);
1018             OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "total data length [%d] bytes", deviceInfo->totalDataLen);
1019
1020             uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen);
1021             if (!newBuf)
1022             {
1023                 OIC_LOG(ERROR, EDR_ADAPTER_TAG, "out of memory");
1024                 //Memory free
1025                 return;
1026             }
1027             deviceInfo->recvData = newBuf;
1028         }
1029     }
1030
1031     if (deviceInfo->totalDataLen == deviceInfo->recvDataLen)
1032     {
1033         if (g_edrPacketReceivedCallback)
1034         {
1035             OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG,"data will be sent to callback routine: %s, %d",
1036                       deviceInfo->recvData, deviceInfo->recvDataLen);
1037
1038             uint32_t sentLength = 0;
1039             g_edrPacketReceivedCallback(device->remoteAddress, (void*) deviceInfo->recvData,
1040                                         deviceInfo->recvDataLen, &sentLength);
1041
1042             OICFree(deviceInfo->recvData);
1043             deviceInfo->recvData = NULL;
1044             deviceInfo->recvDataLen = 0;
1045             deviceInfo->totalDataLen = 0;
1046         }
1047     }
1048
1049     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
1050 }