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"
37 * The handle of the OIC server.
39 static bt_gatt_server_h g_gattServer = NULL;
42 * The handle of the OIC service.
44 static bt_gatt_h g_gattSvcPath = NULL;
47 * The handle of the OIC read characteristics.
49 static bt_gatt_h g_gattReadCharPath = NULL;
52 * The handle of the OIC write characteristics.
54 static bt_gatt_h g_gattWriteCharPath = NULL;
57 * The handle to control Bluetooth LE advertising.
59 static bt_advertiser_h g_hAdvertiser = NULL;
62 * Callback register with LE adapter. This callback is called on reception of any
63 * data from the remote device.
65 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
68 * Callback to notify any error in LE adapter.
70 static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
73 * To keep the state of GATT server if started or not.
75 static bool g_isLEGattServerStarted = false;
78 * Mutex to synchronize the calls to start and stop server.
80 static oc_mutex g_leServerStateMutex = NULL;
83 * Mutex to synchronize writing operations on the characteristics.
85 static oc_mutex g_leCharacteristicMutex = NULL;
88 * Mutex to synchronize to creation of OIC service.
90 static oc_mutex g_leServiceMutex = NULL;
93 * Mutex to synchronize access to the requestResponse callback to be called
94 * when the data needs to be sent from GATTClient.
96 static oc_mutex g_leReqRespCbMutex = NULL;
99 * Mutex to synchronize the task to be pushed to thread pool.
101 static oc_mutex g_leServerThreadPoolMutex = NULL;
104 * Reference to threadpool.
106 static ca_thread_pool_t g_leServerThreadPool = NULL;
109 * GmainLoop to manage the threads to receive the callback from the platfrom.
111 static GMainLoop *g_eventLoop = NULL;
114 * This contains the list of OIC clients connected to the server.
116 static LEClientInfoList *g_LEClientList = NULL;
119 * Mutex to synchronize access to LE ClientList.
121 static oc_mutex g_LEClientListMutex = NULL;
124 * State of connect state
126 static bool g_LEConnectedState = false;
128 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
130 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
132 CAResult_t res = CA_STATUS_OK;
135 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
136 g_LEConnectedState = true;
137 char *addr = OICStrdup(remoteAddress);
138 oc_mutex_lock(g_LEClientListMutex);
139 res = CAAddLEClientInfoToList(&g_LEClientList, addr);
140 if (CA_STATUS_OK != res)
142 OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
143 oc_mutex_unlock(g_LEClientListMutex);
147 oc_mutex_unlock(g_LEClientListMutex);
150 * TV Easysetup does not use IoTivity BLE advertisement.
153 // res = CALEStopAdvertise();
154 // if (CA_STATUS_OK != res)
156 // OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
162 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
163 g_LEConnectedState = false;
164 oc_mutex_lock(g_LEClientListMutex);
165 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
166 oc_mutex_unlock(g_LEClientListMutex);
169 * TV Easysetup does not use IoTivity BLE advertisement.
172 // res = CALEStartAdvertise();
173 // if (CA_STATUS_OK != res)
175 // OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
182 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
183 bt_gatt_h characteristic, bool completed, void *user_data)
185 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
186 bt_gatt_h characteristic, bool completed, void *user_data)
190 (void)characteristic;
194 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
197 CAResult_t CAStartLEGattServer()
199 OIC_LOG(DEBUG, TAG, "IN");
201 oc_mutex_lock(g_leServerStateMutex);
202 if (true == g_isLEGattServerStarted)
204 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
205 oc_mutex_unlock(g_leServerStateMutex);
209 CAResult_t ret = CAInitLEGattServer();
210 if (CA_STATUS_OK != ret)
212 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
213 oc_mutex_unlock(g_leServerStateMutex);
214 CATerminateLEGattServer();
215 return CA_STATUS_FAILED;
218 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
219 if (CA_STATUS_OK != ret)
221 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
222 oc_mutex_unlock(g_leServerStateMutex);
223 CATerminateLEGattServer();
224 return CA_STATUS_FAILED;
227 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
228 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
230 // For Read Characteristics.
231 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
232 sizeof(charReadValue), true);
233 if (CA_STATUS_OK != ret)
235 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
236 oc_mutex_unlock(g_leServerStateMutex);
237 CATerminateLEGattServer();
238 return CA_STATUS_FAILED;
241 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
242 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
245 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
246 sizeof(charWriteValue), false); // For Write Characteristics.
247 if (CA_STATUS_OK != ret )
249 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
250 oc_mutex_unlock(g_leServerStateMutex);
251 CATerminateLEGattServer();
252 return CA_STATUS_FAILED;
255 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
256 if (CA_STATUS_OK != ret )
258 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
259 oc_mutex_unlock(g_leServerStateMutex);
260 CATerminateLEGattServer();
261 return CA_STATUS_FAILED;
265 * TV Easysetup does not use IoTivity BLE advertisement.
268 // ret = CALEStartAdvertise();
269 // if (CA_STATUS_OK != ret)
271 // OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
272 // oc_mutex_unlock(g_leServerStateMutex);
273 // CATerminateLEGattServer();
274 // return CA_STATUS_FAILED;
277 g_isLEGattServerStarted = true;
279 oc_mutex_unlock(g_leServerStateMutex);
281 OIC_LOG(DEBUG, TAG, "OUT");
285 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
292 OIC_LOG(DEBUG, TAG, "IN");
295 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
296 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
297 true, "notifyChar success");
301 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
302 false, "notifyChar failure");
304 OIC_LOG(DEBUG, TAG, "OUT");
307 CAResult_t CALEStartAdvertise()
309 OIC_LOG(DEBUG, TAG, "IN");
311 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
312 if (CA_STATUS_OK != res)
314 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
317 OIC_LOG(DEBUG, TAG, "OUT");
321 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
323 OIC_LOG(DEBUG, TAG, "IN");
325 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
326 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
328 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
329 return CA_STATUS_FAILED;
332 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
333 BT_ADAPTER_LE_PACKET_ADVERTISING,
335 if (BT_ERROR_NONE != res)
337 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
338 CALEGetErrorMsg(res));
339 return CA_STATUS_FAILED;
342 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
343 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
344 if (BT_ERROR_NONE != res)
346 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
347 CALEGetErrorMsg(res));
348 return CA_STATUS_FAILED;
351 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
352 if (BT_ERROR_NONE != res)
354 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
355 CALEGetErrorMsg(res));
356 return CA_STATUS_FAILED;
359 OIC_LOG(DEBUG, TAG, "OUT");
363 CAResult_t CALEStopAdvertise()
365 OIC_LOG(DEBUG, TAG, "IN");
366 if (NULL != g_hAdvertiser)
368 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
371 OIC_LOG_V(ERROR, TAG,
372 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
375 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
378 OIC_LOG_V(ERROR, TAG,
379 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
381 g_hAdvertiser = NULL;
385 OIC_LOG(ERROR, TAG, "Advertising is not running");
386 return CA_STATUS_FAILED;
389 OIC_LOG(DEBUG, TAG, "OUT");
393 CAResult_t CAStopLEGattServer()
395 OIC_LOG(DEBUG, TAG, "IN");
397 oc_mutex_lock(g_leServerStateMutex);
399 if (false == g_isLEGattServerStarted)
401 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
402 oc_mutex_unlock(g_leServerStateMutex);
406 g_isLEGattServerStarted = false;
408 oc_mutex_lock(g_LEClientListMutex);
409 CADisconnectAllClient(g_LEClientList);
410 g_LEClientList = NULL;
411 oc_mutex_unlock(g_LEClientListMutex);
414 * TV Easysetup does not use IoTivity BLE advertisement.
417 // CAResult_t res = CALEStopAdvertise();
419 // OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
422 CAResult_t res = CADeInitLEGattServer();
423 if (CA_STATUS_OK != res)
425 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
428 GMainContext *context_event_loop = NULL;
429 // Required for waking up the thread which is running in gmain loop
430 if (NULL != g_eventLoop)
432 context_event_loop = g_main_loop_get_context(g_eventLoop);
434 if (context_event_loop)
436 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
437 g_main_context_wakeup(context_event_loop);
439 // Kill g main loops and kill threads
440 g_main_loop_quit(g_eventLoop);
446 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
449 oc_mutex_unlock(g_leServerStateMutex);
451 OIC_LOG(DEBUG, TAG, "OUT");
455 CAResult_t CAInitializeLEGattServer()
457 OIC_LOG(DEBUG, TAG, "IN");
459 CAResult_t ret = CAInitGattServerMutexVariables();
460 if (CA_STATUS_OK != ret )
462 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
463 CATerminateGattServerMutexVariables();
464 return CA_SERVER_NOT_STARTED;
466 OIC_LOG(DEBUG, TAG, "OUT");
470 void CATerminateLEGattServer()
472 OIC_LOG(DEBUG, TAG, "IN");
474 // Service and characteristics path will be freed by the platform.
475 oc_mutex_lock(g_leServiceMutex);
476 g_gattSvcPath = NULL;
477 oc_mutex_unlock(g_leServiceMutex);
479 oc_mutex_lock(g_leCharacteristicMutex);
480 g_gattReadCharPath = NULL;
481 g_gattWriteCharPath = NULL;
482 oc_mutex_unlock(g_leCharacteristicMutex);
484 oc_mutex_lock(g_leServerThreadPoolMutex);
485 g_leServerThreadPool = NULL;
486 oc_mutex_unlock(g_leServerThreadPoolMutex);
488 // Terminating all mutex variables.
489 CATerminateGattServerMutexVariables();
490 OIC_LOG(DEBUG, TAG, "OUT");
493 CAResult_t CAInitGattServerMutexVariables()
495 OIC_LOG(DEBUG, TAG, "IN");
496 if (NULL == g_leServerStateMutex)
498 g_leServerStateMutex = oc_mutex_new();
499 if (NULL == g_leServerStateMutex)
501 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
502 return CA_STATUS_FAILED;
506 if (NULL == g_leServiceMutex)
508 g_leServiceMutex = oc_mutex_new();
509 if (NULL == g_leServiceMutex)
511 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
512 return CA_STATUS_FAILED;
516 if (NULL == g_leCharacteristicMutex)
518 g_leCharacteristicMutex = oc_mutex_new();
519 if (NULL == g_leCharacteristicMutex)
521 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
522 return CA_STATUS_FAILED;
526 if (NULL == g_leReqRespCbMutex)
528 g_leReqRespCbMutex = oc_mutex_new();
529 if (NULL == g_leReqRespCbMutex)
531 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
532 return CA_STATUS_FAILED;
536 if (NULL == g_leServerThreadPoolMutex)
538 g_leServerThreadPoolMutex = oc_mutex_new();
539 if (NULL == g_leServerThreadPoolMutex)
541 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
542 return CA_STATUS_FAILED;
546 if (NULL == g_LEClientListMutex)
548 g_LEClientListMutex = oc_mutex_new();
549 if (NULL == g_LEClientListMutex)
551 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
552 return CA_STATUS_FAILED;
556 OIC_LOG(DEBUG, TAG, "OUT");
560 void CATerminateGattServerMutexVariables()
562 OIC_LOG(DEBUG, TAG, "IN");
563 oc_mutex_free(g_leServerStateMutex);
564 g_leServerStateMutex = NULL;
566 oc_mutex_free(g_leServiceMutex);
567 g_leServiceMutex = NULL;
569 oc_mutex_free(g_leCharacteristicMutex);
570 g_leCharacteristicMutex = NULL;
572 oc_mutex_free(g_leReqRespCbMutex);
573 g_leReqRespCbMutex = NULL;
575 oc_mutex_free(g_leServerThreadPoolMutex);
576 g_leServerThreadPoolMutex = NULL;
578 oc_mutex_free(g_LEClientListMutex);
579 g_LEClientListMutex = NULL;
581 OIC_LOG(DEBUG, TAG, "OUT");
584 CAResult_t CAInitLEGattServer()
586 OIC_LOG(DEBUG, TAG, "IN");
588 int ret = bt_gatt_server_initialize();
591 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
592 CALEGetErrorMsg(ret));
593 return CA_STATUS_FAILED;
598 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
599 ret = bt_gatt_server_create(&g_gattServer);
602 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
603 CALEGetErrorMsg(ret));
604 return CA_STATUS_FAILED;
608 OIC_LOG(DEBUG, TAG, "OUT");
612 CAResult_t CADeInitLEGattServer()
614 OIC_LOG(DEBUG, TAG, "IN");
616 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
619 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
620 CALEGetErrorMsg(ret));
621 return CA_STATUS_FAILED;
624 ret = bt_gatt_server_destroy(g_gattServer);
627 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
628 CALEGetErrorMsg(ret));
629 return CA_STATUS_FAILED;
633 ret = bt_gatt_server_deinitialize();
636 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
637 CALEGetErrorMsg(ret));
638 return CA_STATUS_FAILED;
641 OIC_LOG(DEBUG, TAG, "OUT");
645 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
647 OIC_LOG(DEBUG, TAG, "IN");
648 oc_mutex_lock(g_leServerThreadPoolMutex);
649 g_leServerThreadPool = handle;
650 oc_mutex_unlock(g_leServerThreadPoolMutex);
651 OIC_LOG(DEBUG, TAG, "OUT");
654 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
656 OIC_LOG(DEBUG, TAG, "IN");
658 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
660 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
662 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
664 oc_mutex_lock(g_leServiceMutex);
665 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
668 oc_mutex_unlock(g_leServiceMutex);
669 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
670 CALEGetErrorMsg(ret));
671 return CA_STATUS_FAILED;
673 oc_mutex_unlock(g_leServiceMutex);
677 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
680 OIC_LOG(DEBUG, TAG, "OUT");
685 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
686 bt_gatt_server_h server, bt_gatt_h gatt_handle,
687 bool response_needed, int offset, const char *charValue,
688 int charLen, void *userData)
690 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
691 bt_gatt_h gatt_handle, int offset, char *charValue,
692 int charLen, void *userData)
699 OIC_LOG(INFO, TAG, "IN - WriteCharCB");
701 if (NULL == charValue || NULL == remoteAddress)
703 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
707 OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
709 uint8_t *data = OICMalloc(charLen);
712 OIC_LOG(ERROR, TAG, "Malloc failed!");
716 memcpy(data, charValue, charLen);
718 oc_mutex_lock(g_leReqRespCbMutex);
719 if (NULL == g_leServerDataReceivedCallback)
721 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
722 oc_mutex_unlock(g_leReqRespCbMutex);
727 OIC_LOG(INFO, TAG, "Sending data up !");
728 uint32_t sentLength = 0;
729 g_leServerDataReceivedCallback(remoteAddress, data, charLen,
731 oc_mutex_unlock(g_leReqRespCbMutex);
736 OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
739 OIC_LOG(INFO, TAG, "send response to remote client");
740 bt_gatt_server_send_response(request_id,
741 BT_GATT_REQUEST_TYPE_WRITE, offset,
742 BT_ERROR_NONE, NULL, 0);
746 OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
749 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
751 OIC_LOG(DEBUG, TAG, "IN");
753 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
755 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
757 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
760 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
761 CALEGetErrorMsg(ret));
762 return CA_STATUS_FAILED;
766 ret = bt_gatt_server_start();
769 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
770 CALEGetErrorMsg(ret));
771 return CA_STATUS_FAILED;
776 ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
778 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
780 CALEGattRemoteCharacteristicWriteCb, NULL);
784 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
785 CALEGetErrorMsg(ret));
786 return CA_STATUS_FAILED;
789 OIC_LOG(DEBUG, TAG, "OUT");
793 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
794 const char *charValue, int charValueLen, bool read)
797 OIC_LOG(DEBUG, TAG, "IN");
799 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
803 properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
807 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
810 bt_gatt_h charPath = NULL;
812 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
813 charValueLen, &charPath);
815 if (0 != ret || NULL == charPath)
817 OIC_LOG_V(ERROR, TAG,
818 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
819 return CA_STATUS_FAILED;
822 OIC_LOG_V(DEBUG, TAG,
823 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
828 ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
832 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
836 OIC_LOG_V(ERROR, TAG,
838 "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
840 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
842 CALEGetErrorMsg(ret));
843 return CA_STATUS_FAILED;
847 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
850 OIC_LOG_V(ERROR, TAG,
851 "bt_gatt_service_add_characteristic failed with ret[%s]",
852 CALEGetErrorMsg(ret));
853 return CA_STATUS_FAILED;
856 oc_mutex_lock(g_leCharacteristicMutex);
860 g_gattReadCharPath = charPath;
864 char desc_value[2] = {0, 0}; // Notification enabled.
865 bt_gatt_h descriptor = NULL;
866 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
867 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
868 desc_value, sizeof(desc_value),
872 oc_mutex_unlock(g_leCharacteristicMutex);
873 OIC_LOG_V(ERROR, TAG,
874 "bt_gatt_descriptor_create failed with ret[%s]",
875 CALEGetErrorMsg(ret));
876 return CA_STATUS_FAILED;
879 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
882 oc_mutex_unlock(g_leCharacteristicMutex);
883 OIC_LOG_V(ERROR, TAG,
884 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
885 CALEGetErrorMsg(ret));
886 return CA_STATUS_FAILED;
888 g_gattWriteCharPath = charPath;
891 oc_mutex_unlock(g_leCharacteristicMutex);
893 OIC_LOG(DEBUG, TAG, "OUT");
897 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
898 uint32_t charValueLen)
900 OIC_LOG(DEBUG, TAG, "IN");
902 VERIFY_NON_NULL(charValue, TAG, "charValue");
903 VERIFY_NON_NULL(address, TAG, "address");
905 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
907 oc_mutex_lock(g_leCharacteristicMutex);
909 if (!g_LEConnectedState)
911 OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
912 oc_mutex_unlock(g_leCharacteristicMutex);
913 return CA_STATUS_FAILED;
916 if (NULL == g_gattReadCharPath)
918 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
919 oc_mutex_unlock(g_leCharacteristicMutex);
920 return CA_STATUS_FAILED;
923 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
926 OIC_LOG_V(ERROR, TAG,
927 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
928 oc_mutex_unlock(g_leCharacteristicMutex);
929 return CA_STATUS_FAILED;
933 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
934 CALEServerNotificationSentCB,
937 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
943 OIC_LOG_V(ERROR, TAG,
945 "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
947 "bt_gatt_server_notify failed with return [%s]",
949 CALEGetErrorMsg(ret));
950 oc_mutex_unlock(g_leCharacteristicMutex);
951 return CA_STATUS_FAILED;
954 oc_mutex_unlock(g_leCharacteristicMutex);
956 OIC_LOG(DEBUG, TAG, "OUT");
960 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
962 OIC_LOG(DEBUG, TAG, "IN");
964 VERIFY_NON_NULL(charValue, TAG, "charValue");
966 oc_mutex_lock(g_leCharacteristicMutex);
968 if (!g_LEConnectedState)
970 OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
971 oc_mutex_unlock(g_leCharacteristicMutex);
972 return CA_STATUS_FAILED;
975 if (NULL == g_gattReadCharPath)
977 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
978 oc_mutex_unlock(g_leCharacteristicMutex);
979 return CA_STATUS_FAILED;
982 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
985 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
986 oc_mutex_unlock(g_leCharacteristicMutex);
987 return CA_STATUS_FAILED;
991 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
992 CALEServerNotificationSentCB,
995 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1000 OIC_LOG_V(ERROR, TAG,
1002 "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
1004 "bt_gatt_server_notify failed with return[%s]",
1006 CALEGetErrorMsg(ret));
1007 oc_mutex_unlock(g_leCharacteristicMutex);
1008 return CA_STATUS_FAILED;
1011 oc_mutex_unlock(g_leCharacteristicMutex);
1013 OIC_LOG(DEBUG, TAG, "OUT");
1014 return CA_STATUS_OK;
1017 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1019 OIC_LOG(DEBUG, TAG, "IN");
1021 oc_mutex_lock(g_leReqRespCbMutex);
1022 g_leServerDataReceivedCallback = callback;
1023 oc_mutex_unlock(g_leReqRespCbMutex);
1025 OIC_LOG(DEBUG, TAG, "OUT");
1028 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1030 g_serverErrorCallback = callback;
1033 bool CALEServerIsConnected(const char* address)
1040 uint16_t CALEServerGetMtuSize(const char* address)
1042 OIC_LOG(DEBUG, TAG, "IN");
1043 VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1046 int ret = bt_device_get_att_mtu(address, &mtu);
1049 OIC_LOG_V(ERROR, TAG,
1050 "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1051 return CA_DEFAULT_BLE_MTU_SIZE;
1053 OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1054 OIC_LOG(DEBUG, TAG, "OUT");
1055 return mtu - CA_BLE_MTU_HEADER_SIZE;