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_string.h"
28 #include "oic_malloc.h"
32 * Logging tag for module name
34 #define TAG "OIC_CA_LE_SERVER"
37 * Initial buffer size for Gatt Server.
39 #define CA_LE_INITIAL_BUF_SIZE 512
42 * The handle of the OIC server.
44 static bt_gatt_server_h g_gattServer = NULL;
47 * The handle of the OIC service.
49 static bt_gatt_h g_gattSvcPath = NULL;
52 * The handle of the OIC read characteristics.
54 static bt_gatt_h g_gattReadCharPath = NULL;
57 * The handle of the OIC write characteristics.
59 static bt_gatt_h g_gattWriteCharPath = NULL;
62 * The handle to control Bluetooth LE advertising.
64 static bt_advertiser_h g_hAdvertiser = NULL;
67 * Callback register with LE adapter. This callback is called on reception of any
68 * data from the remote device.
70 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
73 * Callback to notify any error in LE adapter.
75 static CABLEErrorHandleCallback g_serverErrorCallback;
78 * To keep the state of GATT server if started or not.
80 static bool g_isLEGattServerStarted = false;
83 * Mutex to synchronize the calls to start and stop server.
85 static ca_mutex g_leServerStateMutex = NULL;
88 * Mutex to synchronize writing operations on the characteristics.
90 static ca_mutex g_leCharacteristicMutex = NULL;
93 * Mutex to synchronize to creation of OIC service.
95 static ca_mutex g_leServiceMutex = NULL;
98 * Mutex to synchronize access to the requestResponse callback to be called
99 * when the data needs to be sent from GATTClient.
101 static ca_mutex g_leReqRespCbMutex = NULL;
104 * Mutex to synchronize the task to be pushed to thread pool.
106 static ca_mutex g_leServerThreadPoolMutex = NULL;
109 * Reference to threadpool.
111 static ca_thread_pool_t g_leServerThreadPool = NULL;
114 * GmainLoop to manage the threads to receive the callback from the platfrom.
116 static GMainLoop *g_eventLoop = NULL;
119 * This contains the list of OIC clients connected to the server.
121 static LEClientInfoList *g_LEClientList = NULL;
124 * Mutex to synchronize access to LE ClientList.
126 static ca_mutex g_LEClientListMutex = NULL;
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);
135 char *addr = OICStrdup(remoteAddress);
136 ca_mutex_lock(g_LEClientListMutex);
137 CAResult_t result = CAAddLEClientInfoToList(&g_LEClientList, addr);
138 if (CA_STATUS_OK != result)
140 OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
141 ca_mutex_unlock(g_LEClientListMutex);
145 ca_mutex_unlock(g_LEClientListMutex);
148 g_connStateCb(CA_ADAPTER_GATT_BTLE, remoteAddress, true);
153 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
154 ca_mutex_lock(g_LEClientListMutex);
155 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
156 ca_mutex_unlock(g_LEClientListMutex);
159 g_connStateCb(CA_ADAPTER_GATT_BTLE, remoteAddress, false);
164 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
165 bt_gatt_h characteristic, bool completed, void *user_data)
167 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
170 CAResult_t CAStartLEGattServer()
172 OIC_LOG(DEBUG, TAG, "IN");
174 ca_mutex_lock(g_leServerStateMutex);
175 if (true == g_isLEGattServerStarted)
177 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
178 ca_mutex_unlock(g_leServerStateMutex);
182 CAResult_t ret = CAInitLEGattServer();
183 if (CA_STATUS_OK != ret)
185 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
186 ca_mutex_unlock(g_leServerStateMutex);
187 CATerminateLEGattServer();
188 return CA_STATUS_FAILED;
191 char *serviceUUID = CA_GATT_SERVICE_UUID;
193 ret = CAAddNewLEServiceInGattServer(serviceUUID);
194 if (CA_STATUS_OK != ret)
196 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
197 ca_mutex_unlock(g_leServerStateMutex);
198 CATerminateLEGattServer();
199 return CA_STATUS_FAILED;
202 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
203 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
205 // For Read Characteristics.
206 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
207 CA_LE_INITIAL_BUF_SIZE, true);
208 if (CA_STATUS_OK != ret)
210 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
211 ca_mutex_unlock(g_leServerStateMutex);
212 CATerminateLEGattServer();
213 return CA_STATUS_FAILED;
216 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
217 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
220 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
221 CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
222 if (CA_STATUS_OK != ret )
224 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
225 ca_mutex_unlock(g_leServerStateMutex);
226 CATerminateLEGattServer();
227 return CA_STATUS_FAILED;
230 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
231 if (CA_STATUS_OK != ret )
233 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
234 ca_mutex_unlock(g_leServerStateMutex);
235 CATerminateLEGattServer();
236 return CA_STATUS_FAILED;
239 ret = CALEStartAdvertise(serviceUUID);
240 if (CA_STATUS_OK != ret)
242 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
243 ca_mutex_unlock(g_leServerStateMutex);
244 CATerminateLEGattServer();
245 return CA_STATUS_FAILED;
248 g_isLEGattServerStarted = true;
250 ca_mutex_unlock(g_leServerStateMutex);
252 OIC_LOG(DEBUG, TAG, "OUT");
256 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
259 OIC_LOG(DEBUG, TAG, "IN");
262 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
264 OIC_LOG(DEBUG, TAG, "OUT");
267 CAResult_t CALEStartAdvertise(const char *serviceUUID)
269 OIC_LOG(DEBUG, TAG, "IN");
271 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
272 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
274 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
275 return CA_STATUS_FAILED;
278 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
279 BT_ADAPTER_LE_PACKET_ADVERTISING,
281 if (BT_ERROR_NONE != res)
283 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
284 CALEGetErrorMsg(res));
285 return CA_STATUS_FAILED;
288 res = bt_adapter_le_start_advertising(g_hAdvertiser, NULL, NULL, NULL);
289 if (BT_ERROR_NONE != res)
291 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising failed with ret[%s]",
292 CALEGetErrorMsg(res));
293 return CA_STATUS_FAILED;
296 OIC_LOG(DEBUG, TAG, "OUT");
300 CAResult_t CALEStopAdvertise()
302 OIC_LOG(DEBUG, TAG, "IN");
303 if (NULL != g_hAdvertiser)
305 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
308 OIC_LOG_V(ERROR, TAG,
309 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
312 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
315 OIC_LOG_V(ERROR, TAG,
316 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
318 g_hAdvertiser = NULL;
322 OIC_LOG(ERROR, TAG, "Advertising is not running");
323 return CA_STATUS_FAILED;
326 OIC_LOG(DEBUG, TAG, "OUT");
330 CAResult_t CAStopLEGattServer()
332 OIC_LOG(DEBUG, TAG, "IN");
334 ca_mutex_lock(g_leServerStateMutex);
336 if (false == g_isLEGattServerStarted)
338 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
339 ca_mutex_unlock(g_leServerStateMutex);
343 g_isLEGattServerStarted = false;
345 ca_mutex_lock(g_LEClientListMutex);
346 CADisconnectAllClient(g_LEClientList);
347 g_LEClientList = NULL;
348 ca_mutex_unlock(g_LEClientListMutex);
350 CAResult_t res = CALEStopAdvertise();
352 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
355 res = CADeInitLEGattServer();
356 if (CA_STATUS_OK != res)
358 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
361 GMainContext *context_event_loop = NULL;
362 // Required for waking up the thread which is running in gmain loop
363 if (NULL != g_eventLoop)
365 context_event_loop = g_main_loop_get_context(g_eventLoop);
367 if (context_event_loop)
369 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
370 g_main_context_wakeup(context_event_loop);
372 // Kill g main loops and kill threads
373 g_main_loop_quit(g_eventLoop);
378 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
381 ca_mutex_unlock(g_leServerStateMutex);
383 OIC_LOG(DEBUG, TAG, "OUT");
387 CAResult_t CAInitializeLEGattServer()
389 OIC_LOG(DEBUG, TAG, "IN");
391 CAResult_t ret = CAInitGattServerMutexVariables();
392 if (CA_STATUS_OK != ret )
394 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
395 CATerminateGattServerMutexVariables();
396 return CA_SERVER_NOT_STARTED;
398 OIC_LOG(DEBUG, TAG, "OUT");
402 void CATerminateLEGattServer()
404 OIC_LOG(DEBUG, TAG, "IN");
406 // Service and characteristics path will be freed by the platform.
407 ca_mutex_lock(g_leServiceMutex);
408 g_gattSvcPath = NULL;
409 ca_mutex_unlock(g_leServiceMutex);
411 ca_mutex_lock(g_leCharacteristicMutex);
412 g_gattReadCharPath = NULL;
413 g_gattWriteCharPath = NULL;
414 ca_mutex_unlock(g_leCharacteristicMutex);
416 ca_mutex_lock(g_leServerThreadPoolMutex);
417 g_leServerThreadPool = NULL;
418 ca_mutex_unlock(g_leServerThreadPoolMutex);
420 // Terminating all mutex variables.
421 CATerminateGattServerMutexVariables();
422 OIC_LOG(DEBUG, TAG, "OUT");
425 CAResult_t CAInitGattServerMutexVariables()
427 OIC_LOG(DEBUG, TAG, "IN");
428 if (NULL == g_leServerStateMutex)
430 g_leServerStateMutex = ca_mutex_new();
431 if (NULL == g_leServerStateMutex)
433 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
434 return CA_STATUS_FAILED;
438 if (NULL == g_leServiceMutex)
440 g_leServiceMutex = ca_mutex_new();
441 if (NULL == g_leServiceMutex)
443 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
444 return CA_STATUS_FAILED;
448 if (NULL == g_leCharacteristicMutex)
450 g_leCharacteristicMutex = ca_mutex_new();
451 if (NULL == g_leCharacteristicMutex)
453 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
454 return CA_STATUS_FAILED;
458 if (NULL == g_leReqRespCbMutex)
460 g_leReqRespCbMutex = ca_mutex_new();
461 if (NULL == g_leReqRespCbMutex)
463 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
464 return CA_STATUS_FAILED;
468 if (NULL == g_leServerThreadPoolMutex)
470 g_leServerThreadPoolMutex = ca_mutex_new();
471 if (NULL == g_leServerThreadPoolMutex)
473 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
474 return CA_STATUS_FAILED;
478 if (NULL == g_LEClientListMutex)
480 g_LEClientListMutex = ca_mutex_new();
481 if (NULL == g_LEClientListMutex)
483 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
484 return CA_STATUS_FAILED;
489 OIC_LOG(DEBUG, TAG, "OUT");
493 void CATerminateGattServerMutexVariables()
495 OIC_LOG(DEBUG, TAG, "IN");
496 ca_mutex_free(g_leServerStateMutex);
497 g_leServerStateMutex = NULL;
499 ca_mutex_free(g_leServiceMutex);
500 g_leServiceMutex = NULL;
502 ca_mutex_free(g_leCharacteristicMutex);
503 g_leCharacteristicMutex = NULL;
505 ca_mutex_free(g_leReqRespCbMutex);
506 g_leReqRespCbMutex = NULL;
508 ca_mutex_free(g_leServerThreadPoolMutex);
509 g_leServerThreadPoolMutex = NULL;
511 ca_mutex_free(g_LEClientListMutex);
512 g_LEClientListMutex = NULL;
514 OIC_LOG(DEBUG, TAG, "OUT");
517 CAResult_t CAInitLEGattServer()
519 OIC_LOG(DEBUG, TAG, "IN");
521 int ret = bt_gatt_server_initialize();
524 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
525 CALEGetErrorMsg(ret));
526 return CA_STATUS_FAILED;
529 bt_gatt_server_h server;
531 ret = bt_gatt_server_create(&server);
534 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
535 CALEGetErrorMsg(ret));
536 return CA_STATUS_FAILED;
539 if (NULL != g_gattServer)
541 OICFree(g_gattServer);
544 g_gattServer = server;
546 OIC_LOG(DEBUG, TAG, "OUT");
550 CAResult_t CADeInitLEGattServer()
552 OIC_LOG(DEBUG, TAG, "IN");
554 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
557 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
558 CALEGetErrorMsg(ret));
559 return CA_STATUS_FAILED;
562 ret = bt_gatt_server_destroy(g_gattServer);
565 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
566 CALEGetErrorMsg(ret));
567 return CA_STATUS_FAILED;
570 ret = bt_gatt_server_deinitialize();
573 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
574 CALEGetErrorMsg(ret));
575 return CA_STATUS_FAILED;
578 OIC_LOG(DEBUG, TAG, "OUT");
582 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
584 OIC_LOG(DEBUG, TAG, "IN");
585 ca_mutex_lock(g_leServerThreadPoolMutex);
586 g_leServerThreadPool = handle;
587 ca_mutex_unlock(g_leServerThreadPoolMutex);
588 OIC_LOG(DEBUG, TAG, "OUT");
591 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
593 OIC_LOG(DEBUG, TAG, "IN");
595 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
597 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
599 bt_gatt_h service = NULL;
600 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
602 int ret = bt_gatt_service_create(serviceUUID, type, &service);
605 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
606 CALEGetErrorMsg(ret));
607 return CA_STATUS_FAILED;
612 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)service);
614 ca_mutex_lock(g_leServiceMutex);
616 if (NULL != g_gattSvcPath)
618 OICFree(g_gattSvcPath);
619 g_gattSvcPath = NULL;
621 g_gattSvcPath = service;
623 ca_mutex_unlock(g_leServiceMutex);
626 OIC_LOG(DEBUG, TAG, "OUT");
630 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
631 bt_gatt_h charPath, int offset, char *charValue,
632 int charValueLen, void *userData)
634 OIC_LOG(DEBUG, TAG, "IN");
636 if (NULL == charValue || NULL == remoteAddress)
638 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
642 OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
643 charValue, charValueLen);
645 uint8_t *data = OICMalloc(charValueLen);
648 OIC_LOG(ERROR, TAG, "Malloc failed!");
652 memcpy(data, charValue, charValueLen);
654 ca_mutex_lock(g_leReqRespCbMutex);
655 if (NULL == g_leServerDataReceivedCallback)
657 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
658 ca_mutex_unlock(g_leReqRespCbMutex);
663 OIC_LOG(DEBUG, TAG, "Sending data up !");
664 uint32_t sentLength = 0;
665 g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
667 ca_mutex_unlock(g_leReqRespCbMutex);
669 OIC_LOG(DEBUG, TAG, "OUT");
672 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
674 OIC_LOG(DEBUG, TAG, "IN");
676 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
678 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
680 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
683 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
684 CALEGetErrorMsg(ret));
685 return CA_STATUS_FAILED;
688 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
689 CALEGattRemoteCharacteristicWriteCb, NULL);
693 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
694 CALEGetErrorMsg(ret));
695 return CA_STATUS_FAILED;
698 OIC_LOG(DEBUG, TAG, "OUT");
702 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
703 const char *charValue, int charValueLen, bool read)
706 OIC_LOG(DEBUG, TAG, "IN");
708 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
709 int properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_NOTIFY;
712 properties = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ;
716 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
721 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
722 charValueLen, &charPath);
724 if (0 != ret || NULL == charPath)
726 OIC_LOG_V(ERROR, TAG,
727 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
728 return CA_STATUS_FAILED;
731 OIC_LOG_V(DEBUG, TAG,
732 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
736 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
739 OIC_LOG_V(ERROR, TAG,
740 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
741 CALEGetErrorMsg(ret));
742 return CA_STATUS_FAILED;
746 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
749 OIC_LOG_V(ERROR, TAG,
750 "bt_gatt_service_add_characteristic failed with ret[%s]",
751 CALEGetErrorMsg(ret));
752 return CA_STATUS_FAILED;
755 ca_mutex_lock(g_leCharacteristicMutex);
759 char desc_value[2] = {1, 0}; // Notification enabled.
760 bt_gatt_h descriptor = NULL;
761 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
762 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID,
763 permissions, desc_value, sizeof(desc_value), &descriptor);
766 OIC_LOG_V(ERROR, TAG,
767 "bt_gatt_descriptor_create failed with ret[%s]",
768 CALEGetErrorMsg(ret));
769 return CA_STATUS_FAILED;
772 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
775 OIC_LOG_V(ERROR, TAG,
776 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
777 CALEGetErrorMsg(ret));
778 return CA_STATUS_FAILED;
781 if (NULL != g_gattReadCharPath)
783 OICFree(g_gattReadCharPath);
784 g_gattReadCharPath = NULL;
786 g_gattReadCharPath = charPath;
791 if (NULL != g_gattWriteCharPath)
793 OICFree(g_gattWriteCharPath);
794 g_gattWriteCharPath = NULL;
796 g_gattWriteCharPath = charPath;
799 ca_mutex_unlock(g_leCharacteristicMutex);
801 OIC_LOG(DEBUG, TAG, "OUT");
805 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
806 uint32_t charValueLen)
808 OIC_LOG(DEBUG, TAG, "IN");
810 VERIFY_NON_NULL(charValue, TAG, "charValue");
811 VERIFY_NON_NULL(address, TAG, "address");
813 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
815 ca_mutex_lock(g_leCharacteristicMutex);
817 if (NULL == g_gattReadCharPath)
819 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
820 ca_mutex_unlock(g_leCharacteristicMutex);
821 return CA_STATUS_FAILED;
824 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
827 OIC_LOG_V(ERROR, TAG,
828 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
829 ca_mutex_unlock(g_leCharacteristicMutex);
830 return CA_STATUS_FAILED;
833 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
837 OIC_LOG_V(ERROR, TAG,
838 "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
839 ca_mutex_unlock(g_leCharacteristicMutex);
840 return CA_STATUS_FAILED;
843 ca_mutex_unlock(g_leCharacteristicMutex);
845 OIC_LOG(DEBUG, TAG, "OUT");
849 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
851 OIC_LOG(DEBUG, TAG, "IN");
853 VERIFY_NON_NULL(charValue, TAG, "charValue");
855 ca_mutex_lock(g_leCharacteristicMutex);
857 if (NULL == g_gattReadCharPath)
859 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
860 ca_mutex_unlock(g_leCharacteristicMutex);
861 return CA_STATUS_FAILED;
864 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
867 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
868 ca_mutex_unlock(g_leCharacteristicMutex);
869 return CA_STATUS_FAILED;
872 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
876 OIC_LOG_V(ERROR, TAG,
877 "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
878 ca_mutex_unlock(g_leCharacteristicMutex);
879 return CA_STATUS_FAILED;
882 ca_mutex_unlock(g_leCharacteristicMutex);
884 OIC_LOG(DEBUG, TAG, "OUT");
888 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
890 OIC_LOG(DEBUG, TAG, "IN");
892 ca_mutex_lock(g_leReqRespCbMutex);
893 g_leServerDataReceivedCallback = callback;
894 ca_mutex_unlock(g_leReqRespCbMutex);
896 OIC_LOG(DEBUG, TAG, "OUT");
899 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
901 g_serverErrorCallback = callback;