Fixes for scan in VD
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / tizen / caleclient_vd.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 #include "caleclient.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <arpa/inet.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <netinet/in.h>
30 #include <pthread.h>
31 #include <gio/gio.h>
32
33 #include "octhread.h"
34 #include "uarraylist.h"
35 #include "caqueueingthread.h"
36 #include "caadapterutils.h"
37 #include "cagattservice.h"
38 #include "oic_string.h"
39 #include "oic_malloc.h"
40
41 /**
42  * Logging tag for module name.
43  */
44 #define TAG "OIC_CA_LE_CLIENT"
45
46 #define MICROSECS_PER_SEC 1000000
47 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
48
49 //For custom uuid ble server
50 #define CA_GATT_CUSTOM_UUID "4209"
51 #define CA_GATT_CUSTOM_UUID2 "4204"
52 #define CUSTOM_UUID_LEN 4
53
54 static const int samsung_code = 117;
55
56 uint64_t const TIMEOUT = 30 * MICROSECS_PER_SEC;
57
58 /**
59  * Flag to check if scanning is in progress
60  */
61 static bool g_isScanningInProgress = false;
62
63 /**
64  * Mutex to synchronize access to g_isScanningInProgress
65  */
66 static oc_mutex g_isScanningInProgressMutex = NULL;
67
68 /**
69  * Flag to check if connection is in progress
70  */
71 static bool g_isConnectionInProgress = false;
72
73 /**
74  * Mutex to synchronize access to g_isConnectionInProgress
75  */
76 static oc_mutex g_isConnectionInProgressMutex = NULL;
77
78 /**
79  * Flag to check if multicast is already in progress.
80  */
81 static bool g_isMulticastInProgress = false;
82
83 /**
84  * Flag to check if unicast scan is in progress
85  */
86 static bool g_isUnicastScanInProgress = false;
87
88 /**
89  * Mutex to synchronize access to g_isMulticastInProgress
90  * and g_isUnicastScanInProgress
91  */
92 static oc_mutex g_scanMutex = NULL;
93
94 /**
95  * Pending multicast data list to be sent.
96  */
97 static u_arraylist_t *g_multicastDataList = NULL;
98
99 /**
100  * Mutex to synchronize the access to Pending multicast data list.
101  */
102 static oc_mutex g_multicastDataListMutex = NULL;
103
104 /**
105  * Condition to start the timer for scanning.
106  */
107 static oc_cond g_startTimerCond = NULL;
108
109 /**
110  * Condition for scanning Time interval.
111  */
112 static oc_cond g_scanningTimeCond = NULL;
113
114 /**
115  * This contains the list of OIC services a client connect tot.
116  */
117 static LEServerInfoList *g_LEServerList = NULL;
118
119 /**
120  * Mutex to synchronize access to BleServiceList.
121  */
122 static oc_mutex g_LEServerListMutex = NULL;
123
124 /**
125  * Boolean variable to keep the state of the GATT Client.
126  */
127 static bool g_isLEGattClientStarted = false;
128
129 /**
130  * Mutex to synchronize access to the requestResponse callback to be called
131  * when the data needs to be sent from GATTClient.
132  */
133 static oc_mutex g_LEReqRespClientCbMutex = NULL;
134
135 /**
136  * Mutex to synchronize access to the requestResponse callback to be called
137  * when the data needs to be sent from GATTClient.
138  */
139 static oc_mutex g_LEClientConnectMutex = NULL;
140
141 /**
142  * Mutex to synchronize the calls to be done to the platform from GATTClient
143  * interfaces from different threads.
144  */
145 static oc_mutex g_LEClientStateMutex = NULL;
146
147 /**
148  * Mutex to synchronize the task to be pushed to thread pool.
149  */
150 static oc_mutex g_LEClientThreadPoolMutex = NULL;
151
152 /**
153  * Mutex to synchronize the task to write characteristic one packet after another.
154  */
155 static oc_mutex g_threadWriteCharacteristicMutex = NULL;
156
157 /**
158  * Condition for Writing characteristic.
159  */
160 static oc_cond g_threadWriteCharacteristicCond = NULL;
161
162 /**
163  * Flag to check status of write characteristic.
164  */
165 static bool g_isSignalSetFlag = false;
166
167 /**
168  * Maintains the callback to be notified on receival of network packets from other
169  *           BLE devices
170  */
171 static CABLEDataReceivedCallback g_LEClientDataReceivedCallback = NULL;
172
173 /**
174  * callback to update the error to le adapter
175  */
176 static CABLEErrorHandleCallback g_clientErrorCallback;
177
178 /**
179  * gmainLoop to manage the threads to receive the callback from the platfrom.
180  */
181 static GMainLoop *g_eventLoop = NULL;
182
183 /**
184  * Reference to threadpool
185  */
186 static ca_thread_pool_t g_LEClientThreadPool = NULL;
187
188 void CALEGattCharacteristicChangedCb(bt_gatt_h characteristic,
189                                      char *value,
190                                      int valueLen, void *userData)
191 {
192     (void)characteristic;
193
194     OIC_LOG(DEBUG, TAG, "IN");
195     OIC_LOG_V(DEBUG, TAG, "Changed characteristic value length [%d]", valueLen);
196
197     oc_mutex_lock(g_LEReqRespClientCbMutex);
198     if (NULL == g_LEClientDataReceivedCallback)
199     {
200         OIC_LOG(ERROR, TAG, "Request response callback is not set");
201         oc_mutex_unlock(g_LEReqRespClientCbMutex);
202         return;
203     }
204
205     uint32_t sentLength = 0;
206     g_LEClientDataReceivedCallback(userData, (uint8_t *)value, valueLen, &sentLength);
207
208     OIC_LOG_V(DEBUG, TAG, "Recv data Length is %d", sentLength);
209
210     oc_mutex_unlock(g_LEReqRespClientCbMutex);
211
212     OIC_LOG(DEBUG, TAG, "OUT");
213 }
214
215 void CALEGattCharacteristicWriteCb(int result, bt_gatt_h reqHandle, void *userData)
216 {
217     (void)reqHandle;
218     (void)userData;
219
220     OIC_LOG(DEBUG, TAG, "IN ");
221
222     if (BT_ERROR_NONE != result)
223     {
224         CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
225                            false, "writeChar failure");
226
227         OIC_LOG(ERROR, TAG, "Write failed Need Retry ");
228         //Need to Implement retry mechanism
229     }
230     else
231     {
232         oc_mutex_lock(g_threadWriteCharacteristicMutex);
233         OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
234         g_isSignalSetFlag = true;
235         oc_cond_signal(g_threadWriteCharacteristicCond);
236         oc_mutex_unlock(g_threadWriteCharacteristicMutex);
237
238         CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
239                            true, "writeChar success");
240     }
241
242     OIC_LOG(DEBUG, TAG, "OUT ");
243 }
244
245 CAResult_t CALEGattInitiateConnection(const char *remoteAddress)
246 {
247     OIC_LOG(DEBUG, TAG, "IN");
248
249     oc_mutex_lock(g_isConnectionInProgressMutex);
250     if (g_isConnectionInProgress)
251     {
252         oc_mutex_unlock(g_isConnectionInProgressMutex);
253         OIC_LOG(DEBUG, TAG, "Connection already in progress, cannot initiate new connection");
254         return CA_STATUS_FAILED;
255     }
256     g_isConnectionInProgress = true;
257     oc_mutex_unlock(g_isConnectionInProgressMutex);
258
259     // Pause the scanning
260     CALEGattStopDeviceScanning();
261
262     OIC_LOG_V(DEBUG, TAG,
263               "Trying to do Gatt connection to [%s]", remoteAddress);
264
265     oc_mutex_lock(g_LEClientThreadPoolMutex);
266     if (NULL == g_LEClientThreadPool)
267     {
268         oc_mutex_unlock(g_LEClientThreadPoolMutex);
269         OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
270         return CA_STATUS_FAILED;
271     }
272
273     char *addr = OICStrdup(remoteAddress);
274     if (NULL == addr)
275     {
276         oc_mutex_unlock(g_LEClientThreadPoolMutex);
277         OIC_LOG(ERROR, TAG, "OICStrdup failed");
278         return CA_STATUS_FAILED;
279     }
280
281     CAResult_t res = ca_thread_pool_add_task(g_LEClientThreadPool, CAGattConnectThread, addr, NULL);
282     oc_mutex_unlock(g_LEClientThreadPoolMutex);
283     if (CA_STATUS_OK != res)
284     {
285         OIC_LOG_V(ERROR, TAG,
286                   "ca_thread_pool_add_task failed with ret [%d]", res);
287         OICFree(addr);
288         return CA_STATUS_FAILED;
289     }
290     OIC_LOG(DEBUG, TAG, "OUT");
291     return CA_STATUS_OK;
292 }
293
294 void CALEGattConnectionStateChanged(bool connected, const char *remoteAddress)
295 {
296     OIC_LOG(DEBUG, TAG, "IN ");
297
298     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
299
300     if (!connected)
301     {
302         OIC_LOG_V(DEBUG, TAG, "DisConnected from [%s] ", remoteAddress);
303         oc_mutex_lock(g_LEServerListMutex);
304         CARemoveLEServerInfoFromList(&g_LEServerList, remoteAddress);
305         oc_mutex_unlock(g_LEServerListMutex);
306     }
307     else
308     {
309         OIC_LOG_V(DEBUG, TAG, "Connected to [%s] ", remoteAddress);
310
311         oc_mutex_lock(g_isConnectionInProgressMutex);
312         g_isConnectionInProgress = false;
313         oc_mutex_unlock(g_isConnectionInProgressMutex);
314
315
316         // TODO:Disabling scanning for now.Need to check.
317         /*oc_mutex_lock(g_scanMutex);
318         if (g_isMulticastInProgress || g_isUnicastScanInProgress)
319         {
320             CAResult_t ret = CALEGattStartDeviceScanning();
321             if (CA_STATUS_OK != ret)
322             {
323                 OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning Failed");
324             }
325         }
326         oc_mutex_unlock(g_scanMutex);
327 */
328         LEServerInfo *serverInfo = NULL;
329         oc_mutex_lock(g_LEServerListMutex);
330         if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
331         {
332             oc_mutex_unlock(g_LEServerListMutex);
333             OIC_LOG_V(ERROR, TAG, "Could not get server info for [%s]", remoteAddress);
334             return;
335         }
336
337         serverInfo->status = LE_STATUS_CONNECTED;
338         oc_mutex_unlock(g_LEServerListMutex);
339
340         oc_mutex_lock(g_LEClientThreadPoolMutex);
341         if (NULL == g_LEClientThreadPool)
342         {
343             oc_mutex_unlock(g_LEClientThreadPoolMutex);
344             OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
345             return;
346         }
347
348         char *addr = OICStrdup(remoteAddress);
349         if (NULL == addr)
350         {
351             oc_mutex_unlock(g_LEClientThreadPoolMutex);
352             OIC_LOG(ERROR, TAG, "addr is NULL");
353             return;
354         }
355
356         CAResult_t ret = ca_thread_pool_add_task(g_LEClientThreadPool, CADiscoverLEServicesThread,
357                                                  addr, NULL);
358         oc_mutex_unlock(g_LEClientThreadPoolMutex);
359         if (CA_STATUS_OK != ret)
360         {
361             OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
362             OICFree(addr);
363         }
364     }
365     OIC_LOG(DEBUG, TAG, "OUT");
366 }
367
368 static bool CALEIsHaveServiceImpl(bt_adapter_le_device_scan_result_info_s *scanInfo,
369                                   const char *service_uuid,
370                                   bt_adapter_le_packet_type_e pkt_type)
371 {
372     bool ret = false;
373     char **uuids = NULL;
374     int count = 0;
375     int result = 0;
376
377     result = bt_adapter_le_get_scan_result_service_uuids(scanInfo,
378              pkt_type, &uuids, &count);
379     if (result == BT_ERROR_NONE && NULL != uuids)
380     {
381         for (int i = 0; i < count; i++)
382         {
383             if (0 == strcasecmp(uuids[i], service_uuid))
384             {
385                 OIC_LOG_V(DEBUG, TAG, "Service[%s] Found in %s",
386                           uuids[i], scanInfo->remote_address);
387                 ret = true;
388             }else if(0 == strncasecmp(uuids[i], service_uuid,CUSTOM_UUID_LEN))
389             {
390                 OIC_LOG_V(DEBUG, TAG, "Custom Service[%s] Found in %s",
391                           uuids[i], scanInfo->remote_address);
392                 ret = true;
393             }
394             OICFree(uuids[i]);
395         }
396         OICFree(uuids);
397     }
398
399     if(ret == false){
400         char *man_data = NULL;
401         int man_data_len;
402         int man_id;
403         result = bt_adapter_le_get_scan_result_manufacturer_data(scanInfo,
404         pkt_type, &man_id, &man_data, &man_data_len);
405
406         if (result == BT_ERROR_NONE && NULL != man_data)
407         {
408             char *compare_man_data = OICMalloc((man_data_len*2)+1);
409             int pos =0;
410             for(int i=0;i<man_data_len;i++){
411                 pos += sprintf(compare_man_data+pos, "%.2x", man_data[i]);
412             }
413             compare_man_data[man_data_len]='\0';
414             if (man_id == samsung_code && 0 == strncasecmp(compare_man_data, service_uuid, CUSTOM_UUID_LEN))
415             {
416                 OIC_LOG_V(DEBUG, TAG, "Manufacture Data[%s] Found in %s",
417                                        compare_man_data, scanInfo->remote_address);
418                 ret = true;
419             }
420             OICFree(compare_man_data);
421             OICFree(man_data);
422         }
423     }
424     return ret;
425 }
426
427 static bool CALEIsHaveService(bt_adapter_le_device_scan_result_info_s *scanInfo,
428                               const char *service_uuid)
429 {
430     return
431         // For arduino servers, scan response will give the UUIDs advertised.
432         CALEIsHaveServiceImpl(scanInfo, service_uuid,
433                               BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) ||
434         // For android/tizen servers, advertising packet will give the UUIDs.
435         CALEIsHaveServiceImpl(scanInfo, service_uuid,
436                               BT_ADAPTER_LE_PACKET_ADVERTISING);
437 }
438
439 void CALEAdapterScanResultCb(int result, bt_adapter_le_device_scan_result_info_s *scanInfo,
440                              void *userData)
441 {
442     (void)userData;
443     OIC_LOG(DEBUG, TAG, "IN");
444
445     VERIFY_NON_NULL_VOID(scanInfo, TAG, "scanInfo");
446     VERIFY_NON_NULL_VOID(scanInfo->remote_address, TAG, "scanInfo->remote_address");
447
448     OIC_LOG_V(DEBUG, TAG, "Remote Address [%s]", scanInfo->remote_address);
449     OIC_LOG_V(DEBUG, TAG, "Scan Result [%d]", result);
450     OIC_LOG_V(DEBUG, TAG,
451               " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
452               scanInfo->adv_data_len, scanInfo->scan_data_len, scanInfo->rssi,
453               scanInfo->address_type);
454
455     // Check if scanning was stopped (since this callback is
456     // being triggered even after stopping the scan)
457     oc_mutex_lock(g_isScanningInProgressMutex);
458     if (!g_isScanningInProgress)
459     {
460         oc_mutex_unlock(g_isScanningInProgressMutex);
461         OIC_LOG(DEBUG, TAG, "Scanning not in progress, so ignoring callback");
462         return;
463     }
464     oc_mutex_unlock(g_isScanningInProgressMutex);
465
466     if (CALEIsHaveService(scanInfo, CA_GATT_SERVICE_UUID) ||
467         CALEIsHaveService(scanInfo, CA_GATT_CUSTOM_UUID)||
468         CALEIsHaveService(scanInfo, CA_GATT_CUSTOM_UUID2))
469     {
470         OIC_LOG_V(DEBUG, TAG, "Device [%s] supports OIC or custom service", scanInfo->remote_address);
471
472         LEServerInfo *serverInfo = NULL;
473         oc_mutex_lock(g_LEServerListMutex);
474         CAResult_t ret = CAGetLEServerInfo(g_LEServerList, scanInfo->remote_address, &serverInfo);
475         if (CA_STATUS_OK != ret)
476         {
477             OIC_LOG_V(DEBUG, TAG,
478                       "Newly discovered device with address [%s] ", scanInfo->remote_address);
479
480             char *addr = OICStrdup(scanInfo->remote_address);
481             if (NULL == addr)
482             {
483                 oc_mutex_unlock(g_LEServerListMutex);
484                 OIC_LOG(ERROR, TAG, "Device address is NULL");
485                 return;
486             }
487             serverInfo = (LEServerInfo *)OICCalloc(1, sizeof(LEServerInfo));
488             if (NULL == serverInfo)
489             {
490                 oc_mutex_unlock(g_LEServerListMutex);
491                 OIC_LOG(ERROR, TAG, "Calloc failed");
492                 OICFree(addr);
493                 return;
494             }
495             serverInfo->remoteAddress = addr;
496             serverInfo->status = LE_STATUS_DISCOVERED;
497
498             if (CA_STATUS_OK != CAAddLEServerInfoToList(&g_LEServerList, serverInfo))
499             {
500                 oc_mutex_unlock(g_LEServerListMutex);
501                 OIC_LOG_V(ERROR, TAG, "Could not add [%s] to server list", scanInfo->remote_address);
502                 CAFreeLEServerInfo(serverInfo);
503                 return;
504             }
505         }else {
506             OIC_LOG_V(DEBUG, TAG,
507                       "Device Present with address [%s] ", scanInfo->remote_address);
508
509             if(serverInfo->status == LE_STATUS_UNICAST_PENDING){
510                 bt_gatt_client_h clientHandle = NULL;
511                 int32_t ret = bt_gatt_client_create(serverInfo->remoteAddress, &clientHandle);
512                 if (BT_ERROR_NONE != ret || NULL == clientHandle)
513                 {
514                     OIC_LOG_V(ERROR, TAG,
515                               "bt_gatt_client_create Failed with ret value [%s] ", CALEGetErrorMsg(ret));
516                     CALEGattDisConnect(serverInfo->remoteAddress);
517                     oc_mutex_unlock(g_LEServerListMutex);
518                     return ;
519                 }
520                 serverInfo->clientHandle = clientHandle;
521
522                 serverInfo->status = LE_STATUS_CONNECTION_INITIATED;
523                 if (CA_STATUS_OK != CALEGattInitiateConnection(serverInfo->remoteAddress))
524                 {
525                     OIC_LOG_V(ERROR, TAG, "Could not initiate connection to [%s]", serverInfo->remoteAddress);
526                     serverInfo->status = LE_STATUS_DISCOVERED;
527                     CADestroyLEDataList(&serverInfo->pendingDataList);
528                     oc_mutex_unlock(g_LEServerListMutex);
529                     return ;
530                  }
531              }
532          }
533     }
534     oc_mutex_unlock(g_LEServerListMutex);
535     OIC_LOG(DEBUG, TAG, "OUT");
536 }
537
538 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
539 {
540     OIC_LOG(DEBUG, TAG, "IN");
541
542     oc_mutex_lock(g_LEClientThreadPoolMutex);
543     g_LEClientThreadPool = handle;
544     oc_mutex_unlock(g_LEClientThreadPoolMutex);
545
546     OIC_LOG(DEBUG, TAG, "OUT");
547 }
548
549 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
550 {
551     OIC_LOG(DEBUG, TAG, "IN");
552
553     oc_mutex_lock(g_LEReqRespClientCbMutex);
554
555     g_LEClientDataReceivedCallback = callback;
556
557     oc_mutex_unlock(g_LEReqRespClientCbMutex);
558
559     OIC_LOG(DEBUG, TAG, "OUT");
560 }
561
562 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
563 {
564     g_clientErrorCallback = callback;
565 }
566
567 CAResult_t CAStartLEGattClient()
568 {
569     OIC_LOG(DEBUG, TAG, "IN");
570
571     oc_mutex_lock(g_LEClientStateMutex);
572     if (true  == g_isLEGattClientStarted)
573     {
574         OIC_LOG(ERROR, TAG, "Gatt Client is already running!!");
575         oc_mutex_unlock(g_LEClientStateMutex);
576         return CA_STATUS_FAILED;
577     }
578
579     CAResult_t  result = CALEGattSetCallbacks();
580     if (CA_STATUS_OK != result)
581     {
582         OIC_LOG(ERROR, TAG, "CABleGattSetCallbacks Failed");
583         oc_mutex_unlock(g_LEClientStateMutex);
584         CATerminateLEGattClient();
585         return CA_STATUS_FAILED;
586     }
587
588     g_isLEGattClientStarted = true;
589     oc_mutex_unlock(g_LEClientStateMutex);
590
591     oc_mutex_lock(g_LEClientThreadPoolMutex);
592     if (NULL == g_LEClientThreadPool)
593     {
594         OIC_LOG(ERROR, TAG, "gBleServerThreadPool is NULL");
595         CATerminateGattClientMutexVariables();
596         oc_mutex_unlock(g_LEClientThreadPoolMutex);
597         return CA_STATUS_FAILED;
598     }
599
600     result = ca_thread_pool_add_task(g_LEClientThreadPool, CAStartTimerThread,
601                                      NULL, NULL);
602     if (CA_STATUS_OK != result)
603     {
604         OIC_LOG(ERROR, TAG, "ca_thread_pool_add_task failed");
605         CATerminateGattClientMutexVariables();
606         oc_mutex_unlock(g_LEClientThreadPoolMutex);
607         return CA_STATUS_FAILED;
608     }
609
610     result= ca_thread_pool_add_task(g_LEClientThreadPool, CALEClientScanThread,
611                                     NULL, NULL);
612     if (CA_STATUS_OK != result)
613     {
614         OIC_LOG(ERROR, TAG, "ca_thread_pool_add_task failed");
615         CATerminateGattClientMutexVariables();
616         oc_mutex_unlock(g_LEClientThreadPoolMutex);
617         return CA_STATUS_FAILED;
618     }
619     oc_mutex_unlock(g_LEClientThreadPoolMutex);
620
621     OIC_LOG(DEBUG, TAG, "OUT");
622     return CA_STATUS_OK;
623 }
624
625 void CALEClientScanThread()
626 {
627     oc_mutex_lock(g_scanMutex);
628     if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
629     {
630         CAResult_t result = CALEGattStartDeviceScanning();
631         if (CA_STATUS_OK != result)
632         {
633             oc_mutex_unlock(g_scanMutex);
634             OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning failed");
635             return ;
636         }
637         g_isUnicastScanInProgress = true;
638         // Start Timer
639         oc_cond_signal(g_startTimerCond);
640     }
641     else
642     {
643         g_isUnicastScanInProgress = true;
644         // Reset Timer
645         oc_cond_signal(g_scanningTimeCond);
646     }
647     oc_mutex_unlock(g_scanMutex);
648
649     OIC_LOG(DEBUG, TAG, "OUT");
650     return ;
651 }
652
653 void CAStartTimerThread(void *data)
654 {
655     (void)data;
656
657     OIC_LOG(DEBUG, TAG, "IN");
658     while (g_isLEGattClientStarted)
659     {
660         oc_mutex_lock(g_scanMutex);
661         if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
662         {
663             OIC_LOG(DEBUG, TAG, "waiting....");
664             oc_cond_wait(g_startTimerCond, g_scanMutex);
665             OIC_LOG(DEBUG, TAG, "Wake up");
666         }
667
668         // Timed conditional wait for stopping the scan.
669         OCWaitResult_t ret = oc_cond_wait_for(g_scanningTimeCond, g_scanMutex,
670                                               TIMEOUT);
671         if (OC_WAIT_TIMEDOUT == ret)
672         {
673             OIC_LOG(DEBUG, TAG, "Scan is timed Out");
674             // Call stop scan.
675             CALEGattStopDeviceScanning();
676
677             if (g_isMulticastInProgress)
678             {
679                 oc_mutex_lock(g_multicastDataListMutex);
680                 // Clear the data list and device list.
681                 u_arraylist_destroy(g_multicastDataList);
682                 g_multicastDataList = NULL;
683                 oc_mutex_unlock(g_multicastDataListMutex);
684                 g_isMulticastInProgress = false;
685             }
686             g_isUnicastScanInProgress = false;
687         }
688         oc_mutex_unlock(g_scanMutex);
689     }
690
691     OIC_LOG(DEBUG, TAG, "OUT");
692 }
693
694 void CAStopLEGattClient()
695 {
696     OIC_LOG(DEBUG,  TAG, "IN");
697
698     oc_mutex_lock(g_LEClientStateMutex);
699
700     if (false == g_isLEGattClientStarted)
701     {
702         OIC_LOG(ERROR, TAG, "Gatt Client is not running to stop");
703         oc_mutex_unlock(g_LEClientStateMutex);
704         return;
705     }
706
707     CALEGattUnSetCallbacks();
708
709     CALEGattStopDeviceScanning();
710
711     g_isLEGattClientStarted = false;
712
713     // Signal the conditions waiting in Start timer.
714     oc_cond_signal(g_startTimerCond);
715     oc_cond_signal(g_scanningTimeCond);
716
717     // Destroy the multicast data list and device list if not empty.
718     if (NULL != g_multicastDataList)
719     {
720         oc_mutex_lock(g_multicastDataListMutex);
721         u_arraylist_destroy(g_multicastDataList);
722         g_multicastDataList = NULL;
723         oc_mutex_unlock(g_multicastDataListMutex);
724     }
725
726     oc_mutex_lock(g_LEServerListMutex);
727     CAFreeLEServerList(g_LEServerList);
728     g_LEServerList = NULL;
729     oc_mutex_unlock(g_LEServerListMutex);
730
731     oc_mutex_lock(g_threadWriteCharacteristicMutex);
732     oc_cond_signal(g_threadWriteCharacteristicCond);
733     oc_mutex_unlock(g_threadWriteCharacteristicMutex);
734
735     GMainContext  *context_event_loop = NULL;
736     // Required for waking up the thread which is running in gmain loop
737     if (NULL != g_eventLoop)
738     {
739         context_event_loop = g_main_loop_get_context(g_eventLoop);
740     }
741     if (context_event_loop)
742     {
743         OIC_LOG_V(DEBUG,  TAG, "g_eventLoop context %p", (void *)context_event_loop);
744         g_main_context_wakeup(context_event_loop);
745
746         // Kill g main loops and kill threads.
747         g_main_loop_quit(g_eventLoop);
748     }
749     else
750     {
751         OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
752     }
753
754     oc_mutex_unlock(g_LEClientStateMutex);
755
756     OIC_LOG(DEBUG,  TAG, "OUT");
757 }
758
759 CAResult_t CAInitializeLEGattClient()
760 {
761     OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
762     CAResult_t res = CAInitGattClientMutexVariables();
763     if (CA_STATUS_OK != res)
764     {
765         OIC_LOG(ERROR, TAG, "CAInitGattClientMutexVariables failed!");
766         CATerminateGattClientMutexVariables();
767         return CA_STATUS_FAILED;
768     }
769     return res;
770 }
771
772 void CATerminateLEGattClient()
773 {
774     OIC_LOG(DEBUG,  TAG, "IN");
775
776     CATerminateGattClientMutexVariables();
777
778     OIC_LOG(DEBUG,  TAG, "OUT");
779 }
780
781 CAResult_t CAInitGattClientMutexVariables()
782 {
783     OIC_LOG(DEBUG,  TAG, "IN");
784     if (NULL == g_LEClientStateMutex)
785     {
786         g_LEClientStateMutex = oc_mutex_new();
787         if (NULL == g_LEClientStateMutex)
788         {
789             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
790             return CA_STATUS_FAILED;
791         }
792     }
793
794     if (NULL == g_LEServerListMutex)
795     {
796         g_LEServerListMutex = oc_mutex_new();
797         if (NULL == g_LEServerListMutex)
798         {
799             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
800             return CA_STATUS_FAILED;
801         }
802     }
803
804     if (NULL == g_LEReqRespClientCbMutex)
805     {
806         g_LEReqRespClientCbMutex = oc_mutex_new();
807         if (NULL == g_LEReqRespClientCbMutex)
808         {
809             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
810             return CA_STATUS_FAILED;
811         }
812     }
813
814     if (NULL == g_LEClientThreadPoolMutex)
815     {
816         g_LEClientThreadPoolMutex = oc_mutex_new();
817         if (NULL == g_LEClientThreadPoolMutex)
818         {
819             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
820             return CA_STATUS_FAILED;
821         }
822     }
823
824     if (NULL == g_LEClientConnectMutex)
825     {
826         g_LEClientConnectMutex = oc_mutex_new();
827         if (NULL == g_LEClientConnectMutex)
828         {
829             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
830             return CA_STATUS_FAILED;
831         }
832     }
833
834     if (NULL == g_isScanningInProgressMutex)
835     {
836         g_isScanningInProgressMutex = oc_mutex_new();
837         if (NULL == g_isScanningInProgressMutex)
838         {
839             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
840             return CA_STATUS_FAILED;
841         }
842     }
843
844     if (NULL == g_isConnectionInProgressMutex)
845     {
846         g_isConnectionInProgressMutex = oc_mutex_new();
847         if (NULL == g_isConnectionInProgressMutex)
848         {
849             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
850             return CA_STATUS_FAILED;
851         }
852     }
853
854     if (NULL == g_multicastDataListMutex)
855     {
856         g_multicastDataListMutex = oc_mutex_new();
857         if (NULL == g_multicastDataListMutex)
858         {
859             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
860             return CA_STATUS_FAILED;
861         }
862     }
863
864     if (NULL == g_scanMutex)
865     {
866         g_scanMutex = oc_mutex_new();
867         if (NULL == g_scanMutex)
868         {
869             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
870             return CA_STATUS_FAILED;
871         }
872     }
873
874     if (NULL == g_threadWriteCharacteristicMutex)
875     {
876         g_threadWriteCharacteristicMutex = oc_mutex_new();
877         if (NULL == g_threadWriteCharacteristicMutex)
878         {
879             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
880             return CA_STATUS_FAILED;
881         }
882     }
883
884     if (NULL == g_startTimerCond)
885     {
886         g_startTimerCond = oc_cond_new();
887         if (NULL == g_startTimerCond)
888         {
889             OIC_LOG(ERROR, TAG, "oc_cond_new failed");
890             return CA_STATUS_FAILED;
891         }
892     }
893
894     if (NULL == g_scanningTimeCond)
895     {
896         g_scanningTimeCond = oc_cond_new();
897         if (NULL == g_scanningTimeCond)
898         {
899             OIC_LOG(ERROR, TAG, "oc_cond_new failed");
900             return CA_STATUS_FAILED;
901         }
902     }
903
904     if (NULL == g_threadWriteCharacteristicCond)
905     {
906         g_threadWriteCharacteristicCond = oc_cond_new();
907         if (NULL == g_threadWriteCharacteristicCond)
908         {
909             OIC_LOG(ERROR, TAG, "oc_cond_new failed");
910             return CA_STATUS_FAILED;
911         }
912     }
913
914     OIC_LOG(DEBUG,  TAG, "OUT");
915     return CA_STATUS_OK;
916 }
917
918 void CATerminateGattClientMutexVariables()
919 {
920     OIC_LOG(DEBUG,  TAG, "IN");
921
922     oc_mutex_free(g_LEClientStateMutex);
923     g_LEClientStateMutex = NULL;
924
925     oc_mutex_free(g_LEServerListMutex);
926     g_LEServerListMutex = NULL;
927
928     oc_mutex_free(g_LEReqRespClientCbMutex);
929     g_LEReqRespClientCbMutex = NULL;
930
931     oc_mutex_free(g_LEClientConnectMutex);
932     g_LEClientConnectMutex = NULL;
933
934     oc_mutex_free(g_LEClientThreadPoolMutex);
935     g_LEClientThreadPoolMutex = NULL;
936
937     oc_mutex_free(g_isScanningInProgressMutex);
938     g_isScanningInProgressMutex = NULL;
939
940     oc_mutex_free(g_isConnectionInProgressMutex);
941     g_isConnectionInProgressMutex = NULL;
942
943     oc_mutex_free(g_multicastDataListMutex);
944     g_multicastDataListMutex = NULL;
945
946     oc_mutex_free(g_scanMutex);
947     g_scanMutex = NULL;
948
949     oc_mutex_free(g_threadWriteCharacteristicMutex);
950     g_threadWriteCharacteristicMutex = NULL;
951
952     oc_cond_free(g_startTimerCond);
953     g_startTimerCond = NULL;
954
955     oc_cond_free(g_scanningTimeCond);
956     g_scanningTimeCond = NULL;
957
958     oc_cond_free(g_threadWriteCharacteristicCond);
959     g_threadWriteCharacteristicCond = NULL;
960     g_isSignalSetFlag = false;
961
962     OIC_LOG(DEBUG,  TAG, "OUT");
963 }
964
965 CAResult_t CALEGattSetCallbacks()
966 {
967     OIC_LOG(DEBUG, TAG, "IN");
968
969     OIC_LOG(DEBUG, TAG, "OUT");
970     return CA_STATUS_OK;
971 }
972
973 void CALEGattUnSetCallbacks()
974 {
975     OIC_LOG(DEBUG, TAG, "IN");
976
977     bt_gatt_unset_connection_state_changed_cb();
978
979     oc_mutex_lock(g_LEServerListMutex);
980     LEServerInfoList *curNode = g_LEServerList;
981     while (curNode)
982     {
983         LEServerInfo *serverInfo = curNode->serverInfo;
984         if (serverInfo->status >= LE_STATUS_SERVICES_DISCOVERED)
985         {
986             bt_gatt_client_unset_characteristic_value_changed_cb(serverInfo->readChar);
987         }
988         curNode = curNode->next;
989     }
990     oc_mutex_unlock(g_LEServerListMutex);
991
992     OIC_LOG(DEBUG, TAG, "OUT");
993 }
994
995 CAResult_t CALEGattStartDeviceScanning()
996 {
997     OIC_LOG(DEBUG, TAG, "IN");
998
999     oc_mutex_lock(g_isScanningInProgressMutex);
1000     if (!g_isScanningInProgress)
1001     {
1002         int ret = bt_adapter_le_start_scan(CALEAdapterScanResultCb, NULL);
1003         if (BT_ERROR_NONE != ret)
1004         {
1005             oc_mutex_unlock(g_isScanningInProgressMutex);
1006             OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_scan failed[%s]",
1007                       CALEGetErrorMsg(ret));
1008             return CA_STATUS_FAILED;
1009         }
1010         g_isScanningInProgress = true;
1011     }
1012     else
1013     {
1014         OIC_LOG(DEBUG, TAG, "Ignore, scanning already in progress");
1015     }
1016     oc_mutex_unlock(g_isScanningInProgressMutex);
1017
1018     OIC_LOG(DEBUG, TAG, "OUT");
1019     return CA_STATUS_OK;
1020 }
1021
1022 void CALEGattStopDeviceScanning()
1023 {
1024     OIC_LOG(DEBUG, TAG, "IN");
1025
1026     oc_mutex_lock(g_isScanningInProgressMutex);
1027     if (g_isScanningInProgress)
1028     {
1029         int ret = bt_adapter_le_stop_scan();
1030         if (BT_ERROR_NONE != ret)
1031         {
1032             oc_mutex_unlock(g_isScanningInProgressMutex);
1033             OIC_LOG_V(ERROR, TAG, "bt_adapter_le_stop_scan failed[%s]",
1034                       CALEGetErrorMsg(ret));
1035             return;
1036         }
1037         g_isScanningInProgress = false;
1038     }
1039     else
1040     {
1041         OIC_LOG(DEBUG, TAG, "Ignore, scanning not in progress");
1042     }
1043     oc_mutex_unlock(g_isScanningInProgressMutex);
1044
1045     OIC_LOG(DEBUG, TAG, "OUT");
1046 }
1047
1048 void CAGattConnectThread (void *remoteAddress)
1049 {
1050     OIC_LOG(DEBUG, TAG, "IN ");
1051
1052     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
1053
1054     char *address  = (char *)remoteAddress;
1055
1056     OIC_LOG_V(DEBUG, TAG, "remote address is [%s]", address);
1057
1058     CAResult_t result = CALEGattConnect(address);
1059
1060     if (CA_STATUS_OK != result)
1061     {
1062         OIC_LOG_V(ERROR, TAG, "bt_gatt_connect failed for [%s]", address);
1063     }
1064
1065     OICFree(address);
1066
1067     OIC_LOG(DEBUG, TAG, "OUT");
1068 }
1069
1070 CAResult_t CALEGattConnect(const char *remoteAddress)
1071 {
1072     OIC_LOG(DEBUG, TAG, "IN");
1073
1074     VERIFY_NON_NULL_RET(remoteAddress, TAG,
1075                         "remote address is NULL", CA_STATUS_FAILED);
1076
1077     oc_mutex_lock(g_LEClientConnectMutex);
1078     CAResult_t result = CA_STATUS_OK;
1079
1080     int ret = bt_gatt_connect(remoteAddress, false);
1081     if (BT_ERROR_NONE != ret)
1082     {
1083         OIC_LOG_V(ERROR, TAG, "bt_gatt_connect Failed with ret value [%s] ",
1084                   CALEGetErrorMsg(ret));
1085         oc_mutex_unlock(g_LEClientConnectMutex);
1086         return CA_STATUS_FAILED;
1087     }
1088
1089     oc_mutex_unlock(g_LEClientConnectMutex);
1090
1091     OIC_LOG(DEBUG, TAG, "OUT");
1092     return result;
1093 }
1094
1095 CAResult_t CALEGattDisConnect(const char *remoteAddress)
1096 {
1097     OIC_LOG(DEBUG, TAG, "IN");
1098
1099     VERIFY_NON_NULL_RET(remoteAddress, TAG,
1100                         "remote address is NULL", CA_STATUS_FAILED);
1101
1102     int ret = bt_gatt_disconnect(remoteAddress);
1103
1104     if (BT_ERROR_NONE != ret)
1105     {
1106         OIC_LOG_V(ERROR, TAG, "bt_gatt_disconnect Failed with ret value [%s] ",
1107                   CALEGetErrorMsg(ret));
1108         return CA_STATUS_FAILED;
1109     }
1110
1111     OIC_LOG(DEBUG, TAG, "OUT");
1112     return CA_STATUS_OK;
1113 }
1114
1115 CAResult_t CAUpdateCharacteristicsToGattServerImpl(LEServerInfo *serverInfo,
1116         const uint8_t *data, const uint32_t dataLen)
1117 {
1118     OIC_LOG(DEBUG, TAG, "IN");
1119
1120     VERIFY_NON_NULL(serverInfo, TAG, "Server Info is NULL");
1121
1122     CALEGattStopDeviceScanning();
1123
1124     OIC_LOG_V(DEBUG, TAG, "Updating the data of length [%d] to [%s] ", dataLen,
1125               serverInfo->remoteAddress);
1126
1127     int result = bt_gatt_set_value(serverInfo->writeChar, (char *)data, dataLen);
1128
1129     if (BT_ERROR_NONE != result)
1130     {
1131         OIC_LOG_V(ERROR, TAG,
1132                   "bt_gatt_set_value Failed with return val [%s]",
1133                   CALEGetErrorMsg(result));
1134         goto exit;
1135     }
1136
1137     result = bt_gatt_client_write_value(serverInfo->writeChar, CALEGattCharacteristicWriteCb,
1138                                         NULL);
1139     if (BT_ERROR_NONE != result)
1140     {
1141         OIC_LOG_V(ERROR, TAG,
1142                   "bt_gatt_client_write_value Failed with return val [%s]",
1143                   CALEGetErrorMsg(result));
1144         goto exit;
1145     }
1146
1147     // wait for callback for write Characteristic with success to sent data
1148     OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
1149     oc_mutex_lock(g_threadWriteCharacteristicMutex);
1150     if (!g_isSignalSetFlag)
1151     {
1152         OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
1153         if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
1154                                                 g_threadWriteCharacteristicMutex,
1155                                                 WAIT_TIME_WRITE_CHARACTERISTIC))
1156         {
1157             g_isSignalSetFlag = false;
1158             oc_mutex_unlock(g_threadWriteCharacteristicMutex);
1159             OIC_LOG(ERROR, TAG, "there is no response. write has failed");
1160             goto exit;
1161         }
1162     }
1163     // reset flag set by writeCharacteristic Callback
1164     g_isSignalSetFlag = false;
1165     oc_mutex_unlock(g_threadWriteCharacteristicMutex);
1166
1167     oc_mutex_lock(g_scanMutex);
1168     if (g_isMulticastInProgress || g_isUnicastScanInProgress)
1169     {
1170         if (CA_STATUS_OK != CALEGattStartDeviceScanning())
1171         {
1172             OIC_LOG(ERROR, TAG, "Could not start device scanning");
1173         }
1174     }
1175     oc_mutex_unlock(g_scanMutex);
1176     OIC_LOG(DEBUG, TAG, "OUT");
1177     return CA_STATUS_OK;
1178
1179 exit:
1180     oc_mutex_lock(g_scanMutex);
1181     if (g_isMulticastInProgress || g_isUnicastScanInProgress)
1182     {
1183         if (CA_STATUS_OK != CALEGattStartDeviceScanning())
1184         {
1185             OIC_LOG(ERROR, TAG, "Could not start device scanning");
1186         }
1187     }
1188     oc_mutex_unlock(g_scanMutex);
1189
1190     OIC_LOG(DEBUG, TAG, "OUT");
1191     return CA_STATUS_FAILED;
1192 }
1193
1194 void CADiscoverLEServicesThread(void *remoteAddress)
1195 {
1196     OIC_LOG(DEBUG, TAG, "IN");
1197
1198     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
1199
1200     char *address  = (char *)remoteAddress;
1201
1202     CAResult_t result = CALEGattDiscoverServices(address);
1203     if (CA_STATUS_OK != result)
1204     {
1205         OIC_LOG(ERROR, TAG, "CALEGattDiscoverServices failed");
1206     }
1207
1208     OICFree(address);
1209     OIC_LOG(DEBUG, TAG, "OUT");
1210 }
1211
1212 CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
1213 {
1214     OIC_LOG(DEBUG, TAG, "IN");
1215
1216     VERIFY_NON_NULL_RET(remoteAddress, TAG,
1217                         "remote address is NULL", CA_STATUS_FAILED);
1218
1219     LEServerInfo *serverInfo = NULL;
1220     oc_mutex_lock(g_LEServerListMutex);
1221     if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
1222     {
1223         oc_mutex_unlock(g_LEServerListMutex);
1224         OIC_LOG_V(ERROR, TAG, "Could not get server info for [%s]", remoteAddress);
1225         CALEGattDisConnect(remoteAddress);
1226         return CA_STATUS_FAILED;
1227     }
1228
1229     bt_gatt_h serviceHandle = NULL;
1230     int32_t ret = bt_gatt_client_get_service(serverInfo->clientHandle, CA_GATT_SERVICE_UUID, &serviceHandle);
1231     if (BT_ERROR_NONE != ret || NULL == serviceHandle)
1232     {
1233         OIC_LOG_V(ERROR, TAG,
1234                   "bt_gatt_client_get_service Failed with ret value [%s] ", CALEGetErrorMsg(ret));
1235         bt_gatt_client_destroy(serverInfo->clientHandle);
1236         CALEGattDisConnect(remoteAddress);
1237         return CA_STATUS_FAILED;
1238     }
1239
1240     // Server will read data on this characteristic.
1241     bt_gatt_h writeChrHandle = NULL;
1242     ret = bt_gatt_service_get_characteristic(serviceHandle, CA_GATT_REQUEST_CHRC_UUID,
1243             &writeChrHandle);
1244     if (BT_ERROR_NONE != ret || NULL == writeChrHandle)
1245     {
1246         OIC_LOG_V(ERROR, TAG,
1247                   "bt_gatt_service_get_characteristic Failed with ret value [%s] ",
1248                   CALEGetErrorMsg(ret));
1249         bt_gatt_client_destroy(serverInfo->clientHandle);
1250         CALEGattDisConnect(remoteAddress);
1251         return CA_STATUS_FAILED;
1252     }
1253
1254     // Server will notify data on this characteristic.
1255     bt_gatt_h readChrHandle = NULL;
1256     ret = bt_gatt_service_get_characteristic(serviceHandle, CA_GATT_RESPONSE_CHRC_UUID,
1257             &readChrHandle);
1258     if (BT_ERROR_NONE != ret || NULL == readChrHandle)
1259     {
1260         OIC_LOG_V(ERROR, TAG,
1261                   "bt_gatt_service_get_characteristic Failed with ret value [%s] ",
1262                   CALEGetErrorMsg(ret));
1263         bt_gatt_client_destroy(serverInfo->clientHandle);
1264         CALEGattDisConnect(remoteAddress);
1265         return CA_STATUS_FAILED;
1266     }
1267
1268     //TODO: This data has to be freed while unsetting the callback.
1269     char *addr = OICStrdup(remoteAddress);
1270     if (NULL == addr)
1271     {
1272         OIC_LOG(ERROR, TAG, "addr is NULL");
1273         bt_gatt_client_destroy(serverInfo->clientHandle);
1274         CALEGattDisConnect(remoteAddress);
1275         return CA_STATUS_FAILED;
1276     }
1277
1278     ret = bt_gatt_client_set_characteristic_value_changed_cb(readChrHandle,
1279             CALEGattCharacteristicChangedCb,
1280             (void *)addr);
1281     if (BT_ERROR_NONE != ret)
1282     {
1283         OIC_LOG_V(ERROR, TAG,
1284                   "bt_gatt_client_set_characteristic_value_changed_cb Failed with ret value [%s]",
1285                   CALEGetErrorMsg(ret));
1286         bt_gatt_client_destroy(serverInfo->clientHandle);
1287         CALEGattDisConnect(remoteAddress);
1288         return CA_STATUS_FAILED;
1289     }
1290
1291     serverInfo->serviceHandle = serviceHandle;
1292     serverInfo->readChar = readChrHandle;
1293     serverInfo->writeChar = writeChrHandle;
1294     serverInfo->status = LE_STATUS_SERVICES_DISCOVERED;
1295
1296     while (serverInfo->pendingDataList)
1297     {
1298         LEData *leData = serverInfo->pendingDataList->data;
1299         if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(
1300                 serverInfo, leData->data, leData->dataLength))
1301         {
1302             OIC_LOG_V(ERROR, TAG, "Failed to send pending data to [%s]",
1303                       serverInfo->remoteAddress);
1304
1305             CADestroyLEDataList(&serverInfo->pendingDataList);
1306             break;
1307         }
1308         CARemoveLEDataFromList(&serverInfo->pendingDataList);
1309     }
1310     oc_mutex_unlock(g_LEServerListMutex);
1311
1312     OIC_LOG(DEBUG, TAG, "OUT");
1313     return CA_STATUS_OK;
1314 }
1315
1316 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
1317         const uint8_t *data, const uint32_t dataLen,
1318         CALETransferType_t type, const int32_t position)
1319 {
1320     OIC_LOG(DEBUG, TAG, "IN");
1321
1322     VERIFY_NON_NULL(data, TAG, "data is NULL");
1323
1324     if (0 >= dataLen)
1325     {
1326         OIC_LOG(ERROR, TAG, "dataLen is less than or equal zero. Invalid input!");
1327         return CA_STATUS_INVALID_PARAM;
1328     }
1329
1330     LEServerInfo *serverInfo = NULL;
1331     oc_mutex_lock(g_LEServerListMutex);
1332     if (LE_UNICAST == type)
1333     {
1334         if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
1335         {
1336             OIC_LOG_V(DEBUG, TAG,
1337                       "Device with address [%s] not yet found, initiating scan",
1338                       remoteAddress);
1339
1340             char *addr = OICStrdup(remoteAddress);
1341             if (NULL == addr)
1342             {
1343                 oc_mutex_unlock(g_LEServerListMutex);
1344                 OIC_LOG(ERROR, TAG, "Device address is NULL");
1345                 return CA_STATUS_FAILED;
1346             }
1347             serverInfo = (LEServerInfo *)OICCalloc(1, sizeof(LEServerInfo));
1348             if (NULL == serverInfo)
1349             {
1350                 oc_mutex_unlock(g_LEServerListMutex);
1351                 OIC_LOG(ERROR, TAG, "Calloc failed");
1352                 OICFree(addr);
1353                 return CA_STATUS_FAILED;
1354             }
1355             serverInfo->remoteAddress = addr;
1356             serverInfo->status = LE_STATUS_UNICAST_PENDING;
1357
1358             if (CA_STATUS_OK != CAAddLEServerInfoToList(&g_LEServerList, serverInfo))
1359             {
1360                 oc_mutex_unlock(g_LEServerListMutex);
1361                 OIC_LOG_V(ERROR, TAG, "Could not add [%s] to server list", remoteAddress);
1362                 CAFreeLEServerInfo(serverInfo);
1363                 return CA_STATUS_FAILED;
1364             }
1365
1366             if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1367             {
1368                 oc_mutex_unlock(g_LEServerListMutex);
1369                 OIC_LOG(ERROR, TAG, "Could not add data to pending list");
1370                 return CA_STATUS_FAILED;
1371             }
1372
1373             oc_mutex_lock(g_scanMutex);
1374             if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
1375             {
1376                 CAResult_t result = CALEGattStartDeviceScanning();
1377                 if (CA_STATUS_OK != result)
1378                 {
1379                     oc_mutex_unlock(g_scanMutex);
1380                     OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning failed");
1381                     return CA_STATUS_FAILED;
1382                 }
1383                 g_isUnicastScanInProgress = true;
1384                 // Start Timer
1385                 oc_cond_signal(g_startTimerCond);
1386             }
1387             else
1388             {
1389                 g_isUnicastScanInProgress = true;
1390                 // Reset Timer
1391                 oc_cond_signal(g_scanningTimeCond);
1392             }
1393             oc_mutex_unlock(g_scanMutex);
1394
1395         }
1396
1397         if (serverInfo->status == LE_STATUS_DISCOVERED)
1398         {
1399             if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1400             {
1401                 oc_mutex_unlock(g_LEServerListMutex);
1402                 OIC_LOG(ERROR, TAG, "Could not add data to pending list");
1403                 return CA_STATUS_FAILED;
1404             }
1405
1406             bt_gatt_client_h clientHandle = NULL;
1407             int32_t ret = bt_gatt_client_create(serverInfo->remoteAddress, &clientHandle);
1408             if (BT_ERROR_NONE != ret || NULL == clientHandle)
1409             {
1410                 OIC_LOG_V(ERROR, TAG,
1411                           "bt_gatt_client_create Failed with ret value [%s] ", CALEGetErrorMsg(ret));
1412                 CALEGattDisConnect(serverInfo->remoteAddress);
1413                 return CA_STATUS_FAILED;
1414             }
1415             serverInfo->clientHandle = clientHandle;
1416
1417             serverInfo->status = LE_STATUS_CONNECTION_INITIATED;
1418             if (CA_STATUS_OK != CALEGattInitiateConnection(serverInfo->remoteAddress))
1419             {
1420                 OIC_LOG_V(ERROR, TAG, "Could not initiate connection to [%s]", serverInfo->remoteAddress);
1421                 serverInfo->status = LE_STATUS_DISCOVERED;
1422                 CADestroyLEDataList(&serverInfo->pendingDataList);
1423                 oc_mutex_unlock(g_LEServerListMutex);
1424                 return CA_STATUS_FAILED;
1425             }
1426         }
1427         else if (serverInfo->status < LE_STATUS_SERVICES_DISCOVERED)
1428         {
1429             if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1430             {
1431                 oc_mutex_unlock(g_LEServerListMutex);
1432                 OIC_LOG(ERROR, TAG, "Could not add data to pending list");
1433                 return CA_STATUS_FAILED;
1434             }
1435         }
1436         else
1437         {
1438             if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(serverInfo, data, dataLen))
1439             {
1440                 OIC_LOG_V(ERROR, TAG, "Could not update characteristic to gatt server [%s]",
1441                           serverInfo->remoteAddress);
1442                 oc_mutex_unlock(g_LEServerListMutex);
1443                 return CA_STATUS_FAILED;
1444             }
1445         }
1446     }
1447     else if (LE_MULTICAST == type)
1448     {
1449         OIC_LOG(ERROR, TAG, "LE_MULTICAST type Not used");
1450     }
1451     oc_mutex_unlock(g_LEServerListMutex);
1452     OIC_LOG(DEBUG, TAG, "OUT");
1453     return CA_STATUS_OK;
1454 }
1455
1456 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
1457 {
1458     OIC_LOG(DEBUG,  TAG, "IN");
1459
1460     VERIFY_NON_NULL(data, TAG, "data is NULL");
1461
1462     if (0 >= dataLen)
1463     {
1464         OIC_LOG(ERROR, TAG, "dataLen is less than or equal zero. Invalid input !");
1465         return CA_STATUS_INVALID_PARAM;
1466     }
1467
1468     oc_mutex_lock(g_LEServerListMutex);
1469     LEServerInfoList *curNode = g_LEServerList;
1470     while (curNode)
1471     {
1472         LEServerInfo *serverInfo = curNode->serverInfo;
1473         if (serverInfo->status == LE_STATUS_SERVICES_DISCOVERED)
1474         {
1475             if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(serverInfo, data, dataLen))
1476             {
1477                 OIC_LOG_V(ERROR, TAG, "Failed to update characteristics to gatt server [%s]",
1478                           serverInfo->remoteAddress);
1479             }
1480         }
1481         else if (serverInfo->status != LE_STATUS_INVALID)
1482         {
1483             if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1484             {
1485                 OIC_LOG(ERROR, TAG, "Failed to add to pending list");
1486             }
1487         }
1488         curNode = curNode->next;
1489     }
1490     oc_mutex_unlock(g_LEServerListMutex);
1491
1492     // Add the data to pending list.
1493     LEData *multicastData = (LEData *)OICCalloc(1, sizeof(LEData));
1494     if (NULL == multicastData)
1495     {
1496         OIC_LOG(ERROR, TAG, "Calloc failed");
1497         goto exit;
1498     }
1499     multicastData->data = OICCalloc(1, dataLen);
1500     if (NULL == multicastData->data)
1501     {
1502         OIC_LOG(ERROR, TAG, "Calloc failed");
1503         goto exit;
1504     }
1505     memcpy(multicastData->data, data, dataLen);
1506     multicastData->dataLength = dataLen;
1507
1508     oc_mutex_lock(g_multicastDataListMutex);
1509     if (NULL == g_multicastDataList)
1510     {
1511         g_multicastDataList = u_arraylist_create();
1512     }
1513     u_arraylist_add(g_multicastDataList, (void *)multicastData);
1514     oc_mutex_unlock(g_multicastDataListMutex);
1515
1516     // Start the scanning, if not started, else reset timer
1517     oc_mutex_lock(g_scanMutex);
1518     if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
1519     {
1520         CAResult_t result = CALEGattStartDeviceScanning();
1521         if (CA_STATUS_OK != result)
1522         {
1523             oc_mutex_unlock(g_scanMutex);
1524             OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning Failed");
1525             goto exit;
1526         }
1527         g_isMulticastInProgress = true;
1528         // Start the timer by signalling it
1529         oc_cond_signal(g_startTimerCond);
1530     }
1531     else
1532     {
1533         g_isMulticastInProgress = true;
1534         // Reset timer
1535         oc_cond_signal(g_scanningTimeCond);
1536     }
1537     oc_mutex_unlock(g_scanMutex);
1538
1539 exit:
1540     OIC_LOG(DEBUG, TAG, "OUT ");
1541     return CA_STATUS_OK;
1542 }