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)
189 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
192 CAResult_t CAStartLEGattServer()
194 OIC_LOG(DEBUG, TAG, "IN");
196 oc_mutex_lock(g_leServerStateMutex);
197 if (true == g_isLEGattServerStarted)
199 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
200 oc_mutex_unlock(g_leServerStateMutex);
204 CAResult_t ret = CAInitLEGattServer();
205 if (CA_STATUS_OK != ret)
207 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
208 oc_mutex_unlock(g_leServerStateMutex);
209 CATerminateLEGattServer();
210 return CA_STATUS_FAILED;
213 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
214 if (CA_STATUS_OK != ret)
216 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
217 oc_mutex_unlock(g_leServerStateMutex);
218 CATerminateLEGattServer();
219 return CA_STATUS_FAILED;
222 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
223 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
225 // For Read Characteristics.
226 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
227 sizeof(charReadValue), true);
228 if (CA_STATUS_OK != ret)
230 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
231 oc_mutex_unlock(g_leServerStateMutex);
232 CATerminateLEGattServer();
233 return CA_STATUS_FAILED;
236 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
237 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
240 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
241 sizeof(charWriteValue), false); // For Write Characteristics.
242 if (CA_STATUS_OK != ret )
244 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
245 oc_mutex_unlock(g_leServerStateMutex);
246 CATerminateLEGattServer();
247 return CA_STATUS_FAILED;
250 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
251 if (CA_STATUS_OK != ret )
253 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
254 oc_mutex_unlock(g_leServerStateMutex);
255 CATerminateLEGattServer();
256 return CA_STATUS_FAILED;
260 * TV Easysetup does not use IoTivity BLE advertisement.
263 // ret = CALEStartAdvertise();
264 // if (CA_STATUS_OK != ret)
266 // OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
267 // oc_mutex_unlock(g_leServerStateMutex);
268 // CATerminateLEGattServer();
269 // return CA_STATUS_FAILED;
272 g_isLEGattServerStarted = true;
274 oc_mutex_unlock(g_leServerStateMutex);
276 OIC_LOG(DEBUG, TAG, "OUT");
280 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
283 OIC_LOG(DEBUG, TAG, "IN");
286 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
287 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
288 true, "notifyChar success");
292 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
293 false, "notifyChar failure");
295 OIC_LOG(DEBUG, TAG, "OUT");
298 CAResult_t CALEStartAdvertise()
300 OIC_LOG(DEBUG, TAG, "IN");
302 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
303 if (CA_STATUS_OK != res)
305 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
308 OIC_LOG(DEBUG, TAG, "OUT");
312 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
314 OIC_LOG(DEBUG, TAG, "IN");
316 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
317 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
319 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
320 return CA_STATUS_FAILED;
323 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
324 BT_ADAPTER_LE_PACKET_ADVERTISING,
326 if (BT_ERROR_NONE != res)
328 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
329 CALEGetErrorMsg(res));
330 return CA_STATUS_FAILED;
333 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
334 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
335 if (BT_ERROR_NONE != res)
337 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
338 CALEGetErrorMsg(res));
339 return CA_STATUS_FAILED;
342 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
343 if (BT_ERROR_NONE != res)
345 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
346 CALEGetErrorMsg(res));
347 return CA_STATUS_FAILED;
350 OIC_LOG(DEBUG, TAG, "OUT");
354 CAResult_t CALEStopAdvertise()
356 OIC_LOG(DEBUG, TAG, "IN");
357 if (NULL != g_hAdvertiser)
359 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
362 OIC_LOG_V(ERROR, TAG,
363 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
366 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
369 OIC_LOG_V(ERROR, TAG,
370 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
372 g_hAdvertiser = NULL;
376 OIC_LOG(ERROR, TAG, "Advertising is not running");
377 return CA_STATUS_FAILED;
380 OIC_LOG(DEBUG, TAG, "OUT");
384 CAResult_t CAStopLEGattServer()
386 OIC_LOG(DEBUG, TAG, "IN");
388 oc_mutex_lock(g_leServerStateMutex);
390 if (false == g_isLEGattServerStarted)
392 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
393 oc_mutex_unlock(g_leServerStateMutex);
397 g_isLEGattServerStarted = false;
399 oc_mutex_lock(g_LEClientListMutex);
400 CADisconnectAllClient(g_LEClientList);
401 g_LEClientList = NULL;
402 oc_mutex_unlock(g_LEClientListMutex);
405 * TV Easysetup does not use IoTivity BLE advertisement.
408 // CAResult_t res = CALEStopAdvertise();
410 // OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
413 CAResult_t res = CADeInitLEGattServer();
414 if (CA_STATUS_OK != res)
416 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
419 GMainContext *context_event_loop = NULL;
420 // Required for waking up the thread which is running in gmain loop
421 if (NULL != g_eventLoop)
423 context_event_loop = g_main_loop_get_context(g_eventLoop);
425 if (context_event_loop)
427 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
428 g_main_context_wakeup(context_event_loop);
430 // Kill g main loops and kill threads
431 g_main_loop_quit(g_eventLoop);
437 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
440 oc_mutex_unlock(g_leServerStateMutex);
442 OIC_LOG(DEBUG, TAG, "OUT");
446 CAResult_t CAInitializeLEGattServer()
448 OIC_LOG(DEBUG, TAG, "IN");
450 CAResult_t ret = CAInitGattServerMutexVariables();
451 if (CA_STATUS_OK != ret )
453 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
454 CATerminateGattServerMutexVariables();
455 return CA_SERVER_NOT_STARTED;
457 OIC_LOG(DEBUG, TAG, "OUT");
461 void CATerminateLEGattServer()
463 OIC_LOG(DEBUG, TAG, "IN");
465 // Service and characteristics path will be freed by the platform.
466 oc_mutex_lock(g_leServiceMutex);
467 g_gattSvcPath = NULL;
468 oc_mutex_unlock(g_leServiceMutex);
470 oc_mutex_lock(g_leCharacteristicMutex);
471 g_gattReadCharPath = NULL;
472 g_gattWriteCharPath = NULL;
473 oc_mutex_unlock(g_leCharacteristicMutex);
475 oc_mutex_lock(g_leServerThreadPoolMutex);
476 g_leServerThreadPool = NULL;
477 oc_mutex_unlock(g_leServerThreadPoolMutex);
479 // Terminating all mutex variables.
480 CATerminateGattServerMutexVariables();
481 OIC_LOG(DEBUG, TAG, "OUT");
484 CAResult_t CAInitGattServerMutexVariables()
486 OIC_LOG(DEBUG, TAG, "IN");
487 if (NULL == g_leServerStateMutex)
489 g_leServerStateMutex = oc_mutex_new();
490 if (NULL == g_leServerStateMutex)
492 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
493 return CA_STATUS_FAILED;
497 if (NULL == g_leServiceMutex)
499 g_leServiceMutex = oc_mutex_new();
500 if (NULL == g_leServiceMutex)
502 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
503 return CA_STATUS_FAILED;
507 if (NULL == g_leCharacteristicMutex)
509 g_leCharacteristicMutex = oc_mutex_new();
510 if (NULL == g_leCharacteristicMutex)
512 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
513 return CA_STATUS_FAILED;
517 if (NULL == g_leReqRespCbMutex)
519 g_leReqRespCbMutex = oc_mutex_new();
520 if (NULL == g_leReqRespCbMutex)
522 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
523 return CA_STATUS_FAILED;
527 if (NULL == g_leServerThreadPoolMutex)
529 g_leServerThreadPoolMutex = oc_mutex_new();
530 if (NULL == g_leServerThreadPoolMutex)
532 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
533 return CA_STATUS_FAILED;
537 if (NULL == g_LEClientListMutex)
539 g_LEClientListMutex = oc_mutex_new();
540 if (NULL == g_LEClientListMutex)
542 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
543 return CA_STATUS_FAILED;
547 OIC_LOG(DEBUG, TAG, "OUT");
551 void CATerminateGattServerMutexVariables()
553 OIC_LOG(DEBUG, TAG, "IN");
554 oc_mutex_free(g_leServerStateMutex);
555 g_leServerStateMutex = NULL;
557 oc_mutex_free(g_leServiceMutex);
558 g_leServiceMutex = NULL;
560 oc_mutex_free(g_leCharacteristicMutex);
561 g_leCharacteristicMutex = NULL;
563 oc_mutex_free(g_leReqRespCbMutex);
564 g_leReqRespCbMutex = NULL;
566 oc_mutex_free(g_leServerThreadPoolMutex);
567 g_leServerThreadPoolMutex = NULL;
569 oc_mutex_free(g_LEClientListMutex);
570 g_LEClientListMutex = NULL;
572 OIC_LOG(DEBUG, TAG, "OUT");
575 CAResult_t CAInitLEGattServer()
577 OIC_LOG(DEBUG, TAG, "IN");
579 int ret = bt_gatt_server_initialize();
582 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
583 CALEGetErrorMsg(ret));
584 return CA_STATUS_FAILED;
589 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
590 ret = bt_gatt_server_create(&g_gattServer);
593 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
594 CALEGetErrorMsg(ret));
595 return CA_STATUS_FAILED;
599 OIC_LOG(DEBUG, TAG, "OUT");
603 CAResult_t CADeInitLEGattServer()
605 OIC_LOG(DEBUG, TAG, "IN");
607 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
610 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
611 CALEGetErrorMsg(ret));
612 return CA_STATUS_FAILED;
615 ret = bt_gatt_server_destroy(g_gattServer);
618 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
619 CALEGetErrorMsg(ret));
620 return CA_STATUS_FAILED;
624 ret = bt_gatt_server_deinitialize();
627 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
628 CALEGetErrorMsg(ret));
629 return CA_STATUS_FAILED;
632 OIC_LOG(DEBUG, TAG, "OUT");
636 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
638 OIC_LOG(DEBUG, TAG, "IN");
639 oc_mutex_lock(g_leServerThreadPoolMutex);
640 g_leServerThreadPool = handle;
641 oc_mutex_unlock(g_leServerThreadPoolMutex);
642 OIC_LOG(DEBUG, TAG, "OUT");
645 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
647 OIC_LOG(DEBUG, TAG, "IN");
649 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
651 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
653 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
655 oc_mutex_lock(g_leServiceMutex);
656 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
659 oc_mutex_unlock(g_leServiceMutex);
660 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
661 CALEGetErrorMsg(ret));
662 return CA_STATUS_FAILED;
664 oc_mutex_unlock(g_leServiceMutex);
668 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
671 OIC_LOG(DEBUG, TAG, "OUT");
676 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
677 bt_gatt_server_h server, bt_gatt_h gatt_handle,
678 bool response_needed, int offset, const char *charValue,
679 int charLen, void *userData)
681 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
682 bt_gatt_h gatt_handle, int offset, char *charValue,
683 int charLen, void *userData)
686 OIC_LOG(INFO, TAG, "IN - WriteCharCB");
688 if (NULL == charValue || NULL == remoteAddress)
690 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
694 OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
696 uint8_t *data = OICMalloc(charLen);
699 OIC_LOG(ERROR, TAG, "Malloc failed!");
703 memcpy(data, charValue, charLen);
705 oc_mutex_lock(g_leReqRespCbMutex);
706 if (NULL == g_leServerDataReceivedCallback)
708 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
709 oc_mutex_unlock(g_leReqRespCbMutex);
714 OIC_LOG(INFO, TAG, "Sending data up !");
715 uint32_t sentLength = 0;
716 g_leServerDataReceivedCallback(remoteAddress, data, charLen,
718 oc_mutex_unlock(g_leReqRespCbMutex);
723 OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
726 OIC_LOG(INFO, TAG, "send response to remote client");
727 bt_gatt_server_send_response(request_id,
728 BT_GATT_REQUEST_TYPE_WRITE, offset,
729 BT_ERROR_NONE, NULL, 0);
733 OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
736 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
738 OIC_LOG(DEBUG, TAG, "IN");
740 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
742 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
744 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
747 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
748 CALEGetErrorMsg(ret));
749 return CA_STATUS_FAILED;
753 ret = bt_gatt_server_start();
756 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
757 CALEGetErrorMsg(ret));
758 return CA_STATUS_FAILED;
763 ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
765 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
767 CALEGattRemoteCharacteristicWriteCb, NULL);
771 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
772 CALEGetErrorMsg(ret));
773 return CA_STATUS_FAILED;
776 OIC_LOG(DEBUG, TAG, "OUT");
780 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
781 const char *charValue, int charValueLen, bool read)
784 OIC_LOG(DEBUG, TAG, "IN");
786 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
790 properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
794 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
797 bt_gatt_h charPath = NULL;
799 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
800 charValueLen, &charPath);
802 if (0 != ret || NULL == charPath)
804 OIC_LOG_V(ERROR, TAG,
805 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
806 return CA_STATUS_FAILED;
809 OIC_LOG_V(DEBUG, TAG,
810 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
815 ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
819 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
823 OIC_LOG_V(ERROR, TAG,
825 "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
827 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
829 CALEGetErrorMsg(ret));
830 return CA_STATUS_FAILED;
834 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
837 OIC_LOG_V(ERROR, TAG,
838 "bt_gatt_service_add_characteristic failed with ret[%s]",
839 CALEGetErrorMsg(ret));
840 return CA_STATUS_FAILED;
843 oc_mutex_lock(g_leCharacteristicMutex);
847 g_gattReadCharPath = charPath;
851 char desc_value[2] = {0, 0}; // Notification enabled.
852 bt_gatt_h descriptor = NULL;
853 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
854 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
855 desc_value, sizeof(desc_value),
859 oc_mutex_unlock(g_leCharacteristicMutex);
860 OIC_LOG_V(ERROR, TAG,
861 "bt_gatt_descriptor_create failed with ret[%s]",
862 CALEGetErrorMsg(ret));
863 return CA_STATUS_FAILED;
866 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
869 oc_mutex_unlock(g_leCharacteristicMutex);
870 OIC_LOG_V(ERROR, TAG,
871 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
872 CALEGetErrorMsg(ret));
873 return CA_STATUS_FAILED;
875 g_gattWriteCharPath = charPath;
878 oc_mutex_unlock(g_leCharacteristicMutex);
880 OIC_LOG(DEBUG, TAG, "OUT");
884 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
885 uint32_t charValueLen)
887 OIC_LOG(DEBUG, TAG, "IN");
889 VERIFY_NON_NULL(charValue, TAG, "charValue");
890 VERIFY_NON_NULL(address, TAG, "address");
892 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
894 oc_mutex_lock(g_leCharacteristicMutex);
896 if (!g_LEConnectedState)
898 OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
899 oc_mutex_unlock(g_leCharacteristicMutex);
900 return CA_STATUS_FAILED;
903 if (NULL == g_gattReadCharPath)
905 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
906 oc_mutex_unlock(g_leCharacteristicMutex);
907 return CA_STATUS_FAILED;
910 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
913 OIC_LOG_V(ERROR, TAG,
914 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
915 oc_mutex_unlock(g_leCharacteristicMutex);
916 return CA_STATUS_FAILED;
920 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
921 CALEServerNotificationSentCB,
924 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
930 OIC_LOG_V(ERROR, TAG,
932 "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
934 "bt_gatt_server_notify failed with return [%s]",
936 CALEGetErrorMsg(ret));
937 oc_mutex_unlock(g_leCharacteristicMutex);
938 return CA_STATUS_FAILED;
941 oc_mutex_unlock(g_leCharacteristicMutex);
943 OIC_LOG(DEBUG, TAG, "OUT");
947 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
949 OIC_LOG(DEBUG, TAG, "IN");
951 VERIFY_NON_NULL(charValue, TAG, "charValue");
953 oc_mutex_lock(g_leCharacteristicMutex);
955 if (!g_LEConnectedState)
957 OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
958 oc_mutex_unlock(g_leCharacteristicMutex);
959 return CA_STATUS_FAILED;
962 if (NULL == g_gattReadCharPath)
964 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
965 oc_mutex_unlock(g_leCharacteristicMutex);
966 return CA_STATUS_FAILED;
969 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
972 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
973 oc_mutex_unlock(g_leCharacteristicMutex);
974 return CA_STATUS_FAILED;
978 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
979 CALEServerNotificationSentCB,
982 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
987 OIC_LOG_V(ERROR, TAG,
989 "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
991 "bt_gatt_server_notify failed with return[%s]",
993 CALEGetErrorMsg(ret));
994 oc_mutex_unlock(g_leCharacteristicMutex);
995 return CA_STATUS_FAILED;
998 oc_mutex_unlock(g_leCharacteristicMutex);
1000 OIC_LOG(DEBUG, TAG, "OUT");
1001 return CA_STATUS_OK;
1004 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1006 OIC_LOG(DEBUG, TAG, "IN");
1008 oc_mutex_lock(g_leReqRespCbMutex);
1009 g_leServerDataReceivedCallback = callback;
1010 oc_mutex_unlock(g_leReqRespCbMutex);
1012 OIC_LOG(DEBUG, TAG, "OUT");
1015 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1017 g_serverErrorCallback = callback;
1020 bool CALEServerIsConnected(const char* address)
1026 uint16_t CALEServerGetMtuSize(const char* address)
1028 OIC_LOG(DEBUG, TAG, "IN");
1029 VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1032 int ret = bt_device_get_att_mtu(address, &mtu);
1035 OIC_LOG_V(ERROR, TAG,
1036 "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1037 return CA_DEFAULT_BLE_MTU_SIZE;
1039 OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1040 OIC_LOG(DEBUG, TAG, "OUT");
1041 return mtu - CA_BLE_MTU_HEADER_SIZE;