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 <bluetooth.h>
22 #include <bluetooth_type.h>
23 #include <bluetooth_internal.h>
25 #include "caleserver.h"
27 #include "cacommonutil.h"
29 #include "caqueueingthread.h"
30 #include "cagattservice.h"
31 #include "oic_malloc.h"
35 * Logging tag for module name
37 #define TAG "OIC_CA_LE_SERVER"
40 * Initial buffer size for Gatt Server.
42 #define CA_LE_INITIAL_BUF_SIZE 512
45 * The handle of the OIC server.
47 static bt_gatt_server_h g_gattServer = NULL;
50 * The handle of the OIC service.
52 static bt_gatt_h g_gattSvcPath = NULL;
55 * The handle of the OIC read characteristics.
57 static bt_gatt_h g_gattReadCharPath = NULL;
60 * The handle of the OIC write characteristics.
62 static bt_gatt_h g_gattWriteCharPath = NULL;
65 * The handle to control Bluetooth LE advertising.
67 static bt_advertiser_h g_hAdvertiser = NULL;
70 * Callback register with LE adapter. This callback is called on reception of any
71 * data from the remote device.
73 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
76 * Callback to notify any error in LE adapter.
78 static CABLEErrorHandleCallback g_serverErrorCallback;
81 * To keep the state of GATT server if started or not.
83 static bool g_isLEGattServerStarted = false;
86 * Mutex to synchronize the calls to start and stop server.
88 static ca_mutex g_leServerStateMutex = NULL;
91 * Mutex to synchronize writing operations on the characteristics.
93 static ca_mutex g_leCharacteristicMutex = NULL;
96 * Mutex to synchronize to creation of OIC service.
98 static ca_mutex g_leServiceMutex = NULL;
101 * Mutex to synchronize access to the requestResponse callback to be called
102 * when the data needs to be sent from GATTClient.
104 static ca_mutex g_leReqRespCbMutex = NULL;
107 * Mutex to synchronize the task to be pushed to thread pool.
109 static ca_mutex g_leServerThreadPoolMutex = NULL;
112 * Reference to threadpool.
114 static ca_thread_pool_t g_leServerThreadPool = NULL;
117 * GmainLoop to manage the threads to receive the callback from the platfrom.
119 static GMainLoop *g_eventLoop = NULL;
121 static CALEConnectionStateChangedCallback g_connStateCb = NULL;
123 void CASetLEConnectionStateChangedCallback(CALEConnectionStateChangedCallback connStateCb)
125 g_connStateCb = connStateCb;
128 void CALEGattServerConnectionStateChangedCb(int result, bool connected,
129 const char *remoteAddress, void *userData)
131 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
133 OIC_LOG_V(DEBUG, TAG, "CABleGattConnectionStateChangedCb result[%d]", result);
137 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
140 g_connStateCb(CA_ADAPTER_GATT_BTLE, remoteAddress, true);
145 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
148 g_connStateCb(CA_ADAPTER_GATT_BTLE, remoteAddress, false);
153 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
154 bt_gatt_h characteristic, bool completed, void *user_data)
156 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
159 CAResult_t CAStartLEGattServer()
161 OIC_LOG(DEBUG, TAG, "IN");
163 ca_mutex_lock(g_leServerThreadPoolMutex);
164 if (NULL == g_leServerThreadPool)
166 OIC_LOG(ERROR, TAG, "g_leServerThreadPool is NULL");
167 ca_mutex_unlock(g_leServerThreadPoolMutex);
168 return CA_STATUS_FAILED;
171 CAResult_t ret = ca_thread_pool_add_task(g_leServerThreadPool, CAStartLEGattServerThread,
173 if (CA_STATUS_OK != ret)
175 OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
176 ca_mutex_unlock(g_leServerThreadPoolMutex);
177 return CA_STATUS_FAILED;
180 ca_mutex_unlock(g_leServerThreadPoolMutex);
181 OIC_LOG(DEBUG, TAG, "OUT");
185 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
188 OIC_LOG(DEBUG, TAG, "IN");
191 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
193 OIC_LOG(DEBUG, TAG, "OUT");
196 CAResult_t CALEStartAdvertise(const char *serviceUUID)
198 OIC_LOG(DEBUG, TAG, "IN");
200 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
201 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
203 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
204 return CA_STATUS_FAILED;
207 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
208 BT_ADAPTER_LE_PACKET_ADVERTISING,
210 if (BT_ERROR_NONE != res)
212 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
213 CALEGetErrorMsg(res));
214 return CA_STATUS_FAILED;
217 res = bt_adapter_le_start_advertising(g_hAdvertiser, NULL, NULL, NULL);
218 if (BT_ERROR_NONE != res)
220 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising failed with ret[%s]",
221 CALEGetErrorMsg(res));
222 return CA_STATUS_FAILED;
225 OIC_LOG(DEBUG, TAG, "OUT");
229 CAResult_t CALEStopAdvertise()
231 OIC_LOG(DEBUG, TAG, "IN");
232 if (NULL != g_hAdvertiser)
234 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
237 OIC_LOG_V(ERROR, TAG,
238 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
241 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
244 OIC_LOG_V(ERROR, TAG,
245 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
247 g_hAdvertiser = NULL;
251 OIC_LOG(ERROR, TAG, "Advertising is not running");
252 return CA_STATUS_FAILED;
255 OIC_LOG(DEBUG, TAG, "OUT");
259 void CAStartLEGattServerThread(void *data)
261 OIC_LOG(DEBUG, TAG, "IN");
262 ca_mutex_lock(g_leServerStateMutex);
263 if (true == g_isLEGattServerStarted)
265 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
266 ca_mutex_unlock(g_leServerStateMutex);
267 CATerminateLEGattServer();
271 CAResult_t ret = CAInitLEGattServer();
272 if (CA_STATUS_OK != ret)
274 OIC_LOG_V(ERROR, TAG, "CAInitLEGattService failed[%d]", ret);
275 ca_mutex_unlock(g_leServerStateMutex);
276 CATerminateLEGattServer();
280 char *serviceUUID = CA_GATT_SERVICE_UUID;
282 ret = CAAddNewLEServiceInGattServer(serviceUUID);
283 if (CA_STATUS_OK != ret)
285 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
286 ca_mutex_unlock(g_leServerStateMutex);
287 CATerminateLEGattServer();
291 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
292 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
294 // For Read Characteristics.
295 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
296 CA_LE_INITIAL_BUF_SIZE, true);
297 if (CA_STATUS_OK != ret)
299 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
300 ca_mutex_unlock(g_leServerStateMutex);
301 CATerminateLEGattServer();
305 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
306 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
309 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
310 CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
311 if (CA_STATUS_OK != ret )
313 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
314 ca_mutex_unlock(g_leServerStateMutex);
315 CATerminateLEGattServer();
319 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
320 if (CA_STATUS_OK != ret )
322 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
323 ca_mutex_unlock(g_leServerStateMutex);
324 CATerminateLEGattServer();
328 int res = bt_gatt_set_connection_state_changed_cb(CALEGattServerConnectionStateChangedCb,
330 if (BT_ERROR_NONE != res)
332 OIC_LOG_V(ERROR, TAG,
333 "bt_gatt_set_connection_state_changed_cb Failed with return as [%s]",
334 CALEGetErrorMsg(res));
338 ret = CALEStartAdvertise(serviceUUID);
339 if (CA_STATUS_OK != ret)
341 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
342 ca_mutex_unlock(g_leServerStateMutex);
343 CATerminateLEGattServer();
347 g_isLEGattServerStarted = true;
349 ca_mutex_unlock(g_leServerStateMutex);
351 OIC_LOG(DEBUG, TAG, "LE Server initialization complete.");
353 GMainContext *thread_context = NULL;
355 thread_context = g_main_context_new();
357 g_eventLoop = g_main_loop_new(thread_context, FALSE);
359 g_main_context_push_thread_default(thread_context);
361 g_main_loop_run(g_eventLoop);
363 OIC_LOG(DEBUG, TAG, "OUT");
366 CAResult_t CAStopLEGattServer()
368 OIC_LOG(DEBUG, TAG, "IN");
370 ca_mutex_lock(g_leServerStateMutex);
372 if (false == g_isLEGattServerStarted)
374 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
375 ca_mutex_unlock(g_leServerStateMutex);
379 g_isLEGattServerStarted = false;
381 CAResult_t res = CALEStopAdvertise();
383 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
386 res = CADeInitLEGattServer();
387 if (CA_STATUS_OK != res)
389 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
392 GMainContext *context_event_loop = NULL;
393 // Required for waking up the thread which is running in gmain loop
394 if (NULL != g_eventLoop)
396 context_event_loop = g_main_loop_get_context(g_eventLoop);
398 if (context_event_loop)
400 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
401 g_main_context_wakeup(context_event_loop);
403 // Kill g main loops and kill threads
404 g_main_loop_quit(g_eventLoop);
409 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
412 ca_mutex_unlock(g_leServerStateMutex);
414 OIC_LOG(DEBUG, TAG, "OUT");
418 CAResult_t CAInitializeLEGattServer()
420 OIC_LOG(DEBUG, TAG, "IN");
422 CAResult_t ret = CAInitGattServerMutexVariables();
423 if (CA_STATUS_OK != ret )
425 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
426 CATerminateGattServerMutexVariables();
427 return CA_SERVER_NOT_STARTED;
429 OIC_LOG(DEBUG, TAG, "OUT");
433 void CATerminateLEGattServer()
435 OIC_LOG(DEBUG, TAG, "IN");
437 // Service and characteristics path will be freed by the platform.
438 ca_mutex_lock(g_leServiceMutex);
439 g_gattSvcPath = NULL;
440 ca_mutex_unlock(g_leServiceMutex);
442 ca_mutex_lock(g_leCharacteristicMutex);
443 g_gattReadCharPath = NULL;
444 g_gattWriteCharPath = NULL;
445 ca_mutex_unlock(g_leCharacteristicMutex);
447 ca_mutex_lock(g_leServerThreadPoolMutex);
448 g_leServerThreadPool = NULL;
449 ca_mutex_unlock(g_leServerThreadPoolMutex);
451 // Terminating all mutex variables.
452 CATerminateGattServerMutexVariables();
453 OIC_LOG(DEBUG, TAG, "OUT");
456 CAResult_t CAInitGattServerMutexVariables()
458 OIC_LOG(DEBUG, TAG, "IN");
459 if (NULL == g_leServerStateMutex)
461 g_leServerStateMutex = ca_mutex_new();
462 if (NULL == g_leServerStateMutex)
464 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
465 return CA_STATUS_FAILED;
469 if (NULL == g_leServiceMutex)
471 g_leServiceMutex = ca_mutex_new();
472 if (NULL == g_leServiceMutex)
474 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
475 return CA_STATUS_FAILED;
479 if (NULL == g_leCharacteristicMutex)
481 g_leCharacteristicMutex = ca_mutex_new();
482 if (NULL == g_leCharacteristicMutex)
484 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
485 return CA_STATUS_FAILED;
489 if (NULL == g_leReqRespCbMutex)
491 g_leReqRespCbMutex = ca_mutex_new();
492 if (NULL == g_leReqRespCbMutex)
494 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
495 return CA_STATUS_FAILED;
498 OIC_LOG(DEBUG, TAG, "OUT");
502 void CATerminateGattServerMutexVariables()
504 OIC_LOG(DEBUG, TAG, "IN");
505 ca_mutex_free(g_leServerStateMutex);
506 g_leServerStateMutex = NULL;
508 ca_mutex_free(g_leServiceMutex);
509 g_leServiceMutex = NULL;
511 ca_mutex_free(g_leCharacteristicMutex);
512 g_leCharacteristicMutex = NULL;
514 ca_mutex_free(g_leReqRespCbMutex);
515 g_leReqRespCbMutex = NULL;
517 OIC_LOG(DEBUG, TAG, "OUT");
520 CAResult_t CAInitLEGattServer()
522 OIC_LOG(DEBUG, TAG, "IN");
524 int ret = bt_gatt_server_initialize();
527 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
528 CALEGetErrorMsg(ret));
529 return CA_STATUS_FAILED;
532 bt_gatt_server_h server;
534 ret = bt_gatt_server_create(&server);
537 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
538 CALEGetErrorMsg(ret));
539 return CA_STATUS_FAILED;
542 if (NULL != g_gattServer)
544 OICFree(g_gattServer);
547 g_gattServer = server;
549 OIC_LOG(DEBUG, TAG, "OUT");
553 CAResult_t CADeInitLEGattServer()
555 OIC_LOG(DEBUG, TAG, "IN");
557 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
560 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
561 CALEGetErrorMsg(ret));
562 return CA_STATUS_FAILED;
565 ret = bt_gatt_server_destroy(g_gattServer);
568 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
569 CALEGetErrorMsg(ret));
570 return CA_STATUS_FAILED;
573 ret = bt_gatt_server_deinitialize();
576 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
577 CALEGetErrorMsg(ret));
578 return CA_STATUS_FAILED;
581 OIC_LOG(DEBUG, TAG, "OUT");
585 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
587 OIC_LOG(DEBUG, TAG, "IN");
588 ca_mutex_lock(g_leServerThreadPoolMutex);
589 g_leServerThreadPool = handle;
590 ca_mutex_unlock(g_leServerThreadPoolMutex);
591 OIC_LOG(DEBUG, TAG, "OUT");
594 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
596 OIC_LOG(DEBUG, TAG, "IN");
598 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
600 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
602 bt_gatt_h service = NULL;
603 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
605 int ret = bt_gatt_service_create(serviceUUID, type, &service);
608 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
609 CALEGetErrorMsg(ret));
610 return CA_STATUS_FAILED;
615 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)service);
617 ca_mutex_lock(g_leServiceMutex);
619 if (NULL != g_gattSvcPath)
621 OICFree(g_gattSvcPath);
622 g_gattSvcPath = NULL;
624 g_gattSvcPath = service;
626 ca_mutex_unlock(g_leServiceMutex);
629 OIC_LOG(DEBUG, TAG, "OUT");
633 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
634 bt_gatt_h charPath, int offset, char *charValue,
635 int charValueLen, void *userData)
637 OIC_LOG(DEBUG, TAG, "IN");
639 if (NULL == charValue || NULL == remoteAddress)
641 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
645 OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
646 charValue, charValueLen);
648 uint8_t *data = OICMalloc(charValueLen);
651 OIC_LOG(ERROR, TAG, "Malloc failed!");
655 memcpy(data, charValue, charValueLen);
657 ca_mutex_lock(g_leReqRespCbMutex);
658 if (NULL == g_leServerDataReceivedCallback)
660 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
661 ca_mutex_unlock(g_leReqRespCbMutex);
666 OIC_LOG(DEBUG, TAG, "Sending data up !");
667 uint32_t sentLength = 0;
668 g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
670 ca_mutex_unlock(g_leReqRespCbMutex);
672 OIC_LOG(DEBUG, TAG, "OUT");
675 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
677 OIC_LOG(DEBUG, TAG, "IN");
679 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
681 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
683 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
686 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
687 CALEGetErrorMsg(ret));
688 return CA_STATUS_FAILED;
691 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
692 CALEGattRemoteCharacteristicWriteCb, NULL);
696 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
697 CALEGetErrorMsg(ret));
698 return CA_STATUS_FAILED;
701 OIC_LOG(DEBUG, TAG, "OUT");
705 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
706 const char *charValue, int charValueLen, bool read)
709 OIC_LOG(DEBUG, TAG, "IN");
711 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
712 int properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_NOTIFY;
715 properties = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ;
719 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
724 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
725 charValueLen, &charPath);
727 if (0 != ret || NULL == charPath)
729 OIC_LOG_V(ERROR, TAG,
730 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
731 return CA_STATUS_FAILED;
734 OIC_LOG_V(DEBUG, TAG,
735 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
739 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
742 OIC_LOG_V(ERROR, TAG,
743 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
744 CALEGetErrorMsg(ret));
745 return CA_STATUS_FAILED;
749 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
752 OIC_LOG_V(ERROR, TAG,
753 "bt_gatt_service_add_characteristic failed with ret[%s]",
754 CALEGetErrorMsg(ret));
755 return CA_STATUS_FAILED;
758 ca_mutex_lock(g_leCharacteristicMutex);
762 char desc_value[2] = {1, 0}; // Notification enabled.
763 bt_gatt_h descriptor = NULL;
764 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
765 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID,
766 permissions, desc_value, sizeof(desc_value), &descriptor);
769 OIC_LOG_V(ERROR, TAG,
770 "bt_gatt_descriptor_create failed with ret[%s]",
771 CALEGetErrorMsg(ret));
772 return CA_STATUS_FAILED;
775 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
778 OIC_LOG_V(ERROR, TAG,
779 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
780 CALEGetErrorMsg(ret));
781 return CA_STATUS_FAILED;
784 if (NULL != g_gattReadCharPath)
786 OICFree(g_gattReadCharPath);
787 g_gattReadCharPath = NULL;
789 g_gattReadCharPath = charPath;
794 if (NULL != g_gattWriteCharPath)
796 OICFree(g_gattWriteCharPath);
797 g_gattWriteCharPath = NULL;
799 g_gattWriteCharPath = charPath;
802 ca_mutex_unlock(g_leCharacteristicMutex);
804 OIC_LOG(DEBUG, TAG, "OUT");
808 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
809 uint32_t charValueLen)
811 OIC_LOG(DEBUG, TAG, "IN");
813 VERIFY_NON_NULL(charValue, TAG, "charValue");
814 VERIFY_NON_NULL(address, TAG, "address");
816 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
818 ca_mutex_lock(g_leCharacteristicMutex);
820 if (NULL == g_gattReadCharPath)
822 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
823 ca_mutex_unlock(g_leCharacteristicMutex);
824 return CA_STATUS_FAILED;
827 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
830 OIC_LOG_V(ERROR, TAG,
831 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
832 ca_mutex_unlock(g_leCharacteristicMutex);
833 return CA_STATUS_FAILED;
836 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
840 OIC_LOG_V(ERROR, TAG,
841 "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
842 ca_mutex_unlock(g_leCharacteristicMutex);
843 return CA_STATUS_FAILED;
846 ca_mutex_unlock(g_leCharacteristicMutex);
848 OIC_LOG(DEBUG, TAG, "OUT");
852 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
854 OIC_LOG(DEBUG, TAG, "IN");
856 VERIFY_NON_NULL(charValue, TAG, "charValue");
858 ca_mutex_lock(g_leCharacteristicMutex);
860 if (NULL == g_gattReadCharPath)
862 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
863 ca_mutex_unlock(g_leCharacteristicMutex);
864 return CA_STATUS_FAILED;
867 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
870 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
871 ca_mutex_unlock(g_leCharacteristicMutex);
872 return CA_STATUS_FAILED;
875 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
879 OIC_LOG_V(ERROR, TAG,
880 "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
881 ca_mutex_unlock(g_leCharacteristicMutex);
882 return CA_STATUS_FAILED;
885 ca_mutex_unlock(g_leCharacteristicMutex);
887 OIC_LOG(DEBUG, TAG, "OUT");
891 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
893 OIC_LOG(DEBUG, TAG, "IN");
895 ca_mutex_lock(g_leReqRespCbMutex);
896 g_leServerDataReceivedCallback = callback;
897 ca_mutex_unlock(g_leReqRespCbMutex);
899 OIC_LOG(DEBUG, TAG, "OUT");
902 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
904 g_serverErrorCallback = callback;