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_leServerThreadPoolMutex);
142 if (NULL == g_leServerThreadPool)
144 OIC_LOG(ERROR, TAG, "g_leServerThreadPool is NULL");
145 ca_mutex_unlock(g_leServerThreadPoolMutex);
146 return CA_STATUS_FAILED;
149 CAResult_t ret = ca_thread_pool_add_task(g_leServerThreadPool, CAStartLEGattServerThread,
151 if (CA_STATUS_OK != ret)
153 OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
154 ca_mutex_unlock(g_leServerThreadPoolMutex);
155 return CA_STATUS_FAILED;
158 ca_mutex_unlock(g_leServerThreadPoolMutex);
159 OIC_LOG(DEBUG, TAG, "OUT");
163 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
166 OIC_LOG(DEBUG, TAG, "IN");
169 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
171 OIC_LOG(DEBUG, TAG, "OUT");
174 CAResult_t CALEStartAdvertise(const char *serviceUUID)
176 OIC_LOG(DEBUG, TAG, "IN");
178 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
179 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
181 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
182 return CA_STATUS_FAILED;
185 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
186 BT_ADAPTER_LE_PACKET_ADVERTISING,
188 if (BT_ERROR_NONE != res)
190 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
191 CALEGetErrorMsg(res));
192 return CA_STATUS_FAILED;
195 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
196 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
197 if (BT_ERROR_NONE != res)
199 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
200 CALEGetErrorMsg(res));
201 return CA_STATUS_FAILED;
204 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
205 if (BT_ERROR_NONE != res)
207 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
208 CALEGetErrorMsg(res));
209 return CA_STATUS_FAILED;
212 OIC_LOG(DEBUG, TAG, "OUT");
216 CAResult_t CALEStopAdvertise()
218 OIC_LOG(DEBUG, TAG, "IN");
219 if (NULL != g_hAdvertiser)
221 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
224 OIC_LOG_V(ERROR, TAG,
225 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
228 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
231 OIC_LOG_V(ERROR, TAG,
232 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
234 g_hAdvertiser = NULL;
238 OIC_LOG(ERROR, TAG, "Advertising is not running");
239 return CA_STATUS_FAILED;
242 OIC_LOG(DEBUG, TAG, "OUT");
246 void CAStartLEGattServerThread(void *data)
248 OIC_LOG(DEBUG, TAG, "IN");
249 ca_mutex_lock(g_leServerStateMutex);
250 if (true == g_isLEGattServerStarted)
252 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
253 ca_mutex_unlock(g_leServerStateMutex);
254 CATerminateLEGattServer();
258 CAResult_t ret = CAInitLEGattServer();
259 if (CA_STATUS_OK != ret)
261 OIC_LOG_V(ERROR, TAG, "CAInitLEGattService failed[%d]", ret);
262 ca_mutex_unlock(g_leServerStateMutex);
263 CATerminateLEGattServer();
267 char *serviceUUID = CA_GATT_SERVICE_UUID;
269 ret = CAAddNewLEServiceInGattServer(serviceUUID);
270 if (CA_STATUS_OK != ret)
272 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
273 ca_mutex_unlock(g_leServerStateMutex);
274 CATerminateLEGattServer();
278 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
279 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
281 // For Read Characteristics.
282 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
283 CA_LE_INITIAL_BUF_SIZE, true);
284 if (CA_STATUS_OK != ret)
286 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
287 ca_mutex_unlock(g_leServerStateMutex);
288 CATerminateLEGattServer();
292 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
293 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
296 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
297 CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
298 if (CA_STATUS_OK != ret )
300 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
301 ca_mutex_unlock(g_leServerStateMutex);
302 CATerminateLEGattServer();
306 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
307 if (CA_STATUS_OK != ret )
309 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
310 ca_mutex_unlock(g_leServerStateMutex);
311 CATerminateLEGattServer();
315 ret = CALEStartAdvertise(serviceUUID);
316 if (CA_STATUS_OK != ret)
318 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
319 ca_mutex_unlock(g_leServerStateMutex);
320 CATerminateLEGattServer();
324 g_isLEGattServerStarted = true;
326 ca_mutex_unlock(g_leServerStateMutex);
328 OIC_LOG(DEBUG, TAG, "LE Server initialization complete.");
330 GMainContext *thread_context = NULL;
332 thread_context = g_main_context_new();
334 g_eventLoop = g_main_loop_new(thread_context, FALSE);
336 g_main_context_push_thread_default(thread_context);
338 g_main_loop_run(g_eventLoop);
340 OIC_LOG(DEBUG, TAG, "OUT");
343 CAResult_t CAStopLEGattServer()
345 OIC_LOG(DEBUG, TAG, "IN");
347 ca_mutex_lock(g_leServerStateMutex);
349 if (false == g_isLEGattServerStarted)
351 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
352 ca_mutex_unlock(g_leServerStateMutex);
356 g_isLEGattServerStarted = false;
358 CAResult_t res = CALEStopAdvertise();
360 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
363 res = CADeInitLEGattServer();
364 if (CA_STATUS_OK != res)
366 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
369 GMainContext *context_event_loop = NULL;
370 // Required for waking up the thread which is running in gmain loop
371 if (NULL != g_eventLoop)
373 context_event_loop = g_main_loop_get_context(g_eventLoop);
375 if (context_event_loop)
377 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
378 g_main_context_wakeup(context_event_loop);
380 // Kill g main loops and kill threads
381 g_main_loop_quit(g_eventLoop);
386 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
389 ca_mutex_unlock(g_leServerStateMutex);
391 OIC_LOG(DEBUG, TAG, "OUT");
395 CAResult_t CAInitializeLEGattServer()
397 OIC_LOG(DEBUG, TAG, "IN");
399 CAResult_t ret = CAInitGattServerMutexVariables();
400 if (CA_STATUS_OK != ret )
402 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
403 CATerminateGattServerMutexVariables();
404 return CA_SERVER_NOT_STARTED;
406 OIC_LOG(DEBUG, TAG, "OUT");
410 void CATerminateLEGattServer()
412 OIC_LOG(DEBUG, TAG, "IN");
414 // Service and characteristics path will be freed by the platform.
415 ca_mutex_lock(g_leServiceMutex);
416 g_gattSvcPath = NULL;
417 ca_mutex_unlock(g_leServiceMutex);
419 ca_mutex_lock(g_leCharacteristicMutex);
420 g_gattReadCharPath = NULL;
421 g_gattWriteCharPath = NULL;
422 ca_mutex_unlock(g_leCharacteristicMutex);
424 ca_mutex_lock(g_leServerThreadPoolMutex);
425 g_leServerThreadPool = NULL;
426 ca_mutex_unlock(g_leServerThreadPoolMutex);
428 // Terminating all mutex variables.
429 CATerminateGattServerMutexVariables();
430 OIC_LOG(DEBUG, TAG, "OUT");
433 CAResult_t CAInitGattServerMutexVariables()
435 OIC_LOG(DEBUG, TAG, "IN");
436 if (NULL == g_leServerStateMutex)
438 g_leServerStateMutex = ca_mutex_new();
439 if (NULL == g_leServerStateMutex)
441 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
442 return CA_STATUS_FAILED;
446 if (NULL == g_leServiceMutex)
448 g_leServiceMutex = ca_mutex_new();
449 if (NULL == g_leServiceMutex)
451 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
452 return CA_STATUS_FAILED;
456 if (NULL == g_leCharacteristicMutex)
458 g_leCharacteristicMutex = ca_mutex_new();
459 if (NULL == g_leCharacteristicMutex)
461 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
462 return CA_STATUS_FAILED;
466 if (NULL == g_leReqRespCbMutex)
468 g_leReqRespCbMutex = ca_mutex_new();
469 if (NULL == g_leReqRespCbMutex)
471 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
472 return CA_STATUS_FAILED;
476 if (NULL == g_leServerThreadPoolMutex)
478 g_leServerThreadPoolMutex = ca_mutex_new();
479 if (NULL == g_leServerThreadPoolMutex)
481 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
482 return CA_STATUS_FAILED;
486 OIC_LOG(DEBUG, TAG, "OUT");
490 void CATerminateGattServerMutexVariables()
492 OIC_LOG(DEBUG, TAG, "IN");
493 ca_mutex_free(g_leServerStateMutex);
494 g_leServerStateMutex = NULL;
496 ca_mutex_free(g_leServiceMutex);
497 g_leServiceMutex = NULL;
499 ca_mutex_free(g_leCharacteristicMutex);
500 g_leCharacteristicMutex = NULL;
502 ca_mutex_free(g_leReqRespCbMutex);
503 g_leReqRespCbMutex = NULL;
505 OIC_LOG(DEBUG, TAG, "OUT");
508 CAResult_t CAInitLEGattServer()
510 OIC_LOG(DEBUG, TAG, "IN");
512 int ret = bt_gatt_server_initialize();
515 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
516 CALEGetErrorMsg(ret));
517 return CA_STATUS_FAILED;
520 bt_gatt_server_h server;
522 ret = bt_gatt_server_create(&server);
525 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
526 CALEGetErrorMsg(ret));
527 return CA_STATUS_FAILED;
530 if (NULL != g_gattServer)
532 OICFree(g_gattServer);
535 g_gattServer = server;
537 OIC_LOG(DEBUG, TAG, "OUT");
541 CAResult_t CADeInitLEGattServer()
543 OIC_LOG(DEBUG, TAG, "IN");
545 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
548 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
549 CALEGetErrorMsg(ret));
550 return CA_STATUS_FAILED;
553 ret = bt_gatt_server_destroy(g_gattServer);
556 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
557 CALEGetErrorMsg(ret));
558 return CA_STATUS_FAILED;
561 ret = bt_gatt_server_deinitialize();
564 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
565 CALEGetErrorMsg(ret));
566 return CA_STATUS_FAILED;
569 OIC_LOG(DEBUG, TAG, "OUT");
573 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
575 OIC_LOG(DEBUG, TAG, "IN");
576 ca_mutex_lock(g_leServerThreadPoolMutex);
577 g_leServerThreadPool = handle;
578 ca_mutex_unlock(g_leServerThreadPoolMutex);
579 OIC_LOG(DEBUG, TAG, "OUT");
582 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
584 OIC_LOG(DEBUG, TAG, "IN");
586 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
588 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
590 bt_gatt_h service = NULL;
591 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
593 int ret = bt_gatt_service_create(serviceUUID, type, &service);
596 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
597 CALEGetErrorMsg(ret));
598 return CA_STATUS_FAILED;
603 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)service);
605 ca_mutex_lock(g_leServiceMutex);
607 if (NULL != g_gattSvcPath)
609 OICFree(g_gattSvcPath);
610 g_gattSvcPath = NULL;
612 g_gattSvcPath = service;
614 ca_mutex_unlock(g_leServiceMutex);
617 OIC_LOG(DEBUG, TAG, "OUT");
621 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
622 bt_gatt_h charPath, int offset, char *charValue,
623 int charValueLen, void *userData)
625 OIC_LOG(DEBUG, TAG, "IN");
627 if (NULL == charValue || NULL == remoteAddress)
629 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
633 OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
634 charValue, charValueLen);
636 uint8_t *data = OICMalloc(charValueLen);
639 OIC_LOG(ERROR, TAG, "Malloc failed!");
643 memcpy(data, charValue, charValueLen);
645 ca_mutex_lock(g_leReqRespCbMutex);
646 if (NULL == g_leServerDataReceivedCallback)
648 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
649 ca_mutex_unlock(g_leReqRespCbMutex);
654 OIC_LOG(DEBUG, TAG, "Sending data up !");
655 uint32_t sentLength = 0;
656 g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
658 ca_mutex_unlock(g_leReqRespCbMutex);
660 OIC_LOG(DEBUG, TAG, "OUT");
663 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
665 OIC_LOG(DEBUG, TAG, "IN");
667 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
669 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
671 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
674 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
675 CALEGetErrorMsg(ret));
676 return CA_STATUS_FAILED;
679 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
680 CALEGattRemoteCharacteristicWriteCb, NULL);
684 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
685 CALEGetErrorMsg(ret));
686 return CA_STATUS_FAILED;
689 OIC_LOG(DEBUG, TAG, "OUT");
693 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
694 const char *charValue, int charValueLen, bool read)
697 OIC_LOG(DEBUG, TAG, "IN");
699 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
703 properties = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ;
707 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
712 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
713 charValueLen, &charPath);
715 if (0 != ret || NULL == charPath)
717 OIC_LOG_V(ERROR, TAG,
718 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
719 return CA_STATUS_FAILED;
722 OIC_LOG_V(DEBUG, TAG,
723 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
727 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
730 OIC_LOG_V(ERROR, TAG,
731 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
732 CALEGetErrorMsg(ret));
733 return CA_STATUS_FAILED;
737 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
740 OIC_LOG_V(ERROR, TAG,
741 "bt_gatt_service_add_characteristic failed with ret[%s]",
742 CALEGetErrorMsg(ret));
743 return CA_STATUS_FAILED;
746 ca_mutex_lock(g_leCharacteristicMutex);
750 char desc_value[2] = {1, 0}; // Notification enabled.
751 bt_gatt_h descriptor = NULL;
752 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
753 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
754 desc_value, sizeof(desc_value),
758 OIC_LOG_V(ERROR, TAG,
759 "bt_gatt_descriptor_create failed with ret[%s]",
760 CALEGetErrorMsg(ret));
761 return CA_STATUS_FAILED;
764 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
767 OIC_LOG_V(ERROR, TAG,
768 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
769 CALEGetErrorMsg(ret));
770 return CA_STATUS_FAILED;
773 if (NULL != g_gattReadCharPath)
775 OICFree(g_gattReadCharPath);
776 g_gattReadCharPath = NULL;
778 g_gattReadCharPath = charPath;
783 if (NULL != g_gattWriteCharPath)
785 OICFree(g_gattWriteCharPath);
786 g_gattWriteCharPath = NULL;
788 g_gattWriteCharPath = charPath;
791 ca_mutex_unlock(g_leCharacteristicMutex);
793 OIC_LOG(DEBUG, TAG, "OUT");
797 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
798 uint32_t charValueLen)
800 OIC_LOG(DEBUG, TAG, "IN");
802 VERIFY_NON_NULL(charValue, TAG, "charValue");
803 VERIFY_NON_NULL(address, TAG, "address");
805 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
807 ca_mutex_lock(g_leCharacteristicMutex);
809 if (NULL == g_gattReadCharPath)
811 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
812 ca_mutex_unlock(g_leCharacteristicMutex);
813 return CA_STATUS_FAILED;
816 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
819 OIC_LOG_V(ERROR, TAG,
820 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
821 ca_mutex_unlock(g_leCharacteristicMutex);
822 return CA_STATUS_FAILED;
825 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
829 OIC_LOG_V(ERROR, TAG,
830 "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
831 ca_mutex_unlock(g_leCharacteristicMutex);
832 return CA_STATUS_FAILED;
835 ca_mutex_unlock(g_leCharacteristicMutex);
837 OIC_LOG(DEBUG, TAG, "OUT");
841 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
843 OIC_LOG(DEBUG, TAG, "IN");
845 VERIFY_NON_NULL(charValue, TAG, "charValue");
847 ca_mutex_lock(g_leCharacteristicMutex);
849 if (NULL == g_gattReadCharPath)
851 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
852 ca_mutex_unlock(g_leCharacteristicMutex);
853 return CA_STATUS_FAILED;
856 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
859 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
860 ca_mutex_unlock(g_leCharacteristicMutex);
861 return CA_STATUS_FAILED;
864 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
868 OIC_LOG_V(ERROR, TAG,
869 "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
870 ca_mutex_unlock(g_leCharacteristicMutex);
871 return CA_STATUS_FAILED;
874 ca_mutex_unlock(g_leCharacteristicMutex);
876 OIC_LOG(DEBUG, TAG, "OUT");
880 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
882 OIC_LOG(DEBUG, TAG, "IN");
884 ca_mutex_lock(g_leReqRespCbMutex);
885 g_leServerDataReceivedCallback = callback;
886 ca_mutex_unlock(g_leReqRespCbMutex);
888 OIC_LOG(DEBUG, TAG, "OUT");
891 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
893 g_serverErrorCallback = callback;