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_VD"
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 = NULL;
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 oc_mutex g_leServerStateMutex = NULL;
87 * Mutex to synchronize writing operations on the characteristics.
89 static oc_mutex g_leCharacteristicMutex = NULL;
92 * Mutex to synchronize to creation of OIC service.
94 static oc_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 oc_mutex g_leReqRespCbMutex = NULL;
103 * Mutex to synchronize the task to be pushed to thread pool.
105 static oc_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;
118 * This contains the list of OIC clients connected to the server.
120 static LEClientInfoList *g_LEClientList = NULL;
123 * Mutex to synchronize access to LE ClientList.
125 static oc_mutex g_LEClientListMutex = NULL;
128 * State of connect state
130 static bool g_LEConnectedState = false;
132 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
134 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
136 CAResult_t res = CA_STATUS_OK;
139 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
140 g_LEConnectedState = true;
141 char *addr = OICStrdup(remoteAddress);
142 oc_mutex_lock(g_LEClientListMutex);
143 res = CAAddLEClientInfoToList(&g_LEClientList, addr);
144 if (CA_STATUS_OK != res)
146 OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
147 oc_mutex_unlock(g_LEClientListMutex);
151 oc_mutex_unlock(g_LEClientListMutex);
154 * TV Easysetup does not use IoTivity BLE advertisement.
157 // res = CALEStopAdvertise();
158 // if (CA_STATUS_OK != res)
160 // OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
166 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
167 g_LEConnectedState = false;
168 oc_mutex_lock(g_LEClientListMutex);
169 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
170 oc_mutex_unlock(g_LEClientListMutex);
173 * TV Easysetup does not use IoTivity BLE advertisement.
176 // res = CALEStartAdvertise();
177 // if (CA_STATUS_OK != res)
179 // OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
186 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
187 bt_gatt_h characteristic, bool completed, void *user_data)
189 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
190 bt_gatt_h characteristic, bool completed, void *user_data)
193 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
196 CAResult_t CAStartLEGattServer()
198 OIC_LOG(DEBUG, TAG, "IN");
200 oc_mutex_lock(g_leServerStateMutex);
201 if (true == g_isLEGattServerStarted)
203 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
204 oc_mutex_unlock(g_leServerStateMutex);
208 CAResult_t ret = CAInitLEGattServer();
209 if (CA_STATUS_OK != ret)
211 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
212 oc_mutex_unlock(g_leServerStateMutex);
213 CATerminateLEGattServer();
214 return CA_STATUS_FAILED;
217 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
218 if (CA_STATUS_OK != ret)
220 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
221 oc_mutex_unlock(g_leServerStateMutex);
222 CATerminateLEGattServer();
223 return CA_STATUS_FAILED;
226 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
227 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
229 // For Read Characteristics.
230 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
231 CA_LE_INITIAL_BUF_SIZE, true);
232 if (CA_STATUS_OK != ret)
234 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
235 oc_mutex_unlock(g_leServerStateMutex);
236 CATerminateLEGattServer();
237 return CA_STATUS_FAILED;
240 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
241 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
244 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
245 CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
246 if (CA_STATUS_OK != ret )
248 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
249 oc_mutex_unlock(g_leServerStateMutex);
250 CATerminateLEGattServer();
251 return CA_STATUS_FAILED;
254 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
255 if (CA_STATUS_OK != ret )
257 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
258 oc_mutex_unlock(g_leServerStateMutex);
259 CATerminateLEGattServer();
260 return CA_STATUS_FAILED;
264 * TV Easysetup does not use IoTivity BLE advertisement.
267 // ret = CALEStartAdvertise();
268 // if (CA_STATUS_OK != ret)
270 // OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
271 // oc_mutex_unlock(g_leServerStateMutex);
272 // CATerminateLEGattServer();
273 // return CA_STATUS_FAILED;
276 g_isLEGattServerStarted = true;
278 oc_mutex_unlock(g_leServerStateMutex);
280 OIC_LOG(DEBUG, TAG, "OUT");
284 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
287 OIC_LOG(DEBUG, TAG, "IN");
290 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
291 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
292 true, "notifyChar success");
296 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
297 false, "notifyChar failure");
299 OIC_LOG(DEBUG, TAG, "OUT");
302 CAResult_t CALEStartAdvertise()
304 OIC_LOG(DEBUG, TAG, "IN");
306 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
307 if (CA_STATUS_OK != res)
309 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
312 OIC_LOG(DEBUG, TAG, "OUT");
316 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
318 OIC_LOG(DEBUG, TAG, "IN");
320 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
321 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
323 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
324 return CA_STATUS_FAILED;
327 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
328 BT_ADAPTER_LE_PACKET_ADVERTISING,
330 if (BT_ERROR_NONE != res)
332 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
333 CALEGetErrorMsg(res));
334 return CA_STATUS_FAILED;
337 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
338 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
339 if (BT_ERROR_NONE != res)
341 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
342 CALEGetErrorMsg(res));
343 return CA_STATUS_FAILED;
346 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
347 if (BT_ERROR_NONE != res)
349 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
350 CALEGetErrorMsg(res));
351 return CA_STATUS_FAILED;
354 OIC_LOG(DEBUG, TAG, "OUT");
358 CAResult_t CALEStopAdvertise()
360 OIC_LOG(DEBUG, TAG, "IN");
361 if (NULL != g_hAdvertiser)
363 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
366 OIC_LOG_V(ERROR, TAG,
367 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
370 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
373 OIC_LOG_V(ERROR, TAG,
374 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
376 g_hAdvertiser = NULL;
380 OIC_LOG(ERROR, TAG, "Advertising is not running");
381 return CA_STATUS_FAILED;
384 OIC_LOG(DEBUG, TAG, "OUT");
388 CAResult_t CAStopLEGattServer()
390 OIC_LOG(DEBUG, TAG, "IN");
392 oc_mutex_lock(g_leServerStateMutex);
394 if (false == g_isLEGattServerStarted)
396 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
397 oc_mutex_unlock(g_leServerStateMutex);
401 g_isLEGattServerStarted = false;
403 oc_mutex_lock(g_LEClientListMutex);
404 CADisconnectAllClient(g_LEClientList);
405 g_LEClientList = NULL;
406 oc_mutex_unlock(g_LEClientListMutex);
409 * TV Easysetup does not use IoTivity BLE advertisement.
412 // CAResult_t res = CALEStopAdvertise();
414 // OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
417 CAResult_t res = CADeInitLEGattServer();
418 if (CA_STATUS_OK != res)
420 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
423 GMainContext *context_event_loop = NULL;
424 // Required for waking up the thread which is running in gmain loop
425 if (NULL != g_eventLoop)
427 context_event_loop = g_main_loop_get_context(g_eventLoop);
429 if (context_event_loop)
431 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
432 g_main_context_wakeup(context_event_loop);
434 // Kill g main loops and kill threads
435 g_main_loop_quit(g_eventLoop);
441 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
444 oc_mutex_unlock(g_leServerStateMutex);
446 OIC_LOG(DEBUG, TAG, "OUT");
450 CAResult_t CAInitializeLEGattServer()
452 OIC_LOG(DEBUG, TAG, "IN");
454 CAResult_t ret = CAInitGattServerMutexVariables();
455 if (CA_STATUS_OK != ret )
457 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
458 CATerminateGattServerMutexVariables();
459 return CA_SERVER_NOT_STARTED;
461 OIC_LOG(DEBUG, TAG, "OUT");
465 void CATerminateLEGattServer()
467 OIC_LOG(DEBUG, TAG, "IN");
469 // Service and characteristics path will be freed by the platform.
470 oc_mutex_lock(g_leServiceMutex);
471 g_gattSvcPath = NULL;
472 oc_mutex_unlock(g_leServiceMutex);
474 oc_mutex_lock(g_leCharacteristicMutex);
475 g_gattReadCharPath = NULL;
476 g_gattWriteCharPath = NULL;
477 oc_mutex_unlock(g_leCharacteristicMutex);
479 oc_mutex_lock(g_leServerThreadPoolMutex);
480 g_leServerThreadPool = NULL;
481 oc_mutex_unlock(g_leServerThreadPoolMutex);
483 // Terminating all mutex variables.
484 CATerminateGattServerMutexVariables();
485 OIC_LOG(DEBUG, TAG, "OUT");
488 CAResult_t CAInitGattServerMutexVariables()
490 OIC_LOG(DEBUG, TAG, "IN");
491 if (NULL == g_leServerStateMutex)
493 g_leServerStateMutex = oc_mutex_new();
494 if (NULL == g_leServerStateMutex)
496 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
497 return CA_STATUS_FAILED;
501 if (NULL == g_leServiceMutex)
503 g_leServiceMutex = oc_mutex_new();
504 if (NULL == g_leServiceMutex)
506 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
507 return CA_STATUS_FAILED;
511 if (NULL == g_leCharacteristicMutex)
513 g_leCharacteristicMutex = oc_mutex_new();
514 if (NULL == g_leCharacteristicMutex)
516 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
517 return CA_STATUS_FAILED;
521 if (NULL == g_leReqRespCbMutex)
523 g_leReqRespCbMutex = oc_mutex_new();
524 if (NULL == g_leReqRespCbMutex)
526 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
527 return CA_STATUS_FAILED;
531 if (NULL == g_leServerThreadPoolMutex)
533 g_leServerThreadPoolMutex = oc_mutex_new();
534 if (NULL == g_leServerThreadPoolMutex)
536 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
537 return CA_STATUS_FAILED;
541 if (NULL == g_LEClientListMutex)
543 g_LEClientListMutex = oc_mutex_new();
544 if (NULL == g_LEClientListMutex)
546 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
547 return CA_STATUS_FAILED;
551 OIC_LOG(DEBUG, TAG, "OUT");
555 void CATerminateGattServerMutexVariables()
557 OIC_LOG(DEBUG, TAG, "IN");
558 oc_mutex_free(g_leServerStateMutex);
559 g_leServerStateMutex = NULL;
561 oc_mutex_free(g_leServiceMutex);
562 g_leServiceMutex = NULL;
564 oc_mutex_free(g_leCharacteristicMutex);
565 g_leCharacteristicMutex = NULL;
567 oc_mutex_free(g_leReqRespCbMutex);
568 g_leReqRespCbMutex = NULL;
570 oc_mutex_free(g_leServerThreadPoolMutex);
571 g_leServerThreadPoolMutex = NULL;
573 oc_mutex_free(g_LEClientListMutex);
574 g_LEClientListMutex = NULL;
576 OIC_LOG(DEBUG, TAG, "OUT");
579 CAResult_t CAInitLEGattServer()
581 OIC_LOG(DEBUG, TAG, "IN");
583 int ret = bt_gatt_server_initialize();
586 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
587 CALEGetErrorMsg(ret));
588 return CA_STATUS_FAILED;
593 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
594 ret = bt_gatt_server_create(&g_gattServer);
597 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
598 CALEGetErrorMsg(ret));
599 return CA_STATUS_FAILED;
603 OIC_LOG(DEBUG, TAG, "OUT");
607 CAResult_t CADeInitLEGattServer()
609 OIC_LOG(DEBUG, TAG, "IN");
611 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
614 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
615 CALEGetErrorMsg(ret));
616 return CA_STATUS_FAILED;
619 ret = bt_gatt_server_destroy(g_gattServer);
622 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
623 CALEGetErrorMsg(ret));
624 return CA_STATUS_FAILED;
628 ret = bt_gatt_server_deinitialize();
631 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
632 CALEGetErrorMsg(ret));
633 return CA_STATUS_FAILED;
636 OIC_LOG(DEBUG, TAG, "OUT");
640 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
642 OIC_LOG(DEBUG, TAG, "IN");
643 oc_mutex_lock(g_leServerThreadPoolMutex);
644 g_leServerThreadPool = handle;
645 oc_mutex_unlock(g_leServerThreadPoolMutex);
646 OIC_LOG(DEBUG, TAG, "OUT");
649 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
651 OIC_LOG(DEBUG, TAG, "IN");
653 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
655 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
657 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
659 oc_mutex_lock(g_leServiceMutex);
660 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
663 oc_mutex_unlock(g_leServiceMutex);
664 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
665 CALEGetErrorMsg(ret));
666 return CA_STATUS_FAILED;
668 oc_mutex_unlock(g_leServiceMutex);
672 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
675 OIC_LOG(DEBUG, TAG, "OUT");
680 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
681 bt_gatt_server_h server, bt_gatt_h gatt_handle,
682 bool response_needed, int offset, const char *charValue,
683 int charLen, void *userData)
685 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
686 bt_gatt_h gatt_handle, int offset, char *charValue,
687 int charLen, void *userData)
690 OIC_LOG(INFO, TAG, "IN - WriteCharCB");
692 if (NULL == charValue || NULL == remoteAddress)
694 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
698 OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
700 uint8_t *data = OICMalloc(charLen);
703 OIC_LOG(ERROR, TAG, "Malloc failed!");
707 memcpy(data, charValue, charLen);
709 oc_mutex_lock(g_leReqRespCbMutex);
710 if (NULL == g_leServerDataReceivedCallback)
712 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
713 oc_mutex_unlock(g_leReqRespCbMutex);
718 OIC_LOG(INFO, TAG, "Sending data up !");
719 uint32_t sentLength = 0;
720 g_leServerDataReceivedCallback(remoteAddress, data, charLen,
722 oc_mutex_unlock(g_leReqRespCbMutex);
727 OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
730 OIC_LOG(INFO, TAG, "send response to remote client");
731 bt_gatt_server_send_response(request_id,
732 BT_GATT_REQUEST_TYPE_WRITE, offset,
733 BT_ERROR_NONE, NULL, 0);
737 OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
740 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
742 OIC_LOG(DEBUG, TAG, "IN");
744 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
746 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
748 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
751 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
752 CALEGetErrorMsg(ret));
753 return CA_STATUS_FAILED;
757 ret = bt_gatt_server_start();
760 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
761 CALEGetErrorMsg(ret));
762 return CA_STATUS_FAILED;
767 ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
769 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
771 CALEGattRemoteCharacteristicWriteCb, NULL);
775 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
776 CALEGetErrorMsg(ret));
777 return CA_STATUS_FAILED;
780 OIC_LOG(DEBUG, TAG, "OUT");
784 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
785 const char *charValue, int charValueLen, bool read)
788 OIC_LOG(DEBUG, TAG, "IN");
790 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
794 properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
798 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
801 bt_gatt_h charPath = NULL;
803 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
804 charValueLen, &charPath);
806 if (0 != ret || NULL == charPath)
808 OIC_LOG_V(ERROR, TAG,
809 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
810 return CA_STATUS_FAILED;
813 OIC_LOG_V(DEBUG, TAG,
814 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
819 ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
823 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
827 OIC_LOG_V(ERROR, TAG,
829 "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
831 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
833 CALEGetErrorMsg(ret));
834 return CA_STATUS_FAILED;
838 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
841 OIC_LOG_V(ERROR, TAG,
842 "bt_gatt_service_add_characteristic failed with ret[%s]",
843 CALEGetErrorMsg(ret));
844 return CA_STATUS_FAILED;
847 oc_mutex_lock(g_leCharacteristicMutex);
851 g_gattReadCharPath = charPath;
855 char desc_value[2] = {0, 0}; // Notification enabled.
856 bt_gatt_h descriptor = NULL;
857 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
858 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
859 desc_value, sizeof(desc_value),
863 oc_mutex_unlock(g_leCharacteristicMutex);
864 OIC_LOG_V(ERROR, TAG,
865 "bt_gatt_descriptor_create failed with ret[%s]",
866 CALEGetErrorMsg(ret));
867 return CA_STATUS_FAILED;
870 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
873 oc_mutex_unlock(g_leCharacteristicMutex);
874 OIC_LOG_V(ERROR, TAG,
875 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
876 CALEGetErrorMsg(ret));
877 return CA_STATUS_FAILED;
879 g_gattWriteCharPath = charPath;
882 oc_mutex_unlock(g_leCharacteristicMutex);
884 OIC_LOG(DEBUG, TAG, "OUT");
888 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
889 uint32_t charValueLen)
891 OIC_LOG(DEBUG, TAG, "IN");
893 VERIFY_NON_NULL(charValue, TAG, "charValue");
894 VERIFY_NON_NULL(address, TAG, "address");
896 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
898 oc_mutex_lock(g_leCharacteristicMutex);
900 if (!g_LEConnectedState)
902 OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
903 oc_mutex_unlock(g_leCharacteristicMutex);
904 return CA_STATUS_FAILED;
907 if (NULL == g_gattReadCharPath)
909 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
910 oc_mutex_unlock(g_leCharacteristicMutex);
911 return CA_STATUS_FAILED;
914 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
917 OIC_LOG_V(ERROR, TAG,
918 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
919 oc_mutex_unlock(g_leCharacteristicMutex);
920 return CA_STATUS_FAILED;
924 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
925 CALEServerNotificationSentCB,
928 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
934 OIC_LOG_V(ERROR, TAG,
936 "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
938 "bt_gatt_server_notify failed with return [%s]",
940 CALEGetErrorMsg(ret));
941 oc_mutex_unlock(g_leCharacteristicMutex);
942 return CA_STATUS_FAILED;
945 oc_mutex_unlock(g_leCharacteristicMutex);
947 OIC_LOG(DEBUG, TAG, "OUT");
951 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
953 OIC_LOG(DEBUG, TAG, "IN");
955 VERIFY_NON_NULL(charValue, TAG, "charValue");
957 oc_mutex_lock(g_leCharacteristicMutex);
959 if (!g_LEConnectedState)
961 OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
962 oc_mutex_unlock(g_leCharacteristicMutex);
963 return CA_STATUS_FAILED;
966 if (NULL == g_gattReadCharPath)
968 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
969 oc_mutex_unlock(g_leCharacteristicMutex);
970 return CA_STATUS_FAILED;
973 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
976 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
977 oc_mutex_unlock(g_leCharacteristicMutex);
978 return CA_STATUS_FAILED;
982 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
983 CALEServerNotificationSentCB,
986 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
991 OIC_LOG_V(ERROR, TAG,
993 "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
995 "bt_gatt_server_notify failed with return[%s]",
997 CALEGetErrorMsg(ret));
998 oc_mutex_unlock(g_leCharacteristicMutex);
999 return CA_STATUS_FAILED;
1002 oc_mutex_unlock(g_leCharacteristicMutex);
1004 OIC_LOG(DEBUG, TAG, "OUT");
1005 return CA_STATUS_OK;
1008 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1010 OIC_LOG(DEBUG, TAG, "IN");
1012 oc_mutex_lock(g_leReqRespCbMutex);
1013 g_leServerDataReceivedCallback = callback;
1014 oc_mutex_unlock(g_leReqRespCbMutex);
1016 OIC_LOG(DEBUG, TAG, "OUT");
1019 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1021 g_serverErrorCallback = callback;
1024 bool CALEServerIsConnected(const char* address)
1030 uint16_t CALEServerGetMtuSize(const char* address)
1032 OIC_LOG(DEBUG, TAG, "IN");
1033 VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1036 int ret = bt_device_get_att_mtu(address, &mtu);
1039 OIC_LOG_V(ERROR, TAG,
1040 "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1041 return CA_DEFAULT_BLE_MTU_SIZE;
1043 OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1044 OIC_LOG(DEBUG, TAG, "OUT");
1045 return mtu - CA_BLE_MTU_HEADER_SIZE;