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"
30 #include "caadapterutils.h"
33 * Logging tag for module name
35 #define TAG "OIC_CA_LE_SERVER_VD"
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;
125 * State of connect state
127 static bool g_LEConnectedState = false;
129 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
131 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
133 CAResult_t res = CA_STATUS_OK;
136 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
137 g_LEConnectedState = true;
138 char *addr = OICStrdup(remoteAddress);
139 oc_mutex_lock(g_LEClientListMutex);
140 res = CAAddLEClientInfoToList(&g_LEClientList, addr);
141 if (CA_STATUS_OK != res)
143 OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
144 oc_mutex_unlock(g_LEClientListMutex);
148 oc_mutex_unlock(g_LEClientListMutex);
151 * TV Easysetup does not use IoTivity BLE advertisement.
154 // res = CALEStopAdvertise();
155 // if (CA_STATUS_OK != res)
157 // OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
163 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
164 g_LEConnectedState = false;
165 oc_mutex_lock(g_LEClientListMutex);
166 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
167 oc_mutex_unlock(g_LEClientListMutex);
170 * TV Easysetup does not use IoTivity BLE advertisement.
173 // res = CALEStartAdvertise();
174 // if (CA_STATUS_OK != res)
176 // OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
183 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
184 bt_gatt_h characteristic, bool completed, void *user_data)
186 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
187 bt_gatt_h characteristic, bool completed, void *user_data)
191 (void)characteristic;
195 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
198 CAResult_t CAStartLEGattServer()
200 OIC_LOG(DEBUG, TAG, "IN");
202 oc_mutex_lock(g_leServerStateMutex);
203 if (true == g_isLEGattServerStarted)
205 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
206 oc_mutex_unlock(g_leServerStateMutex);
210 CAResult_t ret = CAInitLEGattServer();
211 if (CA_STATUS_OK != ret)
213 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
214 oc_mutex_unlock(g_leServerStateMutex);
215 CATerminateLEGattServer();
216 return CA_STATUS_FAILED;
219 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
220 if (CA_STATUS_OK != ret)
222 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
223 oc_mutex_unlock(g_leServerStateMutex);
224 CATerminateLEGattServer();
225 return CA_STATUS_FAILED;
228 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
229 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
231 // For Read Characteristics.
232 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
233 sizeof(charReadValue), true);
234 if (CA_STATUS_OK != ret)
236 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
237 oc_mutex_unlock(g_leServerStateMutex);
238 CATerminateLEGattServer();
239 return CA_STATUS_FAILED;
242 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
243 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
246 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
247 sizeof(charWriteValue), false); // For Write Characteristics.
248 if (CA_STATUS_OK != ret )
250 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
251 oc_mutex_unlock(g_leServerStateMutex);
252 CATerminateLEGattServer();
253 return CA_STATUS_FAILED;
256 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
257 if (CA_STATUS_OK != ret )
259 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
260 oc_mutex_unlock(g_leServerStateMutex);
261 CATerminateLEGattServer();
262 return CA_STATUS_FAILED;
266 * TV Easysetup does not use IoTivity BLE advertisement.
269 // ret = CALEStartAdvertise();
270 // if (CA_STATUS_OK != ret)
272 // OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
273 // oc_mutex_unlock(g_leServerStateMutex);
274 // CATerminateLEGattServer();
275 // return CA_STATUS_FAILED;
278 g_isLEGattServerStarted = true;
280 oc_mutex_unlock(g_leServerStateMutex);
282 OIC_LOG(DEBUG, TAG, "OUT");
286 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
293 OIC_LOG(DEBUG, TAG, "IN");
296 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
297 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
298 true, "notifyChar success");
302 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
303 false, "notifyChar failure");
305 OIC_LOG(DEBUG, TAG, "OUT");
308 CAResult_t CALEStartAdvertise()
310 OIC_LOG(DEBUG, TAG, "IN");
312 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
313 if (CA_STATUS_OK != res)
315 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
318 OIC_LOG(DEBUG, TAG, "OUT");
322 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
324 OIC_LOG(DEBUG, TAG, "IN");
326 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
327 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
329 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
330 return CA_STATUS_FAILED;
333 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
334 BT_ADAPTER_LE_PACKET_ADVERTISING,
336 if (BT_ERROR_NONE != res)
338 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
339 CALEGetErrorMsg(res));
340 return CA_STATUS_FAILED;
343 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
344 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
345 if (BT_ERROR_NONE != res)
347 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
348 CALEGetErrorMsg(res));
349 return CA_STATUS_FAILED;
352 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
353 if (BT_ERROR_NONE != res)
355 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
356 CALEGetErrorMsg(res));
357 return CA_STATUS_FAILED;
360 OIC_LOG(DEBUG, TAG, "OUT");
364 CAResult_t CALEStopAdvertise()
366 OIC_LOG(DEBUG, TAG, "IN");
367 if (NULL != g_hAdvertiser)
369 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
372 OIC_LOG_V(ERROR, TAG,
373 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
376 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
379 OIC_LOG_V(ERROR, TAG,
380 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
382 g_hAdvertiser = NULL;
386 OIC_LOG(ERROR, TAG, "Advertising is not running");
387 return CA_STATUS_FAILED;
390 OIC_LOG(DEBUG, TAG, "OUT");
394 CAResult_t CAStopLEGattServer()
396 OIC_LOG(DEBUG, TAG, "IN");
398 oc_mutex_lock(g_leServerStateMutex);
400 if (false == g_isLEGattServerStarted)
402 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
403 oc_mutex_unlock(g_leServerStateMutex);
407 g_isLEGattServerStarted = false;
409 oc_mutex_lock(g_LEClientListMutex);
410 CADisconnectAllClient(g_LEClientList);
411 g_LEClientList = NULL;
412 oc_mutex_unlock(g_LEClientListMutex);
415 * TV Easysetup does not use IoTivity BLE advertisement.
418 // CAResult_t res = CALEStopAdvertise();
420 // OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
423 CAResult_t res = CADeInitLEGattServer();
424 if (CA_STATUS_OK != res)
426 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
429 GMainContext *context_event_loop = NULL;
430 // Required for waking up the thread which is running in gmain loop
431 if (NULL != g_eventLoop)
433 context_event_loop = g_main_loop_get_context(g_eventLoop);
435 if (context_event_loop)
437 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %p", (void *)context_event_loop);
438 g_main_context_wakeup(context_event_loop);
440 // Kill g main loops and kill threads
441 g_main_loop_quit(g_eventLoop);
447 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
450 oc_mutex_unlock(g_leServerStateMutex);
452 OIC_LOG(DEBUG, TAG, "OUT");
456 CAResult_t CAInitializeLEGattServer()
458 OIC_LOG(DEBUG, TAG, "IN");
460 CAResult_t ret = CAInitGattServerMutexVariables();
461 if (CA_STATUS_OK != ret )
463 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
464 CATerminateGattServerMutexVariables();
465 return CA_SERVER_NOT_STARTED;
467 OIC_LOG(DEBUG, TAG, "OUT");
471 void CATerminateLEGattServer()
473 OIC_LOG(DEBUG, TAG, "IN");
475 // Service and characteristics path will be freed by the platform.
476 oc_mutex_lock(g_leServiceMutex);
477 g_gattSvcPath = NULL;
478 oc_mutex_unlock(g_leServiceMutex);
480 oc_mutex_lock(g_leCharacteristicMutex);
481 g_gattReadCharPath = NULL;
482 g_gattWriteCharPath = NULL;
483 oc_mutex_unlock(g_leCharacteristicMutex);
485 oc_mutex_lock(g_leServerThreadPoolMutex);
486 g_leServerThreadPool = NULL;
487 oc_mutex_unlock(g_leServerThreadPoolMutex);
489 // Terminating all mutex variables.
490 CATerminateGattServerMutexVariables();
491 OIC_LOG(DEBUG, TAG, "OUT");
494 CAResult_t CAInitGattServerMutexVariables()
496 OIC_LOG(DEBUG, TAG, "IN");
497 if (NULL == g_leServerStateMutex)
499 g_leServerStateMutex = oc_mutex_new();
500 if (NULL == g_leServerStateMutex)
502 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
503 return CA_STATUS_FAILED;
507 if (NULL == g_leServiceMutex)
509 g_leServiceMutex = oc_mutex_new();
510 if (NULL == g_leServiceMutex)
512 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
513 return CA_STATUS_FAILED;
517 if (NULL == g_leCharacteristicMutex)
519 g_leCharacteristicMutex = oc_mutex_new();
520 if (NULL == g_leCharacteristicMutex)
522 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
523 return CA_STATUS_FAILED;
527 if (NULL == g_leReqRespCbMutex)
529 g_leReqRespCbMutex = oc_mutex_new();
530 if (NULL == g_leReqRespCbMutex)
532 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
533 return CA_STATUS_FAILED;
537 if (NULL == g_leServerThreadPoolMutex)
539 g_leServerThreadPoolMutex = oc_mutex_new();
540 if (NULL == g_leServerThreadPoolMutex)
542 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
543 return CA_STATUS_FAILED;
547 if (NULL == g_LEClientListMutex)
549 g_LEClientListMutex = oc_mutex_new();
550 if (NULL == g_LEClientListMutex)
552 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
553 return CA_STATUS_FAILED;
557 OIC_LOG(DEBUG, TAG, "OUT");
561 void CATerminateGattServerMutexVariables()
563 OIC_LOG(DEBUG, TAG, "IN");
564 oc_mutex_free(g_leServerStateMutex);
565 g_leServerStateMutex = NULL;
567 oc_mutex_free(g_leServiceMutex);
568 g_leServiceMutex = NULL;
570 oc_mutex_free(g_leCharacteristicMutex);
571 g_leCharacteristicMutex = NULL;
573 oc_mutex_free(g_leReqRespCbMutex);
574 g_leReqRespCbMutex = NULL;
576 oc_mutex_free(g_leServerThreadPoolMutex);
577 g_leServerThreadPoolMutex = NULL;
579 oc_mutex_free(g_LEClientListMutex);
580 g_LEClientListMutex = NULL;
582 OIC_LOG(DEBUG, TAG, "OUT");
585 CAResult_t CAInitLEGattServer()
587 OIC_LOG(DEBUG, TAG, "IN");
589 int ret = bt_gatt_server_initialize();
592 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
593 CALEGetErrorMsg(ret));
594 return CA_STATUS_FAILED;
599 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
600 ret = bt_gatt_server_create(&g_gattServer);
603 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
604 CALEGetErrorMsg(ret));
605 return CA_STATUS_FAILED;
609 OIC_LOG(DEBUG, TAG, "OUT");
613 CAResult_t CADeInitLEGattServer()
615 OIC_LOG(DEBUG, TAG, "IN");
617 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
620 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
621 CALEGetErrorMsg(ret));
622 return CA_STATUS_FAILED;
625 ret = bt_gatt_server_destroy(g_gattServer);
628 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
629 CALEGetErrorMsg(ret));
630 return CA_STATUS_FAILED;
634 ret = bt_gatt_server_deinitialize();
637 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
638 CALEGetErrorMsg(ret));
639 return CA_STATUS_FAILED;
642 OIC_LOG(DEBUG, TAG, "OUT");
646 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
648 OIC_LOG(DEBUG, TAG, "IN");
649 oc_mutex_lock(g_leServerThreadPoolMutex);
650 g_leServerThreadPool = handle;
651 oc_mutex_unlock(g_leServerThreadPoolMutex);
652 OIC_LOG(DEBUG, TAG, "OUT");
655 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
657 OIC_LOG(DEBUG, TAG, "IN");
659 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
661 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
663 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
665 oc_mutex_lock(g_leServiceMutex);
666 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
669 oc_mutex_unlock(g_leServiceMutex);
670 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
671 CALEGetErrorMsg(ret));
672 return CA_STATUS_FAILED;
674 oc_mutex_unlock(g_leServiceMutex);
678 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
681 OIC_LOG(DEBUG, TAG, "OUT");
686 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
687 bt_gatt_server_h server, bt_gatt_h gatt_handle,
688 bool response_needed, int offset, const char *charValue,
689 int charLen, void *userData)
691 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
692 bt_gatt_h gatt_handle, int offset, char *charValue,
693 int charLen, void *userData)
700 OIC_LOG(INFO, TAG, "IN - WriteCharCB");
702 if (NULL == charValue || NULL == remoteAddress)
704 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
708 OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
710 uint8_t *data = OICMalloc(charLen);
713 OIC_LOG(ERROR, TAG, "Malloc failed!");
717 memcpy(data, charValue, charLen);
719 oc_mutex_lock(g_leReqRespCbMutex);
720 if (NULL == g_leServerDataReceivedCallback)
722 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
723 oc_mutex_unlock(g_leReqRespCbMutex);
728 OIC_LOG(INFO, TAG, "Sending data up !");
729 uint32_t sentLength = 0;
730 g_leServerDataReceivedCallback(remoteAddress, data, charLen,
732 oc_mutex_unlock(g_leReqRespCbMutex);
737 OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
740 OIC_LOG(INFO, TAG, "send response to remote client");
741 bt_gatt_server_send_response(request_id,
742 BT_GATT_REQUEST_TYPE_WRITE, offset,
743 BT_ERROR_NONE, NULL, 0);
747 OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
750 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
752 OIC_LOG(DEBUG, TAG, "IN");
754 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
756 OIC_LOG_V(DEBUG, TAG, "svcPath: %s", (char *)svcPath);
758 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
761 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
762 CALEGetErrorMsg(ret));
763 return CA_STATUS_FAILED;
767 ret = bt_gatt_server_start();
770 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
771 CALEGetErrorMsg(ret));
772 return CA_STATUS_FAILED;
777 ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
779 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
781 CALEGattRemoteCharacteristicWriteCb, NULL);
785 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
786 CALEGetErrorMsg(ret));
787 return CA_STATUS_FAILED;
790 OIC_LOG(DEBUG, TAG, "OUT");
794 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
795 const char *charValue, int charValueLen, bool read)
798 OIC_LOG(DEBUG, TAG, "IN");
800 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
804 properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
808 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
811 bt_gatt_h charPath = NULL;
813 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
814 charValueLen, &charPath);
816 if (0 != ret || NULL == charPath)
818 OIC_LOG_V(ERROR, TAG,
819 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
820 return CA_STATUS_FAILED;
823 OIC_LOG_V(DEBUG, TAG,
824 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
829 ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
833 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
837 OIC_LOG_V(ERROR, TAG,
839 "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
841 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
843 CALEGetErrorMsg(ret));
844 return CA_STATUS_FAILED;
848 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
851 OIC_LOG_V(ERROR, TAG,
852 "bt_gatt_service_add_characteristic failed with ret[%s]",
853 CALEGetErrorMsg(ret));
854 return CA_STATUS_FAILED;
857 oc_mutex_lock(g_leCharacteristicMutex);
861 g_gattReadCharPath = charPath;
865 char desc_value[2] = {0, 0}; // Notification enabled.
866 bt_gatt_h descriptor = NULL;
867 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
868 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
869 desc_value, sizeof(desc_value),
873 oc_mutex_unlock(g_leCharacteristicMutex);
874 OIC_LOG_V(ERROR, TAG,
875 "bt_gatt_descriptor_create failed with ret[%s]",
876 CALEGetErrorMsg(ret));
877 return CA_STATUS_FAILED;
880 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
883 oc_mutex_unlock(g_leCharacteristicMutex);
884 OIC_LOG_V(ERROR, TAG,
885 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
886 CALEGetErrorMsg(ret));
887 return CA_STATUS_FAILED;
889 g_gattWriteCharPath = charPath;
892 oc_mutex_unlock(g_leCharacteristicMutex);
894 OIC_LOG(DEBUG, TAG, "OUT");
898 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
899 uint32_t charValueLen)
901 OIC_LOG(DEBUG, TAG, "IN");
903 VERIFY_NON_NULL(charValue, TAG, "charValue");
904 VERIFY_NON_NULL(address, TAG, "address");
906 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
908 oc_mutex_lock(g_leCharacteristicMutex);
910 if (!g_LEConnectedState)
912 OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
913 oc_mutex_unlock(g_leCharacteristicMutex);
914 return CA_STATUS_FAILED;
917 if (NULL == g_gattReadCharPath)
919 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
920 oc_mutex_unlock(g_leCharacteristicMutex);
921 return CA_STATUS_FAILED;
924 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
927 OIC_LOG_V(ERROR, TAG,
928 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
929 oc_mutex_unlock(g_leCharacteristicMutex);
930 return CA_STATUS_FAILED;
934 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
935 CALEServerNotificationSentCB,
938 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
944 OIC_LOG_V(ERROR, TAG,
946 "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
948 "bt_gatt_server_notify failed with return [%s]",
950 CALEGetErrorMsg(ret));
951 oc_mutex_unlock(g_leCharacteristicMutex);
952 return CA_STATUS_FAILED;
955 oc_mutex_unlock(g_leCharacteristicMutex);
957 OIC_LOG(DEBUG, TAG, "OUT");
961 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
963 OIC_LOG(DEBUG, TAG, "IN");
965 VERIFY_NON_NULL(charValue, TAG, "charValue");
967 oc_mutex_lock(g_leCharacteristicMutex);
969 if (!g_LEConnectedState)
971 OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
972 oc_mutex_unlock(g_leCharacteristicMutex);
973 return CA_STATUS_FAILED;
976 if (NULL == g_gattReadCharPath)
978 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
979 oc_mutex_unlock(g_leCharacteristicMutex);
980 return CA_STATUS_FAILED;
983 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
986 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
987 oc_mutex_unlock(g_leCharacteristicMutex);
988 return CA_STATUS_FAILED;
992 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
993 CALEServerNotificationSentCB,
996 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1001 OIC_LOG_V(ERROR, TAG,
1003 "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
1005 "bt_gatt_server_notify failed with return[%s]",
1007 CALEGetErrorMsg(ret));
1008 oc_mutex_unlock(g_leCharacteristicMutex);
1009 return CA_STATUS_FAILED;
1012 oc_mutex_unlock(g_leCharacteristicMutex);
1014 OIC_LOG(DEBUG, TAG, "OUT");
1015 return CA_STATUS_OK;
1018 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1020 OIC_LOG(DEBUG, TAG, "IN");
1022 oc_mutex_lock(g_leReqRespCbMutex);
1023 g_leServerDataReceivedCallback = callback;
1024 oc_mutex_unlock(g_leReqRespCbMutex);
1026 OIC_LOG(DEBUG, TAG, "OUT");
1029 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1031 g_serverErrorCallback = callback;
1034 bool CALEServerIsConnected(const char* address)
1041 uint16_t CALEServerGetMtuSize(const char* address)
1043 OIC_LOG(DEBUG, TAG, "IN");
1044 VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1047 int ret = bt_device_get_att_mtu(address, &mtu);
1050 OIC_LOG_V(ERROR, TAG,
1051 "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1052 return CA_DEFAULT_BLE_MTU_SIZE;
1054 OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1055 OIC_LOG(DEBUG, TAG, "OUT");
1056 return mtu - CA_BLE_MTU_HEADER_SIZE;