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 CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
130 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
134 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
137 g_connStateCb(CA_ADAPTER_GATT_BTLE, remoteAddress, true);
142 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
145 g_connStateCb(CA_ADAPTER_GATT_BTLE, remoteAddress, false);
150 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
151 bt_gatt_h characteristic, bool completed, void *user_data)
153 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
156 CAResult_t CAStartLEGattServer()
158 OIC_LOG(DEBUG, TAG, "IN");
160 ca_mutex_lock(g_leServerThreadPoolMutex);
161 if (NULL == g_leServerThreadPool)
163 OIC_LOG(ERROR, TAG, "g_leServerThreadPool is NULL");
164 ca_mutex_unlock(g_leServerThreadPoolMutex);
165 return CA_STATUS_FAILED;
168 CAResult_t ret = ca_thread_pool_add_task(g_leServerThreadPool, CAStartLEGattServerThread,
170 if (CA_STATUS_OK != ret)
172 OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
173 ca_mutex_unlock(g_leServerThreadPoolMutex);
174 return CA_STATUS_FAILED;
177 ca_mutex_unlock(g_leServerThreadPoolMutex);
178 OIC_LOG(DEBUG, TAG, "OUT");
182 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
185 OIC_LOG(DEBUG, TAG, "IN");
188 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
190 OIC_LOG(DEBUG, TAG, "OUT");
193 CAResult_t CALEStartAdvertise(const char *serviceUUID)
195 OIC_LOG(DEBUG, TAG, "IN");
197 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
198 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
200 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
201 return CA_STATUS_FAILED;
204 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
205 BT_ADAPTER_LE_PACKET_ADVERTISING,
207 if (BT_ERROR_NONE != res)
209 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
210 CALEGetErrorMsg(res));
211 return CA_STATUS_FAILED;
214 res = bt_adapter_le_start_advertising(g_hAdvertiser, NULL, NULL, NULL);
215 if (BT_ERROR_NONE != res)
217 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising failed with ret[%s]",
218 CALEGetErrorMsg(res));
219 return CA_STATUS_FAILED;
222 OIC_LOG(DEBUG, TAG, "OUT");
226 CAResult_t CALEStopAdvertise()
228 OIC_LOG(DEBUG, TAG, "IN");
229 if (NULL != g_hAdvertiser)
231 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
234 OIC_LOG_V(ERROR, TAG,
235 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
238 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
241 OIC_LOG_V(ERROR, TAG,
242 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
244 g_hAdvertiser = NULL;
248 OIC_LOG(ERROR, TAG, "Advertising is not running");
249 return CA_STATUS_FAILED;
252 OIC_LOG(DEBUG, TAG, "OUT");
256 void CAStartLEGattServerThread(void *data)
258 OIC_LOG(DEBUG, TAG, "IN");
259 ca_mutex_lock(g_leServerStateMutex);
260 if (true == g_isLEGattServerStarted)
262 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
263 ca_mutex_unlock(g_leServerStateMutex);
264 CATerminateLEGattServer();
268 CAResult_t ret = CAInitLEGattServer();
269 if (CA_STATUS_OK != ret)
271 OIC_LOG_V(ERROR, TAG, "CAInitLEGattService failed[%d]", ret);
272 ca_mutex_unlock(g_leServerStateMutex);
273 CATerminateLEGattServer();
277 char *serviceUUID = CA_GATT_SERVICE_UUID;
279 ret = CAAddNewLEServiceInGattServer(serviceUUID);
280 if (CA_STATUS_OK != ret)
282 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
283 ca_mutex_unlock(g_leServerStateMutex);
284 CATerminateLEGattServer();
288 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
289 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
291 // For Read Characteristics.
292 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
293 CA_LE_INITIAL_BUF_SIZE, true);
294 if (CA_STATUS_OK != ret)
296 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
297 ca_mutex_unlock(g_leServerStateMutex);
298 CATerminateLEGattServer();
302 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
303 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
306 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
307 CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
308 if (CA_STATUS_OK != ret )
310 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
311 ca_mutex_unlock(g_leServerStateMutex);
312 CATerminateLEGattServer();
316 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
317 if (CA_STATUS_OK != ret )
319 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
320 ca_mutex_unlock(g_leServerStateMutex);
321 CATerminateLEGattServer();
325 ret = CALEStartAdvertise(serviceUUID);
326 if (CA_STATUS_OK != ret)
328 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
329 ca_mutex_unlock(g_leServerStateMutex);
330 CATerminateLEGattServer();
334 g_isLEGattServerStarted = true;
336 ca_mutex_unlock(g_leServerStateMutex);
338 OIC_LOG(DEBUG, TAG, "LE Server initialization complete.");
340 GMainContext *thread_context = NULL;
342 thread_context = g_main_context_new();
344 g_eventLoop = g_main_loop_new(thread_context, FALSE);
346 g_main_context_push_thread_default(thread_context);
348 g_main_loop_run(g_eventLoop);
350 OIC_LOG(DEBUG, TAG, "OUT");
353 CAResult_t CAStopLEGattServer()
355 OIC_LOG(DEBUG, TAG, "IN");
357 ca_mutex_lock(g_leServerStateMutex);
359 if (false == g_isLEGattServerStarted)
361 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
362 ca_mutex_unlock(g_leServerStateMutex);
366 g_isLEGattServerStarted = false;
368 CAResult_t res = CALEStopAdvertise();
370 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
373 res = CADeInitLEGattServer();
374 if (CA_STATUS_OK != res)
376 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
379 GMainContext *context_event_loop = NULL;
380 // Required for waking up the thread which is running in gmain loop
381 if (NULL != g_eventLoop)
383 context_event_loop = g_main_loop_get_context(g_eventLoop);
385 if (context_event_loop)
387 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
388 g_main_context_wakeup(context_event_loop);
390 // Kill g main loops and kill threads
391 g_main_loop_quit(g_eventLoop);
396 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
399 ca_mutex_unlock(g_leServerStateMutex);
401 OIC_LOG(DEBUG, TAG, "OUT");
405 CAResult_t CAInitializeLEGattServer()
407 OIC_LOG(DEBUG, TAG, "IN");
409 CAResult_t ret = CAInitGattServerMutexVariables();
410 if (CA_STATUS_OK != ret )
412 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
413 CATerminateGattServerMutexVariables();
414 return CA_SERVER_NOT_STARTED;
416 OIC_LOG(DEBUG, TAG, "OUT");
420 void CATerminateLEGattServer()
422 OIC_LOG(DEBUG, TAG, "IN");
424 // Service and characteristics path will be freed by the platform.
425 ca_mutex_lock(g_leServiceMutex);
426 g_gattSvcPath = NULL;
427 ca_mutex_unlock(g_leServiceMutex);
429 ca_mutex_lock(g_leCharacteristicMutex);
430 g_gattReadCharPath = NULL;
431 g_gattWriteCharPath = NULL;
432 ca_mutex_unlock(g_leCharacteristicMutex);
434 ca_mutex_lock(g_leServerThreadPoolMutex);
435 g_leServerThreadPool = NULL;
436 ca_mutex_unlock(g_leServerThreadPoolMutex);
438 // Terminating all mutex variables.
439 CATerminateGattServerMutexVariables();
440 OIC_LOG(DEBUG, TAG, "OUT");
443 CAResult_t CAInitGattServerMutexVariables()
445 OIC_LOG(DEBUG, TAG, "IN");
446 if (NULL == g_leServerStateMutex)
448 g_leServerStateMutex = ca_mutex_new();
449 if (NULL == g_leServerStateMutex)
451 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
452 return CA_STATUS_FAILED;
456 if (NULL == g_leServiceMutex)
458 g_leServiceMutex = ca_mutex_new();
459 if (NULL == g_leServiceMutex)
461 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
462 return CA_STATUS_FAILED;
466 if (NULL == g_leCharacteristicMutex)
468 g_leCharacteristicMutex = ca_mutex_new();
469 if (NULL == g_leCharacteristicMutex)
471 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
472 return CA_STATUS_FAILED;
476 if (NULL == g_leReqRespCbMutex)
478 g_leReqRespCbMutex = ca_mutex_new();
479 if (NULL == g_leReqRespCbMutex)
481 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
482 return CA_STATUS_FAILED;
485 OIC_LOG(DEBUG, TAG, "OUT");
489 void CATerminateGattServerMutexVariables()
491 OIC_LOG(DEBUG, TAG, "IN");
492 ca_mutex_free(g_leServerStateMutex);
493 g_leServerStateMutex = NULL;
495 ca_mutex_free(g_leServiceMutex);
496 g_leServiceMutex = NULL;
498 ca_mutex_free(g_leCharacteristicMutex);
499 g_leCharacteristicMutex = NULL;
501 ca_mutex_free(g_leReqRespCbMutex);
502 g_leReqRespCbMutex = NULL;
504 OIC_LOG(DEBUG, TAG, "OUT");
507 CAResult_t CAInitLEGattServer()
509 OIC_LOG(DEBUG, TAG, "IN");
511 int ret = bt_gatt_server_initialize();
514 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
515 CALEGetErrorMsg(ret));
516 return CA_STATUS_FAILED;
519 bt_gatt_server_h server;
521 ret = bt_gatt_server_create(&server);
524 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
525 CALEGetErrorMsg(ret));
526 return CA_STATUS_FAILED;
529 if (NULL != g_gattServer)
531 OICFree(g_gattServer);
534 g_gattServer = server;
536 OIC_LOG(DEBUG, TAG, "OUT");
540 CAResult_t CADeInitLEGattServer()
542 OIC_LOG(DEBUG, TAG, "IN");
544 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
547 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
548 CALEGetErrorMsg(ret));
549 return CA_STATUS_FAILED;
552 ret = bt_gatt_server_destroy(g_gattServer);
555 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
556 CALEGetErrorMsg(ret));
557 return CA_STATUS_FAILED;
560 ret = bt_gatt_server_deinitialize();
563 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
564 CALEGetErrorMsg(ret));
565 return CA_STATUS_FAILED;
568 OIC_LOG(DEBUG, TAG, "OUT");
572 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
574 OIC_LOG(DEBUG, TAG, "IN");
575 ca_mutex_lock(g_leServerThreadPoolMutex);
576 g_leServerThreadPool = handle;
577 ca_mutex_unlock(g_leServerThreadPoolMutex);
578 OIC_LOG(DEBUG, TAG, "OUT");
581 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
583 OIC_LOG(DEBUG, TAG, "IN");
585 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
587 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
589 bt_gatt_h service = NULL;
590 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
592 int ret = bt_gatt_service_create(serviceUUID, type, &service);
595 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
596 CALEGetErrorMsg(ret));
597 return CA_STATUS_FAILED;
602 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)service);
604 ca_mutex_lock(g_leServiceMutex);
606 if (NULL != g_gattSvcPath)
608 OICFree(g_gattSvcPath);
609 g_gattSvcPath = NULL;
611 g_gattSvcPath = service;
613 ca_mutex_unlock(g_leServiceMutex);
616 OIC_LOG(DEBUG, TAG, "OUT");
620 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
621 bt_gatt_h charPath, int offset, char *charValue,
622 int charValueLen, void *userData)
624 OIC_LOG(DEBUG, TAG, "IN");
626 if (NULL == charValue || NULL == remoteAddress)
628 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
632 OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
633 charValue, charValueLen);
635 uint8_t *data = OICMalloc(charValueLen);
638 OIC_LOG(ERROR, TAG, "Malloc failed!");
642 memcpy(data, charValue, charValueLen);
644 ca_mutex_lock(g_leReqRespCbMutex);
645 if (NULL == g_leServerDataReceivedCallback)
647 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
648 ca_mutex_unlock(g_leReqRespCbMutex);
653 OIC_LOG(DEBUG, TAG, "Sending data up !");
654 uint32_t sentLength = 0;
655 g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
657 ca_mutex_unlock(g_leReqRespCbMutex);
659 OIC_LOG(DEBUG, TAG, "OUT");
662 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
664 OIC_LOG(DEBUG, TAG, "IN");
666 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
668 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
670 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
673 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
674 CALEGetErrorMsg(ret));
675 return CA_STATUS_FAILED;
678 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
679 CALEGattRemoteCharacteristicWriteCb, NULL);
683 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
684 CALEGetErrorMsg(ret));
685 return CA_STATUS_FAILED;
688 OIC_LOG(DEBUG, TAG, "OUT");
692 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
693 const char *charValue, int charValueLen, bool read)
696 OIC_LOG(DEBUG, TAG, "IN");
698 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
699 int properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_NOTIFY;
702 properties = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ;
706 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
711 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
712 charValueLen, &charPath);
714 if (0 != ret || NULL == charPath)
716 OIC_LOG_V(ERROR, TAG,
717 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
718 return CA_STATUS_FAILED;
721 OIC_LOG_V(DEBUG, TAG,
722 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
726 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
729 OIC_LOG_V(ERROR, TAG,
730 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
731 CALEGetErrorMsg(ret));
732 return CA_STATUS_FAILED;
736 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
739 OIC_LOG_V(ERROR, TAG,
740 "bt_gatt_service_add_characteristic failed with ret[%s]",
741 CALEGetErrorMsg(ret));
742 return CA_STATUS_FAILED;
745 ca_mutex_lock(g_leCharacteristicMutex);
749 char desc_value[2] = {1, 0}; // Notification enabled.
750 bt_gatt_h descriptor = NULL;
751 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
752 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID,
753 permissions, desc_value, sizeof(desc_value), &descriptor);
756 OIC_LOG_V(ERROR, TAG,
757 "bt_gatt_descriptor_create failed with ret[%s]",
758 CALEGetErrorMsg(ret));
759 return CA_STATUS_FAILED;
762 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
765 OIC_LOG_V(ERROR, TAG,
766 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
767 CALEGetErrorMsg(ret));
768 return CA_STATUS_FAILED;
771 if (NULL != g_gattReadCharPath)
773 OICFree(g_gattReadCharPath);
774 g_gattReadCharPath = NULL;
776 g_gattReadCharPath = charPath;
781 if (NULL != g_gattWriteCharPath)
783 OICFree(g_gattWriteCharPath);
784 g_gattWriteCharPath = NULL;
786 g_gattWriteCharPath = charPath;
789 ca_mutex_unlock(g_leCharacteristicMutex);
791 OIC_LOG(DEBUG, TAG, "OUT");
795 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
796 uint32_t charValueLen)
798 OIC_LOG(DEBUG, TAG, "IN");
800 VERIFY_NON_NULL(charValue, TAG, "charValue");
801 VERIFY_NON_NULL(address, TAG, "address");
803 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
805 ca_mutex_lock(g_leCharacteristicMutex);
807 if (NULL == g_gattReadCharPath)
809 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
810 ca_mutex_unlock(g_leCharacteristicMutex);
811 return CA_STATUS_FAILED;
814 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
817 OIC_LOG_V(ERROR, TAG,
818 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
819 ca_mutex_unlock(g_leCharacteristicMutex);
820 return CA_STATUS_FAILED;
823 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
827 OIC_LOG_V(ERROR, TAG,
828 "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
829 ca_mutex_unlock(g_leCharacteristicMutex);
830 return CA_STATUS_FAILED;
833 ca_mutex_unlock(g_leCharacteristicMutex);
835 OIC_LOG(DEBUG, TAG, "OUT");
839 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
841 OIC_LOG(DEBUG, TAG, "IN");
843 VERIFY_NON_NULL(charValue, TAG, "charValue");
845 ca_mutex_lock(g_leCharacteristicMutex);
847 if (NULL == g_gattReadCharPath)
849 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
850 ca_mutex_unlock(g_leCharacteristicMutex);
851 return CA_STATUS_FAILED;
854 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
857 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
858 ca_mutex_unlock(g_leCharacteristicMutex);
859 return CA_STATUS_FAILED;
862 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
866 OIC_LOG_V(ERROR, TAG,
867 "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
868 ca_mutex_unlock(g_leCharacteristicMutex);
869 return CA_STATUS_FAILED;
872 ca_mutex_unlock(g_leCharacteristicMutex);
874 OIC_LOG(DEBUG, TAG, "OUT");
878 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
880 OIC_LOG(DEBUG, TAG, "IN");
882 ca_mutex_lock(g_leReqRespCbMutex);
883 g_leServerDataReceivedCallback = callback;
884 ca_mutex_unlock(g_leReqRespCbMutex);
886 OIC_LOG(DEBUG, TAG, "OUT");
889 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
891 g_serverErrorCallback = callback;