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 #include <bluetooth_internal.h>
37 * Logging tag for module name
39 #define TAG "OIC_CA_LE_SERVER_VD"
42 * The handle of the OIC server.
44 static bt_gatt_server_h g_gattServer = NULL;
47 * The handle of the OIC service.
49 static bt_gatt_h g_gattSvcPath = NULL;
52 * The handle of the OIC read characteristics.
54 static bt_gatt_h g_gattReadCharPath = NULL;
57 * The handle of the OIC write characteristics.
59 static bt_gatt_h g_gattWriteCharPath = NULL;
62 * The handle to control Bluetooth LE advertising.
64 static bt_advertiser_h g_hAdvertiser = NULL;
67 * Callback register with LE adapter. This callback is called on reception of any
68 * data from the remote device.
70 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
73 * Callback to notify any error in LE adapter.
75 static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
78 * To keep the state of GATT server if started or not.
80 static bool g_isLEGattServerStarted = false;
83 * Mutex to synchronize the calls to start and stop server.
85 static oc_mutex g_leServerStateMutex = NULL;
88 * Mutex to synchronize writing operations on the characteristics.
90 static oc_mutex g_leCharacteristicMutex = NULL;
93 * Mutex to synchronize to creation of OIC service.
95 static oc_mutex g_leServiceMutex = NULL;
98 * Mutex to synchronize access to the requestResponse callback to be called
99 * when the data needs to be sent from GATTClient.
101 static oc_mutex g_leReqRespCbMutex = NULL;
104 * Mutex to synchronize the task to be pushed to thread pool.
106 static oc_mutex g_leServerThreadPoolMutex = NULL;
109 * Reference to threadpool.
111 static ca_thread_pool_t g_leServerThreadPool = NULL;
114 * GmainLoop to manage the threads to receive the callback from the platfrom.
116 static GMainLoop *g_eventLoop = NULL;
119 * This contains the list of OIC clients connected to the server.
121 static LEClientInfoList *g_LEClientList = NULL;
124 * Mutex to synchronize access to LE ClientList.
126 static oc_mutex g_LEClientListMutex = NULL;
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 char *addr = OICStrdup(remoteAddress);
137 oc_mutex_lock(g_LEClientListMutex);
138 res = CAAddLEClientInfoToList(&g_LEClientList, addr);
139 if (CA_STATUS_OK != res)
141 OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
142 oc_mutex_unlock(g_LEClientListMutex);
146 oc_mutex_unlock(g_LEClientListMutex);
149 * TV Easysetup does not use IoTivity BLE advertisement.
152 // res = CALEStopAdvertise();
153 // if (CA_STATUS_OK != res)
155 // OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
161 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
162 oc_mutex_lock(g_LEClientListMutex);
163 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
164 oc_mutex_unlock(g_LEClientListMutex);
167 * TV Easysetup does not use IoTivity BLE advertisement.
170 // res = CALEStartAdvertise();
171 // if (CA_STATUS_OK != res)
173 // OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
180 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
181 bt_gatt_h characteristic, bool completed, void *user_data)
183 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
184 bt_gatt_h characteristic, bool completed, void *user_data)
188 (void)characteristic;
192 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
195 CAResult_t CAStartLEGattServer()
197 OIC_LOG(DEBUG, TAG, "IN");
199 oc_mutex_lock(g_leServerStateMutex);
200 if (true == g_isLEGattServerStarted)
202 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
203 oc_mutex_unlock(g_leServerStateMutex);
207 CAResult_t ret = CAInitLEGattServer();
208 if (CA_STATUS_OK != ret)
210 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
211 oc_mutex_unlock(g_leServerStateMutex);
212 CATerminateLEGattServer();
213 return CA_STATUS_FAILED;
216 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
217 if (CA_STATUS_OK != ret)
219 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
220 oc_mutex_unlock(g_leServerStateMutex);
221 CATerminateLEGattServer();
222 return CA_STATUS_FAILED;
225 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
226 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
228 // For Read Characteristics.
229 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
230 sizeof(charReadValue), true);
231 if (CA_STATUS_OK != ret)
233 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
234 oc_mutex_unlock(g_leServerStateMutex);
235 CATerminateLEGattServer();
236 return CA_STATUS_FAILED;
239 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
240 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
243 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
244 sizeof(charWriteValue), false); // For Write Characteristics.
245 if (CA_STATUS_OK != ret )
247 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
248 oc_mutex_unlock(g_leServerStateMutex);
249 CATerminateLEGattServer();
250 return CA_STATUS_FAILED;
253 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
254 if (CA_STATUS_OK != ret )
256 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
257 oc_mutex_unlock(g_leServerStateMutex);
258 CATerminateLEGattServer();
259 return CA_STATUS_FAILED;
263 * TV Easysetup does not use IoTivity BLE advertisement.
266 // ret = CALEStartAdvertise();
267 // if (CA_STATUS_OK != ret)
269 // OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
270 // oc_mutex_unlock(g_leServerStateMutex);
271 // CATerminateLEGattServer();
272 // return CA_STATUS_FAILED;
275 g_isLEGattServerStarted = true;
277 oc_mutex_unlock(g_leServerStateMutex);
279 OIC_LOG(DEBUG, TAG, "OUT");
283 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
290 OIC_LOG(DEBUG, TAG, "IN");
293 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
294 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
295 true, "notifyChar success");
299 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
300 false, "notifyChar failure");
302 OIC_LOG(DEBUG, TAG, "OUT");
305 CAResult_t CALEStartAdvertise()
307 OIC_LOG(DEBUG, TAG, "IN");
309 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
310 if (CA_STATUS_OK != res)
312 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
315 OIC_LOG(DEBUG, TAG, "OUT");
319 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
321 OIC_LOG(DEBUG, TAG, "IN");
323 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
324 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
326 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
327 return CA_STATUS_FAILED;
330 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
331 BT_ADAPTER_LE_PACKET_ADVERTISING,
333 if (BT_ERROR_NONE != res)
335 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
336 CALEGetErrorMsg(res));
337 return CA_STATUS_FAILED;
340 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
341 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
342 if (BT_ERROR_NONE != res)
344 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
345 CALEGetErrorMsg(res));
346 return CA_STATUS_FAILED;
349 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
350 if (BT_ERROR_NONE != res)
352 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
353 CALEGetErrorMsg(res));
354 return CA_STATUS_FAILED;
357 OIC_LOG(DEBUG, TAG, "OUT");
361 CAResult_t CALEStopAdvertise()
363 OIC_LOG(DEBUG, TAG, "IN");
364 if (NULL != g_hAdvertiser)
366 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
369 OIC_LOG_V(ERROR, TAG,
370 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
373 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
376 OIC_LOG_V(ERROR, TAG,
377 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
379 g_hAdvertiser = NULL;
383 OIC_LOG(ERROR, TAG, "Advertising is not running");
384 return CA_STATUS_FAILED;
387 OIC_LOG(DEBUG, TAG, "OUT");
391 CAResult_t CAStopLEGattServer()
393 OIC_LOG(DEBUG, TAG, "IN");
395 oc_mutex_lock(g_leServerStateMutex);
397 if (false == g_isLEGattServerStarted)
399 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
400 oc_mutex_unlock(g_leServerStateMutex);
404 g_isLEGattServerStarted = false;
406 oc_mutex_lock(g_LEClientListMutex);
407 CADisconnectAllClient(g_LEClientList);
408 g_LEClientList = NULL;
409 oc_mutex_unlock(g_LEClientListMutex);
412 * TV Easysetup does not use IoTivity BLE advertisement.
415 // CAResult_t res = CALEStopAdvertise();
417 // OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
420 CAResult_t res = CADeInitLEGattServer();
421 if (CA_STATUS_OK != res)
423 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
426 GMainContext *context_event_loop = NULL;
427 // Required for waking up the thread which is running in gmain loop
428 if (NULL != g_eventLoop)
430 context_event_loop = g_main_loop_get_context(g_eventLoop);
432 if (context_event_loop)
434 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %p", (void *)context_event_loop);
435 g_main_context_wakeup(context_event_loop);
437 // Kill g main loops and kill threads
438 g_main_loop_quit(g_eventLoop);
444 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
447 oc_mutex_unlock(g_leServerStateMutex);
449 OIC_LOG(DEBUG, TAG, "OUT");
453 CAResult_t CAInitializeLEGattServer()
455 OIC_LOG(DEBUG, TAG, "IN");
457 CAResult_t ret = CAInitGattServerMutexVariables();
458 if (CA_STATUS_OK != ret )
460 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
461 CATerminateGattServerMutexVariables();
462 return CA_SERVER_NOT_STARTED;
464 OIC_LOG(DEBUG, TAG, "OUT");
468 void CATerminateLEGattServer()
470 OIC_LOG(DEBUG, TAG, "IN");
472 // Service and characteristics path will be freed by the platform.
473 oc_mutex_lock(g_leServiceMutex);
474 g_gattSvcPath = NULL;
475 oc_mutex_unlock(g_leServiceMutex);
477 oc_mutex_lock(g_leCharacteristicMutex);
478 g_gattReadCharPath = NULL;
479 g_gattWriteCharPath = NULL;
480 oc_mutex_unlock(g_leCharacteristicMutex);
482 oc_mutex_lock(g_leServerThreadPoolMutex);
483 g_leServerThreadPool = NULL;
484 oc_mutex_unlock(g_leServerThreadPoolMutex);
486 // Terminating all mutex variables.
487 CATerminateGattServerMutexVariables();
488 OIC_LOG(DEBUG, TAG, "OUT");
491 CAResult_t CAInitGattServerMutexVariables()
493 OIC_LOG(DEBUG, TAG, "IN");
494 if (NULL == g_leServerStateMutex)
496 g_leServerStateMutex = oc_mutex_new();
497 if (NULL == g_leServerStateMutex)
499 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
500 return CA_STATUS_FAILED;
504 if (NULL == g_leServiceMutex)
506 g_leServiceMutex = oc_mutex_new();
507 if (NULL == g_leServiceMutex)
509 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
510 return CA_STATUS_FAILED;
514 if (NULL == g_leCharacteristicMutex)
516 g_leCharacteristicMutex = oc_mutex_new();
517 if (NULL == g_leCharacteristicMutex)
519 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
520 return CA_STATUS_FAILED;
524 if (NULL == g_leReqRespCbMutex)
526 g_leReqRespCbMutex = oc_mutex_new();
527 if (NULL == g_leReqRespCbMutex)
529 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
530 return CA_STATUS_FAILED;
534 if (NULL == g_leServerThreadPoolMutex)
536 g_leServerThreadPoolMutex = oc_mutex_new();
537 if (NULL == g_leServerThreadPoolMutex)
539 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
540 return CA_STATUS_FAILED;
544 if (NULL == g_LEClientListMutex)
546 g_LEClientListMutex = oc_mutex_new();
547 if (NULL == g_LEClientListMutex)
549 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
550 return CA_STATUS_FAILED;
554 OIC_LOG(DEBUG, TAG, "OUT");
558 void CATerminateGattServerMutexVariables()
560 OIC_LOG(DEBUG, TAG, "IN");
561 oc_mutex_free(g_leServerStateMutex);
562 g_leServerStateMutex = NULL;
564 oc_mutex_free(g_leServiceMutex);
565 g_leServiceMutex = NULL;
567 oc_mutex_free(g_leCharacteristicMutex);
568 g_leCharacteristicMutex = NULL;
570 oc_mutex_free(g_leReqRespCbMutex);
571 g_leReqRespCbMutex = NULL;
573 oc_mutex_free(g_leServerThreadPoolMutex);
574 g_leServerThreadPoolMutex = NULL;
576 oc_mutex_free(g_LEClientListMutex);
577 g_LEClientListMutex = NULL;
579 OIC_LOG(DEBUG, TAG, "OUT");
582 CAResult_t CAInitLEGattServer()
584 OIC_LOG(DEBUG, TAG, "IN");
586 int ret = bt_gatt_server_initialize();
589 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
590 CALEGetErrorMsg(ret));
591 return CA_STATUS_FAILED;
596 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
597 ret = bt_gatt_server_create(&g_gattServer);
600 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
601 CALEGetErrorMsg(ret));
602 bt_gatt_server_deinitialize();
603 return CA_STATUS_FAILED;
607 OIC_LOG(DEBUG, TAG, "OUT");
611 CAResult_t CADeInitLEGattServer()
613 OIC_LOG(DEBUG, TAG, "IN");
615 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
618 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
619 CALEGetErrorMsg(ret));
620 // CONPRO-1181 continue even bt API fails during DeInit
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 // CONPRO-1181 continue even bt API fails during DeInit
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 // CONPRO-1181 continue even bt API fails during DeInit
640 //return CA_STATUS_FAILED;
643 OIC_LOG(DEBUG, TAG, "OUT");
647 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
649 OIC_LOG(DEBUG, TAG, "IN");
650 oc_mutex_lock(g_leServerThreadPoolMutex);
651 g_leServerThreadPool = handle;
652 oc_mutex_unlock(g_leServerThreadPoolMutex);
653 OIC_LOG(DEBUG, TAG, "OUT");
656 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
658 OIC_LOG(DEBUG, TAG, "IN");
660 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
662 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
664 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
666 oc_mutex_lock(g_leServiceMutex);
667 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
670 oc_mutex_unlock(g_leServiceMutex);
671 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
672 CALEGetErrorMsg(ret));
673 return CA_STATUS_FAILED;
675 oc_mutex_unlock(g_leServiceMutex);
679 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
682 OIC_LOG(DEBUG, TAG, "OUT");
687 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
688 bt_gatt_server_h server, bt_gatt_h gatt_handle,
689 bool response_needed, int offset, const char *charValue,
690 int charLen, void *userData)
692 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
693 bt_gatt_h gatt_handle, int offset, char *charValue,
694 int charLen, void *userData)
701 OIC_LOG(INFO, TAG, "IN - WriteCharCB");
703 if (NULL == charValue || NULL == remoteAddress)
705 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
709 OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
711 uint8_t *data = OICMalloc(charLen);
714 OIC_LOG(ERROR, TAG, "Malloc failed!");
718 memcpy(data, charValue, charLen);
720 oc_mutex_lock(g_leReqRespCbMutex);
721 if (NULL == g_leServerDataReceivedCallback)
723 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
724 oc_mutex_unlock(g_leReqRespCbMutex);
729 OIC_LOG(INFO, TAG, "Sending data up !");
730 uint32_t sentLength = 0;
731 g_leServerDataReceivedCallback(remoteAddress, data, charLen,
733 oc_mutex_unlock(g_leReqRespCbMutex);
738 OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
741 OIC_LOG(INFO, TAG, "send response to remote client");
742 bt_gatt_server_send_response(request_id,
743 BT_GATT_REQUEST_TYPE_WRITE, offset,
744 BT_ERROR_NONE, NULL, 0);
748 OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
751 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
753 OIC_LOG(DEBUG, TAG, "IN");
755 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
757 OIC_LOG_V(DEBUG, TAG, "svcPath: %s", (char *)svcPath);
759 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
762 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
763 CALEGetErrorMsg(ret));
764 return CA_STATUS_FAILED;
768 ret = bt_gatt_server_start();
771 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
772 CALEGetErrorMsg(ret));
773 return CA_STATUS_FAILED;
778 ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
780 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
782 CALEGattRemoteCharacteristicWriteCb, NULL);
786 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
787 CALEGetErrorMsg(ret));
788 return CA_STATUS_FAILED;
791 OIC_LOG(DEBUG, TAG, "OUT");
795 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
796 const char *charValue, int charValueLen, bool read)
799 OIC_LOG(DEBUG, TAG, "IN");
801 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
805 properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
809 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
812 bt_gatt_h charPath = NULL;
814 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
815 charValueLen, &charPath);
817 if (0 != ret || NULL == charPath)
819 OIC_LOG_V(ERROR, TAG,
820 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
821 return CA_STATUS_FAILED;
824 OIC_LOG_V(DEBUG, TAG,
825 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
830 ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
834 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
838 OIC_LOG_V(ERROR, TAG,
840 "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
842 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
844 CALEGetErrorMsg(ret));
845 return CA_STATUS_FAILED;
849 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
852 OIC_LOG_V(ERROR, TAG,
853 "bt_gatt_service_add_characteristic failed with ret[%s]",
854 CALEGetErrorMsg(ret));
855 return CA_STATUS_FAILED;
858 oc_mutex_lock(g_leCharacteristicMutex);
862 g_gattReadCharPath = charPath;
866 char desc_value[2] = {0, 0}; // Notification enabled.
867 bt_gatt_h descriptor = NULL;
868 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
869 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
870 desc_value, sizeof(desc_value),
874 oc_mutex_unlock(g_leCharacteristicMutex);
875 OIC_LOG_V(ERROR, TAG,
876 "bt_gatt_descriptor_create failed with ret[%s]",
877 CALEGetErrorMsg(ret));
878 return CA_STATUS_FAILED;
881 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
884 oc_mutex_unlock(g_leCharacteristicMutex);
885 OIC_LOG_V(ERROR, TAG,
886 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
887 CALEGetErrorMsg(ret));
888 return CA_STATUS_FAILED;
890 g_gattWriteCharPath = charPath;
893 oc_mutex_unlock(g_leCharacteristicMutex);
895 OIC_LOG(DEBUG, TAG, "OUT");
899 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
900 uint32_t charValueLen)
902 OIC_LOG(DEBUG, TAG, "IN");
904 VERIFY_NON_NULL(charValue, TAG, "charValue");
905 VERIFY_NON_NULL(address, TAG, "address");
907 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
909 oc_mutex_lock(g_leCharacteristicMutex);
911 oc_mutex_lock(g_LEClientListMutex);
912 if (CA_STATUS_FAILED == CAIsLEClientInfoInList(g_LEClientList, address))
914 OIC_LOG_V(ERROR, TAG, "%s device is not connected", address);
915 oc_mutex_unlock(g_LEClientListMutex);
916 oc_mutex_unlock(g_leCharacteristicMutex);
917 return CA_STATUS_FAILED;
919 oc_mutex_unlock(g_LEClientListMutex);
921 if (NULL == g_gattReadCharPath)
923 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
924 oc_mutex_unlock(g_leCharacteristicMutex);
925 return CA_STATUS_FAILED;
928 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
931 OIC_LOG_V(ERROR, TAG,
932 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
933 oc_mutex_unlock(g_leCharacteristicMutex);
934 return CA_STATUS_FAILED;
938 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
939 CALEServerNotificationSentCB,
942 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
948 OIC_LOG_V(ERROR, TAG,
950 "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
952 "bt_gatt_server_notify failed with return [%s]",
954 CALEGetErrorMsg(ret));
955 oc_mutex_unlock(g_leCharacteristicMutex);
956 return CA_STATUS_FAILED;
959 oc_mutex_unlock(g_leCharacteristicMutex);
961 OIC_LOG(DEBUG, TAG, "OUT");
965 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
967 OIC_LOG(DEBUG, TAG, "IN");
969 VERIFY_NON_NULL(charValue, TAG, "charValue");
971 oc_mutex_lock(g_leCharacteristicMutex);
973 if (NULL == g_gattReadCharPath)
975 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
976 oc_mutex_unlock(g_leCharacteristicMutex);
977 return CA_STATUS_FAILED;
980 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
983 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
984 oc_mutex_unlock(g_leCharacteristicMutex);
985 return CA_STATUS_FAILED;
989 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
990 CALEServerNotificationSentCB,
993 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
998 OIC_LOG_V(ERROR, TAG,
1000 "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
1002 "bt_gatt_server_notify failed with return[%s]",
1004 CALEGetErrorMsg(ret));
1005 oc_mutex_unlock(g_leCharacteristicMutex);
1006 return CA_STATUS_FAILED;
1009 oc_mutex_unlock(g_leCharacteristicMutex);
1011 OIC_LOG(DEBUG, TAG, "OUT");
1012 return CA_STATUS_OK;
1015 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1017 OIC_LOG(DEBUG, TAG, "IN");
1019 oc_mutex_lock(g_leReqRespCbMutex);
1020 g_leServerDataReceivedCallback = callback;
1021 oc_mutex_unlock(g_leReqRespCbMutex);
1023 OIC_LOG(DEBUG, TAG, "OUT");
1026 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1028 g_serverErrorCallback = callback;
1031 bool CALEServerIsConnected(const char* address)
1038 uint16_t CALEServerGetMtuSize(const char* address)
1040 OIC_LOG(DEBUG, TAG, "IN");
1041 VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1043 unsigned int mtu = CA_DEFAULT_BLE_MTU_SIZE;
1047 bt_gatt_client_h client = NULL;
1048 ret = bt_gatt_client_create(address, &client);
1051 OIC_LOG_V(ERROR, TAG,
1052 "bt_gatt_client_create failed with return [%s]", CALEGetErrorMsg(ret));
1053 return CA_DEFAULT_BLE_MTU_SIZE;
1056 ret = bt_gatt_client_get_att_mtu(client, &mtu);
1059 OIC_LOG_V(ERROR, TAG,
1060 "bt_gatt_client_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1061 return CA_DEFAULT_BLE_MTU_SIZE;
1064 ret = bt_gatt_client_destroy(client);
1067 OIC_LOG_V(ERROR, TAG,
1068 "bt_gatt_client_destroy failed with return [%s]", CALEGetErrorMsg(ret));
1069 return CA_DEFAULT_BLE_MTU_SIZE;
1072 ret = bt_device_get_att_mtu(address, &mtu);
1075 OIC_LOG_V(ERROR, TAG,
1076 "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1077 return CA_DEFAULT_BLE_MTU_SIZE;
1081 OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1082 OIC_LOG(DEBUG, TAG, "OUT");
1083 return mtu - CA_BLE_MTU_HEADER_SIZE;