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 void CALEGattServerConnectionStateChangedCb(int result, bool connected,
122 const char *remoteAddress, void *userData)
124 OIC_LOG(DEBUG, TAG, "IN");
126 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
128 OIC_LOG_V(DEBUG, TAG, "CABleGattConnectionStateChangedCb result[%d]", result);
132 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
134 OIC_LOG(DEBUG, TAG, "OUT");
137 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
138 bt_gatt_h characteristic, bool completed, void *user_data)
140 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
143 CAResult_t CAStartLEGattServer()
145 OIC_LOG(DEBUG, TAG, "IN");
147 ca_mutex_lock(g_leServerThreadPoolMutex);
148 if (NULL == g_leServerThreadPool)
150 OIC_LOG(ERROR, TAG, "g_leServerThreadPool is NULL");
151 ca_mutex_unlock(g_leServerThreadPoolMutex);
152 return CA_STATUS_FAILED;
155 CAResult_t ret = ca_thread_pool_add_task(g_leServerThreadPool, CAStartLEGattServerThread,
157 if (CA_STATUS_OK != ret)
159 OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
160 ca_mutex_unlock(g_leServerThreadPoolMutex);
161 return CA_STATUS_FAILED;
164 ca_mutex_unlock(g_leServerThreadPoolMutex);
165 OIC_LOG(DEBUG, TAG, "OUT");
169 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
172 OIC_LOG(DEBUG, TAG, "IN");
175 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
177 OIC_LOG(DEBUG, TAG, "OUT");
180 CAResult_t CALEStartAdvertise(const char *serviceUUID)
182 OIC_LOG(DEBUG, TAG, "IN");
184 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
185 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
187 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
188 return CA_STATUS_FAILED;
191 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
192 BT_ADAPTER_LE_PACKET_ADVERTISING,
194 if (BT_ERROR_NONE != res)
196 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
197 CALEGetErrorMsg(res));
198 return CA_STATUS_FAILED;
201 res = bt_adapter_le_start_advertising(g_hAdvertiser, NULL, NULL, NULL);
202 if (BT_ERROR_NONE != res)
204 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising failed with ret[%s]",
205 CALEGetErrorMsg(res));
206 return CA_STATUS_FAILED;
209 OIC_LOG(DEBUG, TAG, "OUT");
213 CAResult_t CALEStopAdvertise()
215 OIC_LOG(DEBUG, TAG, "IN");
216 if (NULL != g_hAdvertiser)
218 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
221 OIC_LOG_V(ERROR, TAG,
222 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
225 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
228 OIC_LOG_V(ERROR, TAG,
229 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
231 g_hAdvertiser = NULL;
235 OIC_LOG(ERROR, TAG, "Advertising is not running");
236 return CA_STATUS_FAILED;
239 OIC_LOG(DEBUG, TAG, "OUT");
243 void CAStartLEGattServerThread(void *data)
245 OIC_LOG(DEBUG, TAG, "IN");
246 ca_mutex_lock(g_leServerStateMutex);
247 if (true == g_isLEGattServerStarted)
249 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
250 ca_mutex_unlock(g_leServerStateMutex);
251 CATerminateLEGattServer();
255 CAResult_t ret = CAInitLEGattServer();
256 if (CA_STATUS_OK != ret)
258 OIC_LOG_V(ERROR, TAG, "CAInitLEGattService failed[%d]", ret);
259 ca_mutex_unlock(g_leServerStateMutex);
260 CATerminateLEGattServer();
264 char *serviceUUID = CA_GATT_SERVICE_UUID;
266 ret = CAAddNewLEServiceInGattServer(serviceUUID);
267 if (CA_STATUS_OK != ret)
269 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
270 ca_mutex_unlock(g_leServerStateMutex);
271 CATerminateLEGattServer();
275 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
276 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
278 // For Read Characteristics.
279 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
280 CA_LE_INITIAL_BUF_SIZE, true);
281 if (CA_STATUS_OK != ret)
283 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
284 ca_mutex_unlock(g_leServerStateMutex);
285 CATerminateLEGattServer();
289 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
290 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
293 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
294 CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
295 if (CA_STATUS_OK != ret )
297 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
298 ca_mutex_unlock(g_leServerStateMutex);
299 CATerminateLEGattServer();
303 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
304 if (CA_STATUS_OK != ret )
306 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
307 ca_mutex_unlock(g_leServerStateMutex);
308 CATerminateLEGattServer();
312 int res = bt_gatt_set_connection_state_changed_cb(CALEGattServerConnectionStateChangedCb,
314 if (BT_ERROR_NONE != res)
316 OIC_LOG_V(ERROR, TAG,
317 "bt_gatt_set_connection_state_changed_cb Failed with return as [%s]",
318 CALEGetErrorMsg(res));
322 ret = CALEStartAdvertise(serviceUUID);
323 if (CA_STATUS_OK != ret)
325 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
326 ca_mutex_unlock(g_leServerStateMutex);
327 CATerminateLEGattServer();
331 g_isLEGattServerStarted = true;
333 ca_mutex_unlock(g_leServerStateMutex);
335 OIC_LOG(DEBUG, TAG, "LE Server initialization complete.");
337 GMainContext *thread_context = NULL;
339 thread_context = g_main_context_new();
341 g_eventLoop = g_main_loop_new(thread_context, FALSE);
343 g_main_context_push_thread_default(thread_context);
345 g_main_loop_run(g_eventLoop);
347 OIC_LOG(DEBUG, TAG, "OUT");
350 CAResult_t CAStopLEGattServer()
352 OIC_LOG(DEBUG, TAG, "IN");
354 ca_mutex_lock(g_leServerStateMutex);
356 if (false == g_isLEGattServerStarted)
358 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
359 ca_mutex_unlock(g_leServerStateMutex);
363 g_isLEGattServerStarted = false;
365 CAResult_t res = CALEStopAdvertise();
367 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
370 res = CADeInitLEGattServer();
371 if (CA_STATUS_OK != res)
373 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
376 GMainContext *context_event_loop = NULL;
377 // Required for waking up the thread which is running in gmain loop
378 if (NULL != g_eventLoop)
380 context_event_loop = g_main_loop_get_context(g_eventLoop);
382 if (context_event_loop)
384 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
385 g_main_context_wakeup(context_event_loop);
387 // Kill g main loops and kill threads
388 g_main_loop_quit(g_eventLoop);
393 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
396 ca_mutex_unlock(g_leServerStateMutex);
398 OIC_LOG(DEBUG, TAG, "OUT");
402 CAResult_t CAInitializeLEGattServer()
404 OIC_LOG(DEBUG, TAG, "IN");
406 CAResult_t ret = CAInitGattServerMutexVariables();
407 if (CA_STATUS_OK != ret )
409 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
410 CATerminateGattServerMutexVariables();
411 return CA_SERVER_NOT_STARTED;
413 OIC_LOG(DEBUG, TAG, "OUT");
417 void CATerminateLEGattServer()
419 OIC_LOG(DEBUG, TAG, "IN");
421 // Service and characteristics path will be freed by the platform.
422 ca_mutex_lock(g_leServiceMutex);
423 g_gattSvcPath = NULL;
424 ca_mutex_unlock(g_leServiceMutex);
426 ca_mutex_lock(g_leCharacteristicMutex);
427 g_gattReadCharPath = NULL;
428 g_gattWriteCharPath = NULL;
429 ca_mutex_unlock(g_leCharacteristicMutex);
431 ca_mutex_lock(g_leServerThreadPoolMutex);
432 g_leServerThreadPool = NULL;
433 ca_mutex_unlock(g_leServerThreadPoolMutex);
435 // Terminating all mutex variables.
436 CATerminateGattServerMutexVariables();
437 OIC_LOG(DEBUG, TAG, "OUT");
440 CAResult_t CAInitGattServerMutexVariables()
442 OIC_LOG(DEBUG, TAG, "IN");
443 if (NULL == g_leServerStateMutex)
445 g_leServerStateMutex = ca_mutex_new();
446 if (NULL == g_leServerStateMutex)
448 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
449 return CA_STATUS_FAILED;
453 if (NULL == g_leServiceMutex)
455 g_leServiceMutex = ca_mutex_new();
456 if (NULL == g_leServiceMutex)
458 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
459 return CA_STATUS_FAILED;
463 if (NULL == g_leCharacteristicMutex)
465 g_leCharacteristicMutex = ca_mutex_new();
466 if (NULL == g_leCharacteristicMutex)
468 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
469 return CA_STATUS_FAILED;
473 if (NULL == g_leReqRespCbMutex)
475 g_leReqRespCbMutex = ca_mutex_new();
476 if (NULL == g_leReqRespCbMutex)
478 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
479 return CA_STATUS_FAILED;
482 OIC_LOG(DEBUG, TAG, "OUT");
486 void CATerminateGattServerMutexVariables()
488 OIC_LOG(DEBUG, TAG, "IN");
489 ca_mutex_free(g_leServerStateMutex);
490 g_leServerStateMutex = NULL;
492 ca_mutex_free(g_leServiceMutex);
493 g_leServiceMutex = NULL;
495 ca_mutex_free(g_leCharacteristicMutex);
496 g_leCharacteristicMutex = NULL;
498 ca_mutex_free(g_leReqRespCbMutex);
499 g_leReqRespCbMutex = NULL;
501 OIC_LOG(DEBUG, TAG, "OUT");
504 CAResult_t CAInitLEGattServer()
506 OIC_LOG(DEBUG, TAG, "IN");
508 int ret = bt_gatt_server_initialize();
511 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
512 CALEGetErrorMsg(ret));
513 return CA_STATUS_FAILED;
516 bt_gatt_server_h server;
518 ret = bt_gatt_server_create(&server);
521 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
522 CALEGetErrorMsg(ret));
523 return CA_STATUS_FAILED;
526 if (NULL != g_gattServer)
528 OICFree(g_gattServer);
531 g_gattServer = server;
533 OIC_LOG(DEBUG, TAG, "OUT");
537 CAResult_t CADeInitLEGattServer()
539 OIC_LOG(DEBUG, TAG, "IN");
541 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
544 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
545 CALEGetErrorMsg(ret));
546 return CA_STATUS_FAILED;
549 ret = bt_gatt_server_destroy(g_gattServer);
552 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
553 CALEGetErrorMsg(ret));
554 return CA_STATUS_FAILED;
557 ret = bt_gatt_server_deinitialize();
560 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
561 CALEGetErrorMsg(ret));
562 return CA_STATUS_FAILED;
565 OIC_LOG(DEBUG, TAG, "OUT");
569 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
571 OIC_LOG(DEBUG, TAG, "IN");
572 ca_mutex_lock(g_leServerThreadPoolMutex);
573 g_leServerThreadPool = handle;
574 ca_mutex_unlock(g_leServerThreadPoolMutex);
575 OIC_LOG(DEBUG, TAG, "OUT");
578 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
580 OIC_LOG(DEBUG, TAG, "IN");
582 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
584 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
586 bt_gatt_h service = NULL;
587 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
589 int ret = bt_gatt_service_create(serviceUUID, type, &service);
592 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
593 CALEGetErrorMsg(ret));
594 return CA_STATUS_FAILED;
599 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)service);
601 ca_mutex_lock(g_leServiceMutex);
603 if (NULL != g_gattSvcPath)
605 OICFree(g_gattSvcPath);
606 g_gattSvcPath = NULL;
608 g_gattSvcPath = service;
610 ca_mutex_unlock(g_leServiceMutex);
613 OIC_LOG(DEBUG, TAG, "OUT");
617 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
618 bt_gatt_h charPath, int offset, char *charValue,
619 int charValueLen, void *userData)
621 OIC_LOG(DEBUG, TAG, "IN");
623 if (NULL == charValue || NULL == remoteAddress)
625 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
629 OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
630 charValue, charValueLen);
632 uint8_t *data = OICMalloc(charValueLen);
635 OIC_LOG(ERROR, TAG, "Malloc failed!");
639 memcpy(data, charValue, charValueLen);
641 ca_mutex_lock(g_leReqRespCbMutex);
642 if (NULL == g_leServerDataReceivedCallback)
644 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
645 ca_mutex_unlock(g_leReqRespCbMutex);
650 OIC_LOG(DEBUG, TAG, "Sending data up !");
651 uint32_t sentLength = 0;
652 g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
654 ca_mutex_unlock(g_leReqRespCbMutex);
656 OIC_LOG(DEBUG, TAG, "OUT");
659 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
661 OIC_LOG(DEBUG, TAG, "IN");
663 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
665 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
667 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
670 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
671 CALEGetErrorMsg(ret));
672 return CA_STATUS_FAILED;
675 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
676 CALEGattRemoteCharacteristicWriteCb, NULL);
680 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
681 CALEGetErrorMsg(ret));
682 return CA_STATUS_FAILED;
685 OIC_LOG(DEBUG, TAG, "OUT");
689 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
690 const char *charValue, int charValueLen, bool read)
693 OIC_LOG(DEBUG, TAG, "IN");
695 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
696 int properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_NOTIFY;
699 properties = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ;
703 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
708 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
709 charValueLen, &charPath);
711 if (0 != ret || NULL == charPath)
713 OIC_LOG_V(ERROR, TAG,
714 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
715 return CA_STATUS_FAILED;
718 OIC_LOG_V(DEBUG, TAG,
719 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
723 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
726 OIC_LOG_V(ERROR, TAG,
727 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
728 CALEGetErrorMsg(ret));
729 return CA_STATUS_FAILED;
733 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
736 OIC_LOG_V(ERROR, TAG,
737 "bt_gatt_service_add_characteristic failed with ret[%s]",
738 CALEGetErrorMsg(ret));
739 return CA_STATUS_FAILED;
742 ca_mutex_lock(g_leCharacteristicMutex);
746 char desc_value[2] = {1, 0}; // Notification enabled.
747 bt_gatt_h descriptor = NULL;
748 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
749 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID,
750 permissions, desc_value, sizeof(desc_value), &descriptor);
753 OIC_LOG_V(ERROR, TAG,
754 "bt_gatt_descriptor_create failed with ret[%s]",
755 CALEGetErrorMsg(ret));
756 return CA_STATUS_FAILED;
759 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
762 OIC_LOG_V(ERROR, TAG,
763 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
764 CALEGetErrorMsg(ret));
765 return CA_STATUS_FAILED;
768 if (NULL != g_gattReadCharPath)
770 OICFree(g_gattReadCharPath);
771 g_gattReadCharPath = NULL;
773 g_gattReadCharPath = charPath;
778 if (NULL != g_gattWriteCharPath)
780 OICFree(g_gattWriteCharPath);
781 g_gattWriteCharPath = NULL;
783 g_gattWriteCharPath = charPath;
786 ca_mutex_unlock(g_leCharacteristicMutex);
788 OIC_LOG(DEBUG, TAG, "OUT");
792 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
793 uint32_t charValueLen)
795 OIC_LOG(DEBUG, TAG, "IN");
797 VERIFY_NON_NULL(charValue, TAG, "charValue");
798 VERIFY_NON_NULL(address, TAG, "address");
800 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
802 ca_mutex_lock(g_leCharacteristicMutex);
804 if (NULL == g_gattReadCharPath)
806 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
807 ca_mutex_unlock(g_leCharacteristicMutex);
808 return CA_STATUS_FAILED;
811 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
814 OIC_LOG_V(ERROR, TAG,
815 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
816 ca_mutex_unlock(g_leCharacteristicMutex);
817 return CA_STATUS_FAILED;
820 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
824 OIC_LOG_V(ERROR, TAG,
825 "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
826 ca_mutex_unlock(g_leCharacteristicMutex);
827 return CA_STATUS_FAILED;
830 ca_mutex_unlock(g_leCharacteristicMutex);
832 OIC_LOG(DEBUG, TAG, "OUT");
836 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
838 OIC_LOG(DEBUG, TAG, "IN");
840 VERIFY_NON_NULL(charValue, TAG, "charValue");
842 ca_mutex_lock(g_leCharacteristicMutex);
844 if (NULL == g_gattReadCharPath)
846 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
847 ca_mutex_unlock(g_leCharacteristicMutex);
848 return CA_STATUS_FAILED;
851 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
854 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
855 ca_mutex_unlock(g_leCharacteristicMutex);
856 return CA_STATUS_FAILED;
859 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
863 OIC_LOG_V(ERROR, TAG,
864 "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
865 ca_mutex_unlock(g_leCharacteristicMutex);
866 return CA_STATUS_FAILED;
869 ca_mutex_unlock(g_leCharacteristicMutex);
871 OIC_LOG(DEBUG, TAG, "OUT");
875 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
877 OIC_LOG(DEBUG, TAG, "IN");
879 ca_mutex_lock(g_leReqRespCbMutex);
880 g_leServerDataReceivedCallback = callback;
881 ca_mutex_unlock(g_leReqRespCbMutex);
883 OIC_LOG(DEBUG, TAG, "OUT");
886 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
888 g_serverErrorCallback = callback;