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 = NULL;
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);
149 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
150 ca_mutex_lock(g_LEClientListMutex);
151 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
152 ca_mutex_unlock(g_LEClientListMutex);
156 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
157 bt_gatt_h characteristic, bool completed, void *user_data)
159 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
162 CAResult_t CAStartLEGattServer()
164 OIC_LOG(DEBUG, TAG, "IN");
166 ca_mutex_lock(g_leServerStateMutex);
167 if (true == g_isLEGattServerStarted)
169 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
170 ca_mutex_unlock(g_leServerStateMutex);
174 CAResult_t ret = CAInitLEGattServer();
175 if (CA_STATUS_OK != ret)
177 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
178 ca_mutex_unlock(g_leServerStateMutex);
179 CATerminateLEGattServer();
180 return CA_STATUS_FAILED;
183 char *serviceUUID = CA_GATT_SERVICE_UUID;
185 ret = CAAddNewLEServiceInGattServer(serviceUUID);
186 if (CA_STATUS_OK != ret)
188 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
189 ca_mutex_unlock(g_leServerStateMutex);
190 CATerminateLEGattServer();
191 return CA_STATUS_FAILED;
194 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
195 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
197 // For Read Characteristics.
198 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
199 CA_LE_INITIAL_BUF_SIZE, true);
200 if (CA_STATUS_OK != ret)
202 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
203 ca_mutex_unlock(g_leServerStateMutex);
204 CATerminateLEGattServer();
205 return CA_STATUS_FAILED;
208 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
209 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
212 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
213 CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
214 if (CA_STATUS_OK != ret )
216 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
217 ca_mutex_unlock(g_leServerStateMutex);
218 CATerminateLEGattServer();
219 return CA_STATUS_FAILED;
222 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
223 if (CA_STATUS_OK != ret )
225 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
226 ca_mutex_unlock(g_leServerStateMutex);
227 CATerminateLEGattServer();
228 return CA_STATUS_FAILED;
231 ret = CALEStartAdvertise(serviceUUID);
232 if (CA_STATUS_OK != ret)
234 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
235 ca_mutex_unlock(g_leServerStateMutex);
236 CATerminateLEGattServer();
237 return CA_STATUS_FAILED;
240 g_isLEGattServerStarted = true;
242 ca_mutex_unlock(g_leServerStateMutex);
244 OIC_LOG(DEBUG, TAG, "OUT");
248 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
251 OIC_LOG(DEBUG, TAG, "IN");
254 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
256 OIC_LOG(DEBUG, TAG, "OUT");
259 CAResult_t CALEStartAdvertise(const char *serviceUUID)
261 OIC_LOG(DEBUG, TAG, "IN");
263 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
264 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
266 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
267 return CA_STATUS_FAILED;
270 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
271 BT_ADAPTER_LE_PACKET_ADVERTISING,
273 if (BT_ERROR_NONE != res)
275 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
276 CALEGetErrorMsg(res));
277 return CA_STATUS_FAILED;
280 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
281 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
282 if (BT_ERROR_NONE != res)
284 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
285 CALEGetErrorMsg(res));
286 return CA_STATUS_FAILED;
289 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
290 if (BT_ERROR_NONE != res)
292 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
293 CALEGetErrorMsg(res));
294 return CA_STATUS_FAILED;
297 OIC_LOG(DEBUG, TAG, "OUT");
301 CAResult_t CALEStopAdvertise()
303 OIC_LOG(DEBUG, TAG, "IN");
304 if (NULL != g_hAdvertiser)
306 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
309 OIC_LOG_V(ERROR, TAG,
310 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
313 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
316 OIC_LOG_V(ERROR, TAG,
317 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
319 g_hAdvertiser = NULL;
323 OIC_LOG(ERROR, TAG, "Advertising is not running");
324 return CA_STATUS_FAILED;
327 OIC_LOG(DEBUG, TAG, "OUT");
331 CAResult_t CAStopLEGattServer()
333 OIC_LOG(DEBUG, TAG, "IN");
335 ca_mutex_lock(g_leServerStateMutex);
337 if (false == g_isLEGattServerStarted)
339 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
340 ca_mutex_unlock(g_leServerStateMutex);
344 g_isLEGattServerStarted = false;
346 ca_mutex_lock(g_LEClientListMutex);
347 CADisconnectAllClient(g_LEClientList);
348 g_LEClientList = NULL;
349 ca_mutex_unlock(g_LEClientListMutex);
351 CAResult_t res = CALEStopAdvertise();
353 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
356 res = CADeInitLEGattServer();
357 if (CA_STATUS_OK != res)
359 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
362 GMainContext *context_event_loop = NULL;
363 // Required for waking up the thread which is running in gmain loop
364 if (NULL != g_eventLoop)
366 context_event_loop = g_main_loop_get_context(g_eventLoop);
368 if (context_event_loop)
370 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
371 g_main_context_wakeup(context_event_loop);
373 // Kill g main loops and kill threads
374 g_main_loop_quit(g_eventLoop);
380 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
383 ca_mutex_unlock(g_leServerStateMutex);
385 OIC_LOG(DEBUG, TAG, "OUT");
389 CAResult_t CAInitializeLEGattServer()
391 OIC_LOG(DEBUG, TAG, "IN");
393 CAResult_t ret = CAInitGattServerMutexVariables();
394 if (CA_STATUS_OK != ret )
396 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
397 CATerminateGattServerMutexVariables();
398 return CA_SERVER_NOT_STARTED;
400 OIC_LOG(DEBUG, TAG, "OUT");
404 void CATerminateLEGattServer()
406 OIC_LOG(DEBUG, TAG, "IN");
408 // Service and characteristics path will be freed by the platform.
409 ca_mutex_lock(g_leServiceMutex);
410 g_gattSvcPath = NULL;
411 ca_mutex_unlock(g_leServiceMutex);
413 ca_mutex_lock(g_leCharacteristicMutex);
414 g_gattReadCharPath = NULL;
415 g_gattWriteCharPath = NULL;
416 ca_mutex_unlock(g_leCharacteristicMutex);
418 ca_mutex_lock(g_leServerThreadPoolMutex);
419 g_leServerThreadPool = NULL;
420 ca_mutex_unlock(g_leServerThreadPoolMutex);
422 // Terminating all mutex variables.
423 CATerminateGattServerMutexVariables();
424 OIC_LOG(DEBUG, TAG, "OUT");
427 CAResult_t CAInitGattServerMutexVariables()
429 OIC_LOG(DEBUG, TAG, "IN");
430 if (NULL == g_leServerStateMutex)
432 g_leServerStateMutex = ca_mutex_new();
433 if (NULL == g_leServerStateMutex)
435 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
436 return CA_STATUS_FAILED;
440 if (NULL == g_leServiceMutex)
442 g_leServiceMutex = ca_mutex_new();
443 if (NULL == g_leServiceMutex)
445 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
446 return CA_STATUS_FAILED;
450 if (NULL == g_leCharacteristicMutex)
452 g_leCharacteristicMutex = ca_mutex_new();
453 if (NULL == g_leCharacteristicMutex)
455 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
456 return CA_STATUS_FAILED;
460 if (NULL == g_leReqRespCbMutex)
462 g_leReqRespCbMutex = ca_mutex_new();
463 if (NULL == g_leReqRespCbMutex)
465 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
466 return CA_STATUS_FAILED;
470 if (NULL == g_leServerThreadPoolMutex)
472 g_leServerThreadPoolMutex = ca_mutex_new();
473 if (NULL == g_leServerThreadPoolMutex)
475 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
476 return CA_STATUS_FAILED;
480 if (NULL == g_LEClientListMutex)
482 g_LEClientListMutex = ca_mutex_new();
483 if (NULL == g_LEClientListMutex)
485 OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
486 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 ca_mutex_free(g_leServerThreadPoolMutex);
510 g_leServerThreadPoolMutex = NULL;
512 ca_mutex_free(g_LEClientListMutex);
513 g_LEClientListMutex = NULL;
515 OIC_LOG(DEBUG, TAG, "OUT");
518 CAResult_t CAInitLEGattServer()
520 OIC_LOG(DEBUG, TAG, "IN");
522 int ret = bt_gatt_server_initialize();
525 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
526 CALEGetErrorMsg(ret));
527 return CA_STATUS_FAILED;
532 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
533 ret = bt_gatt_server_create(&g_gattServer);
536 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
537 CALEGetErrorMsg(ret));
538 return CA_STATUS_FAILED;
542 OIC_LOG(DEBUG, TAG, "OUT");
546 CAResult_t CADeInitLEGattServer()
548 OIC_LOG(DEBUG, TAG, "IN");
550 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
553 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
554 CALEGetErrorMsg(ret));
555 return CA_STATUS_FAILED;
558 ret = bt_gatt_server_destroy(g_gattServer);
561 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
562 CALEGetErrorMsg(ret));
563 return CA_STATUS_FAILED;
567 ret = bt_gatt_server_deinitialize();
570 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
571 CALEGetErrorMsg(ret));
572 return CA_STATUS_FAILED;
575 OIC_LOG(DEBUG, TAG, "OUT");
579 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
581 OIC_LOG(DEBUG, TAG, "IN");
582 ca_mutex_lock(g_leServerThreadPoolMutex);
583 g_leServerThreadPool = handle;
584 ca_mutex_unlock(g_leServerThreadPoolMutex);
585 OIC_LOG(DEBUG, TAG, "OUT");
588 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
590 OIC_LOG(DEBUG, TAG, "IN");
592 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
594 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
596 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
598 ca_mutex_lock(g_leServiceMutex);
599 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
602 ca_mutex_unlock(g_leServiceMutex);
603 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
604 CALEGetErrorMsg(ret));
605 return CA_STATUS_FAILED;
607 ca_mutex_unlock(g_leServiceMutex);
611 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
614 OIC_LOG(DEBUG, TAG, "OUT");
618 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
619 bt_gatt_h charPath, int offset, char *charValue,
620 int charValueLen, void *userData)
622 OIC_LOG(DEBUG, TAG, "IN");
624 if (NULL == charValue || NULL == remoteAddress)
626 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
630 OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
631 charValue, charValueLen);
633 uint8_t *data = OICMalloc(charValueLen);
636 OIC_LOG(ERROR, TAG, "Malloc failed!");
640 memcpy(data, charValue, charValueLen);
642 ca_mutex_lock(g_leReqRespCbMutex);
643 if (NULL == g_leServerDataReceivedCallback)
645 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
646 ca_mutex_unlock(g_leReqRespCbMutex);
651 OIC_LOG(DEBUG, TAG, "Sending data up !");
652 uint32_t sentLength = 0;
653 g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
655 ca_mutex_unlock(g_leReqRespCbMutex);
657 OIC_LOG(DEBUG, TAG, "OUT");
660 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
662 OIC_LOG(DEBUG, TAG, "IN");
664 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
666 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
668 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
671 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
672 CALEGetErrorMsg(ret));
673 return CA_STATUS_FAILED;
676 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
677 CALEGattRemoteCharacteristicWriteCb, NULL);
681 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
682 CALEGetErrorMsg(ret));
683 return CA_STATUS_FAILED;
686 OIC_LOG(DEBUG, TAG, "OUT");
690 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
691 const char *charValue, int charValueLen, bool read)
694 OIC_LOG(DEBUG, TAG, "IN");
696 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
700 properties = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ;
704 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
707 bt_gatt_h charPath = NULL;
709 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
710 charValueLen, &charPath);
712 if (0 != ret || NULL == charPath)
714 OIC_LOG_V(ERROR, TAG,
715 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
716 return CA_STATUS_FAILED;
719 OIC_LOG_V(DEBUG, TAG,
720 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
724 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
727 OIC_LOG_V(ERROR, TAG,
728 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
729 CALEGetErrorMsg(ret));
730 return CA_STATUS_FAILED;
734 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
737 OIC_LOG_V(ERROR, TAG,
738 "bt_gatt_service_add_characteristic failed with ret[%s]",
739 CALEGetErrorMsg(ret));
740 return CA_STATUS_FAILED;
743 ca_mutex_lock(g_leCharacteristicMutex);
747 char desc_value[2] = {1, 0}; // Notification enabled.
748 bt_gatt_h descriptor = NULL;
749 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
750 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
751 desc_value, sizeof(desc_value),
755 ca_mutex_unlock(g_leCharacteristicMutex);
756 OIC_LOG_V(ERROR, TAG,
757 "bt_gatt_descriptor_create failed with ret[%s]",
758 CALEGetErrorMsg(ret));
759 return CA_STATUS_FAILED;
762 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
765 ca_mutex_unlock(g_leCharacteristicMutex);
766 OIC_LOG_V(ERROR, TAG,
767 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
768 CALEGetErrorMsg(ret));
769 return CA_STATUS_FAILED;
772 g_gattReadCharPath = charPath;
776 g_gattWriteCharPath = charPath;
779 ca_mutex_unlock(g_leCharacteristicMutex);
781 OIC_LOG(DEBUG, TAG, "OUT");
785 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
786 uint32_t charValueLen)
788 OIC_LOG(DEBUG, TAG, "IN");
790 VERIFY_NON_NULL(charValue, TAG, "charValue");
791 VERIFY_NON_NULL(address, TAG, "address");
793 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
795 ca_mutex_lock(g_leCharacteristicMutex);
797 if (NULL == g_gattReadCharPath)
799 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
800 ca_mutex_unlock(g_leCharacteristicMutex);
801 return CA_STATUS_FAILED;
804 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
807 OIC_LOG_V(ERROR, TAG,
808 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
809 ca_mutex_unlock(g_leCharacteristicMutex);
810 return CA_STATUS_FAILED;
813 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
817 OIC_LOG_V(ERROR, TAG,
818 "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
819 ca_mutex_unlock(g_leCharacteristicMutex);
820 return CA_STATUS_FAILED;
823 ca_mutex_unlock(g_leCharacteristicMutex);
825 OIC_LOG(DEBUG, TAG, "OUT");
829 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
831 OIC_LOG(DEBUG, TAG, "IN");
833 VERIFY_NON_NULL(charValue, TAG, "charValue");
835 ca_mutex_lock(g_leCharacteristicMutex);
837 if (NULL == g_gattReadCharPath)
839 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
840 ca_mutex_unlock(g_leCharacteristicMutex);
841 return CA_STATUS_FAILED;
844 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
847 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
848 ca_mutex_unlock(g_leCharacteristicMutex);
849 return CA_STATUS_FAILED;
852 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
856 OIC_LOG_V(ERROR, TAG,
857 "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
858 ca_mutex_unlock(g_leCharacteristicMutex);
859 return CA_STATUS_FAILED;
862 ca_mutex_unlock(g_leCharacteristicMutex);
864 OIC_LOG(DEBUG, TAG, "OUT");
868 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
870 OIC_LOG(DEBUG, TAG, "IN");
872 ca_mutex_lock(g_leReqRespCbMutex);
873 g_leServerDataReceivedCallback = callback;
874 ca_mutex_unlock(g_leReqRespCbMutex);
876 OIC_LOG(DEBUG, TAG, "OUT");
879 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
881 g_serverErrorCallback = callback;