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 "cagattservice.h"
39 #include "oic_string.h"
40 #include "oic_malloc.h"
43 * Logging tag for module name.
45 #define TZ_BLE_CLIENT_TAG "TZ_BLE_GATT_CLIENT"
48 * This contains the list of OIC services a client connect to.
50 static BLEServiceList *g_bLEServiceList = NULL;
53 * Boolean variable to keep the state of the GATT Client.
55 static bool g_isBleGattClientStarted = false;
58 * Mutex to synchronize access to BleServiceList.
60 static ca_mutex g_bleServiceListMutex = NULL;
63 * Mutex to synchronize access to the requestResponse callback to be called
64 * when the data needs to be sent from GATTClient.
66 static ca_mutex g_bleReqRespClientCbMutex = NULL;
69 * Mutex to synchronize access to the requestResponse callback to be called
70 * when the data needs to be sent from GATTClient.
72 static ca_mutex g_bleClientConnectMutex = NULL;
76 * Mutex to synchronize the calls to be done to the platform from GATTClient
77 * interfaces from different threads.
79 static ca_mutex g_bleClientStateMutex = NULL;
82 * Mutex to synchronize the Server BD Address update on client side.
84 static ca_mutex g_bleServerBDAddressMutex = NULL;
87 * Condition used for notifying handler the presence of data in send queue.
89 static ca_cond g_bleClientSendCondWait = NULL;
92 * Mutex to synchronize the task to be pushed to thread pool.
94 static ca_mutex g_bleClientThreadPoolMutex = NULL;
97 * Maintains the callback to be notified on receival of network packets
98 * from other BLE devices
100 static CABLEDataReceivedCallback g_bleClientDataReceivedCallback = NULL;
103 * callback to update the error to le adapter
105 static CABLEErrorHandleCallback g_clientErrorCallback;
108 * gmainLoop to manage the threads to receive the callback from the platfrom.
110 static GMainLoop *g_eventLoop = NULL;
113 * reference to threadpool.
115 static ca_thread_pool_t g_bleClientThreadPool = NULL;
118 * structure to map the service attribute to BD Address.
120 typedef struct gattService
122 bt_gatt_attribute_h serviceInfo; /**< bluetoth attribute for oic service*/
123 char *address; /**< BD Address of */
124 } stGattServiceInfo_t;
127 * Remote address of Gatt Server.
129 static char *g_remoteAddress = NULL;
131 void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic,
132 unsigned char *value,
136 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
138 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic is [%s]", (char *)characteristic);
139 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic value length [%d]", valueLen);
141 ca_mutex_lock(g_bleReqRespClientCbMutex);
142 if (NULL == g_bleClientDataReceivedCallback)
144 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespCallback is NULL!");
145 ca_mutex_unlock(g_bleReqRespClientCbMutex);
148 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending data up !");
150 ca_mutex_lock(g_bleServerBDAddressMutex);
151 uint32_t sentLength = 0;
152 g_bleClientDataReceivedCallback(g_remoteAddress, value, valueLen,
155 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Sent data Length is %d", sentLength);
156 ca_mutex_unlock(g_bleServerBDAddressMutex);
158 ca_mutex_unlock(g_bleReqRespClientCbMutex);
160 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
163 void CABleGattCharacteristicWriteCb(int result, void *userData)
165 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
168 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
171 void CABleGattDescriptorDiscoveredCb(int result, unsigned char format, int total,
172 bt_gatt_attribute_h descriptor,
173 bt_gatt_attribute_h characteristic, void *userData)
175 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
177 stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)OICCalloc(1, sizeof(
178 stGattCharDescriptor_t));
180 VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed!");
182 stTemp->desc = (uint8_t *)OICMalloc(total);
183 if (NULL == stTemp->desc)
185 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "malloc failed");
189 memcpy(stTemp->desc, descriptor, total);
191 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "result[%d] format[%d] total[%d]", result, format, total);
192 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "characteristic [%s]", (const char *) characteristic);
195 bt_gatt_clone_attribute_handle(&(stTemp->characteristic), characteristic);
196 stTemp->total = total;
198 ca_mutex_lock(g_bleClientThreadPoolMutex);
199 if (NULL == g_bleClientThreadPool)
201 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
202 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
203 OICFree(stTemp->desc);
205 ca_mutex_unlock(g_bleClientThreadPoolMutex);
209 CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
210 CASetCharacteristicDescriptorValueThread,
212 if (CA_STATUS_OK != ret)
214 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed");
215 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
216 OICFree(stTemp->desc);
218 ca_mutex_unlock(g_bleClientThreadPoolMutex);
222 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG,
223 "LE Client initialization flow complete");
225 ca_mutex_unlock(g_bleClientThreadPoolMutex);
227 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
230 bool CABleGattCharacteristicsDiscoveredCb(int result,
231 int inputIndex, int total,
232 bt_gatt_attribute_h characteristic, void *userData)
235 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
237 VERIFY_NON_NULL_RET(characteristic, TZ_BLE_CLIENT_TAG, "Param characteristic is NULL", false);
239 VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
241 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
242 "result [%d] input_index [%d] total [%d]",
243 result, inputIndex, total);
245 BLEServiceInfo *bleServiceInfo = NULL;
247 ca_mutex_lock(g_bleServiceListMutex);
249 char *bdAddress = (char *) userData;
250 CAGetBLEServiceInfo(g_bLEServiceList, bdAddress, &bleServiceInfo);
252 ca_mutex_unlock(g_bleServiceListMutex);
255 bt_gatt_get_service_uuid(characteristic, &uuid);
257 VERIFY_NON_NULL_RET(uuid, TZ_BLE_CLIENT_TAG, "uuid is NULL", false);
259 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "New Characteristics[%s] of uuid[%s] is obtained",
260 (char *)characteristic, uuid);
262 if(0 == strcasecmp(uuid, CA_GATT_RESPONSE_CHRC_UUID)) // Server will read on this characterisctics
264 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Read characteristics is obtained");
266 CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_READ_CHAR, bleServiceInfo);
267 if (CA_STATUS_OK != retVal)
269 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed! ");
273 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
274 sizeof(stGattServiceInfo_t));
276 VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "calloc failed!", false);
278 stTemp->address = OICStrdup(bdAddress);
279 if (NULL == stTemp->address)
281 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
286 bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), characteristic);
288 ca_mutex_lock(g_bleClientThreadPoolMutex);
289 if (NULL == g_bleClientThreadPool)
291 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
292 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
293 OICFree(stTemp->address);
295 ca_mutex_unlock(g_bleClientThreadPoolMutex);
299 retVal = ca_thread_pool_add_task(g_bleClientThreadPool,
300 CADiscoverDescriptorThread,
302 if (CA_STATUS_OK != retVal)
304 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
305 "ca_thread_pool_add_task failed with ret [%d]", retVal);
306 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
307 OICFree(stTemp->address);
309 ca_mutex_unlock(g_bleClientThreadPoolMutex);
312 ca_mutex_unlock(g_bleClientThreadPoolMutex);
314 else if (0 == strcasecmp(uuid, CA_GATT_REQUEST_CHRC_UUID)) // Server will write on this characteristics.
317 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Write characteristics is obtained");
318 CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_WRITE_CHAR, bleServiceInfo);
319 if (CA_STATUS_OK != retVal)
321 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed ");
328 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "service_uuid characteristics is UNKNOWN");
332 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
336 bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int index, int count,
339 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
341 VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "Param service is NULL", false);
343 VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
345 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s] index [%d] count [%d]", (char *)service,
348 CAResult_t result = CAVerifyOICServiceByServiceHandle(service);
350 if (CA_STATUS_OK == result)
352 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
354 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes");
356 result = CABleGattWatchCharacteristicChanges(service);
357 if (CA_STATUS_OK != result)
359 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
360 "CABleGattWatchCharacteristicChanges failed!");
364 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
365 sizeof(stGattServiceInfo_t));
366 VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "Calloc Failed", false);
368 char *bdAddress = (char *)userData;
370 stTemp->address = OICStrdup(bdAddress);
371 if (NULL == stTemp->address)
373 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
378 BLEServiceInfo *bleServiceInfo = NULL;
380 result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo);
381 if (CA_STATUS_OK != result)
383 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CACreateBLEServiceInfo failed! ");
384 OICFree(stTemp->address);
386 OICFree(bleServiceInfo);
389 if (NULL == bleServiceInfo )
391 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , " bleServiceInfo is NULL");
392 OICFree(stTemp->address);
394 OICFree(bleServiceInfo);
398 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG ,
399 " serviceInfo remote address [%s]", bleServiceInfo->bdAddress);
401 ca_mutex_lock(g_bleServiceListMutex);
402 result = CAAddBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo);
403 ca_mutex_unlock(g_bleServiceListMutex);
404 if (CA_STATUS_OK != result)
406 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAddBLEServiceInfoToList failed!");
407 OICFree(stTemp->address);
409 CAFreeBLEServiceInfo(bleServiceInfo);
414 ca_mutex_lock(g_bleClientThreadPoolMutex);
415 if (NULL == g_bleClientThreadPool)
417 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
418 OICFree(stTemp->address);
420 ca_mutex_lock(g_bleServiceListMutex);
421 CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
422 bleServiceInfo->bdAddress);
423 ca_mutex_unlock(g_bleServiceListMutex);
424 ca_mutex_unlock(g_bleClientThreadPoolMutex);
427 bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), service);
429 result = ca_thread_pool_add_task(g_bleClientThreadPool,
430 CADiscoverCharThread,
432 if (CA_STATUS_OK != result)
434 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
435 "ca_thread_pool_add_task failed with ret [%d]", result);
436 OICFree(stTemp->address);
438 ca_mutex_lock(g_bleServiceListMutex);
439 CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
440 bleServiceInfo->bdAddress);
441 ca_mutex_unlock(g_bleServiceListMutex);
442 ca_mutex_unlock(g_bleClientThreadPoolMutex);
445 ca_mutex_unlock(g_bleClientThreadPoolMutex);
448 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
452 void CABleGattConnectionStateChangedCb(int result, bool connected,
453 const char *remoteAddress, void *userData)
455 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
457 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "CABleGattConnectionStateChangedCb result[%d] ", result);
459 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
461 CAResult_t ret = CA_STATUS_FAILED;
464 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress);
466 ret = CABleGattStartDeviceDiscovery();
467 if (CA_STATUS_OK != ret)
469 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattStartDeviceDiscovery failed");
475 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Connected to [%s] ", remoteAddress);
477 ca_mutex_lock(g_bleServerBDAddressMutex);
479 g_remoteAddress = OICStrdup(remoteAddress);
481 ca_mutex_unlock(g_bleServerBDAddressMutex);
483 VERIFY_NON_NULL_VOID(g_remoteAddress, TZ_BLE_CLIENT_TAG, "Malloc failed");
485 char *addr = OICStrdup(remoteAddress);
487 ca_mutex_lock(g_bleClientThreadPoolMutex);
488 if (NULL == g_bleClientThreadPool)
490 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
493 ca_mutex_lock(g_bleServerBDAddressMutex);
494 OICFree(g_remoteAddress);
495 ca_mutex_unlock(g_bleServerBDAddressMutex);
497 ca_mutex_unlock(g_bleClientThreadPoolMutex);
501 ret = ca_thread_pool_add_task(g_bleClientThreadPool, CADiscoverBLEServicesThread,
503 if (CA_STATUS_OK != ret)
505 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
508 ca_mutex_lock(g_bleServerBDAddressMutex);
509 OICFree(g_remoteAddress);
510 ca_mutex_unlock(g_bleServerBDAddressMutex);
512 ca_mutex_unlock(g_bleClientThreadPoolMutex);
515 ca_mutex_unlock(g_bleClientThreadPoolMutex);
518 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
521 void CABtAdapterLeDeviceDiscoveryStateChangedCb(int result,
522 bt_adapter_le_device_discovery_state_e discoveryState,
523 bt_adapter_le_device_discovery_info_s *discoveryInfo,
526 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
528 if (NULL == discoveryInfo && BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND == discoveryState)
530 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL");
534 if (BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND != discoveryState)
536 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
537 " LE Discovery state is [%s]",
538 discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished");
542 CAPrintDiscoveryInformation(discoveryInfo);
544 if (discoveryInfo->service_uuid == NULL)
546 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "NO UUIDS from device");
550 for (int32_t i = discoveryInfo->service_count - 1; i >= 0; i--)
552 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "uuid[%d]: [%s]",
553 i, discoveryInfo->service_uuid[i]);
554 CAResult_t res = CAVerifyOICServiceByUUID(discoveryInfo->service_uuid[i]);
555 if (CA_STATUS_OK == res)
557 char *addr = OICStrdup(discoveryInfo->remote_address);
558 VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
560 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
561 "Trying to do Gatt connection to [%s]", addr);
563 ca_mutex_lock(g_bleClientThreadPoolMutex);
564 if (NULL == g_bleClientThreadPool)
566 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
568 ca_mutex_unlock(g_bleClientThreadPoolMutex);
572 CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
573 CAGattConnectThread, addr);
574 if (CA_STATUS_OK != ret)
576 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
577 "ca_thread_pool_add_task failed with ret [%d]", ret);
579 ca_mutex_unlock(g_bleClientThreadPoolMutex);
582 ca_mutex_unlock(g_bleClientThreadPoolMutex);
583 if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31)
585 bt_adapter_le_stop_device_discovery();
588 break; // Found the OIC Service. No need to verify remaining services.
593 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
597 void CAPrintDiscoveryInformation(const bt_adapter_le_device_discovery_info_s *discoveryInfo)
599 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
601 if (NULL == discoveryInfo)
603 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL ");
607 if (discoveryInfo->remote_address)
609 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Remote Address [%s]", discoveryInfo->remote_address);
612 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
613 " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
614 discoveryInfo->adv_data_len, discoveryInfo->scan_data_len, discoveryInfo->rssi,
615 discoveryInfo->address_type);
616 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
617 " Number of services present in device [%s] is [%d]",
618 discoveryInfo->remote_address, discoveryInfo->service_count);
620 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
623 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
625 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
627 ca_mutex_lock(g_bleClientThreadPoolMutex);
628 g_bleClientThreadPool = handle;
629 ca_mutex_unlock(g_bleClientThreadPoolMutex);
631 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
634 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
636 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
638 ca_mutex_lock(g_bleReqRespClientCbMutex);
640 g_bleClientDataReceivedCallback = callback;
642 ca_mutex_unlock(g_bleReqRespClientCbMutex);
644 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
648 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
650 g_clientErrorCallback = callback;
653 CAResult_t CAStartLEGattClient()
655 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
657 CAResult_t retVal = CAInitGattClientMutexVariables();
659 if (CA_STATUS_OK != retVal)
661 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAInitGattClientMutexVariables failed!");
662 CATerminateGattClientMutexVariables();
663 return CA_STATUS_FAILED;
666 ca_mutex_lock(g_bleClientThreadPoolMutex);
667 if (NULL == g_bleClientThreadPool)
669 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleServerThreadPool is NULL");
670 CATerminateGattClientMutexVariables();
671 ca_mutex_unlock(g_bleClientThreadPoolMutex);
672 return CA_STATUS_FAILED;
675 retVal = ca_thread_pool_add_task(g_bleClientThreadPool, CAStartBleGattClientThread,
677 if (CA_STATUS_OK != retVal)
679 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed");
680 CATerminateGattClientMutexVariables();
681 ca_mutex_unlock(g_bleClientThreadPoolMutex);
682 return CA_STATUS_FAILED;
684 ca_mutex_unlock(g_bleClientThreadPoolMutex);
686 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
690 void CAStartBleGattClientThread(void *data)
692 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
694 ca_mutex_lock(g_bleClientStateMutex);
696 if (true == g_isBleGattClientStarted)
698 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is already running!!");
699 ca_mutex_unlock(g_bleClientStateMutex);
703 CAResult_t ret = CABleGattSetScanParameter();
704 if (CA_STATUS_OK != ret)
706 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleSetScanParameter Failed");
707 ca_mutex_unlock(g_bleClientStateMutex);
708 CATerminateLEGattClient();
712 ret = CABleGattSetCallbacks();
713 if (CA_STATUS_OK != ret)
715 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattSetCallbacks Failed");
716 ca_mutex_unlock(g_bleClientStateMutex);
717 CATerminateLEGattClient();
721 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Starting LE device discovery");
723 ret = CABleGattStartDeviceDiscovery();
724 if (CA_STATUS_OK != ret)
726 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed");
727 ca_mutex_unlock(g_bleClientStateMutex);
728 CATerminateLEGattClient();
732 g_isBleGattClientStarted = true;
734 ca_mutex_unlock(g_bleClientStateMutex);
736 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Giveing the control to threadPool");
738 GMainContext *thread_context = g_main_context_new();
740 g_eventLoop = g_main_loop_new(thread_context, FALSE);
742 g_main_context_push_thread_default(thread_context);
744 g_main_loop_run(g_eventLoop);
746 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
749 void CAStopLEGattClient()
751 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
753 ca_mutex_lock(g_bleClientStateMutex);
755 if (false == g_isBleGattClientStarted)
757 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is not running to stop");
758 ca_mutex_unlock(g_bleClientStateMutex);
762 CABleGattUnSetCallbacks();
764 CABleGattUnWatchCharacteristicChanges();
766 CABleGattStopDeviceDiscovery();
768 g_isBleGattClientStarted = false;
770 GMainContext *context_event_loop = NULL;
771 // Required for waking up the thread which is running in gmain loop
772 if (NULL != g_eventLoop)
774 context_event_loop = g_main_loop_get_context(g_eventLoop);
776 if (context_event_loop)
778 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "g_eventLoop context %x", context_event_loop);
779 g_main_context_wakeup(context_event_loop);
781 // Kill g main loops and kill threads.
782 g_main_loop_quit(g_eventLoop);
786 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_eventLoop context is NULL");
789 ca_mutex_unlock(g_bleClientStateMutex);
791 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
794 void CATerminateLEGattClient()
796 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
797 ca_mutex_lock(g_bleClientStateMutex);
799 ca_mutex_lock(g_bleServerBDAddressMutex);
801 OICFree(g_remoteAddress);
803 ca_mutex_unlock(g_bleServerBDAddressMutex);
805 ca_mutex_lock(g_bleServiceListMutex);
806 CAFreeBLEServiceList(g_bLEServiceList);
807 g_bLEServiceList = NULL;
808 ca_mutex_unlock(g_bleServiceListMutex);
810 CAResetRegisteredServiceCount();
812 ca_mutex_unlock(g_bleClientStateMutex);
814 CATerminateGattClientMutexVariables();
816 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
819 CAResult_t CAInitGattClientMutexVariables()
821 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
822 if (NULL == g_bleClientStateMutex)
824 g_bleClientStateMutex = ca_mutex_new();
825 if (NULL == g_bleClientStateMutex)
827 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
828 return CA_STATUS_FAILED;
832 if (NULL == g_bleServiceListMutex)
834 g_bleServiceListMutex = ca_mutex_new();
835 if (NULL == g_bleServiceListMutex)
837 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
838 return CA_STATUS_FAILED;
842 if (NULL == g_bleReqRespClientCbMutex)
844 g_bleReqRespClientCbMutex = ca_mutex_new();
845 if (NULL == g_bleReqRespClientCbMutex)
847 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
848 return CA_STATUS_FAILED;
852 if (NULL == g_bleClientThreadPoolMutex)
854 g_bleClientThreadPoolMutex = ca_mutex_new();
855 if (NULL == g_bleClientThreadPoolMutex)
857 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
858 return CA_STATUS_FAILED;
862 if (NULL == g_bleClientConnectMutex)
864 g_bleClientConnectMutex = ca_mutex_new();
865 if (NULL == g_bleClientConnectMutex)
867 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
868 return CA_STATUS_FAILED;
872 if (NULL == g_bleClientSendCondWait)
874 g_bleClientSendCondWait = ca_cond_new();
875 if (NULL == g_bleClientSendCondWait)
877 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_cond_new failed");
878 return CA_STATUS_FAILED;
882 if (NULL == g_bleServerBDAddressMutex)
884 g_bleServerBDAddressMutex = ca_mutex_new();
885 if (NULL == g_bleServerBDAddressMutex)
887 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
888 return CA_STATUS_FAILED;
892 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
896 void CATerminateGattClientMutexVariables()
898 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
900 ca_mutex_free(g_bleClientStateMutex);
901 g_bleClientStateMutex = NULL;
903 ca_mutex_free(g_bleServiceListMutex);
904 g_bleServiceListMutex = NULL;
906 ca_mutex_free(g_bleReqRespClientCbMutex);
907 g_bleReqRespClientCbMutex = NULL;
909 ca_mutex_free(g_bleClientConnectMutex);
910 g_bleClientConnectMutex = NULL;
912 ca_mutex_free(g_bleClientThreadPoolMutex);
913 g_bleClientThreadPoolMutex = NULL;
915 ca_mutex_free(g_bleServerBDAddressMutex);
916 g_bleServerBDAddressMutex = NULL;
918 ca_cond_free(g_bleClientSendCondWait);
919 g_bleClientSendCondWait = NULL;
922 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
925 CAResult_t CABleGattSetScanParameter()
927 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
929 bt_adapter_le_scan_params_s scan_param = { 0, };
930 scan_param.type = BT_ADAPTER_LE_PASSIVE_SCAN;
931 scan_param.interval = 1560;
932 scan_param.window = 160;
934 int ret = bt_adapter_le_set_scan_parameter(&scan_param);
935 if (BT_ERROR_NONE != ret)
937 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_set_scan_parameter Failed with ret [%d]", ret);
938 return CA_STATUS_FAILED;
941 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
945 CAResult_t CABleGattSetCallbacks()
947 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
949 int ret = bt_gatt_set_connection_state_changed_cb(CABleGattConnectionStateChangedCb, NULL);
950 if (BT_ERROR_NONE != ret)
952 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
953 "bt_gatt_set_connection_state_changed_cb Failed with return as [%s ]",
954 CABTGetErrorMsg(ret));
955 return CA_STATUS_FAILED;
958 ret = bt_adapter_le_set_device_discovery_state_changed_cb(
959 CABtAdapterLeDeviceDiscoveryStateChangedCb, NULL);
960 if (BT_ERROR_NONE != ret)
962 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
963 "bt_adapter_le_set_device_discovery_state_changed_cb Failed with return as [%s ]",
964 CABTGetErrorMsg(ret));;
965 return CA_STATUS_FAILED;
968 ret = bt_gatt_set_characteristic_changed_cb(CABleGattCharacteristicChangedCb, NULL);
969 if (BT_ERROR_NONE != ret)
971 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_set_characteristic_changed_cb Failed as [%s ]",
972 CABTGetErrorMsg(ret));
973 return CA_STATUS_FAILED;
976 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
980 void CABleGattUnSetCallbacks()
982 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
984 bt_gatt_unset_characteristic_changed_cb();
986 bt_gatt_unset_connection_state_changed_cb();
988 bt_adapter_le_unset_device_discovery_state_changed_cb();
990 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
993 CAResult_t CABleGattWatchCharacteristicChanges(bt_gatt_attribute_h service)
995 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
997 int ret = bt_gatt_watch_characteristic_changes(service);
998 if (BT_ERROR_NONE != ret)
1000 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1001 "bt_gatt_watch_characteristic_changes failed with [%s]",
1002 CABTGetErrorMsg(ret));
1004 return CA_STATUS_FAILED;
1007 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1008 return CA_STATUS_OK;
1011 void CABleGattUnWatchCharacteristicChanges()
1013 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1015 int32_t count = CAGetRegisteredServiceCount();
1017 for (int32_t index = 0; index < count; index++)
1019 BLEServiceInfo *bleServiceInfo = NULL;
1021 ca_mutex_lock(g_bleServiceListMutex);
1023 CAResult_t result = CAGetBLEServiceInfoByPosition(g_bLEServiceList, index, &bleServiceInfo);
1024 if (CA_STATUS_OK == result && NULL != bleServiceInfo
1025 && NULL != bleServiceInfo->service_clone)
1027 bt_gatt_unwatch_characteristic_changes(bleServiceInfo->service_clone);
1028 OIC_LOG(INFO, TZ_BLE_CLIENT_TAG, "bt_gatt_unwatch_characteristic_changes done");
1031 ca_mutex_unlock(g_bleServiceListMutex);
1034 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1037 CAResult_t CABleGattStartDeviceDiscovery()
1039 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1040 bool isDiscovering = false;
1042 int ret = bt_adapter_le_is_discovering(&isDiscovering);
1043 if (BT_ERROR_NONE != ret)
1045 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_is_discovering Failed");
1046 return CA_STATUS_FAILED;
1051 ret = bt_adapter_le_start_device_discovery();
1052 if (BT_ERROR_NONE != ret)
1054 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed Ret: %d, %x", ret, ret);
1055 return CA_STATUS_FAILED;
1059 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1060 return CA_STATUS_OK;
1063 void CABleGattStopDeviceDiscovery()
1065 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1067 bool isDiscovering = false;
1069 int ret = bt_adapter_le_is_discovering(&isDiscovering);
1070 if (BT_ERROR_NONE != ret)
1072 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_is_discovering Failed");
1078 ret = bt_adapter_le_stop_device_discovery();
1079 if (BT_ERROR_NONE != ret)
1081 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_stop_device_discovery Failed");
1086 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1089 void CAGattConnectThread (void *remoteAddress)
1091 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
1093 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1095 char *address = (char *)remoteAddress;
1097 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address is [%s]", address);
1099 CAResult_t result = CABleGattConnect(address);
1101 if (CA_STATUS_OK != result)
1103 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect failed for [%s]", address);
1108 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1111 CAResult_t CABleGattConnect(const char *remoteAddress)
1113 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1115 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1116 "remote address is NULL", CA_STATUS_FAILED);
1118 //Because of the platform issue, we added. Once platform is stablized, then it will be removed
1121 ca_mutex_lock(g_bleClientConnectMutex);
1123 int ret = bt_gatt_connect(remoteAddress, true);
1125 if (BT_ERROR_NONE != ret)
1127 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect Failed with ret value [%s] ",
1128 CABTGetErrorMsg(ret));
1129 ca_mutex_unlock(g_bleClientConnectMutex);
1130 return CA_STATUS_FAILED;
1132 ca_mutex_unlock(g_bleClientConnectMutex);
1134 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1135 return CA_STATUS_OK;
1138 CAResult_t CABleGattDisConnect(const char *remoteAddress)
1140 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1142 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1143 "remote address is NULL", CA_STATUS_FAILED);
1145 int32_t ret = bt_gatt_disconnect(remoteAddress);
1147 if (BT_ERROR_NONE != ret)
1149 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_disconnect Failed with ret value [%d] ",
1151 return CA_STATUS_FAILED;
1154 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1155 return CA_STATUS_OK;
1158 void CADiscoverBLEServicesThread (void *remoteAddress)
1160 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1162 VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
1164 char *address = (char *)remoteAddress;
1166 CAResult_t result = CABleGattDiscoverServices(address);
1167 if (CA_STATUS_OK != result)
1169 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattDiscoverServices failed");
1174 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1177 CAResult_t CABleGattDiscoverServices(const char *remoteAddress)
1179 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1181 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
1182 "remote address is NULL", CA_STATUS_FAILED);
1184 char *addr = OICStrdup(remoteAddress);
1185 VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
1187 int32_t ret = bt_gatt_foreach_primary_services(remoteAddress, CABleGattPrimaryServiceCb,
1188 (void *)addr); // addr memory will be free in callback.
1189 if (BT_ERROR_NONE != ret)
1191 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1192 "bt_gatt_foreach_primary_services Failed with ret value [%d] ", ret);
1194 return CA_STATUS_FAILED;
1198 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
1199 "bt_gatt_foreach_primary_services success for address [%s]", remoteAddress);
1202 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1203 return CA_STATUS_OK;
1206 void CADiscoverCharThread(void *stServiceInfo)
1208 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1210 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1212 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)stServiceInfo;
1214 VERIFY_NON_NULL_VOID(stTemp->address, TZ_BLE_CLIENT_TAG, "stTemp->address is NULL");
1216 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]", stTemp->address);
1218 CAResult_t result = CABleGattDiscoverCharacteristics(stTemp->serviceInfo, stTemp->address);
1219 if (CA_STATUS_OK != result)
1221 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CABleGattDiscoverCharacteristics failed!");
1222 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1223 OICFree(stTemp->address);
1227 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1228 OICFree(stTemp->address);
1231 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1234 CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service,
1235 const char *remoteAddress)
1237 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1239 VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "service is NULL", CA_STATUS_FAILED);
1241 VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG, "remoteAddress is NULL", CA_STATUS_FAILED);
1243 char *addr = OICStrdup(remoteAddress);
1244 VERIFY_NON_NULL_RET(addr, TZ_BLE_CLIENT_TAG, "Malloc failed", CA_STATUS_FAILED);
1246 int32_t ret = bt_gatt_discover_characteristics(service, CABleGattCharacteristicsDiscoveredCb,
1247 (void *)addr); // addr will be freed in callback.
1248 if (BT_ERROR_NONE != ret)
1250 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1251 "bt_gatt_discover_characteristics failed with error [%d]", ret);
1253 return CA_STATUS_FAILED;
1256 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1257 return CA_STATUS_OK;
1260 void CADiscoverDescriptorThread(void *stServiceInfo)
1262 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " IN");
1264 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1266 stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)stServiceInfo;
1268 CAResult_t result = CABleGattDiscoverDescriptor(stTemp->serviceInfo, NULL);
1269 if (CA_STATUS_OK != result)
1271 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
1272 "bt_gatt_discover_characteristic_descriptor failed");
1273 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1274 OICFree(stTemp->address);
1279 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
1280 OICFree(stTemp->address);
1283 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1286 CAResult_t CABleGattDiscoverDescriptor(bt_gatt_attribute_h service, const char *remoteAddress)
1288 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1290 VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "service is NULL", CA_STATUS_FAILED);
1292 int ret = bt_gatt_discover_characteristic_descriptor(service,
1293 CABleGattDescriptorDiscoveredCb, NULL);
1294 if (BT_ERROR_NONE != ret)
1296 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1297 "bt_gatt_discover_characteristic_descriptor failed with returns[%s]",
1298 CABTGetErrorMsg(ret));
1299 return CA_STATUS_FAILED;
1302 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1303 return CA_STATUS_OK;
1306 void CASetCharacteristicDescriptorValueThread(void *stServiceInfo)
1308 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1310 VERIFY_NON_NULL_VOID(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL");
1312 stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)stServiceInfo;
1314 CAResult_t result = CASetCharacteristicDescriptorValue(stTemp);
1315 if (CA_STATUS_OK != result)
1317 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CASetCharacteristicDescriptorValue failed!");
1318 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1319 OICFree(stTemp->desc);
1323 bt_gatt_destroy_attribute_handle(stTemp->characteristic);
1324 OICFree(stTemp->desc);
1327 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1330 CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescInfo)
1332 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1334 unsigned char noti[4] = {0,};
1336 char *strUUID = (char *)OICCalloc(5, sizeof(char));
1338 VERIFY_NON_NULL_RET(strUUID, TZ_BLE_CLIENT_TAG, "calloc failed", CA_STATUS_FAILED);
1340 snprintf(strUUID, 4, "%x%x", stGattCharDescInfo->desc[3], stGattCharDescInfo->desc[2]);
1341 noti[0] = stGattCharDescInfo->desc[0];
1342 noti[1] = stGattCharDescInfo->desc[1];
1346 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x0 [%x]", stGattCharDescInfo->desc[0]);
1347 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x1 [%x]", stGattCharDescInfo->desc[1]);
1348 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x2 [%x]", stGattCharDescInfo->desc[2]);
1349 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x3 [%x]", stGattCharDescInfo->desc[3]);
1352 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "CA_GATT_CONFIGURATION_DESC_UUID strUUID is [%s]",
1354 //if (!strncmp(strUUID, CA_GATT_CONFIGURATION_DESC_UUID, 2))
1356 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "setting notification/indication for descriptor");
1358 int ret = bt_gatt_set_characteristic_desc_value_request(
1359 stGattCharDescInfo->characteristic,
1360 noti, 4, CABleGattCharacteristicWriteCb);
1361 if (BT_ERROR_NONE != ret)
1363 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1364 "bt_gatt_set_characteristic_desc_value_request failed with return[%s]",
1365 CABTGetErrorMsg(ret));
1367 return CA_STATUS_FAILED;
1372 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1373 return CA_STATUS_OK;
1376 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
1377 const uint8_t *data, uint32_t dataLen,
1378 CALETransferType_t type, int32_t position)
1380 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1382 VERIFY_NON_NULL(data, TZ_BLE_CLIENT_TAG, "data is NULL");
1386 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input!");
1387 return CA_STATUS_INVALID_PARAM;
1390 BLEServiceInfo *bleServiceInfo = NULL;
1392 CAResult_t ret = CA_STATUS_FAILED;
1394 ca_mutex_lock(g_bleServiceListMutex);
1395 if ( LE_UNICAST == type)
1397 VERIFY_NON_NULL(remoteAddress, TZ_BLE_CLIENT_TAG, "remoteAddress is NULL");
1399 ret = CAGetBLEServiceInfo(g_bLEServiceList, remoteAddress, &bleServiceInfo);
1401 else if ( LE_MULTICAST == type)
1403 ret = CAGetBLEServiceInfoByPosition(g_bLEServiceList, position, &bleServiceInfo);
1405 ca_mutex_unlock(g_bleServiceListMutex);
1407 if (CA_STATUS_OK != ret)
1409 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAGetBLEServiceInfoByPosition is failed");
1410 return CA_STATUS_FAILED;
1413 VERIFY_NON_NULL(bleServiceInfo, TZ_BLE_CLIENT_TAG, "bleServiceInfo is NULL");
1415 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating the data of length [%u] to [%s] ", dataLen,
1416 bleServiceInfo->bdAddress);
1418 OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating to write char [%s]",
1419 bleServiceInfo->read_char);
1421 int result = bt_gatt_set_characteristic_value(bleServiceInfo->write_char, (unsigned char *)data,
1423 if (BT_ERROR_NONE != result)
1425 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1426 "bt_gatt_set_characteristic_value Failed with return val [%d]",
1428 return CA_STATUS_FAILED;
1431 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
1432 return CA_STATUS_OK;
1435 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data,
1438 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
1440 VERIFY_NON_NULL(data, TZ_BLE_CLIENT_TAG, "data is NULL");
1444 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input !");
1445 return CA_STATUS_INVALID_PARAM;
1448 int numOfServersConnected = CAGetRegisteredServiceCount();
1450 for (int32_t pos = 0; pos < numOfServersConnected; pos++)
1452 /*remoteAddress will be NULL.
1453 Since we have to send to all destinations. pos will be used for getting remote address.
1455 CAResult_t ret = CAUpdateCharacteristicsToGattServer(NULL, data, dataLen, LE_MULTICAST, pos);
1457 if (CA_STATUS_OK != ret)
1459 OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
1460 "CAUpdateCharacteristicsToGattServer Failed with return val [%d] ", ret);
1461 g_clientErrorCallback(NULL, data, dataLen, ret);
1466 OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
1467 return CA_STATUS_OK;