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 ");
348 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "service_uuid characteristics is UNKNOWN");
352 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
356 bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int index, int count,
359 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
361 VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "Param service is NULL", false);
363 VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
365 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s] index [%d] count [%d]", (char *)service,
368 CAResult_t result = CAVerifyOICServiceByServiceHandle(service);
370 if (CA_STATUS_OK == result)
372 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
374 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes");
376 result = CABleGattWatchCharacteristicChanges(service);
377 if (CA_STATUS_OK != result)
379 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
380 "CABleGattWatchCharacteristicChanges failed!");
384 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
385 sizeof(stGattServiceInfo_t));
386 VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "Calloc Failed", false);
388 char *bdAddress = (char *)userData;
390 stTemp->address = OICStrdup(bdAddress);
391 if (NULL == stTemp->address)
393 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
398 BLEServiceInfo *bleServiceInfo = NULL;
400 result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo);
401 if (CA_STATUS_OK != result)
403 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CACreateBLEServiceInfo failed! ");
404 OICFree(stTemp->address);
406 OICFree(bleServiceInfo);
409 if (NULL == bleServiceInfo )
411 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , " bleServiceInfo is NULL");
412 OICFree(stTemp->address);
414 OICFree(bleServiceInfo);
418 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG ,
419 " serviceInfo remote address [%s]", bleServiceInfo->bdAddress);
421 ca_mutex_lock(g_bleServiceListMutex);
422 result = CAAddBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo);
423 ca_mutex_unlock(g_bleServiceListMutex);
424 if (CA_STATUS_OK != result)
426 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAddBLEServiceInfoToList failed!");
427 OICFree(stTemp->address);
429 CAFreeBLEServiceInfo(bleServiceInfo);
434 ca_mutex_lock(g_bleClientThreadPoolMutex);
435 if (NULL == g_bleClientThreadPool)
437 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
438 OICFree(stTemp->address);
440 ca_mutex_lock(g_bleServiceListMutex);
441 CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
442 bleServiceInfo->bdAddress);
443 ca_mutex_unlock(g_bleServiceListMutex);
444 ca_mutex_unlock(g_bleClientThreadPoolMutex);
447 bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), service);
449 result = ca_thread_pool_add_task(g_bleClientThreadPool,
450 CADiscoverCharThread,
452 if (CA_STATUS_OK != result)
454 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
455 "ca_thread_pool_add_task failed with ret [%d]", result);
456 OICFree(stTemp->address);
458 ca_mutex_lock(g_bleServiceListMutex);
459 CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
460 bleServiceInfo->bdAddress);
461 ca_mutex_unlock(g_bleServiceListMutex);
462 ca_mutex_unlock(g_bleClientThreadPoolMutex);
465 ca_mutex_unlock(g_bleClientThreadPoolMutex);
468 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
472 void CABleGattConnectionStateChangedCb(int result, bool connected,
473 const char *remoteAddress, void *userData)
475 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
477 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "CABleGattConnectionStateChangedCb result[%d] ", result);
479 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
481 CAResult_t ret = CA_STATUS_FAILED;
484 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress);
486 ret = CABleGattStartDeviceDiscovery();
487 if (CA_STATUS_OK != ret)
489 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattStartDeviceDiscovery failed");
495 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Connected to [%s] ", remoteAddress);
497 ca_mutex_lock(g_bleServerBDAddressMutex);
499 g_remoteAddress = OICStrdup(remoteAddress);
501 ca_mutex_unlock(g_bleServerBDAddressMutex);
503 VERIFY_NON_NULL_VOID(g_remoteAddress, TZ_BLE_CLIENT_TAG, "Malloc failed");
505 char *addr = OICStrdup(remoteAddress);
507 ca_mutex_lock(g_bleClientThreadPoolMutex);
508 if (NULL == g_bleClientThreadPool)
510 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
513 ca_mutex_lock(g_bleServerBDAddressMutex);
514 OICFree(g_remoteAddress);
515 ca_mutex_unlock(g_bleServerBDAddressMutex);
517 ca_mutex_unlock(g_bleClientThreadPoolMutex);
521 ret = ca_thread_pool_add_task(g_bleClientThreadPool, CADiscoverBLEServicesThread,
523 if (CA_STATUS_OK != ret)
525 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
528 ca_mutex_lock(g_bleServerBDAddressMutex);
529 OICFree(g_remoteAddress);
530 ca_mutex_unlock(g_bleServerBDAddressMutex);
532 ca_mutex_unlock(g_bleClientThreadPoolMutex);
535 ca_mutex_unlock(g_bleClientThreadPoolMutex);
538 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
541 void CABtAdapterLeDeviceDiscoveryStateChangedCb(int result,
542 bt_adapter_le_device_discovery_state_e discoveryState,
543 bt_adapter_le_device_discovery_info_s *discoveryInfo,
546 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
548 if (NULL == discoveryInfo && BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND == discoveryState)
550 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL");
554 if (BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND != discoveryState)
556 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
557 " LE Discovery state is [%s]",
558 discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished");
562 CAPrintDiscoveryInformation(discoveryInfo);
564 if (discoveryInfo->service_uuid == NULL)
566 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "NO UUIDS from device");
570 for (int32_t i = discoveryInfo->service_count - 1; i >= 0; i--)
572 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "uuid[%d]: [%s]",
573 i, discoveryInfo->service_uuid[i]);
574 CAResult_t res = CAVerifyOICServiceByUUID(discoveryInfo->service_uuid[i]);
575 if (CA_STATUS_OK == res)
577 char *addr = OICStrdup(discoveryInfo->remote_address);
578 VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
580 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
581 "Trying to do Gatt connection to [%s]", addr);
583 ca_mutex_lock(g_bleClientThreadPoolMutex);
584 if (NULL == g_bleClientThreadPool)
586 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
588 ca_mutex_unlock(g_bleClientThreadPoolMutex);
592 CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
593 CAGattConnectThread, addr);
594 if (CA_STATUS_OK != ret)
596 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
597 "ca_thread_pool_add_task failed with ret [%d]", ret);
599 ca_mutex_unlock(g_bleClientThreadPoolMutex);
602 ca_mutex_unlock(g_bleClientThreadPoolMutex);
603 if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31)
605 bt_adapter_le_stop_device_discovery();
608 break; // Found the OIC Service. No need to verify remaining services.
613 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
617 void CAPrintDiscoveryInformation(const bt_adapter_le_device_discovery_info_s *discoveryInfo)
619 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
621 if (NULL == discoveryInfo)
623 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL ");
627 if (discoveryInfo->remote_address)
629 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Remote Address [%s]", discoveryInfo->remote_address);
632 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
633 " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
634 discoveryInfo->adv_data_len, discoveryInfo->scan_data_len, discoveryInfo->rssi,
635 discoveryInfo->address_type);
636 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
637 " Number of services present in device [%s] is [%d]",
638 discoveryInfo->remote_address, discoveryInfo->service_count);
640 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
643 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
645 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
647 ca_mutex_lock(g_bleClientThreadPoolMutex);
648 g_bleClientThreadPool = handle;
649 ca_mutex_unlock(g_bleClientThreadPoolMutex);
651 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
654 void CASetLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
656 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
658 ca_mutex_lock(g_bleReqRespClientCbMutex);
660 g_bleClientDataReceivedCallback = callback;
662 ca_mutex_unlock(g_bleReqRespClientCbMutex);
664 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
668 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
670 g_clientErrorCallback = callback;
673 CAResult_t CAStartLEGattClient()
675 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
677 CAResult_t retVal = CAInitGattClientMutexVariables();
679 if (CA_STATUS_OK != retVal)
681 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAInitGattClientMutexVariables failed!");
682 CATerminateGattClientMutexVariables();
683 return CA_STATUS_FAILED;
686 ca_mutex_lock(g_bleClientThreadPoolMutex);
687 if (NULL == g_bleClientThreadPool)
689 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleServerThreadPool is NULL");
690 CATerminateGattClientMutexVariables();
691 ca_mutex_unlock(g_bleClientThreadPoolMutex);
692 return CA_STATUS_FAILED;
695 retVal = ca_thread_pool_add_task(g_bleClientThreadPool, CAStartBleGattClientThread,
697 if (CA_STATUS_OK != retVal)
699 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed");
700 CATerminateGattClientMutexVariables();
701 ca_mutex_unlock(g_bleClientThreadPoolMutex);
702 return CA_STATUS_FAILED;
704 ca_mutex_unlock(g_bleClientThreadPoolMutex);
706 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
710 void CAStartBleGattClientThread(void *data)
712 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
714 ca_mutex_lock(g_bleClientStateMutex);
716 if (true == g_isBleGattClientStarted)
718 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is already running!!");
719 ca_mutex_unlock(g_bleClientStateMutex);
723 CAResult_t ret = CABleGattSetScanParameter();
724 if (CA_STATUS_OK != ret)
726 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleSetScanParameter Failed");
727 ca_mutex_unlock(g_bleClientStateMutex);
728 CATerminateLEGattClient();
732 ret = CABleGattSetCallbacks();
733 if (CA_STATUS_OK != ret)
735 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattSetCallbacks Failed");
736 ca_mutex_unlock(g_bleClientStateMutex);
737 CATerminateLEGattClient();
741 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Starting LE device discovery");
743 ret = CABleGattStartDeviceDiscovery();
744 if (CA_STATUS_OK != ret)
746 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed");
747 ca_mutex_unlock(g_bleClientStateMutex);
748 CATerminateLEGattClient();
752 g_isBleGattClientStarted = true;
754 ca_mutex_unlock(g_bleClientStateMutex);
756 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Giveing the control to threadPool");
758 GMainContext *thread_context = g_main_context_new();
760 g_eventLoop = g_main_loop_new(thread_context, FALSE);
762 g_main_context_push_thread_default(thread_context);
764 g_main_loop_run(g_eventLoop);
766 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
769 void CAStopLEGattClient()
771 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
773 ca_mutex_lock(g_bleClientStateMutex);
775 if (false == g_isBleGattClientStarted)
777 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is not running to stop");
778 ca_mutex_unlock(g_bleClientStateMutex);
782 CABleGattUnSetCallbacks();
784 CABleGattUnWatchCharacteristicChanges();
786 CABleGattStopDeviceDiscovery();
788 g_isBleGattClientStarted = false;
790 GMainContext *context_event_loop = NULL;
791 // Required for waking up the thread which is running in gmain loop
792 if (NULL != g_eventLoop)
794 context_event_loop = g_main_loop_get_context(g_eventLoop);
796 if (context_event_loop)
798 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "g_eventLoop context %x", context_event_loop);
799 g_main_context_wakeup(context_event_loop);
801 // Kill g main loops and kill threads.
802 g_main_loop_quit(g_eventLoop);
806 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_eventLoop context is NULL");
809 ca_mutex_unlock(g_bleClientStateMutex);
811 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
814 void CATerminateLEGattClient()
816 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
817 ca_mutex_lock(g_bleClientStateMutex);
819 ca_mutex_lock(g_bleServerBDAddressMutex);
821 OICFree(g_remoteAddress);
823 ca_mutex_unlock(g_bleServerBDAddressMutex);
825 ca_mutex_lock(g_bleServiceListMutex);
826 CAFreeBLEServiceList(g_bLEServiceList);
827 g_bLEServiceList = NULL;
828 ca_mutex_unlock(g_bleServiceListMutex);
830 CAResetRegisteredServiceCount();
832 ca_mutex_unlock(g_bleClientStateMutex);
834 CATerminateGattClientMutexVariables();
836 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
839 CAResult_t CAInitGattClientMutexVariables()
841 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
842 if (NULL == g_bleClientStateMutex)
844 g_bleClientStateMutex = ca_mutex_new();
845 if (NULL == g_bleClientStateMutex)
847 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
848 return CA_STATUS_FAILED;
852 if (NULL == g_bleServiceListMutex)
854 g_bleServiceListMutex = ca_mutex_new();
855 if (NULL == g_bleServiceListMutex)
857 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
858 return CA_STATUS_FAILED;
862 if (NULL == g_bleReqRespClientCbMutex)
864 g_bleReqRespClientCbMutex = ca_mutex_new();
865 if (NULL == g_bleReqRespClientCbMutex)
867 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
868 return CA_STATUS_FAILED;
872 if (NULL == g_bleClientThreadPoolMutex)
874 g_bleClientThreadPoolMutex = ca_mutex_new();
875 if (NULL == g_bleClientThreadPoolMutex)
877 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
878 return CA_STATUS_FAILED;
882 if (NULL == g_bleClientConnectMutex)
884 g_bleClientConnectMutex = ca_mutex_new();
885 if (NULL == g_bleClientConnectMutex)
887 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
888 return CA_STATUS_FAILED;
892 if (NULL == g_bleClientSendCondWait)
894 g_bleClientSendCondWait = ca_cond_new();
895 if (NULL == g_bleClientSendCondWait)
897 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_cond_new failed");
898 return CA_STATUS_FAILED;
902 if (NULL == g_bleServerBDAddressMutex)
904 g_bleServerBDAddressMutex = ca_mutex_new();
905 if (NULL == g_bleServerBDAddressMutex)
907 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
908 return CA_STATUS_FAILED;
912 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
916 void CATerminateGattClientMutexVariables()
918 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
920 ca_mutex_free(g_bleClientStateMutex);
921 g_bleClientStateMutex = NULL;
923 ca_mutex_free(g_bleServiceListMutex);
924 g_bleServiceListMutex = NULL;
926 ca_mutex_free(g_bleReqRespClientCbMutex);
927 g_bleReqRespClientCbMutex = NULL;
929 ca_mutex_free(g_bleClientConnectMutex);
930 g_bleClientConnectMutex = NULL;
932 ca_mutex_free(g_bleClientThreadPoolMutex);
933 g_bleClientThreadPoolMutex = NULL;
935 ca_mutex_free(g_bleServerBDAddressMutex);
936 g_bleServerBDAddressMutex = NULL;
938 ca_cond_free(g_bleClientSendCondWait);
939 g_bleClientSendCondWait = NULL;
942 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
945 CAResult_t CABleGattSetScanParameter()
947 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
949 bt_adapter_le_scan_params_s scan_param = { 0, };
950 scan_param.type = BT_ADAPTER_LE_PASSIVE_SCAN;
951 scan_param.interval = 1560;
952 scan_param.window = 160;
954 int ret = bt_adapter_le_set_scan_parameter(&scan_param);
955 if (BT_ERROR_NONE != ret)
957 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_set_scan_parameter Failed with ret [%d]", ret);
958 return CA_STATUS_FAILED;
961 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
965 CAResult_t CABleGattSetCallbacks()
967 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
969 int ret = bt_gatt_set_connection_state_changed_cb(CABleGattConnectionStateChangedCb, NULL);
970 if (BT_ERROR_NONE != ret)
972 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
973 "bt_gatt_set_connection_state_changed_cb Failed with return as [%s ]",
974 CABTGetErrorMsg(ret));
975 return CA_STATUS_FAILED;
978 ret = bt_adapter_le_set_device_discovery_state_changed_cb(
979 CABtAdapterLeDeviceDiscoveryStateChangedCb, NULL);
980 if (BT_ERROR_NONE != ret)
982 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
983 "bt_adapter_le_set_device_discovery_state_changed_cb Failed with return as [%s ]",
984 CABTGetErrorMsg(ret));;
985 return CA_STATUS_FAILED;
988 ret = bt_gatt_set_characteristic_changed_cb(CABleGattCharacteristicChangedCb, NULL);
989 if (BT_ERROR_NONE != ret)
991 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_set_characteristic_changed_cb Failed as [%s ]",
992 CABTGetErrorMsg(ret));
993 return CA_STATUS_FAILED;
996 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1000 void CABleGattUnSetCallbacks()
1002 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1004 bt_gatt_unset_characteristic_changed_cb();
1006 bt_gatt_unset_connection_state_changed_cb();
1008 bt_adapter_le_unset_device_discovery_state_changed_cb();
1010 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1013 CAResult_t CABleGattWatchCharacteristicChanges(bt_gatt_attribute_h service)
1015 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1017 int ret = bt_gatt_watch_characteristic_changes(service);
1018 if (BT_ERROR_NONE != ret)
1020 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1021 "bt_gatt_watch_characteristic_changes failed with [%s]",
1022 CABTGetErrorMsg(ret));
1024 return CA_STATUS_FAILED;
1027 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1028 return CA_STATUS_OK;
1031 void CABleGattUnWatchCharacteristicChanges()
1033 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1035 int32_t count = CAGetRegisteredServiceCount();
1037 for (int32_t index = 0; index < count; index++)
1039 BLEServiceInfo *bleServiceInfo = NULL;
1041 ca_mutex_lock(g_bleServiceListMutex);
1043 CAResult_t result = CAGetBLEServiceInfoByPosition(g_bLEServiceList, index, &bleServiceInfo);
1044 if (CA_STATUS_OK == result && NULL != bleServiceInfo
1045 && NULL != bleServiceInfo->service_clone)
1047 bt_gatt_unwatch_characteristic_changes(bleServiceInfo->service_clone);
1048 OIC_LOG(INFO, TZ_BLE_CLIENT_TAG, "bt_gatt_unwatch_characteristic_changes done");
1051 ca_mutex_unlock(g_bleServiceListMutex);
1054 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1057 CAResult_t CABleGattStartDeviceDiscovery()
1059 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1060 bool isDiscovering = false;
1062 int ret = bt_adapter_le_is_discovering(&isDiscovering);
1063 if (BT_ERROR_NONE != ret)
1065 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_is_discovering Failed");
1066 return CA_STATUS_FAILED;
1071 ret = bt_adapter_le_start_device_discovery();
1072 if (BT_ERROR_NONE != ret)
1074 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed Ret: %d, %x", ret, ret);
1075 return CA_STATUS_FAILED;
1079 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1080 return CA_STATUS_OK;
1083 void CABleGattStopDeviceDiscovery()
1085 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1087 bool isDiscovering = false;
1089 int ret = bt_adapter_le_is_discovering(&isDiscovering);
1090 if (BT_ERROR_NONE != ret)
1092 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_is_discovering Failed");
1098 ret = bt_adapter_le_stop_device_discovery();
1099 if (BT_ERROR_NONE != ret)
1101 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_stop_device_discovery Failed");
1106 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1109 void CAGattConnectThread (void *remoteAddress)
1111 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
1113 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1115 char *address = (char *)remoteAddress;
1117 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address is [%s]", address);
1119 CAResult_t result = CABleGattConnect(address);
1121 if (CA_STATUS_OK != result)
1123 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect failed for [%s]", address);
1128 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1131 CAResult_t CABleGattConnect(const char *remoteAddress)
1133 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1135 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1136 "remote address is NULL", CA_STATUS_FAILED);
1138 //Because of the platform issue, we added. Once platform is stablized, then it will be removed
1141 ca_mutex_lock(g_bleClientConnectMutex);
1143 int ret = bt_gatt_connect(remoteAddress, true);
1145 if (BT_ERROR_NONE != ret)
1147 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect Failed with ret value [%s] ",
1148 CABTGetErrorMsg(ret));
1149 ca_mutex_unlock(g_bleClientConnectMutex);
1150 return CA_STATUS_FAILED;
1152 ca_mutex_unlock(g_bleClientConnectMutex);
1154 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1155 return CA_STATUS_OK;
1158 CAResult_t CABleGattDisConnect(const char *remoteAddress)
1160 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1162 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1163 "remote address is NULL", CA_STATUS_FAILED);
1165 int32_t ret = bt_gatt_disconnect(remoteAddress);
1167 if (BT_ERROR_NONE != ret)
1169 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_disconnect Failed with ret value [%d] ",
1171 return CA_STATUS_FAILED;
1174 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1175 return CA_STATUS_OK;
1178 void CADiscoverBLEServicesThread (void *remoteAddress)
1180 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1182 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1184 char *address = (char *)remoteAddress;
1186 CAResult_t result = CABleGattDiscoverServices(address);
1187 if (CA_STATUS_OK != result)
1189 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattDiscoverServices failed");
1194 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1197 CAResult_t CABleGattDiscoverServices(const char *remoteAddress)
1199 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1201 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1202 "remote address is NULL", CA_STATUS_FAILED);
1204 char *addr = OICStrdup(remoteAddress);
1205 VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
1207 int32_t ret = bt_gatt_foreach_primary_services(remoteAddress, CABleGattPrimaryServiceCb,
1208 (void *)addr); // addr memory will be free in callback.
1209 if (BT_ERROR_NONE != ret)
1211 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1212 "bt_gatt_foreach_primary_services Failed with ret value [%d] ", ret);
1214 return CA_STATUS_FAILED;
1218 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
1219 "bt_gatt_foreach_primary_services success for address [%s]", remoteAddress);
1222 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1223 return CA_STATUS_OK;
1226 void CADiscoverCharThread(void *stServiceInfo)
1228 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1230 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1232 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)stServiceInfo;
1234 VERIFY_NON_NULL_VOID(stTemp->address, TZ_BLE_CLIENT_TAG, "stTemp->address is NULL");
1236 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]", stTemp->address);
1238 CAResult_t result = CABleGattDiscoverCharacteristics(stTemp->serviceInfo, stTemp->address);
1239 if (CA_STATUS_OK != result)
1241 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CABleGattDiscoverCharacteristics failed!");
1242 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1243 OICFree(stTemp->address);
1247 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1248 OICFree(stTemp->address);
1251 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1254 CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service,
1255 const char *remoteAddress)
1257 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1259 VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "service is NULL", CA_STATUS_FAILED);
1261 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG, "remoteAddress is NULL", CA_STATUS_FAILED);
1263 char *addr = OICStrdup(remoteAddress);
1264 VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
1266 int32_t ret = bt_gatt_discover_characteristics(service, CABleGattCharacteristicsDiscoveredCb,
1267 (void *)addr); // addr will be freed in callback.
1268 if (BT_ERROR_NONE != ret)
1270 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1271 "bt_gatt_discover_characteristics failed with error [%d]", ret);
1273 return CA_STATUS_FAILED;
1276 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1277 return CA_STATUS_OK;
1280 void CADiscoverDescriptorThread(void *stServiceInfo)
1282 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " IN");
1284 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1286 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)stServiceInfo;
1288 CAResult_t result = CABleGattDiscoverDescriptor(stTemp->serviceInfo, NULL);
1289 if (CA_STATUS_OK != result)
1291 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
1292 "bt_gatt_discover_characteristic_descriptor failed");
1293 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1294 OICFree(stTemp->address);
1299 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1300 OICFree(stTemp->address);
1303 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1306 CAResult_t CABleGattDiscoverDescriptor(bt_gatt_attribute_h service, const char *remoteAddress)
1308 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1310 VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "service is NULL", CA_STATUS_FAILED);
1312 int ret = bt_gatt_discover_characteristic_descriptor(service,
1313 CABleGattDescriptorDiscoveredCb, NULL);
1314 if (BT_ERROR_NONE != ret)
1316 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1317 "bt_gatt_discover_characteristic_descriptor failed with returns[%s]",
1318 CABTGetErrorMsg(ret));
1319 return CA_STATUS_FAILED;
1322 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1323 return CA_STATUS_OK;
1326 void CASetCharacteristicDescriptorValueThread(void *stServiceInfo)
1328 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1330 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1332 stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)stServiceInfo;
1334 CAResult_t result = CASetCharacteristicDescriptorValue(stTemp);
1335 if (CA_STATUS_OK != result)
1337 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CASetCharacteristicDescriptorValue failed!");
1338 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1339 OICFree(stTemp->desc);
1343 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1344 OICFree(stTemp->desc);
1347 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1350 CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescInfo)
1352 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1354 unsigned char noti[4] = {0,};
1356 char *strUUID = (char *)OICCalloc(5, sizeof(char));
1358 VERIFY_NON_NULL_RET(strUUID, TZ_BLE_CLIENT_TAG, "calloc failed", CA_STATUS_FAILED);
1360 snprintf(strUUID, 4, "%x%x", stGattCharDescInfo->desc[3], stGattCharDescInfo->desc[2]);
1361 noti[0] = stGattCharDescInfo->desc[0];
1362 noti[1] = stGattCharDescInfo->desc[1];
1366 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x0 [%x]", stGattCharDescInfo->desc[0]);
1367 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x1 [%x]", stGattCharDescInfo->desc[1]);
1368 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x2 [%x]", stGattCharDescInfo->desc[2]);
1369 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x3 [%x]", stGattCharDescInfo->desc[3]);
1372 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG strUUID is [%s]",
1374 //if (!strncmp(strUUID, BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG, 2))
1376 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "setting notification/indication for descriptor");
1378 int ret = bt_gatt_set_characteristic_desc_value_request(
1379 stGattCharDescInfo->characteristic,
1380 noti, 4, CABleGattCharacteristicWriteCb);
1381 if (BT_ERROR_NONE != ret)
1383 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1384 "bt_gatt_set_characteristic_desc_value_request failed with return[%s]",
1385 CABTGetErrorMsg(ret));
1387 return CA_STATUS_FAILED;
1392 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1393 return CA_STATUS_OK;
1396 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
1397 const char *data, const uint32_t dataLen,
1398 CALETransferType_t type, const int32_t position)
1400 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1402 VERIFY_NON_NULL(data, TZ_BLE_CLIENT_TAG, "data is NULL");
1406 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input!");
1407 return CA_STATUS_INVALID_PARAM;
1410 BLEServiceInfo *bleServiceInfo = NULL;
1412 CAResult_t ret = CA_STATUS_FAILED;
1414 ca_mutex_lock(g_bleServiceListMutex);
1415 if ( LE_UNICAST == type)
1417 VERIFY_NON_NULL(remoteAddress, TZ_BLE_CLIENT_TAG, "remoteAddress is NULL");
1419 ret = CAGetBLEServiceInfo(g_bLEServiceList, remoteAddress, &bleServiceInfo);
1421 else if ( LE_MULTICAST == type)
1423 ret = CAGetBLEServiceInfoByPosition(g_bLEServiceList, position, &bleServiceInfo);
1425 ca_mutex_unlock(g_bleServiceListMutex);
1427 if (CA_STATUS_OK != ret)
1429 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAGetBLEServiceInfoByPosition is failed");
1430 return CA_STATUS_FAILED;
1433 VERIFY_NON_NULL(bleServiceInfo, TZ_BLE_CLIENT_TAG, "bleServiceInfo is NULL");
1435 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating the data of length [%d] to [%s] ", dataLen,
1436 bleServiceInfo->bdAddress);
1438 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating to write char [%s]",
1439 bleServiceInfo->read_char);
1441 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
1442 "Updating the data of length [%d] to [%s]", dataLen,
1443 bleServiceInfo->bdAddress);
1445 int result = bt_gatt_set_characteristic_value(bleServiceInfo->write_char, (unsigned char *)data,
1447 if (BT_ERROR_NONE != result)
1449 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1450 "bt_gatt_set_characteristic_value Failed with return val [%d]",
1452 return CA_STATUS_FAILED;
1455 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1456 return CA_STATUS_OK;
1459 CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data,
1462 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1464 VERIFY_NON_NULL(data, TZ_BLE_CLIENT_TAG, "data is NULL");
1468 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input !");
1469 return CA_STATUS_INVALID_PARAM;
1472 int numOfServersConnected = CAGetRegisteredServiceCount();
1474 for (int32_t pos = 0; pos < numOfServersConnected; pos++)
1476 /*remoteAddress will be NULL.
1477 Since we have to send to all destinations. pos will be used for getting remote address.
1479 CAResult_t ret = CAUpdateCharacteristicsToGattServer(NULL, data, dataLen, LE_MULTICAST, pos);
1481 if (CA_STATUS_OK != ret)
1483 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1484 "CAUpdateCharacteristicsToGattServer Failed with return val [%d] ", ret);
1485 g_clientErrorCallback(NULL, data, dataLen, ret);
1490 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1491 return CA_STATUS_OK;