Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / tizen / cableclient.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 "cableclient.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 "camutex.h"
34 #include "uarraylist.h"
35 #include "caqueueingthread.h"
36 #include "caadapterutils.h"
37 #include "cafragmentation.h"
38 #include "oic_string.h"
39 #include "oic_malloc.h"
40
41 /**
42  * @def TZ_BLE_CLIENT_TAG
43  * @brief Logging tag for module name
44  */
45 #define TZ_BLE_CLIENT_TAG "TZ_BLE_GATT_CLIENT"
46
47 /**
48  * @var BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG
49  * @brief Its the constant value for characteristic descriptor from spec.
50  */
51 #define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG "2902"
52
53 /**
54  * @var g_bLEServiceList
55  * @brief This contains the list of OIC services a client connect tot.
56  */
57 static BLEServiceList *g_bLEServiceList = NULL;
58
59 /**
60  * @var g_isBleGattClientStarted
61  * @brief Boolean variable to keep the state of the GATT Client.
62  */
63 static bool g_isBleGattClientStarted = false;
64
65 /**
66  * @var g_bleServiceListMutex
67  * @brief Mutex to synchronize access to BleServiceList.
68  */
69 static ca_mutex g_bleServiceListMutex = NULL;
70
71 /**
72  * @var g_bleReqRespClientCbMutex
73  * @brief Mutex to synchronize access to the requestResponse callback to be called
74  *           when the data needs to be sent from GATTClient.
75  */
76 static ca_mutex g_bleReqRespClientCbMutex = NULL;
77
78 /**
79  * @var g_bleReqRespClientCbMutex
80  * @brief Mutex to synchronize access to the requestResponse callback to be called
81  *           when the data needs to be sent from GATTClient.
82  */
83 static ca_mutex g_bleClientConnectMutex = NULL;
84
85
86 /**
87  * @var g_bleClientStateMutex
88  * @brief Mutex to synchronize the calls to be done to the platform from GATTClient
89  *           interfaces from different threads.
90  */
91 static ca_mutex g_bleClientStateMutex = NULL;
92
93 /**
94  * @var g_bleServerBDAddressMutex
95  * @brief Mutex to synchronize the Server BD Address update on client side.
96  */
97 static ca_mutex g_bleServerBDAddressMutex = NULL;
98
99 /**
100  * @var g_bleClientSendCondWait
101  * @brief Condition used for notifying handler the presence of data in send queue.
102  */
103 static ca_cond g_bleClientSendCondWait = NULL;
104
105 /**
106  * @var g_bleClientThreadPoolMutex
107  * @brief Mutex to synchronize the task to be pushed to thread pool.
108  */
109 static ca_mutex g_bleClientThreadPoolMutex = NULL;
110
111 /**
112  * @var gNetworkPacketReceivedClientCallback
113  * @brief Maintains the callback to be notified on receival of network packets from other
114  *           BLE devices
115  */
116 static CABLEClientDataReceivedCallback g_bleClientDataReceivedCallback = NULL;
117
118 /**
119  * @var g_clientErrorCallback
120  * @brief callback to update the error to le adapter
121  */
122 static CABLEErrorHandleCallback g_clientErrorCallback;
123
124 /**
125  * @var g_eventLoop
126  * @brief gmainLoop to manage the threads to receive the callback from the platfrom.
127  */
128 static GMainLoop *g_eventLoop = NULL;
129
130 /**
131  * @var g_bleClientThreadPool
132  * @brief reference to threadpool
133  */
134 static ca_thread_pool_t g_bleClientThreadPool = NULL;
135
136 /**
137  * @struct stGattServiceInfo_t
138  * @brief structure to map the service attribute to BD Address.
139  */
140 typedef struct gattService
141 {
142     bt_gatt_attribute_h serviceInfo;         /**< bluetoth attribute for oic service*/
143     char *address;                           /**< BD Address of */
144 } stGattServiceInfo_t;
145
146 /**
147  * @var g_remoteAddress
148  * @brief Remote address of Gatt Server
149  */
150 static char *g_remoteAddress = NULL;
151
152 void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic,
153                                       unsigned char *value,
154                                       int valueLen, void *userData)
155 {
156     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
157
158     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic is  [%s]", (char *)characteristic);
159     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic value length [%d]", valueLen);
160
161     ca_mutex_lock(g_bleReqRespClientCbMutex);
162     if (NULL == g_bleClientDataReceivedCallback)
163     {
164         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespCallback is NULL!");
165         ca_mutex_unlock(g_bleReqRespClientCbMutex);
166         return;
167     }
168     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending data up !");
169
170     ca_mutex_lock(g_bleServerBDAddressMutex);
171     uint32_t sentLength = 0;
172     g_bleClientDataReceivedCallback(g_remoteAddress, OIC_BLE_SERVICE_ID,
173                                      value, valueLen, &sentLength);
174
175     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Sent data Length is %d", sentLength);
176     ca_mutex_unlock(g_bleServerBDAddressMutex);
177
178     ca_mutex_unlock(g_bleReqRespClientCbMutex);
179
180     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
181 }
182
183 void CABleGattCharacteristicWriteCb(int result, void *userData)
184 {
185     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
186
187
188     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
189 }
190
191 void CABleGattDescriptorDiscoveredCb(int result, unsigned char format, int total,
192                                      bt_gatt_attribute_h descriptor,
193                                      bt_gatt_attribute_h characteristic, void *userData)
194 {
195     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
196
197     stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)OICCalloc(1, sizeof(
198                                                                          stGattCharDescriptor_t));
199
200     VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed!");
201
202     stTemp->desc = (uint8_t *)OICMalloc(total);
203     if (NULL == stTemp->desc)
204     {
205         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "malloc failed");
206         OICFree(stTemp);
207         return;
208     }
209     memcpy(stTemp->desc, descriptor, total);
210
211     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "result[%d] format[%d] total[%d]", result, format, total);
212     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "characteristic [%s]", (const char *) characteristic);
213
214
215     bt_gatt_clone_attribute_handle(&(stTemp->characteristic), characteristic);
216     stTemp->total = total;
217
218     ca_mutex_lock(g_bleClientThreadPoolMutex);
219     if (NULL == g_bleClientThreadPool)
220     {
221         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
222         bt_gatt_destroy_attribute_handle(stTemp->characteristic);
223         OICFree(stTemp->desc);
224         OICFree(stTemp);
225         ca_mutex_unlock(g_bleClientThreadPoolMutex);
226         return;
227     }
228
229     CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
230                                             CASetCharacteristicDescriptorValueThread,
231                                             stTemp);
232     if (CA_STATUS_OK != ret)
233     {
234         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed");
235         bt_gatt_destroy_attribute_handle(stTemp->characteristic);
236         OICFree(stTemp->desc);
237         OICFree(stTemp);
238         ca_mutex_unlock(g_bleClientThreadPoolMutex);
239         return;
240     }
241
242     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG,
243             "LE Client initialization flow complete");
244
245     ca_mutex_unlock(g_bleClientThreadPoolMutex);
246
247     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
248 }
249
250 bool CABleGattCharacteristicsDiscoveredCb(int result,
251         int inputIndex, int total,
252         bt_gatt_attribute_h characteristic, void *userData)
253 {
254
255     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
256
257     VERIFY_NON_NULL_RET(characteristic, TZ_BLE_CLIENT_TAG, "Param characteristic is NULL", false);
258
259     VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
260
261     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
262               "result [%d] input_index [%d] total [%d]",
263               result, inputIndex, total);
264
265     BLEServiceInfo *bleServiceInfo = NULL;
266
267     ca_mutex_lock(g_bleServiceListMutex);
268
269     char *bdAddress = (char *) userData;
270     CAGetBLEServiceInfo(g_bLEServiceList, bdAddress, &bleServiceInfo);
271
272     ca_mutex_unlock(g_bleServiceListMutex);
273
274     char *uuid = NULL;
275     bt_gatt_get_service_uuid(characteristic, &uuid);
276
277     VERIFY_NON_NULL_RET(uuid, TZ_BLE_CLIENT_TAG, "uuid is NULL", false);
278
279     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "New Characteristics[%s] of uuid[%s] is obtained",
280               (char *)characteristic, uuid);
281
282     if(0 == strcasecmp(uuid, CA_BLE_READ_CHAR_UUID)) // Server will read on this characterisctics
283     {
284         OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Read characteristics is obtained");
285         OICFree(uuid);
286         CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_READ_CHAR, bleServiceInfo);
287         if (CA_STATUS_OK != retVal)
288         {
289             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed! ");
290             return false;
291         }
292
293         stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
294                                                                       sizeof(stGattServiceInfo_t));
295
296         VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "calloc failed!", false);
297
298         stTemp->address = OICStrdup(bdAddress);
299         if (NULL == stTemp->address)
300         {
301             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
302             OICFree(stTemp);
303             return false;
304         }
305
306         bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), characteristic);
307
308         ca_mutex_lock(g_bleClientThreadPoolMutex);
309         if (NULL == g_bleClientThreadPool)
310         {
311             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
312             bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
313             OICFree(stTemp->address);
314             OICFree(stTemp);
315             ca_mutex_unlock(g_bleClientThreadPoolMutex);
316             return false;
317         }
318
319         retVal = ca_thread_pool_add_task(g_bleClientThreadPool,
320                                         CADiscoverDescriptorThread,
321                                         stTemp);
322         if (CA_STATUS_OK != retVal)
323         {
324             OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
325                       "ca_thread_pool_add_task failed with ret [%d]", retVal);
326             bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
327             OICFree(stTemp->address);
328             OICFree(stTemp);
329             ca_mutex_unlock(g_bleClientThreadPoolMutex);
330             return false;
331         }
332         ca_mutex_unlock(g_bleClientThreadPoolMutex);
333     }
334     else if (0 == strcasecmp(uuid, CA_BLE_WRITE_CHAR_UUID)) // Server will write on this characteristics.
335     {
336         OICFree(uuid);
337         OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Write characteristics is obtained");
338         CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_WRITE_CHAR, bleServiceInfo);
339         if (CA_STATUS_OK != retVal)
340         {
341             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed ");
342             return false;
343         }
344     }
345     else
346     {
347         OICFree(uuid);
348         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "service_uuid characteristics is UNKNOWN");
349         return false;
350     }
351
352     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
353     return true;
354 }
355
356 bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int index, int count,
357                                void *userData)
358 {
359     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
360
361     VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "Param service is NULL", false);
362
363     VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
364
365     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s] index [%d] count [%d]", (char *)service,
366               index, count);
367
368     CAResult_t result = CAVerifyOICServiceByServiceHandle(service);
369
370     if (CA_STATUS_OK == result)
371     {
372         OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
373
374         OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes");
375
376         result = CABleGattWatchCharacteristicChanges(service);
377         if (CA_STATUS_OK != result)
378         {
379             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
380                       "CABleGattWatchCharacteristicChanges failed!");
381             return false;
382         }
383
384         stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
385                                                                       sizeof(stGattServiceInfo_t));
386         VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "Calloc Failed", false);
387
388         char *bdAddress = (char *)userData;
389
390         stTemp->address = OICStrdup(bdAddress);
391         if (NULL == stTemp->address)
392         {
393             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
394             OICFree(stTemp);
395             return false;
396         }
397
398         BLEServiceInfo *bleServiceInfo = NULL;
399
400         result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo);
401         if (CA_STATUS_OK != result)
402         {
403             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CACreateBLEServiceInfo failed! ");
404             OICFree(stTemp->address);
405             OICFree(stTemp);
406             OICFree(bleServiceInfo);
407             return false;
408         }
409         if (NULL == bleServiceInfo )
410         {
411             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , " bleServiceInfo is NULL");
412             OICFree(stTemp->address);
413             OICFree(stTemp);
414             OICFree(bleServiceInfo);
415             return false;
416         }
417
418         OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG ,
419                   " serviceInfo remote address [%s]", bleServiceInfo->bdAddress);
420
421         ca_mutex_lock(g_bleServiceListMutex);
422         result = CAAddBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo);
423         ca_mutex_unlock(g_bleServiceListMutex);
424         if (CA_STATUS_OK != result)
425         {
426             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAddBLEServiceInfoToList failed!");
427             OICFree(stTemp->address);
428             OICFree(stTemp);
429             CAFreeBLEServiceInfo(bleServiceInfo);
430             return false;
431         }
432
433
434         ca_mutex_lock(g_bleClientThreadPoolMutex);
435         if (NULL == g_bleClientThreadPool)
436         {
437             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
438             OICFree(stTemp->address);
439             OICFree(stTemp);
440             ca_mutex_lock(g_bleServiceListMutex);
441             CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
442                                          bleServiceInfo->bdAddress);
443             ca_mutex_unlock(g_bleServiceListMutex);
444             ca_mutex_unlock(g_bleClientThreadPoolMutex);
445             return false;
446         }
447         bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), service);
448
449         result = ca_thread_pool_add_task(g_bleClientThreadPool,
450                                         CADiscoverCharThread,
451                                         stTemp);
452         if (CA_STATUS_OK != result)
453         {
454             OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
455                       "ca_thread_pool_add_task failed with ret [%d]", result);
456             OICFree(stTemp->address);
457             OICFree(stTemp);
458             ca_mutex_lock(g_bleServiceListMutex);
459             CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
460                                          bleServiceInfo->bdAddress);
461             ca_mutex_unlock(g_bleServiceListMutex);
462             ca_mutex_unlock(g_bleClientThreadPoolMutex);
463             return false;
464         }
465         ca_mutex_unlock(g_bleClientThreadPoolMutex);
466     }
467
468     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
469     return true;;
470 }
471
472 void CABleGattConnectionStateChangedCb(int result, bool connected,
473                                        const char *remoteAddress, void *userData)
474 {
475     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
476
477     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "CABleGattConnectionStateChangedCb result[%d] ", result);
478
479     VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
480
481     CAResult_t ret = CA_STATUS_FAILED;
482     if (!connected)
483     {
484         OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress);
485
486         ret = CABleGattStartDeviceDiscovery();
487         if (CA_STATUS_OK != ret)
488         {
489             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattStartDeviceDiscovery failed");
490             return;
491         }
492     }
493     else
494     {
495         OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Connected to [%s] ", remoteAddress);
496
497         ca_mutex_lock(g_bleServerBDAddressMutex);
498
499         g_remoteAddress = OICStrdup(remoteAddress);
500
501         ca_mutex_unlock(g_bleServerBDAddressMutex);
502
503         VERIFY_NON_NULL_VOID(g_remoteAddress, TZ_BLE_CLIENT_TAG, "Malloc failed");
504
505         char *addr = OICStrdup(remoteAddress);
506
507         ca_mutex_lock(g_bleClientThreadPoolMutex);
508         if (NULL == g_bleClientThreadPool)
509         {
510             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
511             OICFree(addr);
512
513             ca_mutex_lock(g_bleServerBDAddressMutex);
514             OICFree(g_remoteAddress);
515             ca_mutex_unlock(g_bleServerBDAddressMutex);
516
517             ca_mutex_unlock(g_bleClientThreadPoolMutex);
518             return;
519         }
520
521         ret = ca_thread_pool_add_task(g_bleClientThreadPool, CADiscoverBLEServicesThread,
522                                      addr);
523         if (CA_STATUS_OK != ret)
524         {
525             OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
526             OICFree(addr);
527
528             ca_mutex_lock(g_bleServerBDAddressMutex);
529             OICFree(g_remoteAddress);
530             ca_mutex_unlock(g_bleServerBDAddressMutex);
531
532             ca_mutex_unlock(g_bleClientThreadPoolMutex);
533             return;
534         }
535         ca_mutex_unlock(g_bleClientThreadPoolMutex);
536     }
537
538     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
539 }
540
541 void CABtAdapterLeDeviceDiscoveryStateChangedCb(int result,
542         bt_adapter_le_device_discovery_state_e discoveryState,
543         bt_adapter_le_device_discovery_info_s *discoveryInfo,
544         void *userData)
545 {
546     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
547
548     if (NULL  == discoveryInfo && BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND == discoveryState)
549     {
550         OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL");
551         return;
552     }
553
554     if (BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND != discoveryState)
555     {
556         OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
557                   " LE Discovery state is [%s]",
558           discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished");
559     }
560     else
561     {
562         CAPrintDiscoveryInformation(discoveryInfo);
563
564         if (discoveryInfo->service_uuid == NULL)
565         {
566             OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "NO UUIDS from device");
567         }
568         else
569         {
570             for (int32_t i = discoveryInfo->service_count - 1; i >= 0; i--)
571             {
572                 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "uuid[%d]: [%s]",
573                           i, discoveryInfo->service_uuid[i]);
574                 CAResult_t res = CAVerifyOICServiceByUUID(discoveryInfo->service_uuid[i]);
575                 if (CA_STATUS_OK == res)
576                 {
577                     char *addr = OICStrdup(discoveryInfo->remote_address);
578                     VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
579
580                     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
581                               "Trying to do Gatt connection to [%s]", addr);
582
583                     ca_mutex_lock(g_bleClientThreadPoolMutex);
584                     if (NULL == g_bleClientThreadPool)
585                     {
586                         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
587                         OICFree(addr);
588                         ca_mutex_unlock(g_bleClientThreadPoolMutex);
589                         return;
590                     }
591
592                     CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
593                                                   CAGattConnectThread, addr);
594                     if (CA_STATUS_OK != ret)
595                     {
596                         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
597                                   "ca_thread_pool_add_task failed with ret [%d]", ret);
598                         OICFree(addr);
599                         ca_mutex_unlock(g_bleClientThreadPoolMutex);
600                         return;
601                     }
602                     ca_mutex_unlock(g_bleClientThreadPoolMutex);
603                     if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31)
604                     {
605                         bt_adapter_le_stop_device_discovery();
606                         return;
607                     }
608                     break;  // Found the OIC Service. No need to verify remaining services.
609                 }
610             }
611         }
612     }
613     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
614 }
615
616
617 void CAPrintDiscoveryInformation(const bt_adapter_le_device_discovery_info_s *discoveryInfo)
618 {
619     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
620
621     if (NULL == discoveryInfo)
622     {
623         OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL ");
624         return;
625     }
626
627     if (discoveryInfo->remote_address)
628     {
629         OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Remote Address [%s]", discoveryInfo->remote_address);
630     }
631
632     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
633               " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
634               discoveryInfo->adv_data_len, discoveryInfo->scan_data_len, discoveryInfo->rssi,
635               discoveryInfo->address_type);
636     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
637               " Number of services present in device [%s] is [%d]",
638               discoveryInfo->remote_address, discoveryInfo->service_count);
639
640     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
641 }
642
643 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
644 {
645     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
646
647     ca_mutex_lock(g_bleClientThreadPoolMutex);
648     g_bleClientThreadPool = handle;
649     ca_mutex_unlock(g_bleClientThreadPoolMutex);
650
651     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
652 }
653
654 void CASetLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
655 {
656     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
657
658     ca_mutex_lock(g_bleReqRespClientCbMutex);
659
660     g_bleClientDataReceivedCallback = callback;
661
662     ca_mutex_unlock(g_bleReqRespClientCbMutex);
663
664     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
665 }
666
667
668 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
669 {
670     g_clientErrorCallback = callback;
671 }
672
673 CAResult_t CAStartLEGattClient()
674 {
675     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
676
677     CAResult_t retVal = CAInitGattClientMutexVariables();
678
679     if (CA_STATUS_OK != retVal)
680     {
681         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAInitGattClientMutexVariables failed!");
682         CATerminateGattClientMutexVariables();
683         return CA_STATUS_FAILED;
684     }
685
686     ca_mutex_lock(g_bleClientThreadPoolMutex);
687     if (NULL == g_bleClientThreadPool)
688     {
689         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleServerThreadPool is NULL");
690         CATerminateGattClientMutexVariables();
691         ca_mutex_unlock(g_bleClientThreadPoolMutex);
692         return CA_STATUS_FAILED;
693     }
694
695     retVal = ca_thread_pool_add_task(g_bleClientThreadPool, CAStartBleGattClientThread,
696                                      NULL);
697     if (CA_STATUS_OK != retVal)
698     {
699         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed");
700         CATerminateGattClientMutexVariables();
701         ca_mutex_unlock(g_bleClientThreadPoolMutex);
702         return CA_STATUS_FAILED;
703     }
704     ca_mutex_unlock(g_bleClientThreadPoolMutex);
705
706     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
707     return CA_STATUS_OK;
708 }
709
710 void CAStartBleGattClientThread(void *data)
711 {
712     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
713
714     ca_mutex_lock(g_bleClientStateMutex);
715
716     if (true  == g_isBleGattClientStarted)
717     {
718         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is already running!!");
719         ca_mutex_unlock(g_bleClientStateMutex);
720         return;
721     }
722
723     CAResult_t  ret = CABleGattSetScanParameter();
724     if (CA_STATUS_OK != ret)
725     {
726         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleSetScanParameter Failed");
727         ca_mutex_unlock(g_bleClientStateMutex);
728         CATerminateLEGattClient();
729         return;
730     }
731
732     ret = CABleGattSetCallbacks();
733     if (CA_STATUS_OK != ret)
734     {
735         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattSetCallbacks Failed");
736         ca_mutex_unlock(g_bleClientStateMutex);
737         CATerminateLEGattClient();
738         return;
739     }
740
741     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Starting LE device discovery");
742
743     ret = CABleGattStartDeviceDiscovery();
744     if (CA_STATUS_OK != ret)
745     {
746         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed");
747         ca_mutex_unlock(g_bleClientStateMutex);
748         CATerminateLEGattClient();
749         return;
750     }
751
752     g_isBleGattClientStarted = true;
753
754     ca_mutex_unlock(g_bleClientStateMutex);
755
756     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Giveing the control to threadPool");
757
758     GMainContext *thread_context = g_main_context_new();
759
760     g_eventLoop = g_main_loop_new(thread_context, FALSE);
761
762     g_main_context_push_thread_default(thread_context);
763
764     g_main_loop_run(g_eventLoop);
765
766     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
767 }
768
769 void CAStopLEGattClient()
770 {
771     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
772
773     ca_mutex_lock(g_bleClientStateMutex);
774
775     if (false == g_isBleGattClientStarted)
776     {
777         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is not running to stop");
778         ca_mutex_unlock(g_bleClientStateMutex);
779         return;
780     }
781
782     CABleGattUnSetCallbacks();
783
784     CABleGattUnWatchCharacteristicChanges();
785
786     CABleGattStopDeviceDiscovery();
787
788     g_isBleGattClientStarted = false;
789
790     GMainContext  *context_event_loop = NULL;
791     // Required for waking up the thread which is running in gmain loop
792     if (NULL != g_eventLoop)
793     {
794         context_event_loop = g_main_loop_get_context(g_eventLoop);
795     }
796     if (context_event_loop)
797     {
798         OIC_LOG_V(DEBUG,  TZ_BLE_CLIENT_TAG, "g_eventLoop context %x", context_event_loop);
799         g_main_context_wakeup(context_event_loop);
800
801         // Kill g main loops and kill threads.
802         g_main_loop_quit(g_eventLoop);
803     }
804     else
805     {
806         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_eventLoop context is NULL");
807     }
808
809     ca_mutex_unlock(g_bleClientStateMutex);
810
811     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
812 }
813
814 void CATerminateLEGattClient()
815 {
816     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
817     ca_mutex_lock(g_bleClientStateMutex);
818
819     ca_mutex_lock(g_bleServerBDAddressMutex);
820
821     OICFree(g_remoteAddress);
822
823     ca_mutex_unlock(g_bleServerBDAddressMutex);
824
825     ca_mutex_lock(g_bleServiceListMutex);
826     CAFreeBLEServiceList(g_bLEServiceList);
827     g_bLEServiceList = NULL;
828     ca_mutex_unlock(g_bleServiceListMutex);
829
830     CAResetRegisteredServiceCount();
831
832     ca_mutex_unlock(g_bleClientStateMutex);
833
834     CATerminateGattClientMutexVariables();
835
836     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
837 }
838
839 CAResult_t CAInitGattClientMutexVariables()
840 {
841     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
842     if (NULL == g_bleClientStateMutex)
843     {
844         g_bleClientStateMutex = ca_mutex_new();
845         if (NULL == g_bleClientStateMutex)
846         {
847             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
848             return CA_STATUS_FAILED;
849         }
850     }
851
852     if (NULL == g_bleServiceListMutex)
853     {
854         g_bleServiceListMutex = ca_mutex_new();
855         if (NULL == g_bleServiceListMutex)
856         {
857             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
858             return CA_STATUS_FAILED;
859         }
860     }
861
862     if (NULL == g_bleReqRespClientCbMutex)
863     {
864         g_bleReqRespClientCbMutex = ca_mutex_new();
865         if (NULL == g_bleReqRespClientCbMutex)
866         {
867             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
868             return CA_STATUS_FAILED;
869         }
870     }
871
872     if (NULL == g_bleClientThreadPoolMutex)
873     {
874         g_bleClientThreadPoolMutex = ca_mutex_new();
875         if (NULL == g_bleClientThreadPoolMutex)
876         {
877             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
878             return CA_STATUS_FAILED;
879         }
880     }
881
882     if (NULL == g_bleClientConnectMutex)
883     {
884         g_bleClientConnectMutex = ca_mutex_new();
885         if (NULL == g_bleClientConnectMutex)
886         {
887             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
888             return CA_STATUS_FAILED;
889         }
890     }
891
892     if (NULL == g_bleClientSendCondWait)
893     {
894         g_bleClientSendCondWait = ca_cond_new();
895         if (NULL == g_bleClientSendCondWait)
896         {
897             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_cond_new failed");
898             return CA_STATUS_FAILED;
899         }
900     }
901
902     if (NULL == g_bleServerBDAddressMutex)
903     {
904         g_bleServerBDAddressMutex = ca_mutex_new();
905         if (NULL == g_bleServerBDAddressMutex)
906         {
907             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
908             return CA_STATUS_FAILED;
909         }
910     }
911
912     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
913     return CA_STATUS_OK;
914 }
915
916 void CATerminateGattClientMutexVariables()
917 {
918     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
919
920     ca_mutex_free(g_bleClientStateMutex);
921     g_bleClientStateMutex = NULL;
922
923     ca_mutex_free(g_bleServiceListMutex);
924     g_bleServiceListMutex = NULL;
925
926     ca_mutex_free(g_bleReqRespClientCbMutex);
927     g_bleReqRespClientCbMutex = NULL;
928
929     ca_mutex_free(g_bleClientConnectMutex);
930     g_bleClientConnectMutex = NULL;
931
932     ca_mutex_free(g_bleClientThreadPoolMutex);
933     g_bleClientThreadPoolMutex = NULL;
934
935     ca_mutex_free(g_bleServerBDAddressMutex);
936     g_bleServerBDAddressMutex = NULL;
937
938     ca_cond_free(g_bleClientSendCondWait);
939     g_bleClientSendCondWait = NULL;
940
941
942     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
943 }
944
945 CAResult_t CABleGattSetScanParameter()
946 {
947     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
948
949     bt_adapter_le_scan_params_s scan_param = { 0, };
950     scan_param.type = BT_ADAPTER_LE_PASSIVE_SCAN;
951     scan_param.interval = 1560;
952     scan_param.window = 160;
953
954     int ret = bt_adapter_le_set_scan_parameter(&scan_param);
955     if (BT_ERROR_NONE != ret)
956     {
957         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_set_scan_parameter Failed with ret [%d]", ret);
958         return CA_STATUS_FAILED;
959     }
960
961     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
962     return CA_STATUS_OK;
963 }
964
965 CAResult_t CABleGattSetCallbacks()
966 {
967     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
968
969     int ret = bt_gatt_set_connection_state_changed_cb(CABleGattConnectionStateChangedCb, NULL);
970     if (BT_ERROR_NONE != ret)
971     {
972         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
973                   "bt_gatt_set_connection_state_changed_cb Failed with return as [%s ]",
974                   CABTGetErrorMsg(ret));
975         return CA_STATUS_FAILED;
976     }
977
978     ret = bt_adapter_le_set_device_discovery_state_changed_cb(
979               CABtAdapterLeDeviceDiscoveryStateChangedCb, NULL);
980     if (BT_ERROR_NONE != ret)
981     {
982         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
983                   "bt_adapter_le_set_device_discovery_state_changed_cb Failed with return as [%s ]",
984                   CABTGetErrorMsg(ret));;
985         return CA_STATUS_FAILED;
986     }
987
988     ret = bt_gatt_set_characteristic_changed_cb(CABleGattCharacteristicChangedCb, NULL);
989     if (BT_ERROR_NONE != ret)
990     {
991         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_set_characteristic_changed_cb Failed as [%s ]",
992                   CABTGetErrorMsg(ret));
993         return CA_STATUS_FAILED;
994     }
995
996     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
997     return CA_STATUS_OK;
998 }
999
1000 void CABleGattUnSetCallbacks()
1001 {
1002     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1003
1004     bt_gatt_unset_characteristic_changed_cb();
1005
1006     bt_gatt_unset_connection_state_changed_cb();
1007
1008     bt_adapter_le_unset_device_discovery_state_changed_cb();
1009
1010     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1011 }
1012
1013 CAResult_t CABleGattWatchCharacteristicChanges(bt_gatt_attribute_h service)
1014 {
1015     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1016
1017     int ret = bt_gatt_watch_characteristic_changes(service);
1018     if (BT_ERROR_NONE != ret)
1019     {
1020         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1021                   "bt_gatt_watch_characteristic_changes failed  with [%s]",
1022                   CABTGetErrorMsg(ret));
1023
1024         return CA_STATUS_FAILED;
1025     }
1026
1027     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1028     return CA_STATUS_OK;
1029 }
1030
1031 void CABleGattUnWatchCharacteristicChanges()
1032 {
1033     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1034
1035     int32_t count = CAGetRegisteredServiceCount();
1036
1037     for (int32_t index = 0; index < count; index++)
1038     {
1039         BLEServiceInfo *bleServiceInfo = NULL;
1040
1041         ca_mutex_lock(g_bleServiceListMutex);
1042
1043         CAResult_t  result = CAGetBLEServiceInfoByPosition(g_bLEServiceList, index, &bleServiceInfo);
1044         if (CA_STATUS_OK == result && NULL != bleServiceInfo
1045             && NULL != bleServiceInfo->service_clone)
1046         {
1047             bt_gatt_unwatch_characteristic_changes(bleServiceInfo->service_clone);
1048             OIC_LOG(INFO, TZ_BLE_CLIENT_TAG, "bt_gatt_unwatch_characteristic_changes done");
1049         }
1050
1051         ca_mutex_unlock(g_bleServiceListMutex);
1052     }
1053
1054     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1055 }
1056
1057 CAResult_t CABleGattStartDeviceDiscovery()
1058 {
1059     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1060     bool isDiscovering = false;
1061
1062     int ret = bt_adapter_le_is_discovering(&isDiscovering);
1063     if (BT_ERROR_NONE != ret)
1064     {
1065         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_is_discovering Failed");
1066         return CA_STATUS_FAILED;
1067     }
1068
1069     if(!isDiscovering)
1070     {
1071         ret = bt_adapter_le_start_device_discovery();
1072         if (BT_ERROR_NONE != ret)
1073         {
1074             OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed Ret: %d, %x", ret, ret);
1075             return CA_STATUS_FAILED;
1076         }
1077     }
1078
1079     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1080     return CA_STATUS_OK;
1081 }
1082
1083 void CABleGattStopDeviceDiscovery()
1084 {
1085     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1086
1087     bool isDiscovering = false;
1088
1089     int ret = bt_adapter_le_is_discovering(&isDiscovering);
1090     if (BT_ERROR_NONE != ret)
1091     {
1092         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_is_discovering Failed");
1093         return;
1094     }
1095
1096     if(isDiscovering)
1097     {
1098         ret = bt_adapter_le_stop_device_discovery();
1099         if (BT_ERROR_NONE != ret)
1100         {
1101             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_stop_device_discovery Failed");
1102             return;
1103         }
1104     }
1105
1106     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1107 }
1108
1109 void CAGattConnectThread (void *remoteAddress)
1110 {
1111     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
1112
1113     VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1114
1115     char *address  = (char *)remoteAddress;
1116
1117     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address is [%s]", address);
1118
1119     CAResult_t result = CABleGattConnect(address);
1120
1121     if (CA_STATUS_OK != result)
1122     {
1123         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect failed for [%s]", address);
1124     }
1125
1126     OICFree(address);
1127
1128     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1129 }
1130
1131 CAResult_t CABleGattConnect(const char *remoteAddress)
1132 {
1133     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1134
1135     VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1136                         "remote address is NULL", CA_STATUS_FAILED);
1137
1138     //Because of the platform issue, we added. Once platform is stablized, then it will be removed
1139     sleep(1);
1140
1141     ca_mutex_lock(g_bleClientConnectMutex);
1142
1143     int ret = bt_gatt_connect(remoteAddress, true);
1144
1145     if (BT_ERROR_NONE != ret)
1146     {
1147         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect Failed with ret value [%s] ",
1148                   CABTGetErrorMsg(ret));
1149         ca_mutex_unlock(g_bleClientConnectMutex);
1150         return CA_STATUS_FAILED;
1151     }
1152     ca_mutex_unlock(g_bleClientConnectMutex);
1153
1154     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1155     return CA_STATUS_OK;
1156 }
1157
1158 CAResult_t CABleGattDisConnect(const char *remoteAddress)
1159 {
1160     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1161
1162     VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1163                         "remote address is NULL", CA_STATUS_FAILED);
1164
1165     int32_t ret = bt_gatt_disconnect(remoteAddress);
1166
1167     if (BT_ERROR_NONE != ret)
1168     {
1169         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_disconnect Failed with ret value [%d] ",
1170                   ret);
1171         return CA_STATUS_FAILED;
1172     }
1173
1174     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1175     return CA_STATUS_OK;
1176 }
1177
1178 void CADiscoverBLEServicesThread (void *remoteAddress)
1179 {
1180     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1181
1182     VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1183
1184     char *address  = (char *)remoteAddress;
1185
1186     CAResult_t result = CABleGattDiscoverServices(address);
1187     if (CA_STATUS_OK != result)
1188     {
1189         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattDiscoverServices failed");
1190     }
1191
1192     OICFree(address);
1193
1194     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1195 }
1196
1197 CAResult_t CABleGattDiscoverServices(const char *remoteAddress)
1198 {
1199     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1200
1201     VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1202                         "remote address is NULL", CA_STATUS_FAILED);
1203
1204     char *addr = OICStrdup(remoteAddress);
1205     VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
1206
1207     int32_t ret = bt_gatt_foreach_primary_services(remoteAddress, CABleGattPrimaryServiceCb,
1208                   (void *)addr); // addr memory will be free in callback.
1209     if (BT_ERROR_NONE != ret)
1210     {
1211         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1212                   "bt_gatt_foreach_primary_services Failed with ret value [%d] ", ret);
1213         OICFree(addr);
1214         return CA_STATUS_FAILED;
1215     }
1216     else
1217     {
1218         OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
1219                   "bt_gatt_foreach_primary_services success for address [%s]", remoteAddress);
1220     }
1221
1222     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1223     return CA_STATUS_OK;
1224 }
1225
1226 void CADiscoverCharThread(void *stServiceInfo)
1227 {
1228     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1229
1230     VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1231
1232     stGattServiceInfo_t *stTemp  = (stGattServiceInfo_t *)stServiceInfo;
1233
1234     VERIFY_NON_NULL_VOID(stTemp->address, TZ_BLE_CLIENT_TAG, "stTemp->address is NULL");
1235
1236     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]", stTemp->address);
1237
1238     CAResult_t  result = CABleGattDiscoverCharacteristics(stTemp->serviceInfo, stTemp->address);
1239     if (CA_STATUS_OK != result)
1240     {
1241         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CABleGattDiscoverCharacteristics failed!");
1242         bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1243         OICFree(stTemp->address);
1244         OICFree(stTemp);
1245         return;
1246     }
1247     bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1248     OICFree(stTemp->address);
1249     OICFree(stTemp);
1250
1251     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1252 }
1253
1254 CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service,
1255         const char *remoteAddress)
1256 {
1257     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1258
1259     VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "service is NULL", CA_STATUS_FAILED);
1260
1261     VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG, "remoteAddress is NULL", CA_STATUS_FAILED);
1262
1263     char *addr = OICStrdup(remoteAddress);
1264     VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
1265
1266     int32_t ret = bt_gatt_discover_characteristics(service, CABleGattCharacteristicsDiscoveredCb,
1267                   (void *)addr); // addr will be freed in callback.
1268     if (BT_ERROR_NONE != ret)
1269     {
1270         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1271                   "bt_gatt_discover_characteristics failed with error [%d]", ret);
1272         OICFree(addr);
1273         return CA_STATUS_FAILED;
1274     }
1275
1276     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1277     return CA_STATUS_OK;
1278 }
1279
1280 void CADiscoverDescriptorThread(void *stServiceInfo)
1281 {
1282     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " IN");
1283
1284     VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1285
1286     stGattServiceInfo_t *stTemp  = (stGattServiceInfo_t *)stServiceInfo;
1287
1288     CAResult_t result = CABleGattDiscoverDescriptor(stTemp->serviceInfo, NULL);
1289     if (CA_STATUS_OK != result)
1290     {
1291         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
1292                   "bt_gatt_discover_characteristic_descriptor failed");
1293         bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1294         OICFree(stTemp->address);
1295         OICFree(stTemp);
1296         return;
1297     }
1298
1299     bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1300     OICFree(stTemp->address);
1301     OICFree(stTemp);
1302
1303     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1304 }
1305
1306 CAResult_t CABleGattDiscoverDescriptor(bt_gatt_attribute_h service, const char *remoteAddress)
1307 {
1308     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1309
1310     VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "service is NULL", CA_STATUS_FAILED);
1311
1312     int ret = bt_gatt_discover_characteristic_descriptor(service,
1313                   CABleGattDescriptorDiscoveredCb, NULL);
1314     if (BT_ERROR_NONE != ret)
1315     {
1316         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1317                   "bt_gatt_discover_characteristic_descriptor failed with returns[%s]",
1318                   CABTGetErrorMsg(ret));
1319         return CA_STATUS_FAILED;
1320     }
1321
1322     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1323     return CA_STATUS_OK;
1324 }
1325
1326 void CASetCharacteristicDescriptorValueThread(void *stServiceInfo)
1327 {
1328     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1329
1330     VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1331
1332     stGattCharDescriptor_t *stTemp  = (stGattCharDescriptor_t *)stServiceInfo;
1333
1334     CAResult_t  result = CASetCharacteristicDescriptorValue(stTemp);
1335     if (CA_STATUS_OK != result)
1336     {
1337         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CASetCharacteristicDescriptorValue failed!");
1338         bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1339         OICFree(stTemp->desc);
1340         OICFree(stTemp);
1341         return;
1342     }
1343     bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1344     OICFree(stTemp->desc);
1345     OICFree(stTemp);
1346
1347     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1348 }
1349
1350 CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescInfo)
1351 {
1352     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1353
1354     unsigned char noti[4] = {0,};
1355
1356     char *strUUID = (char *)OICCalloc(5, sizeof(char));
1357
1358     VERIFY_NON_NULL_RET(strUUID, TZ_BLE_CLIENT_TAG, "calloc failed", CA_STATUS_FAILED);
1359
1360     snprintf(strUUID, 4, "%x%x", stGattCharDescInfo->desc[3], stGattCharDescInfo->desc[2]);
1361     noti[0] = stGattCharDescInfo->desc[0];
1362     noti[1] = stGattCharDescInfo->desc[1];
1363     noti[2] = 0x01;
1364     noti[3] = 0x00;
1365
1366     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x0 [%x]", stGattCharDescInfo->desc[0]);
1367     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x1 [%x]", stGattCharDescInfo->desc[1]);
1368     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x2 [%x]", stGattCharDescInfo->desc[2]);
1369     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x3 [%x]", stGattCharDescInfo->desc[3]);
1370
1371
1372     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG strUUID is [%s]",
1373               strUUID);
1374     //if (!strncmp(strUUID, BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG, 2))
1375     {
1376         OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "setting notification/indication for descriptor");
1377
1378         int ret =  bt_gatt_set_characteristic_desc_value_request(
1379                            stGattCharDescInfo->characteristic,
1380                            noti,  4, CABleGattCharacteristicWriteCb);
1381         if (BT_ERROR_NONE != ret)
1382         {
1383             OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1384                       "bt_gatt_set_characteristic_desc_value_request failed with return[%s]",
1385                       CABTGetErrorMsg(ret));
1386             OICFree(strUUID);
1387             return CA_STATUS_FAILED;
1388         }
1389     }
1390     OICFree(strUUID);
1391
1392     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1393     return CA_STATUS_OK;
1394 }
1395
1396 CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
1397         const char  *data, const uint32_t dataLen,
1398         CALETransferType_t type, const int32_t position)
1399 {
1400     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1401
1402     VERIFY_NON_NULL(data, TZ_BLE_CLIENT_TAG, "data is NULL");
1403
1404     if (0 >= dataLen)
1405     {
1406         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input!");
1407         return CA_STATUS_INVALID_PARAM;
1408     }
1409
1410     BLEServiceInfo *bleServiceInfo = NULL;
1411
1412     CAResult_t ret =  CA_STATUS_FAILED;
1413
1414     ca_mutex_lock(g_bleServiceListMutex);
1415     if ( LE_UNICAST == type)
1416     {
1417         VERIFY_NON_NULL(remoteAddress, TZ_BLE_CLIENT_TAG, "remoteAddress is NULL");
1418
1419         ret = CAGetBLEServiceInfo(g_bLEServiceList, remoteAddress, &bleServiceInfo);
1420     }
1421     else if ( LE_MULTICAST == type)
1422     {
1423         ret = CAGetBLEServiceInfoByPosition(g_bLEServiceList, position, &bleServiceInfo);
1424     }
1425     ca_mutex_unlock(g_bleServiceListMutex);
1426
1427     if (CA_STATUS_OK != ret)
1428     {
1429         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAGetBLEServiceInfoByPosition is failed");
1430         return CA_STATUS_FAILED;
1431     }
1432
1433     VERIFY_NON_NULL(bleServiceInfo, TZ_BLE_CLIENT_TAG, "bleServiceInfo is NULL");
1434
1435     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating the data of length [%d] to [%s] ", dataLen,
1436               bleServiceInfo->bdAddress);
1437
1438     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating to write char [%s]",
1439               bleServiceInfo->read_char);
1440
1441     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
1442               "Updating the data of length [%d] to [%s]", dataLen,
1443               bleServiceInfo->bdAddress);
1444
1445     int result = bt_gatt_set_characteristic_value(bleServiceInfo->write_char, (unsigned char *)data,
1446                      dataLen);
1447     if (BT_ERROR_NONE != result)
1448     {
1449         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1450                   "bt_gatt_set_characteristic_value Failed with return val [%d]",
1451                   result);
1452         return CA_STATUS_FAILED;
1453     }
1454
1455     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1456     return CA_STATUS_OK;
1457 }
1458
1459 CAResult_t  CAUpdateCharacteristicsToAllGattServers(const char  *data,
1460             uint32_t dataLen)
1461 {
1462     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
1463
1464     VERIFY_NON_NULL(data, TZ_BLE_CLIENT_TAG, "data is NULL");
1465
1466     if (0 >= dataLen)
1467     {
1468         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input !");
1469         return CA_STATUS_INVALID_PARAM;
1470     }
1471
1472     int numOfServersConnected = CAGetRegisteredServiceCount();
1473
1474     for (int32_t pos = 0; pos < numOfServersConnected; pos++)
1475     {
1476         /*remoteAddress will be NULL.
1477           Since we have to send to all destinations. pos will be used for getting remote address.
1478          */
1479         CAResult_t  ret = CAUpdateCharacteristicsToGattServer(NULL, data, dataLen, LE_MULTICAST, pos);
1480
1481         if (CA_STATUS_OK != ret)
1482         {
1483             OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1484                       "CAUpdateCharacteristicsToGattServer Failed with return val [%d] ", ret);
1485             g_clientErrorCallback(NULL, data, dataLen, ret);
1486             continue;
1487         }
1488     }
1489
1490     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1491     return CA_STATUS_OK;
1492 }
1493
1494