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"
33 * Logging tag for module name
35 #define TAG "OIC_CA_LE_SERVER"
38 * The handle of the OIC server.
40 static bt_gatt_server_h g_gattServer = NULL;
43 * The handle of the OIC service.
45 static bt_gatt_h g_gattSvcPath = NULL;
48 * The handle of the OIC read characteristics.
50 static bt_gatt_h g_gattReadCharPath = NULL;
53 * The handle of the OIC write characteristics.
55 static bt_gatt_h g_gattWriteCharPath = NULL;
58 * The handle to control Bluetooth LE advertising.
60 static bt_advertiser_h g_hAdvertiser = NULL;
63 * Callback register with LE adapter. This callback is called on reception of any
64 * data from the remote device.
66 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
69 * Callback to notify any error in LE adapter.
71 static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
74 * To keep the state of GATT server if started or not.
76 static bool g_isLEGattServerStarted = false;
79 * Mutex to synchronize the calls to start and stop server.
81 static oc_mutex g_leServerStateMutex = NULL;
84 * Mutex to synchronize writing operations on the characteristics.
86 static oc_mutex g_leCharacteristicMutex = NULL;
89 * Mutex to synchronize to creation of OIC service.
91 static oc_mutex g_leServiceMutex = NULL;
94 * Mutex to synchronize access to the requestResponse callback to be called
95 * when the data needs to be sent from GATTClient.
97 static oc_mutex g_leReqRespCbMutex = NULL;
100 * Mutex to synchronize the task to be pushed to thread pool.
102 static oc_mutex g_leServerThreadPoolMutex = NULL;
105 * Reference to threadpool.
107 static ca_thread_pool_t g_leServerThreadPool = NULL;
110 * GmainLoop to manage the threads to receive the callback from the platfrom.
112 static GMainLoop *g_eventLoop = NULL;
115 * This contains the list of OIC clients connected to the server.
117 static LEClientInfoList *g_LEClientList = NULL;
120 * Mutex to synchronize access to LE ClientList.
122 static oc_mutex g_LEClientListMutex = NULL;
124 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
126 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
128 CAResult_t res = CA_STATUS_OK;
131 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
132 char *addr = OICStrdup(remoteAddress);
133 oc_mutex_lock(g_LEClientListMutex);
134 res = CAAddLEClientInfoToList(&g_LEClientList, addr);
135 if (CA_STATUS_OK != res)
137 OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
138 oc_mutex_unlock(g_LEClientListMutex);
142 oc_mutex_unlock(g_LEClientListMutex);
144 res = CALEStopAdvertise();
145 if (CA_STATUS_OK != res)
147 OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
153 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
154 oc_mutex_lock(g_LEClientListMutex);
155 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
156 oc_mutex_unlock(g_LEClientListMutex);
158 res = CALEStartAdvertise();
159 if (CA_STATUS_OK != res)
161 OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
167 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
168 bt_gatt_h characteristic, bool completed, void *user_data)
170 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
173 CAResult_t CAStartLEGattServer()
175 OIC_LOG(DEBUG, TAG, "IN");
177 oc_mutex_lock(g_leServerStateMutex);
178 if (true == g_isLEGattServerStarted)
180 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
181 oc_mutex_unlock(g_leServerStateMutex);
185 CAResult_t ret = CAInitLEGattServer();
186 if (CA_STATUS_OK != ret)
188 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
189 oc_mutex_unlock(g_leServerStateMutex);
190 CATerminateLEGattServer();
191 return CA_STATUS_FAILED;
194 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
195 if (CA_STATUS_OK != ret)
197 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
198 oc_mutex_unlock(g_leServerStateMutex);
199 CATerminateLEGattServer();
200 return CA_STATUS_FAILED;
203 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
204 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
206 // For Read Characteristics.
207 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
208 sizeof(charReadValue), true);
209 if (CA_STATUS_OK != ret)
211 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
212 oc_mutex_unlock(g_leServerStateMutex);
213 CATerminateLEGattServer();
214 return CA_STATUS_FAILED;
217 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
218 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
221 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
222 sizeof(charWriteValue), false); // For Write Characteristics.
223 if (CA_STATUS_OK != ret )
225 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
226 oc_mutex_unlock(g_leServerStateMutex);
227 CATerminateLEGattServer();
228 return CA_STATUS_FAILED;
231 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
232 if (CA_STATUS_OK != ret )
234 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
235 oc_mutex_unlock(g_leServerStateMutex);
236 CATerminateLEGattServer();
237 return CA_STATUS_FAILED;
240 ret = CALEStartAdvertise();
241 if (CA_STATUS_OK != ret)
243 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
244 oc_mutex_unlock(g_leServerStateMutex);
245 CATerminateLEGattServer();
246 return CA_STATUS_FAILED;
249 g_isLEGattServerStarted = true;
251 oc_mutex_unlock(g_leServerStateMutex);
253 OIC_LOG(DEBUG, TAG, "OUT");
257 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
260 OIC_LOG(DEBUG, TAG, "IN");
263 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
264 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
265 true, "notifyChar success");
269 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
270 false, "notifyChar failure");
272 OIC_LOG(DEBUG, TAG, "OUT");
275 CAResult_t CALEStartAdvertise()
277 OIC_LOG(DEBUG, TAG, "IN");
279 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
280 if (CA_STATUS_OK != res)
282 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
285 OIC_LOG(DEBUG, TAG, "OUT");
289 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
291 OIC_LOG(DEBUG, TAG, "IN");
293 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
294 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
296 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
297 return CA_STATUS_FAILED;
300 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
301 BT_ADAPTER_LE_PACKET_ADVERTISING,
303 if (BT_ERROR_NONE != res)
305 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
306 CALEGetErrorMsg(res));
307 return CA_STATUS_FAILED;
310 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
311 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
312 if (BT_ERROR_NONE != res)
314 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
315 CALEGetErrorMsg(res));
316 return CA_STATUS_FAILED;
319 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
320 if (BT_ERROR_NONE != res)
322 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
323 CALEGetErrorMsg(res));
324 return CA_STATUS_FAILED;
327 OIC_LOG(DEBUG, TAG, "OUT");
331 CAResult_t CALEStopAdvertise()
333 OIC_LOG(DEBUG, TAG, "IN");
334 if (NULL != g_hAdvertiser)
336 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
339 OIC_LOG_V(ERROR, TAG,
340 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
343 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
346 OIC_LOG_V(ERROR, TAG,
347 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
349 g_hAdvertiser = NULL;
353 OIC_LOG(ERROR, TAG, "Advertising is not running");
354 return CA_STATUS_FAILED;
357 OIC_LOG(DEBUG, TAG, "OUT");
361 CAResult_t CAStopLEGattServer()
363 OIC_LOG(DEBUG, TAG, "IN");
365 oc_mutex_lock(g_leServerStateMutex);
367 if (false == g_isLEGattServerStarted)
369 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
370 oc_mutex_unlock(g_leServerStateMutex);
374 g_isLEGattServerStarted = false;
376 oc_mutex_lock(g_LEClientListMutex);
377 CADisconnectAllClient(g_LEClientList);
378 g_LEClientList = NULL;
379 oc_mutex_unlock(g_LEClientListMutex);
381 CAResult_t res = CALEStopAdvertise();
383 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
386 res = CADeInitLEGattServer();
387 if (CA_STATUS_OK != res)
389 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
392 GMainContext *context_event_loop = NULL;
393 // Required for waking up the thread which is running in gmain loop
394 if (NULL != g_eventLoop)
396 context_event_loop = g_main_loop_get_context(g_eventLoop);
398 if (context_event_loop)
400 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
401 g_main_context_wakeup(context_event_loop);
403 // Kill g main loops and kill threads
404 g_main_loop_quit(g_eventLoop);
410 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
413 oc_mutex_unlock(g_leServerStateMutex);
415 OIC_LOG(DEBUG, TAG, "OUT");
419 CAResult_t CAInitializeLEGattServer()
421 OIC_LOG(DEBUG, TAG, "IN");
423 CAResult_t ret = CAInitGattServerMutexVariables();
424 if (CA_STATUS_OK != ret )
426 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
427 CATerminateGattServerMutexVariables();
428 return CA_SERVER_NOT_STARTED;
430 OIC_LOG(DEBUG, TAG, "OUT");
434 void CATerminateLEGattServer()
436 OIC_LOG(DEBUG, TAG, "IN");
438 // Service and characteristics path will be freed by the platform.
439 oc_mutex_lock(g_leServiceMutex);
440 g_gattSvcPath = NULL;
441 oc_mutex_unlock(g_leServiceMutex);
443 oc_mutex_lock(g_leCharacteristicMutex);
444 g_gattReadCharPath = NULL;
445 g_gattWriteCharPath = NULL;
446 oc_mutex_unlock(g_leCharacteristicMutex);
448 oc_mutex_lock(g_leServerThreadPoolMutex);
449 g_leServerThreadPool = NULL;
450 oc_mutex_unlock(g_leServerThreadPoolMutex);
452 // Terminating all mutex variables.
453 CATerminateGattServerMutexVariables();
454 OIC_LOG(DEBUG, TAG, "OUT");
457 CAResult_t CAInitGattServerMutexVariables()
459 OIC_LOG(DEBUG, TAG, "IN");
460 if (NULL == g_leServerStateMutex)
462 g_leServerStateMutex = oc_mutex_new();
463 if (NULL == g_leServerStateMutex)
465 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
466 return CA_STATUS_FAILED;
470 if (NULL == g_leServiceMutex)
472 g_leServiceMutex = oc_mutex_new();
473 if (NULL == g_leServiceMutex)
475 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
476 return CA_STATUS_FAILED;
480 if (NULL == g_leCharacteristicMutex)
482 g_leCharacteristicMutex = oc_mutex_new();
483 if (NULL == g_leCharacteristicMutex)
485 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
486 return CA_STATUS_FAILED;
490 if (NULL == g_leReqRespCbMutex)
492 g_leReqRespCbMutex = oc_mutex_new();
493 if (NULL == g_leReqRespCbMutex)
495 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
496 return CA_STATUS_FAILED;
500 if (NULL == g_leServerThreadPoolMutex)
502 g_leServerThreadPoolMutex = oc_mutex_new();
503 if (NULL == g_leServerThreadPoolMutex)
505 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
506 return CA_STATUS_FAILED;
510 if (NULL == g_LEClientListMutex)
512 g_LEClientListMutex = oc_mutex_new();
513 if (NULL == g_LEClientListMutex)
515 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
516 return CA_STATUS_FAILED;
520 OIC_LOG(DEBUG, TAG, "OUT");
524 void CATerminateGattServerMutexVariables()
526 OIC_LOG(DEBUG, TAG, "IN");
527 oc_mutex_free(g_leServerStateMutex);
528 g_leServerStateMutex = NULL;
530 oc_mutex_free(g_leServiceMutex);
531 g_leServiceMutex = NULL;
533 oc_mutex_free(g_leCharacteristicMutex);
534 g_leCharacteristicMutex = NULL;
536 oc_mutex_free(g_leReqRespCbMutex);
537 g_leReqRespCbMutex = NULL;
539 oc_mutex_free(g_leServerThreadPoolMutex);
540 g_leServerThreadPoolMutex = NULL;
542 oc_mutex_free(g_LEClientListMutex);
543 g_LEClientListMutex = NULL;
545 OIC_LOG(DEBUG, TAG, "OUT");
548 CAResult_t CAInitLEGattServer()
550 OIC_LOG(DEBUG, TAG, "IN");
552 int ret = bt_gatt_server_initialize();
555 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
556 CALEGetErrorMsg(ret));
557 return CA_STATUS_FAILED;
562 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
563 ret = bt_gatt_server_create(&g_gattServer);
566 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
567 CALEGetErrorMsg(ret));
568 bt_gatt_server_deinitialize();
569 return CA_STATUS_FAILED;
573 OIC_LOG(DEBUG, TAG, "OUT");
577 CAResult_t CADeInitLEGattServer()
579 OIC_LOG(DEBUG, TAG, "IN");
581 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
584 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
585 CALEGetErrorMsg(ret));
586 // CONPRO-1181 continue even bt API fails during DeInit
587 //return CA_STATUS_FAILED;
590 ret = bt_gatt_server_destroy(g_gattServer);
593 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
594 CALEGetErrorMsg(ret));
595 // CONPRO-1181 continue even bt API fails during DeInit
596 //return CA_STATUS_FAILED;
600 ret = bt_gatt_server_deinitialize();
603 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
604 CALEGetErrorMsg(ret));
605 // CONPRO-1181 continue even bt API fails during DeInit
606 //return CA_STATUS_FAILED;
609 OIC_LOG(DEBUG, TAG, "OUT");
613 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
615 OIC_LOG(DEBUG, TAG, "IN");
616 oc_mutex_lock(g_leServerThreadPoolMutex);
617 g_leServerThreadPool = handle;
618 oc_mutex_unlock(g_leServerThreadPoolMutex);
619 OIC_LOG(DEBUG, TAG, "OUT");
622 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
624 OIC_LOG(DEBUG, TAG, "IN");
626 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
628 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
630 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
632 oc_mutex_lock(g_leServiceMutex);
633 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
636 oc_mutex_unlock(g_leServiceMutex);
637 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
638 CALEGetErrorMsg(ret));
639 return CA_STATUS_FAILED;
641 oc_mutex_unlock(g_leServiceMutex);
645 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
648 OIC_LOG(DEBUG, TAG, "OUT");
652 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
653 bt_gatt_server_h server, bt_gatt_h charPath,
654 bool response_needed, int offset, const char *charValue,
655 int charValueLen, void *userData)
657 OIC_LOG(INFO, TAG, "IN - WriteCharCB");
659 if (NULL == charValue || NULL == remoteAddress)
661 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
665 OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
666 charValue, charValueLen);
668 uint8_t *data = OICMalloc(charValueLen);
671 OIC_LOG(ERROR, TAG, "Malloc failed!");
675 memcpy(data, charValue, charValueLen);
677 oc_mutex_lock(g_leReqRespCbMutex);
678 if (NULL == g_leServerDataReceivedCallback)
680 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
681 oc_mutex_unlock(g_leReqRespCbMutex);
686 OIC_LOG(INFO, TAG, "Sending data up !");
687 uint32_t sentLength = 0;
688 g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
690 oc_mutex_unlock(g_leReqRespCbMutex);
693 OIC_LOG_V(INFO, TAG, "response needed flag: %d", response_needed);
696 OIC_LOG(INFO, TAG, "send response to remote client");
697 bt_gatt_server_send_response(request_id,
698 BT_GATT_REQUEST_TYPE_WRITE, offset,
699 BT_ERROR_NONE, NULL, 0);
702 OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
705 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
707 OIC_LOG(DEBUG, TAG, "IN");
709 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
711 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
713 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
716 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
717 CALEGetErrorMsg(ret));
718 return CA_STATUS_FAILED;
721 ret = bt_gatt_server_start();
724 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
725 CALEGetErrorMsg(ret));
726 return CA_STATUS_FAILED;
729 ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
730 CALEGattRemoteCharacteristicWriteCb, NULL);
734 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_write_value_requested_cb failed with ret[%s]",
735 CALEGetErrorMsg(ret));
736 return CA_STATUS_FAILED;
739 OIC_LOG(DEBUG, TAG, "OUT");
743 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
744 const char *charValue, int charValueLen, bool read)
747 OIC_LOG(DEBUG, TAG, "IN");
749 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
753 properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
757 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
760 bt_gatt_h charPath = NULL;
762 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
763 charValueLen, &charPath);
765 if (0 != ret || NULL == charPath)
767 OIC_LOG_V(ERROR, TAG,
768 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
769 return CA_STATUS_FAILED;
772 OIC_LOG_V(DEBUG, TAG,
773 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
777 ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
782 OIC_LOG_V(ERROR, TAG,
783 "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
784 CALEGetErrorMsg(ret));
785 return CA_STATUS_FAILED;
789 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
792 OIC_LOG_V(ERROR, TAG,
793 "bt_gatt_service_add_characteristic failed with ret[%s]",
794 CALEGetErrorMsg(ret));
795 return CA_STATUS_FAILED;
798 oc_mutex_lock(g_leCharacteristicMutex);
802 char desc_value[2] = {1, 0}; // Notification enabled.
803 bt_gatt_h descriptor = NULL;
804 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
805 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
806 desc_value, sizeof(desc_value),
810 oc_mutex_unlock(g_leCharacteristicMutex);
811 OIC_LOG_V(ERROR, TAG,
812 "bt_gatt_descriptor_create failed with ret[%s]",
813 CALEGetErrorMsg(ret));
814 return CA_STATUS_FAILED;
817 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
820 oc_mutex_unlock(g_leCharacteristicMutex);
821 OIC_LOG_V(ERROR, TAG,
822 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
823 CALEGetErrorMsg(ret));
824 return CA_STATUS_FAILED;
827 g_gattReadCharPath = charPath;
831 g_gattWriteCharPath = charPath;
834 oc_mutex_unlock(g_leCharacteristicMutex);
836 OIC_LOG(DEBUG, TAG, "OUT");
840 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
841 uint32_t charValueLen)
843 OIC_LOG(DEBUG, TAG, "IN");
845 VERIFY_NON_NULL(charValue, TAG, "charValue");
846 VERIFY_NON_NULL(address, TAG, "address");
848 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
850 oc_mutex_lock(g_leCharacteristicMutex);
852 if (NULL == g_gattReadCharPath)
854 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
855 oc_mutex_unlock(g_leCharacteristicMutex);
856 return CA_STATUS_FAILED;
859 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
862 OIC_LOG_V(ERROR, TAG,
863 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
864 oc_mutex_unlock(g_leCharacteristicMutex);
865 return CA_STATUS_FAILED;
868 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
869 CALEServerNotificationSentCB,
873 OIC_LOG_V(ERROR, TAG,
874 "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]", CALEGetErrorMsg(ret));
875 oc_mutex_unlock(g_leCharacteristicMutex);
876 return CA_STATUS_FAILED;
879 oc_mutex_unlock(g_leCharacteristicMutex);
881 OIC_LOG(DEBUG, TAG, "OUT");
885 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
887 OIC_LOG(DEBUG, TAG, "IN");
889 VERIFY_NON_NULL(charValue, TAG, "charValue");
891 oc_mutex_lock(g_leCharacteristicMutex);
893 if (NULL == g_gattReadCharPath)
895 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
896 oc_mutex_unlock(g_leCharacteristicMutex);
897 return CA_STATUS_FAILED;
900 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
903 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
904 oc_mutex_unlock(g_leCharacteristicMutex);
905 return CA_STATUS_FAILED;
908 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
909 CALEServerNotificationSentCB,
913 OIC_LOG_V(ERROR, TAG,
914 "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]", CALEGetErrorMsg(ret));
915 oc_mutex_unlock(g_leCharacteristicMutex);
916 return CA_STATUS_FAILED;
919 oc_mutex_unlock(g_leCharacteristicMutex);
921 OIC_LOG(DEBUG, TAG, "OUT");
925 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
927 OIC_LOG(DEBUG, TAG, "IN");
929 oc_mutex_lock(g_leReqRespCbMutex);
930 g_leServerDataReceivedCallback = callback;
931 oc_mutex_unlock(g_leReqRespCbMutex);
933 OIC_LOG(DEBUG, TAG, "OUT");
936 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
938 g_serverErrorCallback = callback;
941 bool CALEServerIsConnected(const char* address)
947 uint16_t CALEServerGetMtuSize(const char* address)
949 OIC_LOG(DEBUG, TAG, "IN");
950 VERIFY_NON_NULL_RET(address, TAG, "address is null",
951 CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE);
953 unsigned int mtu = CA_DEFAULT_BLE_MTU_SIZE;
956 bt_gatt_client_h client = NULL;
957 ret = bt_gatt_client_create(address, &client);
960 OIC_LOG_V(ERROR, TAG,
961 "bt_gatt_client_create failed with return [%s]", CALEGetErrorMsg(ret));
962 return CA_DEFAULT_BLE_MTU_SIZE;
965 ret = bt_gatt_client_get_att_mtu(client, &mtu);
968 OIC_LOG_V(ERROR, TAG,
969 "bt_gatt_client_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
970 return CA_DEFAULT_BLE_MTU_SIZE;
973 ret = bt_gatt_client_destroy(client);
976 OIC_LOG_V(ERROR, TAG,
977 "bt_gatt_client_destroy failed with return [%s]", CALEGetErrorMsg(ret));
978 return CA_DEFAULT_BLE_MTU_SIZE;
981 OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
982 return mtu - CA_BLE_MTU_HEADER_SIZE;