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 "cafragmentation.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;
119 * @var g_clientErrorCallback
120 * @brief callback to update the error to le adapter
122 static CABLEErrorHandleCallback g_clientErrorCallback;
126 * @brief gmainLoop to manage the threads to receive the callback from the platfrom.
128 static GMainLoop *g_eventLoop = NULL;
131 * @var g_bleClientThreadPool
132 * @brief reference to threadpool
134 static ca_thread_pool_t g_bleClientThreadPool = NULL;
137 * @struct stGattServiceInfo_t
138 * @brief structure to map the service attribute to BD Address.
140 typedef struct gattService
142 bt_gatt_attribute_h serviceInfo; /**< bluetoth attribute for oic service*/
143 char *address; /**< BD Address of */
144 } stGattServiceInfo_t;
147 * @var g_remoteAddress
148 * @brief Remote address of Gatt Server
150 static char *g_remoteAddress = NULL;
152 void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic,
153 unsigned char *value,
154 int valueLen, void *userData)
156 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
158 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic is [%s]", (char *)characteristic);
159 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic value length [%d]", valueLen);
161 ca_mutex_lock(g_bleReqRespClientCbMutex);
162 if (NULL == g_bleClientDataReceivedCallback)
164 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespCallback is NULL!");
165 ca_mutex_unlock(g_bleReqRespClientCbMutex);
168 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending data up !");
170 ca_mutex_lock(g_bleServerBDAddressMutex);
171 uint32_t sentLength = 0;
172 g_bleClientDataReceivedCallback(g_remoteAddress, OIC_BLE_SERVICE_ID,
173 value, valueLen, &sentLength);
175 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Sent data Length is %d", sentLength);
176 ca_mutex_unlock(g_bleServerBDAddressMutex);
178 ca_mutex_unlock(g_bleReqRespClientCbMutex);
180 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
183 void CABleGattCharacteristicWriteCb(int result, void *userData)
185 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
188 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
191 void CABleGattDescriptorDiscoveredCb(int result, unsigned char format, int total,
192 bt_gatt_attribute_h descriptor,
193 bt_gatt_attribute_h characteristic, void *userData)
195 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
197 stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)OICCalloc(1, sizeof(
198 stGattCharDescriptor_t));
200 VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed!");
202 stTemp->desc = (uint8_t *)OICMalloc(total);
203 if (NULL == stTemp->desc)
205 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "malloc failed");
209 memcpy(stTemp->desc, descriptor, total);
211 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "result[%d] format[%d] total[%d]", result, format, total);
212 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "characteristic [%s]", (const char *) characteristic);
215 bt_gatt_clone_attribute_handle(&(stTemp->characteristic), characteristic);
216 stTemp->total = total;
218 ca_mutex_lock(g_bleClientThreadPoolMutex);
219 if (NULL == g_bleClientThreadPool)
221 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
222 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
223 OICFree(stTemp->desc);
225 ca_mutex_unlock(g_bleClientThreadPoolMutex);
229 CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
230 CASetCharacteristicDescriptorValueThread,
232 if (CA_STATUS_OK != ret)
234 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed");
235 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
236 OICFree(stTemp->desc);
238 ca_mutex_unlock(g_bleClientThreadPoolMutex);
242 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG,
243 "LE Client initialization flow complete");
245 ca_mutex_unlock(g_bleClientThreadPoolMutex);
247 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
250 bool CABleGattCharacteristicsDiscoveredCb(int result,
251 int inputIndex, int total,
252 bt_gatt_attribute_h characteristic, void *userData)
255 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
257 VERIFY_NON_NULL_RET(characteristic, TZ_BLE_CLIENT_TAG, "Param characteristic is NULL", false);
259 VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
261 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
262 "result [%d] input_index [%d] total [%d]",
263 result, inputIndex, total);
265 BLEServiceInfo *bleServiceInfo = NULL;
267 ca_mutex_lock(g_bleServiceListMutex);
269 char *bdAddress = (char *) userData;
270 CAGetBLEServiceInfo(g_bLEServiceList, bdAddress, &bleServiceInfo);
272 ca_mutex_unlock(g_bleServiceListMutex);
275 bt_gatt_get_service_uuid(characteristic, &uuid);
277 VERIFY_NON_NULL_RET(uuid, TZ_BLE_CLIENT_TAG, "uuid is NULL", false);
279 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "New Characteristics[%s] of uuid[%s] is obtained",
280 (char *)characteristic, uuid);
282 if(0 == strcasecmp(uuid, CA_BLE_READ_CHAR_UUID)) // Server will read on this characterisctics
284 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Read characteristics is obtained");
286 CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_READ_CHAR, bleServiceInfo);
287 if (CA_STATUS_OK != retVal)
289 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed! ");
293 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
294 sizeof(stGattServiceInfo_t));
296 VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "calloc failed!", false);
298 stTemp->address = OICStrdup(bdAddress);
299 if (NULL == stTemp->address)
301 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
306 bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), characteristic);
308 ca_mutex_lock(g_bleClientThreadPoolMutex);
309 if (NULL == g_bleClientThreadPool)
311 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
312 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
313 OICFree(stTemp->address);
315 ca_mutex_unlock(g_bleClientThreadPoolMutex);
319 retVal = ca_thread_pool_add_task(g_bleClientThreadPool,
320 CADiscoverDescriptorThread,
322 if (CA_STATUS_OK != retVal)
324 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
325 "ca_thread_pool_add_task failed with ret [%d]", retVal);
326 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
327 OICFree(stTemp->address);
329 ca_mutex_unlock(g_bleClientThreadPoolMutex);
332 ca_mutex_unlock(g_bleClientThreadPoolMutex);
334 else if (0 == strcasecmp(uuid, CA_BLE_WRITE_CHAR_UUID)) // Server will write on this characteristics.
337 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Write characteristics is obtained");
338 CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_WRITE_CHAR, bleServiceInfo);
339 if (CA_STATUS_OK != retVal)
341 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed ");
346 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
350 bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int index, int count,
353 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
355 VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "Param service is NULL", false);
357 VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
359 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s] index [%d] count [%d]", (char *)service,
362 CAResult_t result = CAVerifyOICServiceByServiceHandle(service);
364 if (CA_STATUS_OK == result)
366 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
368 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes");
370 result = CABleGattWatchCharacteristicChanges(service);
371 if (CA_STATUS_OK != result)
373 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
374 "CABleGattWatchCharacteristicChanges failed!");
378 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
379 sizeof(stGattServiceInfo_t));
380 VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "Calloc Failed", false);
382 char *bdAddress = (char *)userData;
384 stTemp->address = OICStrdup(bdAddress);
385 if (NULL == stTemp->address)
387 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
392 BLEServiceInfo *bleServiceInfo = NULL;
394 result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo);
395 if (CA_STATUS_OK != result)
397 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CACreateBLEServiceInfo failed! ");
398 OICFree(stTemp->address);
400 OICFree(bleServiceInfo);
403 if (NULL == bleServiceInfo )
405 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , " bleServiceInfo is NULL");
406 OICFree(stTemp->address);
408 OICFree(bleServiceInfo);
412 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG ,
413 " serviceInfo remote address [%s]", bleServiceInfo->bdAddress);
415 ca_mutex_lock(g_bleServiceListMutex);
416 result = CAAddBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo);
417 ca_mutex_unlock(g_bleServiceListMutex);
418 if (CA_STATUS_OK != result)
420 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAddBLEServiceInfoToList failed!");
421 OICFree(stTemp->address);
423 CAFreeBLEServiceInfo(bleServiceInfo);
428 ca_mutex_lock(g_bleClientThreadPoolMutex);
429 if (NULL == g_bleClientThreadPool)
431 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
432 OICFree(stTemp->address);
434 ca_mutex_lock(g_bleServiceListMutex);
435 CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
436 bleServiceInfo->bdAddress);
437 ca_mutex_unlock(g_bleServiceListMutex);
438 ca_mutex_unlock(g_bleClientThreadPoolMutex);
441 bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), service);
443 result = ca_thread_pool_add_task(g_bleClientThreadPool,
444 CADiscoverCharThread,
446 if (CA_STATUS_OK != result)
448 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
449 "ca_thread_pool_add_task failed with ret [%d]", result);
450 OICFree(stTemp->address);
452 ca_mutex_lock(g_bleServiceListMutex);
453 CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
454 bleServiceInfo->bdAddress);
455 ca_mutex_unlock(g_bleServiceListMutex);
456 ca_mutex_unlock(g_bleClientThreadPoolMutex);
459 ca_mutex_unlock(g_bleClientThreadPoolMutex);
462 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
466 void CABleGattConnectionStateChangedCb(int result, bool connected,
467 const char *remoteAddress, void *userData)
469 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
471 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "CABleGattConnectionStateChangedCb result[%d] ", result);
473 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
475 CAResult_t ret = CA_STATUS_FAILED;
478 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress);
480 ret = CABleGattStartDeviceDiscovery();
481 if (CA_STATUS_OK != ret)
483 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattStartDeviceDiscovery failed");
489 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Connected to [%s] ", remoteAddress);
491 ca_mutex_lock(g_bleServerBDAddressMutex);
493 g_remoteAddress = OICStrdup(remoteAddress);
495 ca_mutex_unlock(g_bleServerBDAddressMutex);
497 VERIFY_NON_NULL_VOID(g_remoteAddress, TZ_BLE_CLIENT_TAG, "Malloc failed");
499 char *addr = OICStrdup(remoteAddress);
501 ca_mutex_lock(g_bleClientThreadPoolMutex);
502 if (NULL == g_bleClientThreadPool)
504 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
507 ca_mutex_lock(g_bleServerBDAddressMutex);
508 OICFree(g_remoteAddress);
509 ca_mutex_unlock(g_bleServerBDAddressMutex);
511 ca_mutex_unlock(g_bleClientThreadPoolMutex);
515 ret = ca_thread_pool_add_task(g_bleClientThreadPool, CADiscoverBLEServicesThread,
517 if (CA_STATUS_OK != ret)
519 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
522 ca_mutex_lock(g_bleServerBDAddressMutex);
523 OICFree(g_remoteAddress);
524 ca_mutex_unlock(g_bleServerBDAddressMutex);
526 ca_mutex_unlock(g_bleClientThreadPoolMutex);
529 ca_mutex_unlock(g_bleClientThreadPoolMutex);
532 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
535 void CABtAdapterLeDeviceDiscoveryStateChangedCb(int result,
536 bt_adapter_le_device_discovery_state_e discoveryState,
537 bt_adapter_le_device_discovery_info_s *discoveryInfo,
540 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
542 if (NULL == discoveryInfo && BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND == discoveryState)
544 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL");
548 if (BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND != discoveryState)
550 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
551 " LE Discovery state is [%s]",
552 discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished");
556 CAPrintDiscoveryInformation(discoveryInfo);
558 if (discoveryInfo->service_uuid == NULL)
560 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "NO UUIDS from device");
564 for (int32_t i = discoveryInfo->service_count - 1; i >= 0; i--)
566 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "uuid[%d]: [%s]",
567 i, discoveryInfo->service_uuid[i]);
568 CAResult_t res = CAVerifyOICServiceByUUID(discoveryInfo->service_uuid[i]);
569 if (CA_STATUS_OK == res)
571 char *addr = OICStrdup(discoveryInfo->remote_address);
572 VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
574 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
575 "Trying to do Gatt connection to [%s]", addr);
577 ca_mutex_lock(g_bleClientThreadPoolMutex);
578 if (NULL == g_bleClientThreadPool)
580 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
582 ca_mutex_unlock(g_bleClientThreadPoolMutex);
586 CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
587 CAGattConnectThread, addr);
588 if (CA_STATUS_OK != ret)
590 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
591 "ca_thread_pool_add_task failed with ret [%d]", ret);
593 ca_mutex_unlock(g_bleClientThreadPoolMutex);
596 ca_mutex_unlock(g_bleClientThreadPoolMutex);
597 if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31)
599 bt_adapter_le_stop_device_discovery();
602 break; // Found the OIC Service. No need to verify remaining services.
607 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
611 void CAPrintDiscoveryInformation(const bt_adapter_le_device_discovery_info_s *discoveryInfo)
613 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
615 if (NULL == discoveryInfo)
617 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL ");
621 if (discoveryInfo->remote_address)
623 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Remote Address [%s]", discoveryInfo->remote_address);
626 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
627 " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
628 discoveryInfo->adv_data_len, discoveryInfo->scan_data_len, discoveryInfo->rssi,
629 discoveryInfo->address_type);
630 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
631 " Number of services present in device [%s] is [%d]",
632 discoveryInfo->remote_address, discoveryInfo->service_count);
634 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
637 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
639 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
641 ca_mutex_lock(g_bleClientThreadPoolMutex);
642 g_bleClientThreadPool = handle;
643 ca_mutex_unlock(g_bleClientThreadPoolMutex);
645 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
648 void CASetLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
650 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
652 ca_mutex_lock(g_bleReqRespClientCbMutex);
654 g_bleClientDataReceivedCallback = callback;
656 ca_mutex_unlock(g_bleReqRespClientCbMutex);
658 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
662 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
664 g_clientErrorCallback = callback;
667 CAResult_t CAStartLEGattClient()
669 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
671 CAResult_t retVal = CAInitGattClientMutexVariables();
673 if (CA_STATUS_OK != retVal)
675 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAInitGattClientMutexVariables failed!");
676 CATerminateGattClientMutexVariables();
677 return CA_STATUS_FAILED;
680 ca_mutex_lock(g_bleClientThreadPoolMutex);
681 if (NULL == g_bleClientThreadPool)
683 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleServerThreadPool is NULL");
684 CATerminateGattClientMutexVariables();
685 ca_mutex_unlock(g_bleClientThreadPoolMutex);
686 return CA_STATUS_FAILED;
689 retVal = ca_thread_pool_add_task(g_bleClientThreadPool, CAStartBleGattClientThread,
691 if (CA_STATUS_OK != retVal)
693 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed");
694 CATerminateGattClientMutexVariables();
695 ca_mutex_unlock(g_bleClientThreadPoolMutex);
696 return CA_STATUS_FAILED;
698 ca_mutex_unlock(g_bleClientThreadPoolMutex);
700 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
704 void CAStartBleGattClientThread(void *data)
706 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
708 ca_mutex_lock(g_bleClientStateMutex);
710 if (true == g_isBleGattClientStarted)
712 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is already running!!");
713 ca_mutex_unlock(g_bleClientStateMutex);
717 CAResult_t ret = CABleGattSetScanParameter();
718 if (CA_STATUS_OK != ret)
720 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleSetScanParameter Failed");
721 ca_mutex_unlock(g_bleClientStateMutex);
722 CATerminateLEGattClient();
726 ret = CABleGattSetCallbacks();
727 if (CA_STATUS_OK != ret)
729 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattSetCallbacks Failed");
730 ca_mutex_unlock(g_bleClientStateMutex);
731 CATerminateLEGattClient();
735 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Starting LE device discovery");
737 ret = CABleGattStartDeviceDiscovery();
738 if (CA_STATUS_OK != ret)
740 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed");
741 ca_mutex_unlock(g_bleClientStateMutex);
742 CATerminateLEGattClient();
746 g_isBleGattClientStarted = true;
748 ca_mutex_unlock(g_bleClientStateMutex);
750 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Giveing the control to threadPool");
752 GMainContext *thread_context = g_main_context_new();
754 g_eventLoop = g_main_loop_new(thread_context, FALSE);
756 g_main_context_push_thread_default(thread_context);
758 g_main_loop_run(g_eventLoop);
760 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
763 void CAStopLEGattClient()
765 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
767 ca_mutex_lock(g_bleClientStateMutex);
769 if (false == g_isBleGattClientStarted)
771 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is not running to stop");
772 ca_mutex_unlock(g_bleClientStateMutex);
776 CABleGattUnSetCallbacks();
778 CABleGattUnWatchCharacteristicChanges();
780 CABleGattStopDeviceDiscovery();
782 g_isBleGattClientStarted = false;
784 GMainContext *context_event_loop = NULL;
785 // Required for waking up the thread which is running in gmain loop
786 if (NULL != g_eventLoop)
788 context_event_loop = g_main_loop_get_context(g_eventLoop);
790 if (context_event_loop)
792 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "g_eventLoop context %x", context_event_loop);
793 g_main_context_wakeup(context_event_loop);
795 // Kill g main loops and kill threads.
796 g_main_loop_quit(g_eventLoop);
800 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_eventLoop context is NULL");
803 ca_mutex_unlock(g_bleClientStateMutex);
805 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
808 void CATerminateLEGattClient()
810 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
811 ca_mutex_lock(g_bleClientStateMutex);
813 ca_mutex_lock(g_bleServerBDAddressMutex);
815 OICFree(g_remoteAddress);
817 ca_mutex_unlock(g_bleServerBDAddressMutex);
819 ca_mutex_lock(g_bleServiceListMutex);
820 CAFreeBLEServiceList(g_bLEServiceList);
821 g_bLEServiceList = NULL;
822 ca_mutex_unlock(g_bleServiceListMutex);
824 CAResetRegisteredServiceCount();
826 ca_mutex_unlock(g_bleClientStateMutex);
828 CATerminateGattClientMutexVariables();
830 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
833 CAResult_t CAInitGattClientMutexVariables()
835 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
836 if (NULL == g_bleClientStateMutex)
838 g_bleClientStateMutex = ca_mutex_new();
839 if (NULL == g_bleClientStateMutex)
841 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
842 return CA_STATUS_FAILED;
846 if (NULL == g_bleServiceListMutex)
848 g_bleServiceListMutex = ca_mutex_new();
849 if (NULL == g_bleServiceListMutex)
851 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
852 return CA_STATUS_FAILED;
856 if (NULL == g_bleReqRespClientCbMutex)
858 g_bleReqRespClientCbMutex = ca_mutex_new();
859 if (NULL == g_bleReqRespClientCbMutex)
861 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
862 return CA_STATUS_FAILED;
866 if (NULL == g_bleClientThreadPoolMutex)
868 g_bleClientThreadPoolMutex = ca_mutex_new();
869 if (NULL == g_bleClientThreadPoolMutex)
871 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
872 return CA_STATUS_FAILED;
876 if (NULL == g_bleClientConnectMutex)
878 g_bleClientConnectMutex = ca_mutex_new();
879 if (NULL == g_bleClientConnectMutex)
881 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
882 return CA_STATUS_FAILED;
886 if (NULL == g_bleClientSendCondWait)
888 g_bleClientSendCondWait = ca_cond_new();
889 if (NULL == g_bleClientSendCondWait)
891 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_cond_new failed");
892 return CA_STATUS_FAILED;
896 if (NULL == g_bleServerBDAddressMutex)
898 g_bleServerBDAddressMutex = ca_mutex_new();
899 if (NULL == g_bleServerBDAddressMutex)
901 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
902 return CA_STATUS_FAILED;
906 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
910 void CATerminateGattClientMutexVariables()
912 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
914 ca_mutex_free(g_bleClientStateMutex);
915 g_bleClientStateMutex = NULL;
917 ca_mutex_free(g_bleServiceListMutex);
918 g_bleServiceListMutex = NULL;
920 ca_mutex_free(g_bleReqRespClientCbMutex);
921 g_bleReqRespClientCbMutex = NULL;
923 ca_mutex_free(g_bleClientConnectMutex);
924 g_bleClientConnectMutex = NULL;
926 ca_mutex_free(g_bleClientThreadPoolMutex);
927 g_bleClientThreadPoolMutex = NULL;
929 ca_mutex_free(g_bleServerBDAddressMutex);
930 g_bleServerBDAddressMutex = NULL;
932 ca_cond_free(g_bleClientSendCondWait);
933 g_bleClientSendCondWait = NULL;
936 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
939 CAResult_t CABleGattSetScanParameter()
941 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
943 bt_adapter_le_scan_params_s scan_param = { 0, };
944 scan_param.type = BT_ADAPTER_LE_PASSIVE_SCAN;
945 scan_param.interval = 1560;
946 scan_param.window = 160;
948 int ret = bt_adapter_le_set_scan_parameter(&scan_param);
949 if (BT_ERROR_NONE != ret)
951 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_set_scan_parameter Failed with ret [%d]", ret);
952 return CA_STATUS_FAILED;
955 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
959 CAResult_t CABleGattSetCallbacks()
961 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
963 int ret = bt_gatt_set_connection_state_changed_cb(CABleGattConnectionStateChangedCb, NULL);
964 if (BT_ERROR_NONE != ret)
966 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
967 "bt_gatt_set_connection_state_changed_cb Failed with return as [%s ]",
968 CABTGetErrorMsg(ret));
969 return CA_STATUS_FAILED;
972 ret = bt_adapter_le_set_device_discovery_state_changed_cb(
973 CABtAdapterLeDeviceDiscoveryStateChangedCb, NULL);
974 if (BT_ERROR_NONE != ret)
976 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
977 "bt_adapter_le_set_device_discovery_state_changed_cb Failed with return as [%s ]",
978 CABTGetErrorMsg(ret));;
979 return CA_STATUS_FAILED;
982 ret = bt_gatt_set_characteristic_changed_cb(CABleGattCharacteristicChangedCb, NULL);
983 if (BT_ERROR_NONE != ret)
985 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_set_characteristic_changed_cb Failed as [%s ]",
986 CABTGetErrorMsg(ret));
987 return CA_STATUS_FAILED;
990 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
994 void CABleGattUnSetCallbacks()
996 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
998 bt_gatt_unset_characteristic_changed_cb();
1000 bt_gatt_unset_connection_state_changed_cb();
1002 bt_adapter_le_unset_device_discovery_state_changed_cb();
1004 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1007 CAResult_t CABleGattWatchCharacteristicChanges(bt_gatt_attribute_h service)
1009 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1011 int ret = bt_gatt_watch_characteristic_changes(service);
1012 if (BT_ERROR_NONE != ret)
1014 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1015 "bt_gatt_watch_characteristic_changes failed with [%s]",
1016 CABTGetErrorMsg(ret));
1018 return CA_STATUS_FAILED;
1021 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1022 return CA_STATUS_OK;
1025 void CABleGattUnWatchCharacteristicChanges()
1027 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1029 int32_t count = CAGetRegisteredServiceCount();
1031 for (int32_t index = 0; index < count; index++)
1033 BLEServiceInfo *bleServiceInfo = NULL;
1035 ca_mutex_lock(g_bleServiceListMutex);
1037 CAResult_t result = CAGetBLEServiceInfoByPosition(g_bLEServiceList, index, &bleServiceInfo);
1038 if (CA_STATUS_OK == result && NULL != bleServiceInfo
1039 && NULL != bleServiceInfo->service_clone)
1041 bt_gatt_unwatch_characteristic_changes(bleServiceInfo->service_clone);
1042 OIC_LOG(INFO, TZ_BLE_CLIENT_TAG, "bt_gatt_unwatch_characteristic_changes done");
1045 ca_mutex_unlock(g_bleServiceListMutex);
1048 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1051 CAResult_t CABleGattStartDeviceDiscovery()
1053 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1054 bool isDiscovering = false;
1056 int ret = bt_adapter_le_is_discovering(&isDiscovering);
1057 if (BT_ERROR_NONE != ret)
1059 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_is_discovering Failed");
1060 return CA_STATUS_FAILED;
1065 ret = bt_adapter_le_start_device_discovery();
1066 if (BT_ERROR_NONE != ret)
1068 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed Ret: %d, %x", ret, ret);
1069 return CA_STATUS_FAILED;
1073 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1074 return CA_STATUS_OK;
1077 void CABleGattStopDeviceDiscovery()
1079 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1081 bool isDiscovering = false;
1083 int ret = bt_adapter_le_is_discovering(&isDiscovering);
1084 if (BT_ERROR_NONE != ret)
1086 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_is_discovering Failed");
1092 ret = bt_adapter_le_stop_device_discovery();
1093 if (BT_ERROR_NONE != ret)
1095 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_stop_device_discovery Failed");
1100 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1103 void CAGattConnectThread (void *remoteAddress)
1105 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
1107 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1109 char *address = (char *)remoteAddress;
1111 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address is [%s]", address);
1113 CAResult_t result = CABleGattConnect(address);
1115 if (CA_STATUS_OK != result)
1117 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect failed for [%s]", address);
1122 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1125 CAResult_t CABleGattConnect(const char *remoteAddress)
1127 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1129 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1130 "remote address is NULL", CA_STATUS_FAILED);
1132 //Because of the platform issue, we added. Once platform is stablized, then it will be removed
1135 ca_mutex_lock(g_bleClientConnectMutex);
1137 int ret = bt_gatt_connect(remoteAddress, true);
1139 if (BT_ERROR_NONE != ret)
1141 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect Failed with ret value [%s] ",
1142 CABTGetErrorMsg(ret));
1143 ca_mutex_unlock(g_bleClientConnectMutex);
1144 return CA_STATUS_FAILED;
1146 ca_mutex_unlock(g_bleClientConnectMutex);
1148 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1149 return CA_STATUS_OK;
1152 CAResult_t CABleGattDisConnect(const char *remoteAddress)
1154 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1156 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1157 "remote address is NULL", CA_STATUS_FAILED);
1159 int32_t ret = bt_gatt_disconnect(remoteAddress);
1161 if (BT_ERROR_NONE != ret)
1163 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_disconnect Failed with ret value [%d] ",
1165 return CA_STATUS_FAILED;
1168 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1169 return CA_STATUS_OK;
1172 void CADiscoverBLEServicesThread (void *remoteAddress)
1174 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1176 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1178 char *address = (char *)remoteAddress;
1180 CAResult_t result = CABleGattDiscoverServices(address);
1181 if (CA_STATUS_OK != result)
1183 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattDiscoverServices failed");
1188 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1191 CAResult_t CABleGattDiscoverServices(const char *remoteAddress)
1193 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1195 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1196 "remote address is NULL", CA_STATUS_FAILED);
1198 char *addr = OICStrdup(remoteAddress);
1199 VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
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 char *addr = OICStrdup(remoteAddress);
1258 VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
1260 int32_t ret = bt_gatt_discover_characteristics(service, CABleGattCharacteristicsDiscoveredCb,
1261 (void *)addr); // addr will be freed in callback.
1262 if (BT_ERROR_NONE != ret)
1264 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1265 "bt_gatt_discover_characteristics failed with error [%d]", ret);
1267 return CA_STATUS_FAILED;
1270 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1271 return CA_STATUS_OK;
1274 void CADiscoverDescriptorThread(void *stServiceInfo)
1276 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " IN");
1278 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1280 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)stServiceInfo;
1282 CAResult_t result = CABleGattDiscoverDescriptor(stTemp->serviceInfo, NULL);
1283 if (CA_STATUS_OK != result)
1285 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
1286 "bt_gatt_discover_characteristic_descriptor failed");
1287 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1288 OICFree(stTemp->address);
1293 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1294 OICFree(stTemp->address);
1297 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1300 CAResult_t CABleGattDiscoverDescriptor(bt_gatt_attribute_h service, const char *remoteAddress)
1302 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1304 VERIFY_NON_NULL_RET(service, NULL, "service is NULL", CA_STATUS_FAILED);
1306 int ret = bt_gatt_discover_characteristic_descriptor(service,
1307 CABleGattDescriptorDiscoveredCb, NULL);
1308 if (BT_ERROR_NONE != ret)
1310 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1311 "bt_gatt_discover_characteristic_descriptor failed with returns[%s]",
1312 CABTGetErrorMsg(ret));
1313 return CA_STATUS_FAILED;
1316 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1317 return CA_STATUS_OK;
1320 void CASetCharacteristicDescriptorValueThread(void *stServiceInfo)
1322 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1324 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1326 stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)stServiceInfo;
1328 CAResult_t result = CASetCharacteristicDescriptorValue(stTemp);
1329 if (CA_STATUS_OK != result)
1331 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CASetCharacteristicDescriptorValue failed!");
1332 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1333 OICFree(stTemp->desc);
1337 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1338 OICFree(stTemp->desc);
1341 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1344 CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescInfo)
1346 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1348 unsigned char noti[4] = {0,};
1350 char *strUUID = (char *)OICCalloc(5, sizeof(char));
1352 VERIFY_NON_NULL_RET(strUUID, TZ_BLE_CLIENT_TAG, "calloc failed", CA_STATUS_FAILED);
1354 snprintf(strUUID, 4, "%x%x", stGattCharDescInfo->desc[3], stGattCharDescInfo->desc[2]);
1355 noti[0] = stGattCharDescInfo->desc[0];
1356 noti[1] = stGattCharDescInfo->desc[1];
1360 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x0 [%x]", stGattCharDescInfo->desc[0]);
1361 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x1 [%x]", stGattCharDescInfo->desc[1]);
1362 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x2 [%x]", stGattCharDescInfo->desc[2]);
1363 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x3 [%x]", stGattCharDescInfo->desc[3]);
1366 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG strUUID is [%s]",
1368 //if (!strncmp(strUUID, BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG, 2))
1370 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "setting notification/indication for descriptor");
1372 int ret = bt_gatt_set_characteristic_desc_value_request(
1373 stGattCharDescInfo->characteristic,
1374 noti, 4, CABleGattCharacteristicWriteCb);
1375 if (BT_ERROR_NONE != ret)
1377 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1378 "bt_gatt_set_characteristic_desc_value_request failed with return[%s]",
1379 CABTGetErrorMsg(ret));
1381 return CA_STATUS_FAILED;
1386 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1387 return CA_STATUS_OK;
1390 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
1391 const char *data, const uint32_t dataLen,
1392 CALETransferType_t type, const int32_t position)
1394 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1396 VERIFY_NON_NULL(data, NULL, "data is NULL");
1400 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input!");
1401 return CA_STATUS_INVALID_PARAM;
1404 BLEServiceInfo *bleServiceInfo = NULL;
1406 CAResult_t ret = CA_STATUS_FAILED;
1408 ca_mutex_lock(g_bleServiceListMutex);
1409 if ( LE_UNICAST == type)
1411 VERIFY_NON_NULL(remoteAddress, NULL, "remoteAddress is NULL");
1413 ret = CAGetBLEServiceInfo(g_bLEServiceList, remoteAddress, &bleServiceInfo);
1415 else if ( LE_MULTICAST == type)
1417 ret = CAGetBLEServiceInfoByPosition(g_bLEServiceList, position, &bleServiceInfo);
1419 ca_mutex_unlock(g_bleServiceListMutex);
1421 if (CA_STATUS_OK != ret)
1423 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAGetBLEServiceInfoByPosition is failed");
1424 return CA_STATUS_FAILED;
1427 VERIFY_NON_NULL(bleServiceInfo, NULL, "bleServiceInfo is NULL");
1429 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating the data of length [%d] to [%s] ", dataLen,
1430 bleServiceInfo->bdAddress);
1432 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating to write char [%s]",
1433 bleServiceInfo->read_char);
1435 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
1436 "Updating the data of length [%d] to [%s]", dataLen,
1437 bleServiceInfo->bdAddress);
1439 int result = bt_gatt_set_characteristic_value(bleServiceInfo->write_char, (unsigned char *)data,
1441 if (BT_ERROR_NONE != result)
1443 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1444 "bt_gatt_set_characteristic_value Failed with return val [%d]",
1446 return CA_STATUS_FAILED;
1449 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1450 return CA_STATUS_OK;
1453 CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data,
1456 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1458 VERIFY_NON_NULL(data, NULL, "data is NULL");
1462 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input !");
1463 return CA_STATUS_INVALID_PARAM;
1466 int numOfServersConnected = CAGetRegisteredServiceCount();
1468 for (int32_t pos = 0; pos < numOfServersConnected; pos++)
1470 /*remoteAddress will be NULL.
1471 Since we have to send to all destinations. pos will be used for getting remote address.
1473 CAResult_t ret = CAUpdateCharacteristicsToGattServer(NULL, data, dataLen, LE_MULTICAST, pos);
1475 if (CA_STATUS_OK != ret)
1477 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1478 "CAUpdateCharacteristicsToGattServer Failed with return val [%d] ", ret);
1479 g_clientErrorCallback(NULL, data, dataLen, ret);
1484 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1485 return CA_STATUS_OK;