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