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);
155 ca_mutex_lock(g_bleReqRespClientCbMutex);
156 if (NULL == g_bleClientDataReceivedCallback)
158 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespCallback is NULL!");
159 ca_mutex_unlock(g_bleReqRespClientCbMutex);
162 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending data up !");
164 ca_mutex_lock(g_bleServerBDAddressMutex);
165 uint32_t sentLength = 0;
166 g_bleClientDataReceivedCallback(g_remoteAddress, OIC_BLE_SERVICE_ID,
167 value, valueLen, &sentLength);
169 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Sent data Length is %d", sentLength);
170 ca_mutex_unlock(g_bleServerBDAddressMutex);
172 ca_mutex_unlock(g_bleReqRespClientCbMutex);
174 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
177 void CABleGattCharacteristicWriteCb(int result, void *userData)
179 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
182 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
185 void CABleGattDescriptorDiscoveredCb(int result, unsigned char format, int total,
186 bt_gatt_attribute_h descriptor,
187 bt_gatt_attribute_h characteristic, void *userData)
189 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
191 stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)OICCalloc(1, sizeof(
192 stGattCharDescriptor_t));
194 VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed!");
196 stTemp->desc = (uint8_t *)OICMalloc(total);
197 if (NULL == stTemp->desc)
199 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "malloc failed");
203 memcpy(stTemp->desc, descriptor, total);
205 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "result[%d] format[%d] total[%d]", result, format, total);
206 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "characteristic [%s]", (const char *) characteristic);
209 bt_gatt_clone_attribute_handle(&(stTemp->characteristic), characteristic);
210 stTemp->total = total;
212 ca_mutex_lock(g_bleClientThreadPoolMutex);
213 if (NULL == g_bleClientThreadPool)
215 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
216 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
217 OICFree(stTemp->desc);
219 ca_mutex_unlock(g_bleClientThreadPoolMutex);
223 CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
224 CASetCharacteristicDescriptorValueThread,
226 if (CA_STATUS_OK != ret)
228 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed");
229 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
230 OICFree(stTemp->desc);
232 ca_mutex_unlock(g_bleClientThreadPoolMutex);
236 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG,
237 "LE Client initialization flow complete");
239 ca_mutex_unlock(g_bleClientThreadPoolMutex);
241 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
244 bool CABleGattCharacteristicsDiscoveredCb(int result,
245 int inputIndex, int total,
246 bt_gatt_attribute_h characteristic, void *userData)
249 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
251 VERIFY_NON_NULL_RET(characteristic, TZ_BLE_CLIENT_TAG, "Param characteristic is NULL", false);
253 VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
255 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
256 "result [%d] input_index [%d] total [%d]",
257 result, inputIndex, total);
259 BLEServiceInfo *bleServiceInfo = NULL;
261 ca_mutex_lock(g_bleServiceListMutex);
263 char *bdAddress = (char *) userData;
264 CAGetBLEServiceInfo(g_bLEServiceList, bdAddress, &bleServiceInfo);
266 ca_mutex_unlock(g_bleServiceListMutex);
269 bt_gatt_get_service_uuid(characteristic, &uuid);
271 VERIFY_NON_NULL_RET(uuid, TZ_BLE_CLIENT_TAG, "uuid is NULL", false);
273 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "New Characteristics[%s] of uuid[%s] is obtained",
274 (char *)characteristic, uuid);
276 if(0 == strcasecmp(uuid, CA_BLE_READ_CHAR_UUID)) // Server will read on this characterisctics
278 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Read characteristics is obtained");
280 CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_READ_CHAR, bleServiceInfo);
281 if (CA_STATUS_OK != retVal)
283 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed! ");
287 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
288 sizeof(stGattServiceInfo_t));
290 VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "calloc failed!", false);
292 size_t len = strlen(bdAddress);
293 stTemp->address = (char *)OICMalloc(sizeof(char) * (len + 1));
294 if (NULL == stTemp->address)
296 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
301 strncpy(stTemp->address, bdAddress, len + 1);
302 bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), characteristic);
304 ca_mutex_lock(g_bleClientThreadPoolMutex);
305 if (NULL == g_bleClientThreadPool)
307 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
308 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
309 OICFree(stTemp->address);
311 ca_mutex_unlock(g_bleClientThreadPoolMutex);
315 retVal = ca_thread_pool_add_task(g_bleClientThreadPool,
316 CADiscoverDescriptorThread,
318 if (CA_STATUS_OK != retVal)
320 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
321 "ca_thread_pool_add_task failed with ret [%d]", retVal);
322 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
323 OICFree(stTemp->address);
325 ca_mutex_unlock(g_bleClientThreadPoolMutex);
328 ca_mutex_unlock(g_bleClientThreadPoolMutex);
330 else if (0 == strcasecmp(uuid, CA_BLE_WRITE_CHAR_UUID)) // Server will write on this characteristics.
333 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Write characteristics is obtained");
334 CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_WRITE_CHAR, bleServiceInfo);
335 if (CA_STATUS_OK != retVal)
337 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed ");
342 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
346 bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int index, int count,
349 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
351 VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "Param service is NULL", false);
353 VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
355 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s] index [%d] count [%d]", (char *)service,
358 CAResult_t result = CAVerifyOICServiceByServiceHandle(service);
360 if (CA_STATUS_OK == result)
362 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
364 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes");
366 result = CABleGattWatchCharacteristicChanges(service);
367 if (CA_STATUS_OK != result)
369 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
370 "CABleGattWatchCharacteristicChanges failed!");
374 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
375 sizeof(stGattServiceInfo_t));
376 VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "Calloc Failed", false);
378 char *bdAddress = (char *)userData;
379 size_t len = strlen(bdAddress);
381 stTemp->address = (char *)OICMalloc(sizeof(char) * (len + 1));
382 if (NULL == stTemp->address)
384 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
389 strncpy(stTemp->address, bdAddress, len + 1);
391 BLEServiceInfo *bleServiceInfo = NULL;
393 result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo);
394 if (CA_STATUS_OK != result)
396 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CACreateBLEServiceInfo failed! ");
397 OICFree(stTemp->address);
399 OICFree(bleServiceInfo);
402 if (NULL == bleServiceInfo )
404 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , " bleServiceInfo is NULL");
405 OICFree(stTemp->address);
407 OICFree(bleServiceInfo);
411 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG ,
412 " serviceInfo remote address [%s]", bleServiceInfo->bdAddress);
414 ca_mutex_lock(g_bleServiceListMutex);
415 result = CAAddBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo);
416 ca_mutex_unlock(g_bleServiceListMutex);
417 if (CA_STATUS_OK != result)
419 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAddBLEServiceInfoToList failed!");
420 OICFree(stTemp->address);
422 CAFreeBLEServiceInfo(bleServiceInfo);
427 ca_mutex_lock(g_bleClientThreadPoolMutex);
428 if (NULL == g_bleClientThreadPool)
430 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
431 OICFree(stTemp->address);
433 ca_mutex_lock(g_bleServiceListMutex);
434 CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
435 bleServiceInfo->bdAddress);
436 ca_mutex_unlock(g_bleServiceListMutex);
437 ca_mutex_unlock(g_bleClientThreadPoolMutex);
440 bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), service);
442 result = ca_thread_pool_add_task(g_bleClientThreadPool,
443 CADiscoverCharThread,
445 if (CA_STATUS_OK != result)
447 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
448 "ca_thread_pool_add_task failed with ret [%d]", result);
449 OICFree(stTemp->address);
451 ca_mutex_lock(g_bleServiceListMutex);
452 CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
453 bleServiceInfo->bdAddress);
454 ca_mutex_unlock(g_bleServiceListMutex);
455 ca_mutex_unlock(g_bleClientThreadPoolMutex);
458 ca_mutex_unlock(g_bleClientThreadPoolMutex);
461 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
465 void CABleGattConnectionStateChangedCb(int result, bool connected,
466 const char *remoteAddress, void *userData)
468 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
470 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "CABleGattConnectionStateChangedCb result[%d] ", result);
472 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
474 CAResult_t ret = CA_STATUS_FAILED;
477 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress);
479 ret = CABleGattStartDeviceDiscovery();
480 if (CA_STATUS_OK != ret)
482 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattStartDeviceDiscovery failed");
488 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Connected to [%s] ", remoteAddress);
490 ca_mutex_lock(g_bleServerBDAddressMutex);
492 g_remoteAddress = OICStrdup(remoteAddress);
494 ca_mutex_unlock(g_bleServerBDAddressMutex);
496 VERIFY_NON_NULL_VOID(g_remoteAddress, TZ_BLE_CLIENT_TAG, "Malloc failed");
498 char *addr = OICStrdup(remoteAddress);
500 ca_mutex_lock(g_bleClientThreadPoolMutex);
501 if (NULL == g_bleClientThreadPool)
503 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
506 ca_mutex_lock(g_bleServerBDAddressMutex);
507 OICFree(g_remoteAddress);
508 ca_mutex_unlock(g_bleServerBDAddressMutex);
510 ca_mutex_unlock(g_bleClientThreadPoolMutex);
514 ret = ca_thread_pool_add_task(g_bleClientThreadPool, CADiscoverBLEServicesThread,
516 if (CA_STATUS_OK != ret)
518 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
521 ca_mutex_lock(g_bleServerBDAddressMutex);
522 OICFree(g_remoteAddress);
523 ca_mutex_unlock(g_bleServerBDAddressMutex);
525 ca_mutex_unlock(g_bleClientThreadPoolMutex);
528 ca_mutex_unlock(g_bleClientThreadPoolMutex);
531 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
534 void CABtAdapterLeDeviceDiscoveryStateChangedCb(int result,
535 bt_adapter_le_device_discovery_state_e discoveryState,
536 bt_adapter_le_device_discovery_info_s *discoveryInfo,
539 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
541 if (NULL == discoveryInfo && BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND == discoveryState)
543 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL");
547 if (BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND != discoveryState)
549 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
550 " LE Discovery state is [%s]",
551 discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished");
555 CAPrintDiscoveryInformation(discoveryInfo);
557 if (discoveryInfo->service_uuid == NULL)
559 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "NO UUIDS from device");
563 for (int32_t i = discoveryInfo->service_count - 1; i >= 0; i--)
565 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "uuid[%d]: [%s]",
566 i, discoveryInfo->service_uuid[i]);
567 CAResult_t res = CAVerifyOICServiceByUUID(discoveryInfo->service_uuid[i]);
568 if (CA_STATUS_OK == res)
571 size_t len = strlen(discoveryInfo->remote_address);
573 char *addr = (char *)OICMalloc(sizeof(char) * (len + 1));
574 VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
575 strncpy(addr, discoveryInfo->remote_address, len + 1);
577 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
578 "Trying to do Gatt connection to [%s]", addr);
580 ca_mutex_lock(g_bleClientThreadPoolMutex);
581 if (NULL == g_bleClientThreadPool)
583 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
585 ca_mutex_unlock(g_bleClientThreadPoolMutex);
589 CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
590 CAGattConnectThread, addr);
591 if (CA_STATUS_OK != ret)
593 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
594 "ca_thread_pool_add_task failed with ret [%d]", ret);
596 ca_mutex_unlock(g_bleClientThreadPoolMutex);
599 ca_mutex_unlock(g_bleClientThreadPoolMutex);
600 if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31)
602 bt_adapter_le_stop_device_discovery();
605 break; // Found the OIC Service. No need to verify remaining services.
610 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
614 void CAPrintDiscoveryInformation(const bt_adapter_le_device_discovery_info_s *discoveryInfo)
616 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
618 if (NULL == discoveryInfo)
620 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL ");
624 if (discoveryInfo->remote_address)
626 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Remote Address [%s]", discoveryInfo->remote_address);
629 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
630 " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
631 discoveryInfo->adv_data_len, discoveryInfo->scan_data_len, discoveryInfo->rssi,
632 discoveryInfo->address_type);
633 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
634 " Number of services present in device [%s] is [%d]",
635 discoveryInfo->remote_address, discoveryInfo->service_count);
637 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
640 void CASetBleClientThreadPoolHandle(ca_thread_pool_t handle)
642 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
644 ca_mutex_lock(g_bleClientThreadPoolMutex);
645 g_bleClientThreadPool = handle;
646 ca_mutex_unlock(g_bleClientThreadPoolMutex);
648 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
651 void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
653 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
655 ca_mutex_lock(g_bleReqRespClientCbMutex);
657 g_bleClientDataReceivedCallback = callback;
659 ca_mutex_unlock(g_bleReqRespClientCbMutex);
661 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
664 CAResult_t CAStartBLEGattClient()
666 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
668 CAResult_t retVal = CAInitGattClientMutexVariables();
670 if (CA_STATUS_OK != retVal)
672 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAInitGattClientMutexVariables failed!");
673 CATerminateGattClientMutexVariables();
674 return CA_STATUS_FAILED;
677 ca_mutex_lock(g_bleClientThreadPoolMutex);
678 if (NULL == g_bleClientThreadPool)
680 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleServerThreadPool is NULL");
681 CATerminateGattClientMutexVariables();
682 ca_mutex_unlock(g_bleClientThreadPoolMutex);
683 return CA_STATUS_FAILED;
686 retVal = ca_thread_pool_add_task(g_bleClientThreadPool, CAStartBleGattClientThread,
688 if (CA_STATUS_OK != retVal)
690 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed");
691 CATerminateGattClientMutexVariables();
692 ca_mutex_unlock(g_bleClientThreadPoolMutex);
693 return CA_STATUS_FAILED;
695 ca_mutex_unlock(g_bleClientThreadPoolMutex);
697 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
701 void CAStartBleGattClientThread(void *data)
703 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
705 ca_mutex_lock(g_bleClientStateMutex);
707 if (true == g_isBleGattClientStarted)
709 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is already running!!");
710 ca_mutex_unlock(g_bleClientStateMutex);
714 CAResult_t ret = CABleGattSetScanParameter();
715 if (CA_STATUS_OK != ret)
717 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleSetScanParameter Failed");
718 ca_mutex_unlock(g_bleClientStateMutex);
719 CATerminateBLEGattClient();
723 ret = CABleGattSetCallbacks();
724 if (CA_STATUS_OK != ret)
726 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattSetCallbacks Failed");
727 ca_mutex_unlock(g_bleClientStateMutex);
728 CATerminateBLEGattClient();
732 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Starting LE device discovery");
734 ret = CABleGattStartDeviceDiscovery();
735 if (CA_STATUS_OK != ret)
737 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed");
738 ca_mutex_unlock(g_bleClientStateMutex);
739 CATerminateBLEGattClient();
743 g_isBleGattClientStarted = true;
745 ca_mutex_unlock(g_bleClientStateMutex);
747 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Giveing the control to threadPool");
749 GMainContext *thread_context = g_main_context_new();
751 g_eventLoop = g_main_loop_new(thread_context, FALSE);
753 g_main_context_push_thread_default(thread_context);
755 g_main_loop_run(g_eventLoop);
757 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
760 void CAStopBLEGattClient()
762 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
764 ca_mutex_lock(g_bleClientStateMutex);
766 if (false == g_isBleGattClientStarted)
768 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is not running to stop");
769 ca_mutex_unlock(g_bleClientStateMutex);
773 CABleGattUnSetCallbacks();
775 CABleGattUnWatchCharacteristicChanges();
777 CABleGattStopDeviceDiscovery();
779 g_isBleGattClientStarted = false;
781 GMainContext *context_event_loop = NULL;
782 // Required for waking up the thread which is running in gmain loop
783 if (NULL != g_eventLoop)
785 context_event_loop = g_main_loop_get_context(g_eventLoop);
787 if (context_event_loop)
789 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "g_eventLoop context %x", context_event_loop);
790 g_main_context_wakeup(context_event_loop);
792 // Kill g main loops and kill threads.
793 g_main_loop_quit(g_eventLoop);
797 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_eventLoop context is NULL");
800 ca_mutex_unlock(g_bleClientStateMutex);
802 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
805 void CATerminateBLEGattClient()
807 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
808 ca_mutex_lock(g_bleClientStateMutex);
810 ca_mutex_lock(g_bleServerBDAddressMutex);
812 OICFree(g_remoteAddress);
814 ca_mutex_unlock(g_bleServerBDAddressMutex);
816 ca_mutex_lock(g_bleServiceListMutex);
817 CAFreeBLEServiceList(g_bLEServiceList);
818 g_bLEServiceList = NULL;
819 ca_mutex_unlock(g_bleServiceListMutex);
821 CAResetRegisteredServiceCount();
823 ca_mutex_unlock(g_bleClientStateMutex);
825 CATerminateGattClientMutexVariables();
827 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
830 CAResult_t CAInitGattClientMutexVariables()
832 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
833 if (NULL == g_bleClientStateMutex)
835 g_bleClientStateMutex = ca_mutex_new();
836 if (NULL == g_bleClientStateMutex)
838 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
839 return CA_STATUS_FAILED;
843 if (NULL == g_bleServiceListMutex)
845 g_bleServiceListMutex = ca_mutex_new();
846 if (NULL == g_bleServiceListMutex)
848 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
849 return CA_STATUS_FAILED;
853 if (NULL == g_bleReqRespClientCbMutex)
855 g_bleReqRespClientCbMutex = ca_mutex_new();
856 if (NULL == g_bleReqRespClientCbMutex)
858 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
859 return CA_STATUS_FAILED;
863 if (NULL == g_bleClientThreadPoolMutex)
865 g_bleClientThreadPoolMutex = ca_mutex_new();
866 if (NULL == g_bleClientThreadPoolMutex)
868 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
869 return CA_STATUS_FAILED;
873 if (NULL == g_bleClientConnectMutex)
875 g_bleClientConnectMutex = ca_mutex_new();
876 if (NULL == g_bleClientConnectMutex)
878 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
879 return CA_STATUS_FAILED;
883 if (NULL == g_bleClientSendCondWait)
885 g_bleClientSendCondWait = ca_cond_new();
886 if (NULL == g_bleClientSendCondWait)
888 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_cond_new failed");
889 return CA_STATUS_FAILED;
893 if (NULL == g_bleServerBDAddressMutex)
895 g_bleServerBDAddressMutex = ca_mutex_new();
896 if (NULL == g_bleServerBDAddressMutex)
898 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
899 return CA_STATUS_FAILED;
903 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
907 void CATerminateGattClientMutexVariables()
909 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
911 ca_mutex_free(g_bleClientStateMutex);
912 g_bleClientStateMutex = NULL;
914 ca_mutex_free(g_bleServiceListMutex);
915 g_bleServiceListMutex = NULL;
917 ca_mutex_free(g_bleReqRespClientCbMutex);
918 g_bleReqRespClientCbMutex = NULL;
920 ca_mutex_free(g_bleClientConnectMutex);
921 g_bleClientConnectMutex = NULL;
923 ca_mutex_free(g_bleClientThreadPoolMutex);
924 g_bleClientThreadPoolMutex = NULL;
926 ca_mutex_free(g_bleServerBDAddressMutex);
927 g_bleServerBDAddressMutex = NULL;
929 ca_cond_free(g_bleClientSendCondWait);
930 g_bleClientSendCondWait = NULL;
933 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
936 CAResult_t CABleGattSetScanParameter()
938 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
940 bt_adapter_le_scan_params_s scan_param = { 0, };
941 scan_param.type = BT_ADAPTER_LE_PASSIVE_SCAN;
942 scan_param.interval = 1560;
943 scan_param.window = 160;
945 int ret = bt_adapter_le_set_scan_parameter(&scan_param);
946 if (BT_ERROR_NONE != ret)
948 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_set_scan_parameter Failed with ret [%d]", ret);
949 return CA_STATUS_FAILED;
952 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
956 CAResult_t CABleGattSetCallbacks()
958 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
960 int ret = bt_gatt_set_connection_state_changed_cb(CABleGattConnectionStateChangedCb, NULL);
961 if (BT_ERROR_NONE != ret)
963 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
964 "bt_gatt_set_connection_state_changed_cb Failed with return as [%s ]",
965 CABTGetErrorMsg(ret));
966 return CA_STATUS_FAILED;
969 ret = bt_adapter_le_set_device_discovery_state_changed_cb(
970 CABtAdapterLeDeviceDiscoveryStateChangedCb, NULL);
971 if (BT_ERROR_NONE != ret)
973 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
974 "bt_adapter_le_set_device_discovery_state_changed_cb Failed with return as [%s ]",
975 CABTGetErrorMsg(ret));;
976 return CA_STATUS_FAILED;
979 ret = bt_gatt_set_characteristic_changed_cb(CABleGattCharacteristicChangedCb, NULL);
980 if (BT_ERROR_NONE != ret)
982 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_set_characteristic_changed_cb Failed as [%s ]",
983 CABTGetErrorMsg(ret));
984 return CA_STATUS_FAILED;
987 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
991 void CABleGattUnSetCallbacks()
993 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
995 bt_gatt_unset_characteristic_changed_cb();
997 bt_gatt_unset_connection_state_changed_cb();
999 bt_adapter_le_unset_device_discovery_state_changed_cb();
1001 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1004 CAResult_t CABleGattWatchCharacteristicChanges(bt_gatt_attribute_h service)
1006 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1008 int ret = bt_gatt_watch_characteristic_changes(service);
1009 if (BT_ERROR_NONE != ret)
1011 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1012 "bt_gatt_watch_characteristic_changes failed with [%s]",
1013 CABTGetErrorMsg(ret));
1015 return CA_STATUS_FAILED;
1018 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1019 return CA_STATUS_OK;
1022 void CABleGattUnWatchCharacteristicChanges()
1024 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1026 int32_t count = CAGetRegisteredServiceCount();
1028 for (int32_t index = 0; index < count; index++)
1030 BLEServiceInfo *bleServiceInfo = NULL;
1032 ca_mutex_lock(g_bleServiceListMutex);
1034 CAResult_t result = CAGetBLEServiceInfoByPosition(g_bLEServiceList, index, &bleServiceInfo);
1035 if (CA_STATUS_OK == result && NULL != bleServiceInfo
1036 && NULL != bleServiceInfo->service_clone)
1038 bt_gatt_unwatch_characteristic_changes(bleServiceInfo->service_clone);
1039 OIC_LOG(INFO, TZ_BLE_CLIENT_TAG, "bt_gatt_unwatch_characteristic_changes done");
1042 ca_mutex_unlock(g_bleServiceListMutex);
1045 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1048 CAResult_t CABleGattStartDeviceDiscovery()
1050 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1051 bool isDiscovering = false;
1053 int ret = bt_adapter_le_is_discovering(&isDiscovering);
1054 if (BT_ERROR_NONE != ret)
1056 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_is_discovering Failed");
1057 return CA_STATUS_FAILED;
1062 ret = bt_adapter_le_start_device_discovery();
1063 if (BT_ERROR_NONE != ret)
1065 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed Ret: %d, %x", ret, ret);
1066 return CA_STATUS_FAILED;
1070 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1071 return CA_STATUS_OK;
1074 void CABleGattStopDeviceDiscovery()
1076 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1078 bool isDiscovering = false;
1080 int ret = bt_adapter_le_is_discovering(&isDiscovering);
1081 if (BT_ERROR_NONE != ret)
1083 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_is_discovering Failed");
1089 ret = bt_adapter_le_stop_device_discovery();
1090 if (BT_ERROR_NONE != ret)
1092 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_stop_device_discovery Failed");
1097 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1100 void CAGattConnectThread (void *remoteAddress)
1102 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
1104 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1106 char *address = (char *)remoteAddress;
1108 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address is [%s]", address);
1110 CAResult_t result = CABleGattConnect(address);
1112 if (CA_STATUS_OK != result)
1114 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect failed for [%s]", address);
1119 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1122 CAResult_t CABleGattConnect(const char *remoteAddress)
1124 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1126 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1127 "remote address is NULL", CA_STATUS_FAILED);
1129 //Because of the platform issue, we added. Once platform is stablized, then it will be removed
1132 ca_mutex_lock(g_bleClientConnectMutex);
1134 int ret = bt_gatt_connect(remoteAddress, true);
1136 if (BT_ERROR_NONE != ret)
1138 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect Failed with ret value [%s] ",
1139 CABTGetErrorMsg(ret));
1140 ca_mutex_unlock(g_bleClientConnectMutex);
1141 return CA_STATUS_FAILED;
1143 ca_mutex_unlock(g_bleClientConnectMutex);
1145 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1146 return CA_STATUS_OK;
1149 CAResult_t CABleGattDisConnect(const char *remoteAddress)
1151 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1153 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1154 "remote address is NULL", CA_STATUS_FAILED);
1156 int32_t ret = bt_gatt_disconnect(remoteAddress);
1158 if (BT_ERROR_NONE != ret)
1160 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_disconnect Failed with ret value [%d] ",
1162 return CA_STATUS_FAILED;
1165 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1166 return CA_STATUS_OK;
1169 void CADiscoverBLEServicesThread (void *remoteAddress)
1171 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1173 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1175 char *address = (char *)remoteAddress;
1177 CAResult_t result = CABleGattDiscoverServices(address);
1178 if (CA_STATUS_OK != result)
1180 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattDiscoverServices failed");
1185 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1188 CAResult_t CABleGattDiscoverServices(const char *remoteAddress)
1190 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1192 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1193 "remote address is NULL", CA_STATUS_FAILED);
1195 size_t len = strlen(remoteAddress);
1196 char *addr = (char *)OICMalloc(sizeof(char) * (len + 1));
1197 VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
1199 strncpy(addr, remoteAddress, len + 1);
1201 int32_t ret = bt_gatt_foreach_primary_services(remoteAddress, CABleGattPrimaryServiceCb,
1202 (void *)addr); // addr memory will be free in callback.
1203 if (BT_ERROR_NONE != ret)
1205 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1206 "bt_gatt_foreach_primary_services Failed with ret value [%d] ", ret);
1208 return CA_STATUS_FAILED;
1212 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
1213 "bt_gatt_foreach_primary_services success for address [%s]", remoteAddress);
1216 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1217 return CA_STATUS_OK;
1220 void CADiscoverCharThread(void *stServiceInfo)
1222 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1224 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1226 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)stServiceInfo;
1228 VERIFY_NON_NULL_VOID(stTemp->address, TZ_BLE_CLIENT_TAG, "stTemp->address is NULL");
1230 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]", stTemp->address);
1232 CAResult_t result = CABleGattDiscoverCharacteristics(stTemp->serviceInfo, stTemp->address);
1233 if (CA_STATUS_OK != result)
1235 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CABleGattDiscoverCharacteristics failed!");
1236 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1237 OICFree(stTemp->address);
1241 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1242 OICFree(stTemp->address);
1245 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1248 CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service,
1249 const char *remoteAddress)
1251 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1253 VERIFY_NON_NULL_RET(service, NULL, "service is NULL", CA_STATUS_FAILED);
1255 VERIFY_NON_NULL_RET(remoteAddress, NULL, "remoteAddress is NULL", CA_STATUS_FAILED);
1257 size_t len = strlen(remoteAddress);
1259 char *addr = (char *)OICMalloc(sizeof(char) * (len + 1));
1260 VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
1261 strncpy(addr, remoteAddress, len + 1);
1263 int32_t ret = bt_gatt_discover_characteristics(service, CABleGattCharacteristicsDiscoveredCb,
1264 (void *)addr); // addr will be freed in callback.
1265 if (BT_ERROR_NONE != ret)
1267 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1268 "bt_gatt_discover_characteristics failed with error [%d]", ret);
1270 return CA_STATUS_FAILED;
1273 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1274 return CA_STATUS_OK;
1277 void CADiscoverDescriptorThread(void *stServiceInfo)
1279 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " IN");
1281 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1283 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)stServiceInfo;
1285 CAResult_t result = CABleGattDiscoverDescriptor(stTemp->serviceInfo, NULL);
1286 if (CA_STATUS_OK != result)
1288 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
1289 "bt_gatt_discover_characteristic_descriptor failed");
1290 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1291 OICFree(stTemp->address);
1296 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1297 OICFree(stTemp->address);
1300 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1303 CAResult_t CABleGattDiscoverDescriptor(bt_gatt_attribute_h service, const char *remoteAddress)
1305 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1307 VERIFY_NON_NULL_RET(service, NULL, "service is NULL", CA_STATUS_FAILED);
1309 int ret = bt_gatt_discover_characteristic_descriptor(service,
1310 CABleGattDescriptorDiscoveredCb, NULL);
1311 if (BT_ERROR_NONE != ret)
1313 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1314 "bt_gatt_discover_characteristic_descriptor failed with returns[%s]",
1315 CABTGetErrorMsg(ret));
1316 return CA_STATUS_FAILED;
1319 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1320 return CA_STATUS_OK;
1323 void CASetCharacteristicDescriptorValueThread(void *stServiceInfo)
1325 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1327 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1329 stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)stServiceInfo;
1331 CAResult_t result = CASetCharacteristicDescriptorValue(stTemp);
1332 if (CA_STATUS_OK != result)
1334 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CASetCharacteristicDescriptorValue failed!");
1335 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1336 OICFree(stTemp->desc);
1340 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1341 OICFree(stTemp->desc);
1344 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1347 CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescInfo)
1349 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1351 unsigned char noti[4] = {0,};
1353 char *strUUID = (char *)OICCalloc(5, sizeof(char));
1355 VERIFY_NON_NULL_RET(strUUID, TZ_BLE_CLIENT_TAG, "calloc failed", CA_STATUS_FAILED);
1357 snprintf(strUUID, 4, "%x%x", stGattCharDescInfo->desc[3], stGattCharDescInfo->desc[2]);
1358 noti[0] = stGattCharDescInfo->desc[0];
1359 noti[1] = stGattCharDescInfo->desc[1];
1363 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x0 [%x]", stGattCharDescInfo->desc[0]);
1364 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x1 [%x]", stGattCharDescInfo->desc[1]);
1365 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x2 [%x]", stGattCharDescInfo->desc[2]);
1366 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x3 [%x]", stGattCharDescInfo->desc[3]);
1369 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG strUUID is [%s]",
1371 //if (!strncmp(strUUID, BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG, 2))
1373 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "setting notification/indication for descriptor");
1375 int ret = bt_gatt_set_characteristic_desc_value_request(
1376 stGattCharDescInfo->characteristic,
1377 noti, 4, CABleGattCharacteristicWriteCb);
1378 if (BT_ERROR_NONE != ret)
1380 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1381 "bt_gatt_set_characteristic_desc_value_request failed with return[%s]",
1382 CABTGetErrorMsg(ret));
1384 return CA_STATUS_FAILED;
1389 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1390 return CA_STATUS_OK;
1393 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
1394 const char *data, const uint32_t dataLen,
1395 CALETransferType_t type, const int32_t position)
1397 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1399 VERIFY_NON_NULL(data, NULL, "data is NULL");
1403 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input!");
1404 return CA_STATUS_INVALID_PARAM;
1407 BLEServiceInfo *bleServiceInfo = NULL;
1409 CAResult_t ret = CA_STATUS_FAILED;
1411 ca_mutex_lock(g_bleServiceListMutex);
1412 if ( LE_UNICAST == type)
1414 VERIFY_NON_NULL(remoteAddress, NULL, "remoteAddress is NULL");
1416 ret = CAGetBLEServiceInfo(g_bLEServiceList, remoteAddress, &bleServiceInfo);
1418 else if ( LE_MULTICAST == type)
1420 ret = CAGetBLEServiceInfoByPosition(g_bLEServiceList, position, &bleServiceInfo);
1422 ca_mutex_unlock(g_bleServiceListMutex);
1424 if (CA_STATUS_OK != ret)
1426 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAGetBLEServiceInfoByPosition is failed");
1427 return CA_STATUS_FAILED;
1430 VERIFY_NON_NULL(bleServiceInfo, NULL, "bleServiceInfo is NULL");
1432 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating the data of length [%d] to [%s] ", dataLen,
1433 bleServiceInfo->bdAddress);
1435 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating to write char [%s]",
1436 bleServiceInfo->read_char);
1438 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
1439 "Updating the data of length [%d] to [%s]", dataLen,
1440 bleServiceInfo->bdAddress);
1442 int result = bt_gatt_set_characteristic_value(bleServiceInfo->write_char, (unsigned char *)data,
1444 if (BT_ERROR_NONE != result)
1446 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1447 "bt_gatt_set_characteristic_value Failed with return val [%d]",
1449 return CA_STATUS_FAILED;
1452 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1453 return CA_STATUS_OK;
1456 CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data,
1459 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1461 VERIFY_NON_NULL(data, NULL, "data is NULL");
1465 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input !");
1466 return CA_STATUS_INVALID_PARAM;
1469 int numOfServersConnected = CAGetRegisteredServiceCount();
1471 for (int32_t pos = 0; pos < numOfServersConnected; pos++)
1473 /*remoteAddress will be NULL.
1474 Since we have to send to all destinations. pos will be used for getting remote address.
1476 int32_t ret = CAUpdateCharacteristicsToGattServer(NULL, data, dataLen, LE_MULTICAST, pos);
1478 if (CA_STATUS_OK != ret)
1480 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1481 "CAUpdateCharacteristicsToGattServer Failed with return val [%d] ", ret);
1485 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1486 return CA_STATUS_OK;