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 static CALEConnectionStateChangedCallback g_connStateCb = NULL;
119 void CASetLEConnectionStateChangedCallback(CALEConnectionStateChangedCallback connStateCb)
121 g_connStateCb = connStateCb;
124 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
126 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
130 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
133 g_connStateCb(CA_ADAPTER_GATT_BTLE, remoteAddress, true);
138 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
141 g_connStateCb(CA_ADAPTER_GATT_BTLE, remoteAddress, false);
146 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
147 bt_gatt_h characteristic, bool completed, void *user_data)
149 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
152 CAResult_t CAStartLEGattServer()
154 OIC_LOG(DEBUG, TAG, "IN");
156 ca_mutex_lock(g_leServerThreadPoolMutex);
157 if (NULL == g_leServerThreadPool)
159 OIC_LOG(ERROR, TAG, "g_leServerThreadPool is NULL");
160 ca_mutex_unlock(g_leServerThreadPoolMutex);
161 return CA_STATUS_FAILED;
164 CAResult_t ret = ca_thread_pool_add_task(g_leServerThreadPool, CAStartLEGattServerThread,
166 if (CA_STATUS_OK != ret)
168 OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
169 ca_mutex_unlock(g_leServerThreadPoolMutex);
170 return CA_STATUS_FAILED;
173 ca_mutex_unlock(g_leServerThreadPoolMutex);
174 OIC_LOG(DEBUG, TAG, "OUT");
178 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
181 OIC_LOG(DEBUG, TAG, "IN");
184 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
186 OIC_LOG(DEBUG, TAG, "OUT");
189 CAResult_t CALEStartAdvertise(const char *serviceUUID)
191 OIC_LOG(DEBUG, TAG, "IN");
193 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
194 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
196 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
197 return CA_STATUS_FAILED;
200 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
201 BT_ADAPTER_LE_PACKET_ADVERTISING,
203 if (BT_ERROR_NONE != res)
205 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
206 CALEGetErrorMsg(res));
207 return CA_STATUS_FAILED;
210 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
211 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
212 if (BT_ERROR_NONE != res)
214 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
215 CALEGetErrorMsg(res));
216 return CA_STATUS_FAILED;
219 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
220 if (BT_ERROR_NONE != res)
222 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
223 CALEGetErrorMsg(res));
224 return CA_STATUS_FAILED;
227 OIC_LOG(DEBUG, TAG, "OUT");
231 CAResult_t CALEStopAdvertise()
233 OIC_LOG(DEBUG, TAG, "IN");
234 if (NULL != g_hAdvertiser)
236 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
239 OIC_LOG_V(ERROR, TAG,
240 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
243 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
246 OIC_LOG_V(ERROR, TAG,
247 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
249 g_hAdvertiser = NULL;
253 OIC_LOG(ERROR, TAG, "Advertising is not running");
254 return CA_STATUS_FAILED;
257 OIC_LOG(DEBUG, TAG, "OUT");
261 void CAStartLEGattServerThread(void *data)
263 OIC_LOG(DEBUG, TAG, "IN");
264 ca_mutex_lock(g_leServerStateMutex);
265 if (true == g_isLEGattServerStarted)
267 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
268 ca_mutex_unlock(g_leServerStateMutex);
269 CATerminateLEGattServer();
273 CAResult_t ret = CAInitLEGattServer();
274 if (CA_STATUS_OK != ret)
276 OIC_LOG_V(ERROR, TAG, "CAInitLEGattService failed[%d]", ret);
277 ca_mutex_unlock(g_leServerStateMutex);
278 CATerminateLEGattServer();
282 char *serviceUUID = CA_GATT_SERVICE_UUID;
284 ret = CAAddNewLEServiceInGattServer(serviceUUID);
285 if (CA_STATUS_OK != ret)
287 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
288 ca_mutex_unlock(g_leServerStateMutex);
289 CATerminateLEGattServer();
293 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
294 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
296 // For Read Characteristics.
297 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
298 CA_LE_INITIAL_BUF_SIZE, true);
299 if (CA_STATUS_OK != ret)
301 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
302 ca_mutex_unlock(g_leServerStateMutex);
303 CATerminateLEGattServer();
307 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
308 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
311 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
312 CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
313 if (CA_STATUS_OK != ret )
315 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
316 ca_mutex_unlock(g_leServerStateMutex);
317 CATerminateLEGattServer();
321 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
322 if (CA_STATUS_OK != ret )
324 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
325 ca_mutex_unlock(g_leServerStateMutex);
326 CATerminateLEGattServer();
330 ret = CALEStartAdvertise(serviceUUID);
331 if (CA_STATUS_OK != ret)
333 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
334 ca_mutex_unlock(g_leServerStateMutex);
335 CATerminateLEGattServer();
339 g_isLEGattServerStarted = true;
341 ca_mutex_unlock(g_leServerStateMutex);
343 OIC_LOG(DEBUG, TAG, "LE Server initialization complete.");
345 GMainContext *thread_context = NULL;
347 thread_context = g_main_context_new();
349 g_eventLoop = g_main_loop_new(thread_context, FALSE);
351 g_main_context_push_thread_default(thread_context);
353 g_main_loop_run(g_eventLoop);
355 OIC_LOG(DEBUG, TAG, "OUT");
358 CAResult_t CAStopLEGattServer()
360 OIC_LOG(DEBUG, TAG, "IN");
362 ca_mutex_lock(g_leServerStateMutex);
364 if (false == g_isLEGattServerStarted)
366 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
367 ca_mutex_unlock(g_leServerStateMutex);
371 g_isLEGattServerStarted = false;
373 CAResult_t res = CALEStopAdvertise();
375 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
378 res = CADeInitLEGattServer();
379 if (CA_STATUS_OK != res)
381 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
384 GMainContext *context_event_loop = NULL;
385 // Required for waking up the thread which is running in gmain loop
386 if (NULL != g_eventLoop)
388 context_event_loop = g_main_loop_get_context(g_eventLoop);
390 if (context_event_loop)
392 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
393 g_main_context_wakeup(context_event_loop);
395 // Kill g main loops and kill threads
396 g_main_loop_quit(g_eventLoop);
401 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
404 ca_mutex_unlock(g_leServerStateMutex);
406 OIC_LOG(DEBUG, TAG, "OUT");
410 CAResult_t CAInitializeLEGattServer()
412 OIC_LOG(DEBUG, TAG, "IN");
414 CAResult_t ret = CAInitGattServerMutexVariables();
415 if (CA_STATUS_OK != ret )
417 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
418 CATerminateGattServerMutexVariables();
419 return CA_SERVER_NOT_STARTED;
421 OIC_LOG(DEBUG, TAG, "OUT");
425 void CATerminateLEGattServer()
427 OIC_LOG(DEBUG, TAG, "IN");
429 // Service and characteristics path will be freed by the platform.
430 ca_mutex_lock(g_leServiceMutex);
431 g_gattSvcPath = NULL;
432 ca_mutex_unlock(g_leServiceMutex);
434 ca_mutex_lock(g_leCharacteristicMutex);
435 g_gattReadCharPath = NULL;
436 g_gattWriteCharPath = NULL;
437 ca_mutex_unlock(g_leCharacteristicMutex);
439 ca_mutex_lock(g_leServerThreadPoolMutex);
440 g_leServerThreadPool = NULL;
441 ca_mutex_unlock(g_leServerThreadPoolMutex);
443 // Terminating all mutex variables.
444 CATerminateGattServerMutexVariables();
445 OIC_LOG(DEBUG, TAG, "OUT");
448 CAResult_t CAInitGattServerMutexVariables()
450 OIC_LOG(DEBUG, TAG, "IN");
451 if (NULL == g_leServerStateMutex)
453 g_leServerStateMutex = ca_mutex_new();
454 if (NULL == g_leServerStateMutex)
456 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
457 return CA_STATUS_FAILED;
461 if (NULL == g_leServiceMutex)
463 g_leServiceMutex = ca_mutex_new();
464 if (NULL == g_leServiceMutex)
466 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
467 return CA_STATUS_FAILED;
471 if (NULL == g_leCharacteristicMutex)
473 g_leCharacteristicMutex = ca_mutex_new();
474 if (NULL == g_leCharacteristicMutex)
476 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
477 return CA_STATUS_FAILED;
481 if (NULL == g_leReqRespCbMutex)
483 g_leReqRespCbMutex = ca_mutex_new();
484 if (NULL == g_leReqRespCbMutex)
486 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
487 return CA_STATUS_FAILED;
490 OIC_LOG(DEBUG, TAG, "OUT");
494 void CATerminateGattServerMutexVariables()
496 OIC_LOG(DEBUG, TAG, "IN");
497 ca_mutex_free(g_leServerStateMutex);
498 g_leServerStateMutex = NULL;
500 ca_mutex_free(g_leServiceMutex);
501 g_leServiceMutex = NULL;
503 ca_mutex_free(g_leCharacteristicMutex);
504 g_leCharacteristicMutex = NULL;
506 ca_mutex_free(g_leReqRespCbMutex);
507 g_leReqRespCbMutex = NULL;
509 OIC_LOG(DEBUG, TAG, "OUT");
512 CAResult_t CAInitLEGattServer()
514 OIC_LOG(DEBUG, TAG, "IN");
516 int ret = bt_gatt_server_initialize();
519 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
520 CALEGetErrorMsg(ret));
521 return CA_STATUS_FAILED;
524 bt_gatt_server_h server;
526 ret = bt_gatt_server_create(&server);
529 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
530 CALEGetErrorMsg(ret));
531 return CA_STATUS_FAILED;
534 if (NULL != g_gattServer)
536 OICFree(g_gattServer);
539 g_gattServer = server;
541 OIC_LOG(DEBUG, TAG, "OUT");
545 CAResult_t CADeInitLEGattServer()
547 OIC_LOG(DEBUG, TAG, "IN");
549 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
552 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
553 CALEGetErrorMsg(ret));
554 return CA_STATUS_FAILED;
557 ret = bt_gatt_server_destroy(g_gattServer);
560 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
561 CALEGetErrorMsg(ret));
562 return CA_STATUS_FAILED;
565 ret = bt_gatt_server_deinitialize();
568 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
569 CALEGetErrorMsg(ret));
570 return CA_STATUS_FAILED;
573 OIC_LOG(DEBUG, TAG, "OUT");
577 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
579 OIC_LOG(DEBUG, TAG, "IN");
580 ca_mutex_lock(g_leServerThreadPoolMutex);
581 g_leServerThreadPool = handle;
582 ca_mutex_unlock(g_leServerThreadPoolMutex);
583 OIC_LOG(DEBUG, TAG, "OUT");
586 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
588 OIC_LOG(DEBUG, TAG, "IN");
590 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
592 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
594 bt_gatt_h service = NULL;
595 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
597 int ret = bt_gatt_service_create(serviceUUID, type, &service);
600 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
601 CALEGetErrorMsg(ret));
602 return CA_STATUS_FAILED;
607 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)service);
609 ca_mutex_lock(g_leServiceMutex);
611 if (NULL != g_gattSvcPath)
613 OICFree(g_gattSvcPath);
614 g_gattSvcPath = NULL;
616 g_gattSvcPath = service;
618 ca_mutex_unlock(g_leServiceMutex);
621 OIC_LOG(DEBUG, TAG, "OUT");
625 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
626 bt_gatt_h charPath, int offset, char *charValue,
627 int charValueLen, void *userData)
629 OIC_LOG(DEBUG, TAG, "IN");
631 if (NULL == charValue || NULL == remoteAddress)
633 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
637 OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
638 charValue, charValueLen);
640 uint8_t *data = OICMalloc(charValueLen);
643 OIC_LOG(ERROR, TAG, "Malloc failed!");
647 memcpy(data, charValue, charValueLen);
649 ca_mutex_lock(g_leReqRespCbMutex);
650 if (NULL == g_leServerDataReceivedCallback)
652 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
653 ca_mutex_unlock(g_leReqRespCbMutex);
658 OIC_LOG(DEBUG, TAG, "Sending data up !");
659 uint32_t sentLength = 0;
660 g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
662 ca_mutex_unlock(g_leReqRespCbMutex);
664 OIC_LOG(DEBUG, TAG, "OUT");
667 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
669 OIC_LOG(DEBUG, TAG, "IN");
671 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
673 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
675 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
678 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
679 CALEGetErrorMsg(ret));
680 return CA_STATUS_FAILED;
683 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
684 CALEGattRemoteCharacteristicWriteCb, NULL);
688 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
689 CALEGetErrorMsg(ret));
690 return CA_STATUS_FAILED;
693 OIC_LOG(DEBUG, TAG, "OUT");
697 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
698 const char *charValue, int charValueLen, bool read)
701 OIC_LOG(DEBUG, TAG, "IN");
703 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
707 properties = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ;
711 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
716 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
717 charValueLen, &charPath);
719 if (0 != ret || NULL == charPath)
721 OIC_LOG_V(ERROR, TAG,
722 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
723 return CA_STATUS_FAILED;
726 OIC_LOG_V(DEBUG, TAG,
727 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
731 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
734 OIC_LOG_V(ERROR, TAG,
735 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
736 CALEGetErrorMsg(ret));
737 return CA_STATUS_FAILED;
741 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
744 OIC_LOG_V(ERROR, TAG,
745 "bt_gatt_service_add_characteristic failed with ret[%s]",
746 CALEGetErrorMsg(ret));
747 return CA_STATUS_FAILED;
750 ca_mutex_lock(g_leCharacteristicMutex);
754 char desc_value[2] = {1, 0}; // Notification enabled.
755 bt_gatt_h descriptor = NULL;
756 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
757 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
758 desc_value, sizeof(desc_value),
762 OIC_LOG_V(ERROR, TAG,
763 "bt_gatt_descriptor_create failed with ret[%s]",
764 CALEGetErrorMsg(ret));
765 return CA_STATUS_FAILED;
768 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
771 OIC_LOG_V(ERROR, TAG,
772 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
773 CALEGetErrorMsg(ret));
774 return CA_STATUS_FAILED;
777 if (NULL != g_gattReadCharPath)
779 OICFree(g_gattReadCharPath);
780 g_gattReadCharPath = NULL;
782 g_gattReadCharPath = charPath;
787 if (NULL != g_gattWriteCharPath)
789 OICFree(g_gattWriteCharPath);
790 g_gattWriteCharPath = NULL;
792 g_gattWriteCharPath = charPath;
795 ca_mutex_unlock(g_leCharacteristicMutex);
797 OIC_LOG(DEBUG, TAG, "OUT");
801 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
802 uint32_t charValueLen)
804 OIC_LOG(DEBUG, TAG, "IN");
806 VERIFY_NON_NULL(charValue, TAG, "charValue");
807 VERIFY_NON_NULL(address, TAG, "address");
809 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
811 ca_mutex_lock(g_leCharacteristicMutex);
813 if (NULL == g_gattReadCharPath)
815 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
816 ca_mutex_unlock(g_leCharacteristicMutex);
817 return CA_STATUS_FAILED;
820 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
823 OIC_LOG_V(ERROR, TAG,
824 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
825 ca_mutex_unlock(g_leCharacteristicMutex);
826 return CA_STATUS_FAILED;
829 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
833 OIC_LOG_V(ERROR, TAG,
834 "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
835 ca_mutex_unlock(g_leCharacteristicMutex);
836 return CA_STATUS_FAILED;
839 ca_mutex_unlock(g_leCharacteristicMutex);
841 OIC_LOG(DEBUG, TAG, "OUT");
845 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
847 OIC_LOG(DEBUG, TAG, "IN");
849 VERIFY_NON_NULL(charValue, TAG, "charValue");
851 ca_mutex_lock(g_leCharacteristicMutex);
853 if (NULL == g_gattReadCharPath)
855 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
856 ca_mutex_unlock(g_leCharacteristicMutex);
857 return CA_STATUS_FAILED;
860 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
863 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
864 ca_mutex_unlock(g_leCharacteristicMutex);
865 return CA_STATUS_FAILED;
868 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
872 OIC_LOG_V(ERROR, TAG,
873 "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
874 ca_mutex_unlock(g_leCharacteristicMutex);
875 return CA_STATUS_FAILED;
878 ca_mutex_unlock(g_leCharacteristicMutex);
880 OIC_LOG(DEBUG, TAG, "OUT");
884 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
886 OIC_LOG(DEBUG, TAG, "IN");
888 ca_mutex_lock(g_leReqRespCbMutex);
889 g_leServerDataReceivedCallback = callback;
890 ca_mutex_unlock(g_leReqRespCbMutex);
892 OIC_LOG(DEBUG, TAG, "OUT");
895 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
897 g_serverErrorCallback = callback;