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 "caleserver.h"
23 #include "cacommonutil.h"
25 #include "caqueueingthread.h"
26 #include "cagattservice.h"
27 #include "oic_malloc.h"
31 * Logging tag for module name
33 #define TAG "OIC_CA_LE_SERVER"
36 * Initial buffer size for Gatt Server.
38 #define CA_LE_INITIAL_BUF_SIZE 512
41 * The handle of the OIC server.
43 static bt_gatt_server_h g_gattServer = NULL;
46 * The handle of the OIC service.
48 static bt_gatt_h g_gattSvcPath = NULL;
51 * The handle of the OIC read characteristics.
53 static bt_gatt_h g_gattReadCharPath = NULL;
56 * The handle of the OIC write characteristics.
58 static bt_gatt_h g_gattWriteCharPath = NULL;
61 * The handle to control Bluetooth LE advertising.
63 static bt_advertiser_h g_hAdvertiser = NULL;
66 * Callback register with LE adapter. This callback is called on reception of any
67 * data from the remote device.
69 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
72 * Callback to notify any error in LE adapter.
74 static CABLEErrorHandleCallback g_serverErrorCallback;
77 * To keep the state of GATT server if started or not.
79 static bool g_isLEGattServerStarted = false;
82 * Mutex to synchronize the calls to start and stop server.
84 static ca_mutex g_leServerStateMutex = NULL;
87 * Mutex to synchronize writing operations on the characteristics.
89 static ca_mutex g_leCharacteristicMutex = NULL;
92 * Mutex to synchronize to creation of OIC service.
94 static ca_mutex g_leServiceMutex = NULL;
97 * Mutex to synchronize access to the requestResponse callback to be called
98 * when the data needs to be sent from GATTClient.
100 static ca_mutex g_leReqRespCbMutex = NULL;
103 * Mutex to synchronize the task to be pushed to thread pool.
105 static ca_mutex g_leServerThreadPoolMutex = NULL;
108 * Reference to threadpool.
110 static ca_thread_pool_t g_leServerThreadPool = NULL;
113 * GmainLoop to manage the threads to receive the callback from the platfrom.
115 static GMainLoop *g_eventLoop = NULL;
117 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
119 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
123 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
127 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
131 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
132 bt_gatt_h characteristic, bool completed, void *user_data)
134 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
137 CAResult_t CAStartLEGattServer()
139 OIC_LOG(DEBUG, TAG, "IN");
141 ca_mutex_lock(g_leServerStateMutex);
142 if (true == g_isLEGattServerStarted)
144 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
145 ca_mutex_unlock(g_leServerStateMutex);
149 CAResult_t ret = CAInitLEGattServer();
150 if (CA_STATUS_OK != ret)
152 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
153 ca_mutex_unlock(g_leServerStateMutex);
154 CATerminateLEGattServer();
155 return CA_STATUS_FAILED;
158 char *serviceUUID = CA_GATT_SERVICE_UUID;
160 ret = CAAddNewLEServiceInGattServer(serviceUUID);
161 if (CA_STATUS_OK != ret)
163 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
164 ca_mutex_unlock(g_leServerStateMutex);
165 CATerminateLEGattServer();
166 return CA_STATUS_FAILED;
169 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
170 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
172 // For Read Characteristics.
173 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
174 CA_LE_INITIAL_BUF_SIZE, true);
175 if (CA_STATUS_OK != ret)
177 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
178 ca_mutex_unlock(g_leServerStateMutex);
179 CATerminateLEGattServer();
180 return CA_STATUS_FAILED;
183 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
184 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
187 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
188 CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
189 if (CA_STATUS_OK != ret )
191 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
192 ca_mutex_unlock(g_leServerStateMutex);
193 CATerminateLEGattServer();
194 return CA_STATUS_FAILED;
197 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
198 if (CA_STATUS_OK != ret )
200 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
201 ca_mutex_unlock(g_leServerStateMutex);
202 CATerminateLEGattServer();
203 return CA_STATUS_FAILED;
206 ret = CALEStartAdvertise(serviceUUID);
207 if (CA_STATUS_OK != ret)
209 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
210 ca_mutex_unlock(g_leServerStateMutex);
211 CATerminateLEGattServer();
212 return CA_STATUS_FAILED;
215 g_isLEGattServerStarted = true;
217 ca_mutex_unlock(g_leServerStateMutex);
219 OIC_LOG(DEBUG, TAG, "OUT");
223 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
226 OIC_LOG(DEBUG, TAG, "IN");
229 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
231 OIC_LOG(DEBUG, TAG, "OUT");
234 CAResult_t CALEStartAdvertise(const char *serviceUUID)
236 OIC_LOG(DEBUG, TAG, "IN");
238 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
239 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
241 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
242 return CA_STATUS_FAILED;
245 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
246 BT_ADAPTER_LE_PACKET_ADVERTISING,
248 if (BT_ERROR_NONE != res)
250 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
251 CALEGetErrorMsg(res));
252 return CA_STATUS_FAILED;
255 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
256 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
257 if (BT_ERROR_NONE != res)
259 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
260 CALEGetErrorMsg(res));
261 return CA_STATUS_FAILED;
264 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
265 if (BT_ERROR_NONE != res)
267 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
268 CALEGetErrorMsg(res));
269 return CA_STATUS_FAILED;
272 OIC_LOG(DEBUG, TAG, "OUT");
276 CAResult_t CALEStopAdvertise()
278 OIC_LOG(DEBUG, TAG, "IN");
279 if (NULL != g_hAdvertiser)
281 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
284 OIC_LOG_V(ERROR, TAG,
285 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
288 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
291 OIC_LOG_V(ERROR, TAG,
292 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
294 g_hAdvertiser = NULL;
298 OIC_LOG(ERROR, TAG, "Advertising is not running");
299 return CA_STATUS_FAILED;
302 OIC_LOG(DEBUG, TAG, "OUT");
306 CAResult_t CAStopLEGattServer()
308 OIC_LOG(DEBUG, TAG, "IN");
310 ca_mutex_lock(g_leServerStateMutex);
312 if (false == g_isLEGattServerStarted)
314 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
315 ca_mutex_unlock(g_leServerStateMutex);
319 g_isLEGattServerStarted = false;
321 CAResult_t res = CALEStopAdvertise();
323 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
326 res = CADeInitLEGattServer();
327 if (CA_STATUS_OK != res)
329 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
332 GMainContext *context_event_loop = NULL;
333 // Required for waking up the thread which is running in gmain loop
334 if (NULL != g_eventLoop)
336 context_event_loop = g_main_loop_get_context(g_eventLoop);
338 if (context_event_loop)
340 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
341 g_main_context_wakeup(context_event_loop);
343 // Kill g main loops and kill threads
344 g_main_loop_quit(g_eventLoop);
349 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
352 ca_mutex_unlock(g_leServerStateMutex);
354 OIC_LOG(DEBUG, TAG, "OUT");
358 CAResult_t CAInitializeLEGattServer()
360 OIC_LOG(DEBUG, TAG, "IN");
362 CAResult_t ret = CAInitGattServerMutexVariables();
363 if (CA_STATUS_OK != ret )
365 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
366 CATerminateGattServerMutexVariables();
367 return CA_SERVER_NOT_STARTED;
369 OIC_LOG(DEBUG, TAG, "OUT");
373 void CATerminateLEGattServer()
375 OIC_LOG(DEBUG, TAG, "IN");
377 // Service and characteristics path will be freed by the platform.
378 ca_mutex_lock(g_leServiceMutex);
379 g_gattSvcPath = NULL;
380 ca_mutex_unlock(g_leServiceMutex);
382 ca_mutex_lock(g_leCharacteristicMutex);
383 g_gattReadCharPath = NULL;
384 g_gattWriteCharPath = NULL;
385 ca_mutex_unlock(g_leCharacteristicMutex);
387 ca_mutex_lock(g_leServerThreadPoolMutex);
388 g_leServerThreadPool = NULL;
389 ca_mutex_unlock(g_leServerThreadPoolMutex);
391 // Terminating all mutex variables.
392 CATerminateGattServerMutexVariables();
393 OIC_LOG(DEBUG, TAG, "OUT");
396 CAResult_t CAInitGattServerMutexVariables()
398 OIC_LOG(DEBUG, TAG, "IN");
399 if (NULL == g_leServerStateMutex)
401 g_leServerStateMutex = ca_mutex_new();
402 if (NULL == g_leServerStateMutex)
404 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
405 return CA_STATUS_FAILED;
409 if (NULL == g_leServiceMutex)
411 g_leServiceMutex = ca_mutex_new();
412 if (NULL == g_leServiceMutex)
414 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
415 return CA_STATUS_FAILED;
419 if (NULL == g_leCharacteristicMutex)
421 g_leCharacteristicMutex = ca_mutex_new();
422 if (NULL == g_leCharacteristicMutex)
424 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
425 return CA_STATUS_FAILED;
429 if (NULL == g_leReqRespCbMutex)
431 g_leReqRespCbMutex = ca_mutex_new();
432 if (NULL == g_leReqRespCbMutex)
434 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
435 return CA_STATUS_FAILED;
439 if (NULL == g_leServerThreadPoolMutex)
441 g_leServerThreadPoolMutex = ca_mutex_new();
442 if (NULL == g_leServerThreadPoolMutex)
444 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
445 return CA_STATUS_FAILED;
449 OIC_LOG(DEBUG, TAG, "OUT");
453 void CATerminateGattServerMutexVariables()
455 OIC_LOG(DEBUG, TAG, "IN");
456 ca_mutex_free(g_leServerStateMutex);
457 g_leServerStateMutex = NULL;
459 ca_mutex_free(g_leServiceMutex);
460 g_leServiceMutex = NULL;
462 ca_mutex_free(g_leCharacteristicMutex);
463 g_leCharacteristicMutex = NULL;
465 ca_mutex_free(g_leReqRespCbMutex);
466 g_leReqRespCbMutex = NULL;
468 OIC_LOG(DEBUG, TAG, "OUT");
471 CAResult_t CAInitLEGattServer()
473 OIC_LOG(DEBUG, TAG, "IN");
475 int ret = bt_gatt_server_initialize();
478 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
479 CALEGetErrorMsg(ret));
480 return CA_STATUS_FAILED;
483 bt_gatt_server_h server;
485 ret = bt_gatt_server_create(&server);
488 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
489 CALEGetErrorMsg(ret));
490 return CA_STATUS_FAILED;
493 if (NULL != g_gattServer)
495 OICFree(g_gattServer);
498 g_gattServer = server;
500 OIC_LOG(DEBUG, TAG, "OUT");
504 CAResult_t CADeInitLEGattServer()
506 OIC_LOG(DEBUG, TAG, "IN");
508 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
511 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
512 CALEGetErrorMsg(ret));
513 return CA_STATUS_FAILED;
516 ret = bt_gatt_server_destroy(g_gattServer);
519 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
520 CALEGetErrorMsg(ret));
521 return CA_STATUS_FAILED;
524 ret = bt_gatt_server_deinitialize();
527 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
528 CALEGetErrorMsg(ret));
529 return CA_STATUS_FAILED;
532 OIC_LOG(DEBUG, TAG, "OUT");
536 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
538 OIC_LOG(DEBUG, TAG, "IN");
539 ca_mutex_lock(g_leServerThreadPoolMutex);
540 g_leServerThreadPool = handle;
541 ca_mutex_unlock(g_leServerThreadPoolMutex);
542 OIC_LOG(DEBUG, TAG, "OUT");
545 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
547 OIC_LOG(DEBUG, TAG, "IN");
549 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
551 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
553 bt_gatt_h service = NULL;
554 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
556 int ret = bt_gatt_service_create(serviceUUID, type, &service);
559 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
560 CALEGetErrorMsg(ret));
561 return CA_STATUS_FAILED;
566 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)service);
568 ca_mutex_lock(g_leServiceMutex);
570 if (NULL != g_gattSvcPath)
572 OICFree(g_gattSvcPath);
573 g_gattSvcPath = NULL;
575 g_gattSvcPath = service;
577 ca_mutex_unlock(g_leServiceMutex);
580 OIC_LOG(DEBUG, TAG, "OUT");
584 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
585 bt_gatt_h charPath, int offset, char *charValue,
586 int charValueLen, void *userData)
588 OIC_LOG(DEBUG, TAG, "IN");
590 if (NULL == charValue || NULL == remoteAddress)
592 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
596 OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
597 charValue, charValueLen);
599 uint8_t *data = OICMalloc(charValueLen);
602 OIC_LOG(ERROR, TAG, "Malloc failed!");
606 memcpy(data, charValue, charValueLen);
608 ca_mutex_lock(g_leReqRespCbMutex);
609 if (NULL == g_leServerDataReceivedCallback)
611 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
612 ca_mutex_unlock(g_leReqRespCbMutex);
617 OIC_LOG(DEBUG, TAG, "Sending data up !");
618 uint32_t sentLength = 0;
619 g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
621 ca_mutex_unlock(g_leReqRespCbMutex);
623 OIC_LOG(DEBUG, TAG, "OUT");
626 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
628 OIC_LOG(DEBUG, TAG, "IN");
630 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
632 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
634 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
637 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
638 CALEGetErrorMsg(ret));
639 return CA_STATUS_FAILED;
642 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
643 CALEGattRemoteCharacteristicWriteCb, NULL);
647 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
648 CALEGetErrorMsg(ret));
649 return CA_STATUS_FAILED;
652 OIC_LOG(DEBUG, TAG, "OUT");
656 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
657 const char *charValue, int charValueLen, bool read)
660 OIC_LOG(DEBUG, TAG, "IN");
662 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
666 properties = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ;
670 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
675 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
676 charValueLen, &charPath);
678 if (0 != ret || NULL == charPath)
680 OIC_LOG_V(ERROR, TAG,
681 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
682 return CA_STATUS_FAILED;
685 OIC_LOG_V(DEBUG, TAG,
686 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
690 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
693 OIC_LOG_V(ERROR, TAG,
694 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
695 CALEGetErrorMsg(ret));
696 return CA_STATUS_FAILED;
700 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
703 OIC_LOG_V(ERROR, TAG,
704 "bt_gatt_service_add_characteristic failed with ret[%s]",
705 CALEGetErrorMsg(ret));
706 return CA_STATUS_FAILED;
709 ca_mutex_lock(g_leCharacteristicMutex);
713 char desc_value[2] = {1, 0}; // Notification enabled.
714 bt_gatt_h descriptor = NULL;
715 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
716 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
717 desc_value, sizeof(desc_value),
721 OIC_LOG_V(ERROR, TAG,
722 "bt_gatt_descriptor_create failed with ret[%s]",
723 CALEGetErrorMsg(ret));
724 return CA_STATUS_FAILED;
727 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
730 OIC_LOG_V(ERROR, TAG,
731 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
732 CALEGetErrorMsg(ret));
733 return CA_STATUS_FAILED;
736 if (NULL != g_gattReadCharPath)
738 OICFree(g_gattReadCharPath);
739 g_gattReadCharPath = NULL;
741 g_gattReadCharPath = charPath;
746 if (NULL != g_gattWriteCharPath)
748 OICFree(g_gattWriteCharPath);
749 g_gattWriteCharPath = NULL;
751 g_gattWriteCharPath = charPath;
754 ca_mutex_unlock(g_leCharacteristicMutex);
756 OIC_LOG(DEBUG, TAG, "OUT");
760 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
761 uint32_t charValueLen)
763 OIC_LOG(DEBUG, TAG, "IN");
765 VERIFY_NON_NULL(charValue, TAG, "charValue");
766 VERIFY_NON_NULL(address, TAG, "address");
768 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
770 ca_mutex_lock(g_leCharacteristicMutex);
772 if (NULL == g_gattReadCharPath)
774 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
775 ca_mutex_unlock(g_leCharacteristicMutex);
776 return CA_STATUS_FAILED;
779 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
782 OIC_LOG_V(ERROR, TAG,
783 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
784 ca_mutex_unlock(g_leCharacteristicMutex);
785 return CA_STATUS_FAILED;
788 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
792 OIC_LOG_V(ERROR, TAG,
793 "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
794 ca_mutex_unlock(g_leCharacteristicMutex);
795 return CA_STATUS_FAILED;
798 ca_mutex_unlock(g_leCharacteristicMutex);
800 OIC_LOG(DEBUG, TAG, "OUT");
804 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
806 OIC_LOG(DEBUG, TAG, "IN");
808 VERIFY_NON_NULL(charValue, TAG, "charValue");
810 ca_mutex_lock(g_leCharacteristicMutex);
812 if (NULL == g_gattReadCharPath)
814 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
815 ca_mutex_unlock(g_leCharacteristicMutex);
816 return CA_STATUS_FAILED;
819 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
822 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
823 ca_mutex_unlock(g_leCharacteristicMutex);
824 return CA_STATUS_FAILED;
827 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
831 OIC_LOG_V(ERROR, TAG,
832 "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
833 ca_mutex_unlock(g_leCharacteristicMutex);
834 return CA_STATUS_FAILED;
837 ca_mutex_unlock(g_leCharacteristicMutex);
839 OIC_LOG(DEBUG, TAG, "OUT");
843 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
845 OIC_LOG(DEBUG, TAG, "IN");
847 ca_mutex_lock(g_leReqRespCbMutex);
848 g_leServerDataReceivedCallback = callback;
849 ca_mutex_unlock(g_leReqRespCbMutex);
851 OIC_LOG(DEBUG, TAG, "OUT");
854 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
856 g_serverErrorCallback = callback;