1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
21 #include "cableclient.h"
28 #include<sys/socket.h>
29 #include<netinet/in.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"
42 * @def TZ_BLE_CLIENT_TAG
43 * @brief Logging tag for module name
45 #define TZ_BLE_CLIENT_TAG "TZ_BLE_GATT_CLIENT"
48 * @var BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG
49 * @brief Its the constant value for characteristic descriptor from spec.
51 #define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG "2902"
54 * @var g_bLEServiceList
55 * @brief This contains the list of OIC services a client connect tot.
57 static BLEServiceList *g_bLEServiceList = NULL;
60 * @var g_isBleGattClientStarted
61 * @brief Boolean variable to keep the state of the GATT Client.
63 static bool g_isBleGattClientStarted = false;
66 * @var g_bleServiceListMutex
67 * @brief Mutex to synchronize access to BleServiceList.
69 static ca_mutex g_bleServiceListMutex = NULL;
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.
76 static ca_mutex g_bleReqRespClientCbMutex = NULL;
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.
83 static ca_mutex g_bleClientConnectMutex = NULL;
87 * @var g_bleClientStateMutex
88 * @brief Mutex to synchronize the calls to be done to the platform from GATTClient
89 * interfaces from different threads.
91 static ca_mutex g_bleClientStateMutex = NULL;
94 * @var g_bleServerBDAddressMutex
95 * @brief Mutex to synchronize the Server BD Address update on client side.
97 static ca_mutex g_bleServerBDAddressMutex = NULL;
100 * @var g_bleClientSendCondWait
101 * @brief Condition used for notifying handler the presence of data in send queue.
103 static ca_cond g_bleClientSendCondWait = NULL;
106 * @var g_bleClientThreadPoolMutex
107 * @brief Mutex to synchronize the task to be pushed to thread pool.
109 static ca_mutex g_bleClientThreadPoolMutex = NULL;
112 * @var gNetworkPacketReceivedClientCallback
113 * @brief Maintains the callback to be notified on receival of network packets from other
116 static CABLEClientDataReceivedCallback g_bleClientDataReceivedCallback = NULL;
120 * @brief gmainLoop to manage the threads to receive the callback from the platfrom.
122 static GMainLoop *g_eventLoop = NULL;
125 * @var g_bleClientThreadPool
126 * @brief reference to threadpool
128 static ca_thread_pool_t g_bleClientThreadPool = NULL;
131 * @struct stGattServiceInfo_t
132 * @brief structure to map the service attribute to BD Address.
134 typedef struct gattService
136 bt_gatt_attribute_h serviceInfo; /**< bluetoth attribute for oic service*/
137 char *address; /**< BD Address of */
138 } stGattServiceInfo_t;
141 * @var g_remoteAddress
142 * @brief Remote address of Gatt Server
144 static char *g_remoteAddress = NULL;
146 void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic,
147 unsigned char *value,
148 int valueLen, void *userData)
150 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
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);
156 char *data = (char *)OICMalloc(sizeof(char) * (valueLen + 1));
159 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Malloc failed!");
163 strncpy(data, (char *)value, valueLen + 1);
165 ca_mutex_lock(g_bleReqRespClientCbMutex);
166 if (NULL == g_bleClientDataReceivedCallback)
168 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespCallback is NULL!");
169 ca_mutex_unlock(g_bleReqRespClientCbMutex);
173 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending data up !");
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);
180 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Sent data Length is %d", sentLength);
181 ca_mutex_unlock(g_bleServerBDAddressMutex);
183 ca_mutex_unlock(g_bleReqRespClientCbMutex);
187 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
191 void CABleGattCharacteristicWriteCb(int result, void *userData)
193 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
196 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
199 void CABleGattDescriptorDiscoveredCb(int result, unsigned char format, int total,
200 bt_gatt_attribute_h descriptor,
201 bt_gatt_attribute_h characteristic, void *userData)
203 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
205 stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)OICCalloc(1, sizeof(
206 stGattCharDescriptor_t));
208 VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed!");
210 stTemp->desc = (uint8_t *)OICMalloc(total);
211 if (NULL == stTemp->desc)
213 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "malloc failed");
217 memcpy(stTemp->desc, descriptor, total);
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);
223 bt_gatt_clone_attribute_handle(&(stTemp->characteristic), characteristic);
224 stTemp->total = total;
226 ca_mutex_lock(g_bleClientThreadPoolMutex);
227 if (NULL == g_bleClientThreadPool)
229 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
230 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
231 OICFree(stTemp->desc);
233 ca_mutex_unlock(g_bleClientThreadPoolMutex);
237 CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
238 CASetCharacteristicDescriptorValueThread,
240 if (CA_STATUS_OK != ret)
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);
246 ca_mutex_unlock(g_bleClientThreadPoolMutex);
250 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG,
251 "LE Client initialization flow complete");
253 ca_mutex_unlock(g_bleClientThreadPoolMutex);
255 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
258 bool CABleGattCharacteristicsDiscoveredCb(int result,
259 int inputIndex, int total,
260 bt_gatt_attribute_h characteristic, void *userData)
263 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
265 VERIFY_NON_NULL_RET(characteristic, TZ_BLE_CLIENT_TAG, "Param characteristic is NULL", false);
267 VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
269 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
270 "result [%d] input_index [%d] total [%d]",
271 result, inputIndex, total);
273 BLEServiceInfo *bleServiceInfo = NULL;
275 ca_mutex_lock(g_bleServiceListMutex);
277 char *bdAddress = (char *) userData;
278 CAGetBLEServiceInfo(g_bLEServiceList, bdAddress, &bleServiceInfo);
280 ca_mutex_unlock(g_bleServiceListMutex);
283 if (BLE_GATT_READ_CHAR_INDEX == inputIndex) // Server will read on this characteristics.
285 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "new read Characteristics is obtained [%s]",
286 (char *)characteristic);
288 CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_READ_CHAR, bleServiceInfo);
289 if (CA_STATUS_OK != retVal)
291 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed ");
296 bt_gatt_get_service_uuid(characteristic, &uuid);
297 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "new read Characteristics uuid is obtained [%s]",
300 else if (BLE_GATT_WRITE_CHAR_INDEX == inputIndex) // Server will write on this characterisctics
302 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "new write Characteristics is obtained [%s]",
303 (char *)characteristic);
305 CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_WRITE_CHAR, bleServiceInfo);
306 if (CA_STATUS_OK != retVal)
308 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed! ");
313 bt_gatt_get_service_uuid(characteristic, &uuid);
314 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "new write Characteristics uuid is obtained [%s]",
317 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
318 sizeof(stGattServiceInfo_t));
320 VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "calloc failed!", false);
322 size_t len = strlen(bdAddress);
323 stTemp->address = (char *)OICMalloc(sizeof(char) * (len + 1));
324 if (NULL == stTemp->address)
326 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
331 strncpy(stTemp->address, bdAddress, len + 1);
332 bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), characteristic);
334 ca_mutex_lock(g_bleClientThreadPoolMutex);
335 if (NULL == g_bleClientThreadPool)
337 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
338 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
339 OICFree(stTemp->address);
341 ca_mutex_unlock(g_bleClientThreadPoolMutex);
345 retVal = ca_thread_pool_add_task(g_bleClientThreadPool,
346 CADiscoverDescriptorThread,
348 if (CA_STATUS_OK != retVal)
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);
355 ca_mutex_unlock(g_bleClientThreadPoolMutex);
358 ca_mutex_unlock(g_bleClientThreadPoolMutex);
360 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
365 void CABtGattBondCreatedCb(int result, bt_device_info_s *device_info, void *user_data)
367 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
368 if (BT_ERROR_NONE != result)
370 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
371 " create_bond Failed as [%s ]", CABTGetErrorMsg(result));
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);
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");
384 BLEServiceInfo *bleServiceInfo = NULL;
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)
391 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAGetBLEServiceInfo failed! ");
395 VERIFY_NON_NULL_VOID(bleServiceInfo, TZ_BLE_CLIENT_TAG,
396 "bleServiceInfo is NULL");
398 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
400 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
401 "serviceInfo remote address [%s]", bleServiceInfo->bdAddress);
403 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
404 sizeof(stGattServiceInfo_t));
406 VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed");
408 bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), bleServiceInfo->service_clone);
410 size_t len = strlen(bleServiceInfo->bdAddress);
411 stTemp->address = (char *)OICMalloc(sizeof(char) * (len + 1));
412 if (NULL == stTemp->address)
414 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
415 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
420 strncpy(stTemp->address, bleServiceInfo->bdAddress, len + 1);
422 ca_mutex_lock(g_bleClientThreadPoolMutex);
423 if (NULL == g_bleClientThreadPool)
425 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
426 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
427 OICFree(stTemp->address);
429 ca_mutex_unlock(g_bleClientThreadPoolMutex);
433 CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
434 CADiscoverCharThread, stTemp);
435 if (CA_STATUS_OK != ret)
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);
442 ca_mutex_unlock(g_bleClientThreadPoolMutex);
445 ca_mutex_unlock(g_bleClientThreadPoolMutex);
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);
452 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
455 bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int index, int count,
458 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
460 VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "Param service is NULL", false);
462 VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
464 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s] index [%d] count [%d]", (char *)service,
467 CAResult_t result = CAVerifyOICServiceByServiceHandle(service);
469 if (CA_STATUS_OK == result)
471 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
473 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes \n");
475 result = CABleGattWatchCharacteristicChanges(service);
476 if (CA_STATUS_OK != result)
478 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
479 "CABleGattWatchCharacteristicChanges failed!");
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);
487 char *bdAddress = (char *)userData;
488 size_t len = strlen(bdAddress);
490 stTemp->address = (char *)OICMalloc(sizeof(char) * (len + 1));
491 if (NULL == stTemp->address)
493 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
498 strncpy(stTemp->address, bdAddress, len + 1);
500 BLEServiceInfo *bleServiceInfo = NULL;
502 result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo);
503 if (CA_STATUS_OK != result)
505 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CACreateBLEServiceInfo failed! ");
506 OICFree(stTemp->address);
508 OICFree(bleServiceInfo);
511 if (NULL == bleServiceInfo )
513 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , " bleServiceInfo is NULL");
514 OICFree(stTemp->address);
516 OICFree(bleServiceInfo);
520 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG ,
521 " serviceInfo remote address [%s]", bleServiceInfo->bdAddress);
523 ca_mutex_lock(g_bleServiceListMutex);
524 result = CAAddBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo);
525 ca_mutex_unlock(g_bleServiceListMutex);
526 if (CA_STATUS_OK != result)
528 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAddBLEServiceInfoToList failed!");
529 OICFree(stTemp->address);
531 CAFreeBLEServiceInfo(bleServiceInfo);
532 bleServiceInfo = NULL;
537 ca_mutex_lock(g_bleClientThreadPoolMutex);
538 if (NULL == g_bleClientThreadPool)
540 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
541 OICFree(stTemp->address);
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);
551 result = ca_thread_pool_add_task(g_bleClientThreadPool,
552 CAGATTCreateBondThread,
554 if (CA_STATUS_OK != result)
556 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
557 "ca_thread_pool_add_task failed with ret [%d]", result);
558 OICFree(stTemp->address);
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);
567 ca_mutex_unlock(g_bleClientThreadPoolMutex);
570 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
574 void CABleGattConnectionStateChangedCb(int result, bool connected,
575 const char *remoteAddress, void *userData)
577 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
579 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "CABleGattConnectionStateChangedCb result[%d] ", result);
581 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
583 CAResult_t ret = CA_STATUS_FAILED;
586 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress);
588 ret = CABleGattStartDeviceDiscovery();
589 if (CA_STATUS_OK != ret)
591 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattStartDeviceDiscovery failed");
597 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Connected to [%s] ", remoteAddress);
599 ca_mutex_lock(g_bleServerBDAddressMutex);
601 g_remoteAddress = OICStrdup(remoteAddress);
603 ca_mutex_unlock(g_bleServerBDAddressMutex);
605 VERIFY_NON_NULL_VOID(g_remoteAddress, TZ_BLE_CLIENT_TAG, "Malloc failed");
607 char *addr = OICStrdup(remoteAddress);
609 ca_mutex_lock(g_bleClientThreadPoolMutex);
610 if (NULL == g_bleClientThreadPool)
612 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
615 ca_mutex_lock(g_bleServerBDAddressMutex);
616 OICFree(g_remoteAddress);
617 ca_mutex_unlock(g_bleServerBDAddressMutex);
619 ca_mutex_unlock(g_bleClientThreadPoolMutex);
623 ret = ca_thread_pool_add_task(g_bleClientThreadPool, CADiscoverBLEServicesThread,
625 if (CA_STATUS_OK != ret)
627 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
630 ca_mutex_lock(g_bleServerBDAddressMutex);
631 OICFree(g_remoteAddress);
632 ca_mutex_unlock(g_bleServerBDAddressMutex);
634 ca_mutex_unlock(g_bleClientThreadPoolMutex);
637 ca_mutex_unlock(g_bleClientThreadPoolMutex);
640 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
643 void CABtAdapterLeDeviceDiscoveryStateChangedCb(int result,
644 bt_adapter_le_device_discovery_state_e discoveryState,
645 bt_adapter_le_device_discovery_info_s *discoveryInfo,
648 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
650 if (NULL == discoveryInfo && BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND == discoveryState)
652 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL");
656 if (BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND != discoveryState)
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");
664 CAPrintDiscoveryInformation(discoveryInfo);
666 if (discoveryInfo->service_uuid == NULL)
668 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "NO UUIDS from device");
672 for (int32_t i = discoveryInfo->service_count - 1; i > 0; i--)
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)
680 size_t len = strlen(discoveryInfo->remote_address);
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);
686 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
687 "Trying to do Gatt connection to [%s]", addr);
689 ca_mutex_lock(g_bleClientThreadPoolMutex);
690 if (NULL == g_bleClientThreadPool)
692 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
694 ca_mutex_unlock(g_bleClientThreadPoolMutex);
698 CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
699 CAGattConnectThread, addr);
700 if (CA_STATUS_OK != ret)
702 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
703 "ca_thread_pool_add_task failed with ret [%d]", ret);
705 ca_mutex_unlock(g_bleClientThreadPoolMutex);
708 ca_mutex_unlock(g_bleClientThreadPoolMutex);
709 if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31)
711 bt_adapter_le_stop_device_discovery();
714 break; // Found the OIC Service. No need to verify remaining services.
719 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
723 void CAPrintDiscoveryInformation(const bt_adapter_le_device_discovery_info_s *discoveryInfo)
725 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
727 if (NULL == discoveryInfo)
729 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL ");
733 if (discoveryInfo->remote_address)
735 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Remote Address [%s]", discoveryInfo->remote_address);
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);
746 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
749 void CASetBleClientThreadPoolHandle(ca_thread_pool_t handle)
751 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
753 ca_mutex_lock(g_bleClientThreadPoolMutex);
754 g_bleClientThreadPool = handle;
755 ca_mutex_unlock(g_bleClientThreadPoolMutex);
757 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
760 void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
762 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
764 ca_mutex_lock(g_bleReqRespClientCbMutex);
766 g_bleClientDataReceivedCallback = callback;
768 ca_mutex_unlock(g_bleReqRespClientCbMutex);
770 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
773 CAResult_t CAStartBLEGattClient()
775 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
777 CAResult_t retVal = CAInitGattClientMutexVariables();
779 if (CA_STATUS_OK != retVal)
781 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAInitGattClientMutexVariables failed!");
782 CATerminateGattClientMutexVariables();
783 return CA_STATUS_FAILED;
786 ca_mutex_lock(g_bleClientThreadPoolMutex);
787 if (NULL == g_bleClientThreadPool)
789 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleServerThreadPool is NULL");
790 CATerminateGattClientMutexVariables();
791 ca_mutex_unlock(g_bleClientThreadPoolMutex);
792 return CA_STATUS_FAILED;
795 retVal = ca_thread_pool_add_task(g_bleClientThreadPool, CAStartBleGattClientThread,
797 if (CA_STATUS_OK != retVal)
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;
804 ca_mutex_unlock(g_bleClientThreadPoolMutex);
806 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
810 void CAStartBleGattClientThread(void *data)
812 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
814 ca_mutex_lock(g_bleClientStateMutex);
816 if (true == g_isBleGattClientStarted)
818 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is already running!!");
819 ca_mutex_unlock(g_bleClientStateMutex);
823 CAResult_t ret = CABleGattSetScanParameter();
824 if (CA_STATUS_OK != ret)
826 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleSetScanParameter Failed");
827 ca_mutex_unlock(g_bleClientStateMutex);
828 CATerminateBLEGattClient();
832 ret = CABleGattSetCallbacks();
833 if (CA_STATUS_OK != ret)
835 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattSetCallbacks Failed");
836 ca_mutex_unlock(g_bleClientStateMutex);
837 CATerminateBLEGattClient();
841 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Starting LE device discovery");
843 ret = CABleGattStartDeviceDiscovery();
844 if (CA_STATUS_OK != ret)
846 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed");
847 ca_mutex_unlock(g_bleClientStateMutex);
848 CATerminateBLEGattClient();
852 g_isBleGattClientStarted = true;
854 ca_mutex_unlock(g_bleClientStateMutex);
856 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Giveing the control to threadPool");
858 GMainContext *thread_context = g_main_context_new();
860 g_eventLoop = g_main_loop_new(thread_context, FALSE);
862 g_main_context_push_thread_default(thread_context);
864 g_main_loop_run(g_eventLoop);
866 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
869 void CAStopBLEGattClient()
871 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
873 ca_mutex_lock(g_bleClientStateMutex);
875 if (false == g_isBleGattClientStarted)
877 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is not running to stop");
878 ca_mutex_unlock(g_bleClientStateMutex);
881 ca_mutex_unlock(g_bleClientStateMutex);
883 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
886 void CATerminateBLEGattClient()
888 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
889 ca_mutex_lock(g_bleClientStateMutex);
891 GMainContext *context_event_loop = NULL;
892 // Required for waking up the thread which is running in gmain loop
893 if (NULL != g_eventLoop)
895 context_event_loop = g_main_loop_get_context(g_eventLoop);
897 if (context_event_loop)
899 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "g_eventLoop context %x", context_event_loop);
900 g_main_context_wakeup(context_event_loop);
902 // Kill g main loops and kill threads.
903 g_main_loop_quit(g_eventLoop);
907 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_eventLoop context is NULL");
910 ca_mutex_lock(g_bleServerBDAddressMutex);
912 OICFree(g_remoteAddress);
914 ca_mutex_unlock(g_bleServerBDAddressMutex);
916 CABleGattUnWatchCharacteristicChanges();
918 CABleGattUnSetCallbacks();
920 CABleGattStopDeviceDiscovery();
922 ca_mutex_lock(g_bleServiceListMutex);
923 CAFreeBLEServiceList(g_bLEServiceList);
924 g_bLEServiceList = NULL;
925 ca_mutex_unlock(g_bleServiceListMutex);
927 CAResetRegisteredServiceCount();
929 g_isBleGattClientStarted = false;
930 ca_mutex_unlock(g_bleClientStateMutex);
932 CATerminateGattClientMutexVariables();
934 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
937 CAResult_t CAInitGattClientMutexVariables()
939 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
940 if (NULL == g_bleClientStateMutex)
942 g_bleClientStateMutex = ca_mutex_new();
943 if (NULL == g_bleClientStateMutex)
945 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
946 return CA_STATUS_FAILED;
950 if (NULL == g_bleServiceListMutex)
952 g_bleServiceListMutex = ca_mutex_new();
953 if (NULL == g_bleServiceListMutex)
955 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
956 return CA_STATUS_FAILED;
960 if (NULL == g_bleReqRespClientCbMutex)
962 g_bleReqRespClientCbMutex = ca_mutex_new();
963 if (NULL == g_bleReqRespClientCbMutex)
965 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
966 return CA_STATUS_FAILED;
970 if (NULL == g_bleClientThreadPoolMutex)
972 g_bleClientThreadPoolMutex = ca_mutex_new();
973 if (NULL == g_bleClientThreadPoolMutex)
975 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
976 return CA_STATUS_FAILED;
980 if (NULL == g_bleClientConnectMutex)
982 g_bleClientConnectMutex = ca_mutex_new();
983 if (NULL == g_bleClientConnectMutex)
985 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
986 return CA_STATUS_FAILED;
990 if (NULL == g_bleClientSendCondWait)
992 g_bleClientSendCondWait = ca_cond_new();
993 if (NULL == g_bleClientSendCondWait)
995 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_cond_new failed");
996 return CA_STATUS_FAILED;
1000 if (NULL == g_bleServerBDAddressMutex)
1002 g_bleServerBDAddressMutex = ca_mutex_new();
1003 if (NULL == g_bleServerBDAddressMutex)
1005 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
1006 return CA_STATUS_FAILED;
1010 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1011 return CA_STATUS_OK;
1014 void CATerminateGattClientMutexVariables()
1016 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1018 ca_mutex_free(g_bleClientStateMutex);
1019 g_bleClientStateMutex = NULL;
1021 ca_mutex_free(g_bleServiceListMutex);
1022 g_bleServiceListMutex = NULL;
1024 ca_mutex_free(g_bleReqRespClientCbMutex);
1025 g_bleReqRespClientCbMutex = NULL;
1027 ca_mutex_free(g_bleClientConnectMutex);
1028 g_bleClientConnectMutex = NULL;
1030 ca_mutex_free(g_bleClientThreadPoolMutex);
1031 g_bleClientThreadPoolMutex = NULL;
1033 ca_mutex_free(g_bleServerBDAddressMutex);
1034 g_bleServerBDAddressMutex = NULL;
1036 ca_cond_free(g_bleClientSendCondWait);
1037 g_bleClientSendCondWait = NULL;
1040 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1043 CAResult_t CABleGattSetScanParameter()
1045 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
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;
1052 int ret = bt_adapter_le_set_scan_parameter(&scan_param);
1053 if (BT_ERROR_NONE != ret)
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;
1059 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1060 return CA_STATUS_OK;
1063 CAResult_t CABleGattSetCallbacks()
1065 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1067 int ret = bt_gatt_set_connection_state_changed_cb(CABleGattConnectionStateChangedCb, NULL);
1068 if (BT_ERROR_NONE != ret)
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;
1076 ret = bt_adapter_le_set_device_discovery_state_changed_cb(
1077 CABtAdapterLeDeviceDiscoveryStateChangedCb, NULL);
1078 if (BT_ERROR_NONE != ret)
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;
1086 ret = bt_gatt_set_characteristic_changed_cb(CABleGattCharacteristicChangedCb, NULL);
1087 if (BT_ERROR_NONE != ret)
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;
1094 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Setting bt_device_set_bond_created_cb \n");
1096 ret = bt_device_set_bond_created_cb(CABtGattBondCreatedCb, NULL);
1097 if (BT_ERROR_NONE != ret)
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;
1104 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1105 return CA_STATUS_OK;
1108 void CABleGattUnSetCallbacks()
1110 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1112 bt_gatt_unset_characteristic_changed_cb();
1114 bt_device_unset_bond_created_cb();
1116 bt_gatt_unset_connection_state_changed_cb();
1118 bt_adapter_le_unset_device_discovery_state_changed_cb();
1120 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1123 CAResult_t CABleGattWatchCharacteristicChanges(bt_gatt_attribute_h service)
1125 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1127 int ret = bt_gatt_watch_characteristic_changes(service);
1128 if (BT_ERROR_NONE != ret)
1130 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1131 "bt_gatt_watch_characteristic_changes failed with [%s] \n",
1132 CABTGetErrorMsg(ret));
1134 return CA_STATUS_FAILED;
1137 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1138 return CA_STATUS_OK;
1141 void CABleGattUnWatchCharacteristicChanges()
1143 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1145 int32_t count = CAGetRegisteredServiceCount();
1147 for (int32_t index = 0; index < count; index++)
1149 BLEServiceInfo *bleServiceInfo = NULL;
1151 ca_mutex_lock(g_bleServiceListMutex);
1153 CAResult_t result = CAGetBLEServiceInfoByPosition(g_bLEServiceList, index, &bleServiceInfo);
1154 if (CA_STATUS_OK == result && NULL != bleServiceInfo
1155 && NULL != bleServiceInfo->service_clone)
1157 bt_gatt_unwatch_characteristic_changes(bleServiceInfo->service_clone);
1158 OIC_LOG(INFO, TZ_BLE_CLIENT_TAG, "bt_gatt_unwatch_characteristic_changes done");
1161 ca_mutex_unlock(g_bleServiceListMutex);
1164 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1167 CAResult_t CABleGattStartDeviceDiscovery()
1169 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1171 int ret = bt_adapter_le_start_device_discovery();
1172 if (BT_ERROR_NONE != ret)
1174 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed");
1175 return CA_STATUS_FAILED;
1178 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1179 return CA_STATUS_OK;
1182 void CABleGattStopDeviceDiscovery()
1184 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1186 bt_adapter_le_stop_device_discovery();
1188 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1191 void CAGattConnectThread (void *remoteAddress)
1193 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
1195 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1197 char *address = (char *)remoteAddress;
1199 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address is [%s]", address);
1201 CAResult_t result = CABleGattConnect(address);
1203 if (CA_STATUS_OK != result)
1205 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect failed for [%s]", address);
1210 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1213 CAResult_t CABleGattConnect(const char *remoteAddress)
1215 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1217 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1218 "remote address is NULL", CA_STATUS_FAILED);
1220 //Because of the platform issue, we added. Once platform is stablized, then it will be removed
1223 ca_mutex_lock(g_bleClientConnectMutex);
1225 int ret = bt_gatt_connect(remoteAddress, true);
1227 if (BT_ERROR_NONE != ret)
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;
1234 ca_mutex_unlock(g_bleClientConnectMutex);
1236 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1237 return CA_STATUS_OK;
1240 CAResult_t CABleGattDisConnect(const char *remoteAddress)
1242 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1244 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1245 "remote address is NULL", CA_STATUS_FAILED);
1247 int32_t ret = bt_gatt_disconnect(remoteAddress);
1249 if (BT_ERROR_NONE != ret)
1251 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_disconnect Failed with ret value [%d] ",
1253 return CA_STATUS_FAILED;
1256 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1257 return CA_STATUS_OK;
1260 void CADiscoverBLEServicesThread (void *remoteAddress)
1262 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1264 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1266 char *address = (char *)remoteAddress;
1268 CAResult_t result = CABleGattDiscoverServices(address);
1269 if (CA_STATUS_OK != result)
1271 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattDiscoverServices failed");
1276 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1279 CAResult_t CABleGattDiscoverServices(const char *remoteAddress)
1281 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1283 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1284 "remote address is NULL", CA_STATUS_FAILED);
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);
1290 strncpy(addr, remoteAddress, len + 1);
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)
1296 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1297 "bt_gatt_foreach_primary_services Failed with ret value [%d] ", ret);
1299 return CA_STATUS_FAILED;
1303 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1304 "bt_gatt_foreach_primary_services success for address [%s]", remoteAddress);
1307 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1308 return CA_STATUS_OK;
1311 void CADiscoverCharThread(void *stServiceInfo)
1313 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1315 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1317 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)stServiceInfo;
1319 VERIFY_NON_NULL_VOID(stTemp->address, TZ_BLE_CLIENT_TAG, "stTemp->address is NULL");
1321 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]", stTemp->address);
1323 CAResult_t result = CABleGattDiscoverCharacteristics(stTemp->serviceInfo, stTemp->address);
1324 if (CA_STATUS_OK != result)
1326 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CABleGattDiscoverCharacteristics failed!");
1327 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1328 OICFree(stTemp->address);
1332 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1333 OICFree(stTemp->address);
1336 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1339 CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service,
1340 const char *remoteAddress)
1342 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1344 VERIFY_NON_NULL_RET(service, NULL, "service is NULL", CA_STATUS_FAILED);
1346 VERIFY_NON_NULL_RET(remoteAddress, NULL, "remoteAddress is NULL", CA_STATUS_FAILED);
1348 size_t len = strlen(remoteAddress);
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);
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)
1358 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1359 "bt_gatt_discover_characteristics failed with error [%d]", ret);
1361 return CA_STATUS_FAILED;
1364 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1365 return CA_STATUS_OK;
1368 void CADiscoverDescriptorThread(void *stServiceInfo)
1370 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " IN");
1372 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1374 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)stServiceInfo;
1376 CAResult_t result = CABleGattDiscoverDescriptor(stTemp->serviceInfo, NULL);
1377 if (CA_STATUS_OK != result)
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);
1387 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1388 OICFree(stTemp->address);
1391 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1394 CAResult_t CABleGattDiscoverDescriptor(bt_gatt_attribute_h service, const char *remoteAddress)
1396 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1398 VERIFY_NON_NULL_RET(service, NULL, "service is NULL", CA_STATUS_FAILED);
1400 int ret = bt_gatt_discover_characteristic_descriptor(service,
1401 CABleGattDescriptorDiscoveredCb, NULL);
1402 if (BT_ERROR_NONE != ret)
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;
1410 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1411 return CA_STATUS_OK;
1414 void CASetCharacteristicDescriptorValueThread(void *stServiceInfo)
1416 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1418 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1420 stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)stServiceInfo;
1422 CAResult_t result = CASetCharacteristicDescriptorValue(stTemp);
1423 if (CA_STATUS_OK != result)
1425 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CASetCharacteristicDescriptorValue failed!");
1426 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1427 OICFree(stTemp->desc);
1431 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1432 OICFree(stTemp->desc);
1435 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1438 CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescInfo)
1440 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1442 unsigned char noti[4] = {0,};
1444 char *strUUID = (char *)OICCalloc(5, sizeof(char));
1446 VERIFY_NON_NULL_RET(strUUID, TZ_BLE_CLIENT_TAG, "calloc failed", CA_STATUS_FAILED);
1448 snprintf(strUUID, 4, "%x%x", stGattCharDescInfo->desc[3], stGattCharDescInfo->desc[2]);
1449 noti[0] = stGattCharDescInfo->desc[0];
1450 noti[1] = stGattCharDescInfo->desc[1];
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]);
1460 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG strUUID is [%s]",
1462 //if (!strncmp(strUUID, BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG, 2))
1464 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "setting notification/indication for descriptor");
1466 int ret = bt_gatt_set_characteristic_desc_value_request(
1467 stGattCharDescInfo->characteristic,
1468 noti, 4, CABleGattCharacteristicWriteCb);
1469 if (BT_ERROR_NONE != ret)
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));
1475 return CA_STATUS_FAILED;
1480 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1481 return CA_STATUS_OK;
1484 void CAGATTCreateBondThread(void *stServiceInfo)
1486 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1488 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1490 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)stServiceInfo;
1492 VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "stTemp is NULL");
1494 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]",
1497 CAResult_t result = CABleGATTCreateBond(stTemp->address);
1498 if (CA_STATUS_OK != result)
1500 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG ,
1501 "CABleGattDiscoverCharacteristics failed!");
1502 OICFree(stTemp->address);
1506 OICFree(stTemp->address);
1509 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1512 CAResult_t CABleGATTCreateBond(const char *remoteAddress)
1514 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1516 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1517 "remote address is NULL", CA_STATUS_FAILED);
1519 int ret = bt_device_create_bond(remoteAddress);
1521 if (BT_ERROR_NONE != ret)
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;
1529 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1530 " bt_device_create_bond query success for address [%s]", remoteAddress);
1532 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1534 return CA_STATUS_OK;
1537 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
1538 const char *data, const int32_t dataLen,
1539 CALETransferType_t type, const int32_t position)
1541 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1543 VERIFY_NON_NULL(data, NULL, "data is NULL");
1547 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input!");
1548 return CA_STATUS_INVALID_PARAM;
1551 BLEServiceInfo *bleServiceInfo = NULL;
1553 CAResult_t ret = CA_STATUS_FAILED;
1555 ca_mutex_lock(g_bleServiceListMutex);
1556 if ( LE_UNICAST == type)
1558 VERIFY_NON_NULL(remoteAddress, NULL, "remoteAddress is NULL");
1560 ret = CAGetBLEServiceInfo(g_bLEServiceList, remoteAddress, &bleServiceInfo);
1562 else if ( LE_MULTICAST == type)
1564 ret = CAGetBLEServiceInfoByPosition(g_bLEServiceList, position, &bleServiceInfo);
1566 ca_mutex_unlock(g_bleServiceListMutex);
1568 if (CA_STATUS_OK != ret)
1570 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAGetBLEServiceInfoByPosition is failed");
1571 return CA_STATUS_FAILED;
1574 VERIFY_NON_NULL(bleServiceInfo, NULL, "bleServiceInfo is NULL");
1576 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating the data of length [%d] to [%s] ", dataLen,
1577 bleServiceInfo->bdAddress);
1579 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating to write char [%s]",
1580 bleServiceInfo->read_char);
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);
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));
1590 int result = bt_gatt_set_characteristic_value_request(bleServiceInfo->read_char, (unsigned char *)value,
1592 CABleGattCharacteristicWriteCb);
1593 if (BT_ERROR_NONE != result)
1595 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1596 "bt_gatt_set_characteristic_value_request Failed with return val [%d]",
1599 return CA_STATUS_FAILED;
1604 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1605 return CA_STATUS_OK;
1608 CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data,
1611 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1613 VERIFY_NON_NULL(data, NULL, "data is NULL");
1617 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input !");
1618 return CA_STATUS_INVALID_PARAM;
1621 int numOfServersConnected = CAGetRegisteredServiceCount();
1623 for (int32_t pos = 0; pos < numOfServersConnected; pos++)
1625 /*remoteAddress will be NULL.
1626 Since we have to send to all destinations. pos will be used for getting remote address.
1628 int32_t ret = CAUpdateCharacteristicsToGattServer(NULL, data, dataLen, LE_MULTICAST, pos);
1630 if (CA_STATUS_OK != ret)
1632 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1633 "CAUpdateCharacteristicsToGattServer Failed with return val [%d] ", ret);
1637 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1638 return CA_STATUS_OK;