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