f8954d0b1d2c1e67e8fb7f9debee1e9bf4000897
[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 "75004209-0000-0000-0000-000000000000"
51 #define CA_GATT_CUSTOM_UUID2 "75004204-0000-0000-0000-000000000000"
52 #define CUSTOM_UUID_LEN 9
53
54 uint64_t const TIMEOUT = 30 * MICROSECS_PER_SEC;
55
56 /**
57  * Flag to check if scanning is in progress
58  */
59 static bool g_isScanningInProgress = false;
60
61 /**
62  * Mutex to synchronize access to g_isScanningInProgress
63  */
64 static oc_mutex g_isScanningInProgressMutex = NULL;
65
66 /**
67  * Flag to check if connection is in progress
68  */
69 static bool g_isConnectionInProgress = false;
70
71 /**
72  * Mutex to synchronize access to g_isConnectionInProgress
73  */
74 static oc_mutex g_isConnectionInProgressMutex = NULL;
75
76 /**
77  * Flag to check if multicast is already in progress.
78  */
79 static bool g_isMulticastInProgress = false;
80
81 /**
82  * Flag to check if unicast scan is in progress
83  */
84 static bool g_isUnicastScanInProgress = false;
85
86 /**
87  * Mutex to synchronize access to g_isMulticastInProgress
88  * and g_isUnicastScanInProgress
89  */
90 static oc_mutex g_scanMutex = NULL;
91
92 /**
93  * Pending multicast data list to be sent.
94  */
95 static u_arraylist_t *g_multicastDataList = NULL;
96
97 /**
98  * Mutex to synchronize the access to Pending multicast data list.
99  */
100 static oc_mutex g_multicastDataListMutex = NULL;
101
102 /**
103  * Condition to start the timer for scanning.
104  */
105 static oc_cond g_startTimerCond = NULL;
106
107 /**
108  * Condition for scanning Time interval.
109  */
110 static oc_cond g_scanningTimeCond = NULL;
111
112 /**
113  * This contains the list of OIC services a client connect tot.
114  */
115 static LEServerInfoList *g_LEServerList = NULL;
116
117 /**
118  * Mutex to synchronize access to BleServiceList.
119  */
120 static oc_mutex g_LEServerListMutex = NULL;
121
122 /**
123  * Boolean variable to keep the state of the GATT Client.
124  */
125 static bool g_isLEGattClientStarted = false;
126
127 /**
128  * Mutex to synchronize access to the requestResponse callback to be called
129  * when the data needs to be sent from GATTClient.
130  */
131 static oc_mutex g_LEReqRespClientCbMutex = NULL;
132
133 /**
134  * Mutex to synchronize access to the requestResponse callback to be called
135  * when the data needs to be sent from GATTClient.
136  */
137 static oc_mutex g_LEClientConnectMutex = NULL;
138
139 /**
140  * Mutex to synchronize the calls to be done to the platform from GATTClient
141  * interfaces from different threads.
142  */
143 static oc_mutex g_LEClientStateMutex = NULL;
144
145 /**
146  * Mutex to synchronize the task to be pushed to thread pool.
147  */
148 static oc_mutex g_LEClientThreadPoolMutex = NULL;
149
150 /**
151  * Mutex to synchronize the task to write characteristic one packet after another.
152  */
153 static oc_mutex g_threadWriteCharacteristicMutex = NULL;
154
155 /**
156  * Condition for Writing characteristic.
157  */
158 static oc_cond g_threadWriteCharacteristicCond = NULL;
159
160 /**
161  * Flag to check status of write characteristic.
162  */
163 static bool g_isSignalSetFlag = false;
164
165 /**
166  * Maintains the callback to be notified on receival of network packets from other
167  *           BLE devices
168  */
169 static CABLEDataReceivedCallback g_LEClientDataReceivedCallback = NULL;
170
171 /**
172  * callback to update the error to le adapter
173  */
174 static CABLEErrorHandleCallback g_clientErrorCallback;
175
176 /**
177  * gmainLoop to manage the threads to receive the callback from the platfrom.
178  */
179 static GMainLoop *g_eventLoop = NULL;
180
181 /**
182  * Reference to threadpool
183  */
184 static ca_thread_pool_t g_LEClientThreadPool = NULL;
185
186 CAResult_t CALEClientScanThread();
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     return ret;
399 }
400
401 static bool CALEIsHaveService(bt_adapter_le_device_scan_result_info_s *scanInfo,
402                               const char *service_uuid)
403 {
404     return
405         // For arduino servers, scan response will give the UUIDs advertised.
406         CALEIsHaveServiceImpl(scanInfo, service_uuid,
407                               BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) ||
408         // For android/tizen servers, advertising packet will give the UUIDs.
409         CALEIsHaveServiceImpl(scanInfo, service_uuid,
410                               BT_ADAPTER_LE_PACKET_ADVERTISING);
411 }
412
413 void CALEAdapterScanResultCb(int result, bt_adapter_le_device_scan_result_info_s *scanInfo,
414                              void *userData)
415 {
416     (void)userData;
417     OIC_LOG(DEBUG, TAG, "IN");
418
419     VERIFY_NON_NULL_VOID(scanInfo, TAG, "scanInfo");
420     VERIFY_NON_NULL_VOID(scanInfo->remote_address, TAG, "scanInfo->remote_address");
421
422     OIC_LOG_V(DEBUG, TAG, "Remote Address [%s]", scanInfo->remote_address);
423     OIC_LOG_V(DEBUG, TAG, "Scan Result [%d]", result);
424     OIC_LOG_V(DEBUG, TAG,
425               " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
426               scanInfo->adv_data_len, scanInfo->scan_data_len, scanInfo->rssi,
427               scanInfo->address_type);
428
429     // Check if scanning was stopped (since this callback is
430     // being triggered even after stopping the scan)
431     oc_mutex_lock(g_isScanningInProgressMutex);
432     if (!g_isScanningInProgress)
433     {
434         oc_mutex_unlock(g_isScanningInProgressMutex);
435         OIC_LOG(DEBUG, TAG, "Scanning not in progress, so ignoring callback");
436         return;
437     }
438     oc_mutex_unlock(g_isScanningInProgressMutex);
439
440     LEServerInfo *serverInfo = NULL;
441     oc_mutex_lock(g_LEServerListMutex);
442     CAResult_t ret = CAGetLEServerInfo(g_LEServerList, scanInfo->remote_address, &serverInfo);
443     if (CA_STATUS_OK != ret)
444     {
445             OIC_LOG_V(DEBUG, TAG,
446                       "Newly discovered device with address [%s] ", scanInfo->remote_address);
447
448         if (CALEIsHaveService(scanInfo, CA_GATT_SERVICE_UUID) ||
449             CALEIsHaveService(scanInfo, CA_GATT_CUSTOM_UUID)||
450             CALEIsHaveService(scanInfo, CA_GATT_CUSTOM_UUID2))
451         {
452             OIC_LOG_V(DEBUG, TAG, "Device [%s] supports OIC or custom service", scanInfo->remote_address);
453
454             char *addr = OICStrdup(scanInfo->remote_address);
455             if (NULL == addr)
456             {
457                 oc_mutex_unlock(g_LEServerListMutex);
458                 OIC_LOG(ERROR, TAG, "Device address is NULL");
459                 return;
460             }
461             serverInfo = (LEServerInfo *)OICCalloc(1, sizeof(LEServerInfo));
462             if (NULL == serverInfo)
463             {
464                 oc_mutex_unlock(g_LEServerListMutex);
465                 OIC_LOG(ERROR, TAG, "Calloc failed");
466                 OICFree(addr);
467                 return;
468             }
469             serverInfo->remoteAddress = addr;
470             serverInfo->status = LE_STATUS_DISCOVERED;
471
472             if (CA_STATUS_OK != CAAddLEServerInfoToList(&g_LEServerList, serverInfo))
473             {
474                 oc_mutex_unlock(g_LEServerListMutex);
475                 OIC_LOG_V(ERROR, TAG, "Could not add [%s] to server list", scanInfo->remote_address);
476                 CAFreeLEServerInfo(serverInfo);
477                 return;
478             }
479         }
480     }
481     oc_mutex_unlock(g_LEServerListMutex);
482     OIC_LOG(DEBUG, TAG, "OUT");
483 }
484
485 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
486 {
487     OIC_LOG(DEBUG, TAG, "IN");
488
489     oc_mutex_lock(g_LEClientThreadPoolMutex);
490     g_LEClientThreadPool = handle;
491     oc_mutex_unlock(g_LEClientThreadPoolMutex);
492
493     OIC_LOG(DEBUG, TAG, "OUT");
494 }
495
496 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
497 {
498     OIC_LOG(DEBUG, TAG, "IN");
499
500     oc_mutex_lock(g_LEReqRespClientCbMutex);
501
502     g_LEClientDataReceivedCallback = callback;
503
504     oc_mutex_unlock(g_LEReqRespClientCbMutex);
505
506     OIC_LOG(DEBUG, TAG, "OUT");
507 }
508
509 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
510 {
511     g_clientErrorCallback = callback;
512 }
513
514 CAResult_t CAStartLEGattClient()
515 {
516     OIC_LOG(DEBUG, TAG, "IN");
517
518     oc_mutex_lock(g_LEClientStateMutex);
519     if (true  == g_isLEGattClientStarted)
520     {
521         OIC_LOG(ERROR, TAG, "Gatt Client is already running!!");
522         oc_mutex_unlock(g_LEClientStateMutex);
523         return CA_STATUS_FAILED;
524     }
525
526     CAResult_t  result = CALEGattSetCallbacks();
527     if (CA_STATUS_OK != result)
528     {
529         OIC_LOG(ERROR, TAG, "CABleGattSetCallbacks Failed");
530         oc_mutex_unlock(g_LEClientStateMutex);
531         CATerminateLEGattClient();
532         return CA_STATUS_FAILED;
533     }
534
535     g_isLEGattClientStarted = true;
536     oc_mutex_unlock(g_LEClientStateMutex);
537
538     oc_mutex_lock(g_LEClientThreadPoolMutex);
539     if (NULL == g_LEClientThreadPool)
540     {
541         OIC_LOG(ERROR, TAG, "gBleServerThreadPool is NULL");
542         CATerminateGattClientMutexVariables();
543         oc_mutex_unlock(g_LEClientThreadPoolMutex);
544         return CA_STATUS_FAILED;
545     }
546
547     result = ca_thread_pool_add_task(g_LEClientThreadPool, CAStartTimerThread,
548                                      NULL, NULL);
549     if (CA_STATUS_OK != result)
550     {
551         OIC_LOG(ERROR, TAG, "ca_thread_pool_add_task failed");
552         CATerminateGattClientMutexVariables();
553         oc_mutex_unlock(g_LEClientThreadPoolMutex);
554         return CA_STATUS_FAILED;
555     }
556
557     result= ca_thread_pool_add_task(g_LEClientThreadPool, CALEClientScanThread,
558                                     NULL, NULL);
559     if (CA_STATUS_OK != result)
560     {
561         OIC_LOG(ERROR, TAG, "ca_thread_pool_add_task failed");
562         CATerminateGattClientMutexVariables();
563         oc_mutex_unlock(g_LEClientThreadPoolMutex);
564         return CA_STATUS_FAILED;
565     }
566     oc_mutex_unlock(g_LEClientThreadPoolMutex);
567
568     OIC_LOG(DEBUG, TAG, "OUT");
569     return CA_STATUS_OK;
570 }
571
572 CAResult_t CALEClientScanThread()
573 {
574     oc_mutex_lock(g_scanMutex);
575     if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
576     {
577         CAResult_t result = CALEGattStartDeviceScanning();
578         if (CA_STATUS_OK != result)
579         {
580             oc_mutex_unlock(g_scanMutex);
581             OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning failed");
582             return CA_STATUS_FAILED;
583         }
584         g_isUnicastScanInProgress = true;
585         // Start Timer
586         oc_cond_signal(g_startTimerCond);
587     }
588     else
589     {
590         g_isUnicastScanInProgress = true;
591         // Reset Timer
592         oc_cond_signal(g_scanningTimeCond);
593     }
594     oc_mutex_unlock(g_scanMutex);
595
596     OIC_LOG(DEBUG, TAG, "OUT");
597     return CA_STATUS_OK;
598 }
599
600 void CAStartTimerThread(void *data)
601 {
602     (void)data;
603
604     OIC_LOG(DEBUG, TAG, "IN");
605     while (g_isLEGattClientStarted)
606     {
607         oc_mutex_lock(g_scanMutex);
608         if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
609         {
610             OIC_LOG(DEBUG, TAG, "waiting....");
611             oc_cond_wait(g_startTimerCond, g_scanMutex);
612             OIC_LOG(DEBUG, TAG, "Wake up");
613         }
614
615         // Timed conditional wait for stopping the scan.
616         OCWaitResult_t ret = oc_cond_wait_for(g_scanningTimeCond, g_scanMutex,
617                                               TIMEOUT);
618         if (OC_WAIT_TIMEDOUT == ret)
619         {
620             OIC_LOG(DEBUG, TAG, "Scan is timed Out");
621             // Call stop scan.
622             CALEGattStopDeviceScanning();
623
624             if (g_isMulticastInProgress)
625             {
626                 oc_mutex_lock(g_multicastDataListMutex);
627                 // Clear the data list and device list.
628                 u_arraylist_destroy(g_multicastDataList);
629                 g_multicastDataList = NULL;
630                 oc_mutex_unlock(g_multicastDataListMutex);
631                 g_isMulticastInProgress = false;
632             }
633             g_isUnicastScanInProgress = false;
634         }
635         oc_mutex_unlock(g_scanMutex);
636     }
637
638     OIC_LOG(DEBUG, TAG, "OUT");
639 }
640
641 void CAStopLEGattClient()
642 {
643     OIC_LOG(DEBUG,  TAG, "IN");
644
645     oc_mutex_lock(g_LEClientStateMutex);
646
647     if (false == g_isLEGattClientStarted)
648     {
649         OIC_LOG(ERROR, TAG, "Gatt Client is not running to stop");
650         oc_mutex_unlock(g_LEClientStateMutex);
651         return;
652     }
653
654     CALEGattUnSetCallbacks();
655
656     CALEGattStopDeviceScanning();
657
658     g_isLEGattClientStarted = false;
659
660     // Signal the conditions waiting in Start timer.
661     oc_cond_signal(g_startTimerCond);
662     oc_cond_signal(g_scanningTimeCond);
663
664     // Destroy the multicast data list and device list if not empty.
665     if (NULL != g_multicastDataList)
666     {
667         oc_mutex_lock(g_multicastDataListMutex);
668         u_arraylist_destroy(g_multicastDataList);
669         g_multicastDataList = NULL;
670         oc_mutex_unlock(g_multicastDataListMutex);
671     }
672
673     oc_mutex_lock(g_LEServerListMutex);
674     CAFreeLEServerList(g_LEServerList);
675     g_LEServerList = NULL;
676     oc_mutex_unlock(g_LEServerListMutex);
677
678     oc_mutex_lock(g_threadWriteCharacteristicMutex);
679     oc_cond_signal(g_threadWriteCharacteristicCond);
680     oc_mutex_unlock(g_threadWriteCharacteristicMutex);
681
682     GMainContext  *context_event_loop = NULL;
683     // Required for waking up the thread which is running in gmain loop
684     if (NULL != g_eventLoop)
685     {
686         context_event_loop = g_main_loop_get_context(g_eventLoop);
687     }
688     if (context_event_loop)
689     {
690         OIC_LOG_V(DEBUG,  TAG, "g_eventLoop context %p", (void *)context_event_loop);
691         g_main_context_wakeup(context_event_loop);
692
693         // Kill g main loops and kill threads.
694         g_main_loop_quit(g_eventLoop);
695     }
696     else
697     {
698         OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
699     }
700
701     oc_mutex_unlock(g_LEClientStateMutex);
702
703     OIC_LOG(DEBUG,  TAG, "OUT");
704 }
705
706 CAResult_t CAInitializeLEGattClient()
707 {
708     OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
709     CAResult_t res = CAInitGattClientMutexVariables();
710     if (CA_STATUS_OK != res)
711     {
712         OIC_LOG(ERROR, TAG, "CAInitGattClientMutexVariables failed!");
713         CATerminateGattClientMutexVariables();
714         return CA_STATUS_FAILED;
715     }
716     return res;
717 }
718
719 void CATerminateLEGattClient()
720 {
721     OIC_LOG(DEBUG,  TAG, "IN");
722
723     CATerminateGattClientMutexVariables();
724
725     OIC_LOG(DEBUG,  TAG, "OUT");
726 }
727
728 CAResult_t CAInitGattClientMutexVariables()
729 {
730     OIC_LOG(DEBUG,  TAG, "IN");
731     if (NULL == g_LEClientStateMutex)
732     {
733         g_LEClientStateMutex = oc_mutex_new();
734         if (NULL == g_LEClientStateMutex)
735         {
736             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
737             return CA_STATUS_FAILED;
738         }
739     }
740
741     if (NULL == g_LEServerListMutex)
742     {
743         g_LEServerListMutex = oc_mutex_new();
744         if (NULL == g_LEServerListMutex)
745         {
746             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
747             return CA_STATUS_FAILED;
748         }
749     }
750
751     if (NULL == g_LEReqRespClientCbMutex)
752     {
753         g_LEReqRespClientCbMutex = oc_mutex_new();
754         if (NULL == g_LEReqRespClientCbMutex)
755         {
756             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
757             return CA_STATUS_FAILED;
758         }
759     }
760
761     if (NULL == g_LEClientThreadPoolMutex)
762     {
763         g_LEClientThreadPoolMutex = oc_mutex_new();
764         if (NULL == g_LEClientThreadPoolMutex)
765         {
766             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
767             return CA_STATUS_FAILED;
768         }
769     }
770
771     if (NULL == g_LEClientConnectMutex)
772     {
773         g_LEClientConnectMutex = oc_mutex_new();
774         if (NULL == g_LEClientConnectMutex)
775         {
776             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
777             return CA_STATUS_FAILED;
778         }
779     }
780
781     if (NULL == g_isScanningInProgressMutex)
782     {
783         g_isScanningInProgressMutex = oc_mutex_new();
784         if (NULL == g_isScanningInProgressMutex)
785         {
786             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
787             return CA_STATUS_FAILED;
788         }
789     }
790
791     if (NULL == g_isConnectionInProgressMutex)
792     {
793         g_isConnectionInProgressMutex = oc_mutex_new();
794         if (NULL == g_isConnectionInProgressMutex)
795         {
796             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
797             return CA_STATUS_FAILED;
798         }
799     }
800
801     if (NULL == g_multicastDataListMutex)
802     {
803         g_multicastDataListMutex = oc_mutex_new();
804         if (NULL == g_multicastDataListMutex)
805         {
806             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
807             return CA_STATUS_FAILED;
808         }
809     }
810
811     if (NULL == g_scanMutex)
812     {
813         g_scanMutex = oc_mutex_new();
814         if (NULL == g_scanMutex)
815         {
816             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
817             return CA_STATUS_FAILED;
818         }
819     }
820
821     if (NULL == g_threadWriteCharacteristicMutex)
822     {
823         g_threadWriteCharacteristicMutex = oc_mutex_new();
824         if (NULL == g_threadWriteCharacteristicMutex)
825         {
826             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
827             return CA_STATUS_FAILED;
828         }
829     }
830
831     if (NULL == g_startTimerCond)
832     {
833         g_startTimerCond = oc_cond_new();
834         if (NULL == g_startTimerCond)
835         {
836             OIC_LOG(ERROR, TAG, "oc_cond_new failed");
837             return CA_STATUS_FAILED;
838         }
839     }
840
841     if (NULL == g_scanningTimeCond)
842     {
843         g_scanningTimeCond = oc_cond_new();
844         if (NULL == g_scanningTimeCond)
845         {
846             OIC_LOG(ERROR, TAG, "oc_cond_new failed");
847             return CA_STATUS_FAILED;
848         }
849     }
850
851     if (NULL == g_threadWriteCharacteristicCond)
852     {
853         g_threadWriteCharacteristicCond = oc_cond_new();
854         if (NULL == g_threadWriteCharacteristicCond)
855         {
856             OIC_LOG(ERROR, TAG, "oc_cond_new failed");
857             return CA_STATUS_FAILED;
858         }
859     }
860
861     OIC_LOG(DEBUG,  TAG, "OUT");
862     return CA_STATUS_OK;
863 }
864
865 void CATerminateGattClientMutexVariables()
866 {
867     OIC_LOG(DEBUG,  TAG, "IN");
868
869     oc_mutex_free(g_LEClientStateMutex);
870     g_LEClientStateMutex = NULL;
871
872     oc_mutex_free(g_LEServerListMutex);
873     g_LEServerListMutex = NULL;
874
875     oc_mutex_free(g_LEReqRespClientCbMutex);
876     g_LEReqRespClientCbMutex = NULL;
877
878     oc_mutex_free(g_LEClientConnectMutex);
879     g_LEClientConnectMutex = NULL;
880
881     oc_mutex_free(g_LEClientThreadPoolMutex);
882     g_LEClientThreadPoolMutex = NULL;
883
884     oc_mutex_free(g_isScanningInProgressMutex);
885     g_isScanningInProgressMutex = NULL;
886
887     oc_mutex_free(g_isConnectionInProgressMutex);
888     g_isConnectionInProgressMutex = NULL;
889
890     oc_mutex_free(g_multicastDataListMutex);
891     g_multicastDataListMutex = NULL;
892
893     oc_mutex_free(g_scanMutex);
894     g_scanMutex = NULL;
895
896     oc_mutex_free(g_threadWriteCharacteristicMutex);
897     g_threadWriteCharacteristicMutex = NULL;
898
899     oc_cond_free(g_startTimerCond);
900     g_startTimerCond = NULL;
901
902     oc_cond_free(g_scanningTimeCond);
903     g_scanningTimeCond = NULL;
904
905     oc_cond_free(g_threadWriteCharacteristicCond);
906     g_threadWriteCharacteristicCond = NULL;
907     g_isSignalSetFlag = false;
908
909     OIC_LOG(DEBUG,  TAG, "OUT");
910 }
911
912 CAResult_t CALEGattSetCallbacks()
913 {
914     OIC_LOG(DEBUG, TAG, "IN");
915
916     OIC_LOG(DEBUG, TAG, "OUT");
917     return CA_STATUS_OK;
918 }
919
920 void CALEGattUnSetCallbacks()
921 {
922     OIC_LOG(DEBUG, TAG, "IN");
923
924     bt_gatt_unset_connection_state_changed_cb();
925
926     oc_mutex_lock(g_LEServerListMutex);
927     LEServerInfoList *curNode = g_LEServerList;
928     while (curNode)
929     {
930         LEServerInfo *serverInfo = curNode->serverInfo;
931         if (serverInfo->status >= LE_STATUS_SERVICES_DISCOVERED)
932         {
933             bt_gatt_client_unset_characteristic_value_changed_cb(serverInfo->readChar);
934         }
935         curNode = curNode->next;
936     }
937     oc_mutex_unlock(g_LEServerListMutex);
938
939     OIC_LOG(DEBUG, TAG, "OUT");
940 }
941
942 CAResult_t CALEGattStartDeviceScanning()
943 {
944     OIC_LOG(DEBUG, TAG, "IN");
945
946     oc_mutex_lock(g_isScanningInProgressMutex);
947     if (!g_isScanningInProgress)
948     {
949         int ret = bt_adapter_le_start_scan(CALEAdapterScanResultCb, NULL);
950         if (BT_ERROR_NONE != ret)
951         {
952             oc_mutex_unlock(g_isScanningInProgressMutex);
953             OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_scan failed[%s]",
954                       CALEGetErrorMsg(ret));
955             return CA_STATUS_FAILED;
956         }
957         g_isScanningInProgress = true;
958     }
959     else
960     {
961         OIC_LOG(DEBUG, TAG, "Ignore, scanning already in progress");
962     }
963     oc_mutex_unlock(g_isScanningInProgressMutex);
964
965     OIC_LOG(DEBUG, TAG, "OUT");
966     return CA_STATUS_OK;
967 }
968
969 void CALEGattStopDeviceScanning()
970 {
971     OIC_LOG(DEBUG, TAG, "IN");
972
973     oc_mutex_lock(g_isScanningInProgressMutex);
974     if (g_isScanningInProgress)
975     {
976         int ret = bt_adapter_le_stop_scan();
977         if (BT_ERROR_NONE != ret)
978         {
979             oc_mutex_unlock(g_isScanningInProgressMutex);
980             OIC_LOG_V(ERROR, TAG, "bt_adapter_le_stop_scan failed[%s]",
981                       CALEGetErrorMsg(ret));
982             return;
983         }
984         g_isScanningInProgress = false;
985     }
986     else
987     {
988         OIC_LOG(DEBUG, TAG, "Ignore, scanning not in progress");
989     }
990     oc_mutex_unlock(g_isScanningInProgressMutex);
991
992     OIC_LOG(DEBUG, TAG, "OUT");
993 }
994
995 void CAGattConnectThread (void *remoteAddress)
996 {
997     OIC_LOG(DEBUG, TAG, "IN ");
998
999     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
1000
1001     char *address  = (char *)remoteAddress;
1002
1003     OIC_LOG_V(DEBUG, TAG, "remote address is [%s]", address);
1004
1005     CAResult_t result = CALEGattConnect(address);
1006
1007     if (CA_STATUS_OK != result)
1008     {
1009         OIC_LOG_V(ERROR, TAG, "bt_gatt_connect failed for [%s]", address);
1010     }
1011
1012     OICFree(address);
1013
1014     OIC_LOG(DEBUG, TAG, "OUT");
1015 }
1016
1017 CAResult_t CALEGattConnect(const char *remoteAddress)
1018 {
1019     OIC_LOG(DEBUG, TAG, "IN");
1020
1021     VERIFY_NON_NULL_RET(remoteAddress, TAG,
1022                         "remote address is NULL", CA_STATUS_FAILED);
1023
1024     oc_mutex_lock(g_LEClientConnectMutex);
1025     CAResult_t result = CA_STATUS_OK;
1026
1027     int ret = bt_gatt_connect(remoteAddress, false);
1028     if (BT_ERROR_NONE != ret)
1029     {
1030         OIC_LOG_V(ERROR, TAG, "bt_gatt_connect Failed with ret value [%s] ",
1031                   CALEGetErrorMsg(ret));
1032         oc_mutex_unlock(g_LEClientConnectMutex);
1033         return CA_STATUS_FAILED;
1034     }
1035
1036     oc_mutex_unlock(g_LEClientConnectMutex);
1037
1038     OIC_LOG(DEBUG, TAG, "OUT");
1039     return result;
1040 }
1041
1042 CAResult_t CALEGattDisConnect(const char *remoteAddress)
1043 {
1044     OIC_LOG(DEBUG, TAG, "IN");
1045
1046     VERIFY_NON_NULL_RET(remoteAddress, TAG,
1047                         "remote address is NULL", CA_STATUS_FAILED);
1048
1049     int ret = bt_gatt_disconnect(remoteAddress);
1050
1051     if (BT_ERROR_NONE != ret)
1052     {
1053         OIC_LOG_V(ERROR, TAG, "bt_gatt_disconnect Failed with ret value [%s] ",
1054                   CALEGetErrorMsg(ret));
1055         return CA_STATUS_FAILED;
1056     }
1057
1058     OIC_LOG(DEBUG, TAG, "OUT");
1059     return CA_STATUS_OK;
1060 }
1061
1062 CAResult_t CAUpdateCharacteristicsToGattServerImpl(LEServerInfo *serverInfo,
1063         const uint8_t *data, const uint32_t dataLen)
1064 {
1065     OIC_LOG(DEBUG, TAG, "IN");
1066
1067     VERIFY_NON_NULL(serverInfo, TAG, "Server Info is NULL");
1068
1069     CALEGattStopDeviceScanning();
1070
1071     OIC_LOG_V(DEBUG, TAG, "Updating the data of length [%d] to [%s] ", dataLen,
1072               serverInfo->remoteAddress);
1073
1074     int result = bt_gatt_set_value(serverInfo->writeChar, (char *)data, dataLen);
1075
1076     if (BT_ERROR_NONE != result)
1077     {
1078         OIC_LOG_V(ERROR, TAG,
1079                   "bt_gatt_set_value Failed with return val [%s]",
1080                   CALEGetErrorMsg(result));
1081         goto exit;
1082     }
1083
1084     result = bt_gatt_client_write_value(serverInfo->writeChar, CALEGattCharacteristicWriteCb,
1085                                         NULL);
1086     if (BT_ERROR_NONE != result)
1087     {
1088         OIC_LOG_V(ERROR, TAG,
1089                   "bt_gatt_client_write_value Failed with return val [%s]",
1090                   CALEGetErrorMsg(result));
1091         goto exit;
1092     }
1093
1094     // wait for callback for write Characteristic with success to sent data
1095     OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
1096     oc_mutex_lock(g_threadWriteCharacteristicMutex);
1097     if (!g_isSignalSetFlag)
1098     {
1099         OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
1100         if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
1101                                                 g_threadWriteCharacteristicMutex,
1102                                                 WAIT_TIME_WRITE_CHARACTERISTIC))
1103         {
1104             g_isSignalSetFlag = false;
1105             oc_mutex_unlock(g_threadWriteCharacteristicMutex);
1106             OIC_LOG(ERROR, TAG, "there is no response. write has failed");
1107             goto exit;
1108         }
1109     }
1110     // reset flag set by writeCharacteristic Callback
1111     g_isSignalSetFlag = false;
1112     oc_mutex_unlock(g_threadWriteCharacteristicMutex);
1113
1114     oc_mutex_lock(g_scanMutex);
1115     if (g_isMulticastInProgress || g_isUnicastScanInProgress)
1116     {
1117         if (CA_STATUS_OK != CALEGattStartDeviceScanning())
1118         {
1119             OIC_LOG(ERROR, TAG, "Could not start device scanning");
1120         }
1121     }
1122     oc_mutex_unlock(g_scanMutex);
1123     OIC_LOG(DEBUG, TAG, "OUT");
1124     return CA_STATUS_OK;
1125
1126 exit:
1127     oc_mutex_lock(g_scanMutex);
1128     if (g_isMulticastInProgress || g_isUnicastScanInProgress)
1129     {
1130         if (CA_STATUS_OK != CALEGattStartDeviceScanning())
1131         {
1132             OIC_LOG(ERROR, TAG, "Could not start device scanning");
1133         }
1134     }
1135     oc_mutex_unlock(g_scanMutex);
1136
1137     OIC_LOG(DEBUG, TAG, "OUT");
1138     return CA_STATUS_FAILED;
1139 }
1140
1141 void CADiscoverLEServicesThread(void *remoteAddress)
1142 {
1143     OIC_LOG(DEBUG, TAG, "IN");
1144     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
1145
1146     char *address  = (char *)remoteAddress;
1147
1148     CAResult_t result = CALEGattDiscoverServices(address);
1149     if (CA_STATUS_OK != result)
1150     {
1151         OIC_LOG(ERROR, TAG, "CALEGattDiscoverServices failed");
1152     }
1153
1154     OICFree(address);
1155     OIC_LOG(DEBUG, TAG, "OUT");
1156 }
1157
1158 CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
1159 {
1160     OIC_LOG(DEBUG, TAG, "IN");
1161
1162     VERIFY_NON_NULL_RET(remoteAddress, TAG,
1163                         "remote address is NULL", CA_STATUS_FAILED);
1164
1165     LEServerInfo *serverInfo = NULL;
1166     oc_mutex_lock(g_LEServerListMutex);
1167     if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
1168     {
1169         oc_mutex_unlock(g_LEServerListMutex);
1170         OIC_LOG_V(ERROR, TAG, "Could not get server info for [%s]", remoteAddress);
1171         CALEGattDisConnect(remoteAddress);
1172         return CA_STATUS_FAILED;
1173     }
1174
1175     bt_gatt_h serviceHandle = NULL;
1176     int32_t ret = bt_gatt_client_get_service(serverInfo->clientHandle, CA_GATT_SERVICE_UUID, &serviceHandle);
1177     if (BT_ERROR_NONE != ret || NULL == serviceHandle)
1178     {
1179         OIC_LOG_V(ERROR, TAG,
1180                   "bt_gatt_client_get_service Failed with ret value [%s] ", CALEGetErrorMsg(ret));
1181         bt_gatt_client_destroy(serverInfo->clientHandle);
1182         CALEGattDisConnect(remoteAddress);
1183         return CA_STATUS_FAILED;
1184     }
1185
1186     // Server will read data on this characteristic.
1187     bt_gatt_h writeChrHandle = NULL;
1188     ret = bt_gatt_service_get_characteristic(serviceHandle, CA_GATT_REQUEST_CHRC_UUID,
1189             &writeChrHandle);
1190     if (BT_ERROR_NONE != ret || NULL == writeChrHandle)
1191     {
1192         OIC_LOG_V(ERROR, TAG,
1193                   "bt_gatt_service_get_characteristic Failed with ret value [%s] ",
1194                   CALEGetErrorMsg(ret));
1195         bt_gatt_client_destroy(serverInfo->clientHandle);
1196         CALEGattDisConnect(remoteAddress);
1197         return CA_STATUS_FAILED;
1198     }
1199
1200     // Server will notify data on this characteristic.
1201     bt_gatt_h readChrHandle = NULL;
1202     ret = bt_gatt_service_get_characteristic(serviceHandle, CA_GATT_RESPONSE_CHRC_UUID,
1203             &readChrHandle);
1204     if (BT_ERROR_NONE != ret || NULL == readChrHandle)
1205     {
1206         OIC_LOG_V(ERROR, TAG,
1207                   "bt_gatt_service_get_characteristic Failed with ret value [%s] ",
1208                   CALEGetErrorMsg(ret));
1209         bt_gatt_client_destroy(serverInfo->clientHandle);
1210         CALEGattDisConnect(remoteAddress);
1211         return CA_STATUS_FAILED;
1212     }
1213
1214     //TODO: This data has to be freed while unsetting the callback.
1215     char *addr = OICStrdup(remoteAddress);
1216     if (NULL == addr)
1217     {
1218         OIC_LOG(ERROR, TAG, "addr is NULL");
1219         bt_gatt_client_destroy(serverInfo->clientHandle);
1220         CALEGattDisConnect(remoteAddress);
1221         return CA_STATUS_FAILED;
1222     }
1223
1224     ret = bt_gatt_client_set_characteristic_value_changed_cb(readChrHandle,
1225             CALEGattCharacteristicChangedCb,
1226             (void *)addr);
1227     if (BT_ERROR_NONE != ret)
1228     {
1229         OIC_LOG_V(ERROR, TAG,
1230                   "bt_gatt_client_set_characteristic_value_changed_cb Failed with ret value [%s]",
1231                   CALEGetErrorMsg(ret));
1232         bt_gatt_client_destroy(serverInfo->clientHandle);
1233         CALEGattDisConnect(remoteAddress);
1234         return CA_STATUS_FAILED;
1235     }
1236
1237     serverInfo->serviceHandle = serviceHandle;
1238     serverInfo->readChar = readChrHandle;
1239     serverInfo->writeChar = writeChrHandle;
1240     serverInfo->status = LE_STATUS_SERVICES_DISCOVERED;
1241
1242     while (serverInfo->pendingDataList)
1243     {
1244         LEData *leData = serverInfo->pendingDataList->data;
1245         if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(
1246                 serverInfo, leData->data, leData->dataLength))
1247         {
1248             OIC_LOG_V(ERROR, TAG, "Failed to send pending data to [%s]",
1249                       serverInfo->remoteAddress);
1250
1251             CADestroyLEDataList(&serverInfo->pendingDataList);
1252             break;
1253         }
1254         CARemoveLEDataFromList(&serverInfo->pendingDataList);
1255     }
1256     oc_mutex_unlock(g_LEServerListMutex);
1257
1258     OIC_LOG(DEBUG, TAG, "OUT");
1259     return CA_STATUS_OK;
1260 }
1261
1262 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
1263         const uint8_t *data, const uint32_t dataLen,
1264         CALETransferType_t type, const int32_t position)
1265 {
1266     OIC_LOG(DEBUG, TAG, "IN");
1267
1268     VERIFY_NON_NULL(data, TAG, "data is NULL");
1269
1270     if (0 >= dataLen)
1271     {
1272         OIC_LOG(ERROR, TAG, "dataLen is less than or equal zero. Invalid input!");
1273         return CA_STATUS_INVALID_PARAM;
1274     }
1275
1276     LEServerInfo *serverInfo = NULL;
1277     oc_mutex_lock(g_LEServerListMutex);
1278     if (LE_UNICAST == type)
1279     {
1280         if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
1281         {
1282             OIC_LOG_V(DEBUG, TAG,
1283                       "Device with address [%s] not yet found, initiating scan",
1284                       remoteAddress);
1285
1286             if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1287             {
1288                 oc_mutex_unlock(g_LEServerListMutex);
1289                 OIC_LOG(ERROR, TAG, "Could not add data to pending list");
1290                 return CA_STATUS_FAILED;
1291             }
1292
1293             oc_mutex_unlock(g_LEServerListMutex);
1294
1295             oc_mutex_lock(g_scanMutex);
1296             if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
1297             {
1298                 CAResult_t result = CALEGattStartDeviceScanning();
1299                 if (CA_STATUS_OK != result)
1300                 {
1301                     oc_mutex_unlock(g_scanMutex);
1302                     OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning failed");
1303                     return CA_STATUS_FAILED;
1304                 }
1305                 g_isUnicastScanInProgress = true;
1306                 // Start Timer
1307                 oc_cond_signal(g_startTimerCond);
1308             }
1309             else
1310             {
1311                 g_isUnicastScanInProgress = true;
1312                 // Reset Timer
1313                 oc_cond_signal(g_scanningTimeCond);
1314             }
1315             oc_mutex_unlock(g_scanMutex);
1316
1317             OIC_LOG(DEBUG, TAG, "OUT");
1318             return CA_STATUS_OK;
1319         }
1320
1321         if (serverInfo->status == LE_STATUS_DISCOVERED)
1322         {
1323             if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1324             {
1325                 oc_mutex_unlock(g_LEServerListMutex);
1326                 OIC_LOG(ERROR, TAG, "Could not add data to pending list");
1327                 return CA_STATUS_FAILED;
1328             }
1329             
1330             bt_gatt_client_h clientHandle = NULL;
1331             int32_t ret = bt_gatt_client_create(serverInfo->remoteAddress, &clientHandle);
1332             if (BT_ERROR_NONE != ret || NULL == clientHandle)
1333             {
1334                 OIC_LOG_V(ERROR, TAG,
1335                           "bt_gatt_client_create Failed with ret value [%s] ", CALEGetErrorMsg(ret));
1336                 CALEGattDisConnect(serverInfo->remoteAddress);
1337                 return CA_STATUS_FAILED;
1338             }
1339             serverInfo->clientHandle = clientHandle;
1340
1341             serverInfo->status = LE_STATUS_CONNECTION_INITIATED;
1342             if (CA_STATUS_OK != CALEGattInitiateConnection(serverInfo->remoteAddress))
1343             {
1344                 OIC_LOG_V(ERROR, TAG, "Could not initiate connection to [%s]", serverInfo->remoteAddress);
1345                 serverInfo->status = LE_STATUS_DISCOVERED;
1346                 CADestroyLEDataList(&serverInfo->pendingDataList);
1347                 oc_mutex_unlock(g_LEServerListMutex);
1348                 return CA_STATUS_FAILED;
1349             }
1350         }
1351         else if (serverInfo->status < LE_STATUS_SERVICES_DISCOVERED)
1352         {
1353             if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1354             {
1355                 oc_mutex_unlock(g_LEServerListMutex);
1356                 OIC_LOG(ERROR, TAG, "Could not add data to pending list");
1357                 return CA_STATUS_FAILED;
1358             }
1359         }
1360         else
1361         {
1362             if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(serverInfo, data, dataLen))
1363             {
1364                 OIC_LOG_V(ERROR, TAG, "Could not update characteristic to gatt server [%s]",
1365                           serverInfo->remoteAddress);
1366                 oc_mutex_unlock(g_LEServerListMutex);
1367                 return CA_STATUS_FAILED;
1368             }
1369         }
1370     }
1371     else if (LE_MULTICAST == type)
1372     {
1373         OIC_LOG(ERROR, TAG, "LE_MULTICAST type Not used");
1374     }
1375     oc_mutex_unlock(g_LEServerListMutex);
1376     OIC_LOG(DEBUG, TAG, "OUT");
1377     return CA_STATUS_OK;
1378 }
1379
1380 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
1381 {
1382     OIC_LOG(DEBUG,  TAG, "IN");
1383
1384     VERIFY_NON_NULL(data, TAG, "data is NULL");
1385
1386     if (0 >= dataLen)
1387     {
1388         OIC_LOG(ERROR, TAG, "dataLen is less than or equal zero. Invalid input !");
1389         return CA_STATUS_INVALID_PARAM;
1390     }
1391
1392     oc_mutex_lock(g_LEServerListMutex);
1393     LEServerInfoList *curNode = g_LEServerList;
1394     while (curNode)
1395     {
1396         LEServerInfo *serverInfo = curNode->serverInfo;
1397         if (serverInfo->status == LE_STATUS_SERVICES_DISCOVERED)
1398         {
1399             if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(serverInfo, data, dataLen))
1400             {
1401                 OIC_LOG_V(ERROR, TAG, "Failed to update characteristics to gatt server [%s]",
1402                           serverInfo->remoteAddress);
1403             }
1404         }
1405         else if (serverInfo->status != LE_STATUS_INVALID)
1406         {
1407             if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1408             {
1409                 OIC_LOG(ERROR, TAG, "Failed to add to pending list");
1410             }
1411         }
1412         curNode = curNode->next;
1413     }
1414     oc_mutex_unlock(g_LEServerListMutex);
1415
1416     // Add the data to pending list.
1417     LEData *multicastData = (LEData *)OICCalloc(1, sizeof(LEData));
1418     if (NULL == multicastData)
1419     {
1420         OIC_LOG(ERROR, TAG, "Calloc failed");
1421         goto exit;
1422     }
1423     multicastData->data = OICCalloc(1, dataLen);
1424     if (NULL == multicastData->data)
1425     {
1426         OIC_LOG(ERROR, TAG, "Calloc failed");
1427         goto exit;
1428     }
1429     memcpy(multicastData->data, data, dataLen);
1430     multicastData->dataLength = dataLen;
1431
1432     oc_mutex_lock(g_multicastDataListMutex);
1433     if (NULL == g_multicastDataList)
1434     {
1435         g_multicastDataList = u_arraylist_create();
1436     }
1437     u_arraylist_add(g_multicastDataList, (void *)multicastData);
1438     oc_mutex_unlock(g_multicastDataListMutex);
1439
1440     // Start the scanning, if not started, else reset timer
1441     oc_mutex_lock(g_scanMutex);
1442     if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
1443     {
1444         CAResult_t result = CALEGattStartDeviceScanning();
1445         if (CA_STATUS_OK != result)
1446         {
1447             oc_mutex_unlock(g_scanMutex);
1448             OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning Failed");
1449             goto exit;
1450         }
1451         g_isMulticastInProgress = true;
1452         // Start the timer by signalling it
1453         oc_cond_signal(g_startTimerCond);
1454     }
1455     else
1456     {
1457         g_isMulticastInProgress = true;
1458         // Reset timer
1459         oc_cond_signal(g_scanningTimeCond);
1460     }
1461     oc_mutex_unlock(g_scanMutex);
1462
1463 exit:
1464     OIC_LOG(DEBUG, TAG, "OUT ");
1465     return CA_STATUS_OK;
1466 }