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"
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;
123 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
125 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
127 CAResult_t res = CA_STATUS_OK;
130 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
131 char *addr = OICStrdup(remoteAddress);
132 oc_mutex_lock(g_LEClientListMutex);
133 res = CAAddLEClientInfoToList(&g_LEClientList, addr);
134 if (CA_STATUS_OK != res)
136 OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
137 oc_mutex_unlock(g_LEClientListMutex);
141 oc_mutex_unlock(g_LEClientListMutex);
143 res = CALEStopAdvertise();
144 if (CA_STATUS_OK != res)
146 OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
152 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
153 oc_mutex_lock(g_LEClientListMutex);
154 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
155 oc_mutex_unlock(g_LEClientListMutex);
157 res = CALEStartAdvertise();
158 if (CA_STATUS_OK != res)
160 OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
166 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
167 bt_gatt_h characteristic, bool completed, void *user_data)
169 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
172 CAResult_t CAStartLEGattServer()
174 OIC_LOG(DEBUG, TAG, "IN");
176 oc_mutex_lock(g_leServerStateMutex);
177 if (true == g_isLEGattServerStarted)
179 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
180 oc_mutex_unlock(g_leServerStateMutex);
184 CAResult_t ret = CAInitLEGattServer();
185 if (CA_STATUS_OK != ret)
187 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
188 oc_mutex_unlock(g_leServerStateMutex);
189 CATerminateLEGattServer();
190 return CA_STATUS_FAILED;
193 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
194 if (CA_STATUS_OK != ret)
196 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
197 oc_mutex_unlock(g_leServerStateMutex);
198 CATerminateLEGattServer();
199 return CA_STATUS_FAILED;
202 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
203 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
205 // For Read Characteristics.
206 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
207 sizeof(charReadValue), true);
208 if (CA_STATUS_OK != ret)
210 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
211 oc_mutex_unlock(g_leServerStateMutex);
212 CATerminateLEGattServer();
213 return CA_STATUS_FAILED;
216 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
217 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
220 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
221 sizeof(charWriteValue), false); // For Write Characteristics.
222 if (CA_STATUS_OK != ret )
224 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
225 oc_mutex_unlock(g_leServerStateMutex);
226 CATerminateLEGattServer();
227 return CA_STATUS_FAILED;
230 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
231 if (CA_STATUS_OK != ret )
233 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
234 oc_mutex_unlock(g_leServerStateMutex);
235 CATerminateLEGattServer();
236 return CA_STATUS_FAILED;
239 ret = CALEStartAdvertise();
240 if (CA_STATUS_OK != ret)
242 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
243 oc_mutex_unlock(g_leServerStateMutex);
244 CATerminateLEGattServer();
245 return CA_STATUS_FAILED;
248 g_isLEGattServerStarted = true;
250 oc_mutex_unlock(g_leServerStateMutex);
252 OIC_LOG(DEBUG, TAG, "OUT");
256 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
259 OIC_LOG(DEBUG, TAG, "IN");
262 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
263 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
264 true, "notifyChar success");
268 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
269 false, "notifyChar failure");
271 OIC_LOG(DEBUG, TAG, "OUT");
274 CAResult_t CALEStartAdvertise()
276 OIC_LOG(DEBUG, TAG, "IN");
278 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
279 if (CA_STATUS_OK != res)
281 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
284 OIC_LOG(DEBUG, TAG, "OUT");
288 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
290 OIC_LOG(DEBUG, TAG, "IN");
292 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
293 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
295 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
296 return CA_STATUS_FAILED;
299 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
300 BT_ADAPTER_LE_PACKET_ADVERTISING,
302 if (BT_ERROR_NONE != res)
304 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
305 CALEGetErrorMsg(res));
306 return CA_STATUS_FAILED;
309 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
310 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
311 if (BT_ERROR_NONE != res)
313 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
314 CALEGetErrorMsg(res));
315 return CA_STATUS_FAILED;
318 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
319 if (BT_ERROR_NONE != res)
321 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
322 CALEGetErrorMsg(res));
323 return CA_STATUS_FAILED;
326 OIC_LOG(DEBUG, TAG, "OUT");
330 CAResult_t CALEStopAdvertise()
332 OIC_LOG(DEBUG, TAG, "IN");
333 if (NULL != g_hAdvertiser)
335 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
338 OIC_LOG_V(ERROR, TAG,
339 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
342 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
345 OIC_LOG_V(ERROR, TAG,
346 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
348 g_hAdvertiser = NULL;
352 OIC_LOG(ERROR, TAG, "Advertising is not running");
353 return CA_STATUS_FAILED;
356 OIC_LOG(DEBUG, TAG, "OUT");
360 CAResult_t CAStopLEGattServer()
362 OIC_LOG(DEBUG, TAG, "IN");
364 oc_mutex_lock(g_leServerStateMutex);
366 if (false == g_isLEGattServerStarted)
368 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
369 oc_mutex_unlock(g_leServerStateMutex);
373 g_isLEGattServerStarted = false;
375 oc_mutex_lock(g_LEClientListMutex);
376 CADisconnectAllClient(g_LEClientList);
377 g_LEClientList = NULL;
378 oc_mutex_unlock(g_LEClientListMutex);
380 CAResult_t res = CALEStopAdvertise();
382 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
385 res = CADeInitLEGattServer();
386 if (CA_STATUS_OK != res)
388 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
391 GMainContext *context_event_loop = NULL;
392 // Required for waking up the thread which is running in gmain loop
393 if (NULL != g_eventLoop)
395 context_event_loop = g_main_loop_get_context(g_eventLoop);
397 if (context_event_loop)
399 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
400 g_main_context_wakeup(context_event_loop);
402 // Kill g main loops and kill threads
403 g_main_loop_quit(g_eventLoop);
409 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
412 oc_mutex_unlock(g_leServerStateMutex);
414 OIC_LOG(DEBUG, TAG, "OUT");
418 CAResult_t CAInitializeLEGattServer()
420 OIC_LOG(DEBUG, TAG, "IN");
422 CAResult_t ret = CAInitGattServerMutexVariables();
423 if (CA_STATUS_OK != ret )
425 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
426 CATerminateGattServerMutexVariables();
427 return CA_SERVER_NOT_STARTED;
429 OIC_LOG(DEBUG, TAG, "OUT");
433 void CATerminateLEGattServer()
435 OIC_LOG(DEBUG, TAG, "IN");
437 // Service and characteristics path will be freed by the platform.
438 oc_mutex_lock(g_leServiceMutex);
439 g_gattSvcPath = NULL;
440 oc_mutex_unlock(g_leServiceMutex);
442 oc_mutex_lock(g_leCharacteristicMutex);
443 g_gattReadCharPath = NULL;
444 g_gattWriteCharPath = NULL;
445 oc_mutex_unlock(g_leCharacteristicMutex);
447 oc_mutex_lock(g_leServerThreadPoolMutex);
448 g_leServerThreadPool = NULL;
449 oc_mutex_unlock(g_leServerThreadPoolMutex);
451 // Terminating all mutex variables.
452 CATerminateGattServerMutexVariables();
453 OIC_LOG(DEBUG, TAG, "OUT");
456 CAResult_t CAInitGattServerMutexVariables()
458 OIC_LOG(DEBUG, TAG, "IN");
459 if (NULL == g_leServerStateMutex)
461 g_leServerStateMutex = oc_mutex_new();
462 if (NULL == g_leServerStateMutex)
464 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
465 return CA_STATUS_FAILED;
469 if (NULL == g_leServiceMutex)
471 g_leServiceMutex = oc_mutex_new();
472 if (NULL == g_leServiceMutex)
474 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
475 return CA_STATUS_FAILED;
479 if (NULL == g_leCharacteristicMutex)
481 g_leCharacteristicMutex = oc_mutex_new();
482 if (NULL == g_leCharacteristicMutex)
484 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
485 return CA_STATUS_FAILED;
489 if (NULL == g_leReqRespCbMutex)
491 g_leReqRespCbMutex = oc_mutex_new();
492 if (NULL == g_leReqRespCbMutex)
494 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
495 return CA_STATUS_FAILED;
499 if (NULL == g_leServerThreadPoolMutex)
501 g_leServerThreadPoolMutex = oc_mutex_new();
502 if (NULL == g_leServerThreadPoolMutex)
504 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
505 return CA_STATUS_FAILED;
509 if (NULL == g_LEClientListMutex)
511 g_LEClientListMutex = oc_mutex_new();
512 if (NULL == g_LEClientListMutex)
514 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
515 return CA_STATUS_FAILED;
519 OIC_LOG(DEBUG, TAG, "OUT");
523 void CATerminateGattServerMutexVariables()
525 OIC_LOG(DEBUG, TAG, "IN");
526 oc_mutex_free(g_leServerStateMutex);
527 g_leServerStateMutex = NULL;
529 oc_mutex_free(g_leServiceMutex);
530 g_leServiceMutex = NULL;
532 oc_mutex_free(g_leCharacteristicMutex);
533 g_leCharacteristicMutex = NULL;
535 oc_mutex_free(g_leReqRespCbMutex);
536 g_leReqRespCbMutex = NULL;
538 oc_mutex_free(g_leServerThreadPoolMutex);
539 g_leServerThreadPoolMutex = NULL;
541 oc_mutex_free(g_LEClientListMutex);
542 g_LEClientListMutex = NULL;
544 OIC_LOG(DEBUG, TAG, "OUT");
547 CAResult_t CAInitLEGattServer()
549 OIC_LOG(DEBUG, TAG, "IN");
551 int ret = bt_gatt_server_initialize();
554 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
555 CALEGetErrorMsg(ret));
556 return CA_STATUS_FAILED;
561 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
562 ret = bt_gatt_server_create(&g_gattServer);
565 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
566 CALEGetErrorMsg(ret));
567 bt_gatt_server_deinitialize();
568 return CA_STATUS_FAILED;
572 OIC_LOG(DEBUG, TAG, "OUT");
576 CAResult_t CADeInitLEGattServer()
578 OIC_LOG(DEBUG, TAG, "IN");
580 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
583 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
584 CALEGetErrorMsg(ret));
585 // CONPRO-1181 continue even bt API fails during DeInit
586 //return CA_STATUS_FAILED;
589 ret = bt_gatt_server_destroy(g_gattServer);
592 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
593 CALEGetErrorMsg(ret));
594 // CONPRO-1181 continue even bt API fails during DeInit
595 //return CA_STATUS_FAILED;
599 ret = bt_gatt_server_deinitialize();
602 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
603 CALEGetErrorMsg(ret));
604 // CONPRO-1181 continue even bt API fails during DeInit
605 //return CA_STATUS_FAILED;
608 OIC_LOG(DEBUG, TAG, "OUT");
612 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
614 OIC_LOG(DEBUG, TAG, "IN");
615 oc_mutex_lock(g_leServerThreadPoolMutex);
616 g_leServerThreadPool = handle;
617 oc_mutex_unlock(g_leServerThreadPoolMutex);
618 OIC_LOG(DEBUG, TAG, "OUT");
621 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
623 OIC_LOG(DEBUG, TAG, "IN");
625 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
627 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
629 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
631 oc_mutex_lock(g_leServiceMutex);
632 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
635 oc_mutex_unlock(g_leServiceMutex);
636 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
637 CALEGetErrorMsg(ret));
638 return CA_STATUS_FAILED;
640 oc_mutex_unlock(g_leServiceMutex);
644 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
647 OIC_LOG(DEBUG, TAG, "OUT");
651 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
652 bt_gatt_h charPath, int offset, char *charValue,
653 int charValueLen, void *userData)
655 OIC_LOG(INFO, TAG, "IN - WriteCharCB");
657 if (NULL == charValue || NULL == remoteAddress)
659 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
663 OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
664 charValue, charValueLen);
666 uint8_t *data = OICMalloc(charValueLen);
669 OIC_LOG(ERROR, TAG, "Malloc failed!");
673 memcpy(data, charValue, charValueLen);
675 oc_mutex_lock(g_leReqRespCbMutex);
676 if (NULL == g_leServerDataReceivedCallback)
678 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
679 oc_mutex_unlock(g_leReqRespCbMutex);
684 OIC_LOG(INFO, TAG, "Sending data up !");
685 uint32_t sentLength = 0;
686 g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
688 oc_mutex_unlock(g_leReqRespCbMutex);
690 OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
693 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
695 OIC_LOG(DEBUG, TAG, "IN");
697 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
699 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
701 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
704 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
705 CALEGetErrorMsg(ret));
706 return CA_STATUS_FAILED;
709 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
710 CALEGattRemoteCharacteristicWriteCb, NULL);
714 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
715 CALEGetErrorMsg(ret));
716 return CA_STATUS_FAILED;
719 OIC_LOG(DEBUG, TAG, "OUT");
723 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
724 const char *charValue, int charValueLen, bool read)
727 OIC_LOG(DEBUG, TAG, "IN");
729 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
733 properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
737 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
740 bt_gatt_h charPath = NULL;
742 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
743 charValueLen, &charPath);
745 if (0 != ret || NULL == charPath)
747 OIC_LOG_V(ERROR, TAG,
748 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
749 return CA_STATUS_FAILED;
752 OIC_LOG_V(DEBUG, TAG,
753 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
757 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
760 OIC_LOG_V(ERROR, TAG,
761 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
762 CALEGetErrorMsg(ret));
763 return CA_STATUS_FAILED;
767 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
770 OIC_LOG_V(ERROR, TAG,
771 "bt_gatt_service_add_characteristic failed with ret[%s]",
772 CALEGetErrorMsg(ret));
773 return CA_STATUS_FAILED;
776 oc_mutex_lock(g_leCharacteristicMutex);
780 char desc_value[2] = {1, 0}; // Notification enabled.
781 bt_gatt_h descriptor = NULL;
782 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
783 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
784 desc_value, sizeof(desc_value),
788 oc_mutex_unlock(g_leCharacteristicMutex);
789 OIC_LOG_V(ERROR, TAG,
790 "bt_gatt_descriptor_create failed with ret[%s]",
791 CALEGetErrorMsg(ret));
792 return CA_STATUS_FAILED;
795 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
798 oc_mutex_unlock(g_leCharacteristicMutex);
799 OIC_LOG_V(ERROR, TAG,
800 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
801 CALEGetErrorMsg(ret));
802 return CA_STATUS_FAILED;
805 g_gattReadCharPath = charPath;
809 g_gattWriteCharPath = charPath;
812 oc_mutex_unlock(g_leCharacteristicMutex);
814 OIC_LOG(DEBUG, TAG, "OUT");
818 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
819 uint32_t charValueLen)
821 OIC_LOG(DEBUG, TAG, "IN");
823 VERIFY_NON_NULL(charValue, TAG, "charValue");
824 VERIFY_NON_NULL(address, TAG, "address");
826 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
828 oc_mutex_lock(g_leCharacteristicMutex);
830 if (NULL == g_gattReadCharPath)
832 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
833 oc_mutex_unlock(g_leCharacteristicMutex);
834 return CA_STATUS_FAILED;
837 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
840 OIC_LOG_V(ERROR, TAG,
841 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
842 oc_mutex_unlock(g_leCharacteristicMutex);
843 return CA_STATUS_FAILED;
846 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
850 OIC_LOG_V(ERROR, TAG,
851 "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
852 oc_mutex_unlock(g_leCharacteristicMutex);
853 return CA_STATUS_FAILED;
856 oc_mutex_unlock(g_leCharacteristicMutex);
858 OIC_LOG(DEBUG, TAG, "OUT");
862 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
864 OIC_LOG(DEBUG, TAG, "IN");
866 VERIFY_NON_NULL(charValue, TAG, "charValue");
868 oc_mutex_lock(g_leCharacteristicMutex);
870 if (NULL == g_gattReadCharPath)
872 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
873 oc_mutex_unlock(g_leCharacteristicMutex);
874 return CA_STATUS_FAILED;
877 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
880 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
881 oc_mutex_unlock(g_leCharacteristicMutex);
882 return CA_STATUS_FAILED;
885 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
889 OIC_LOG_V(ERROR, TAG,
890 "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
891 oc_mutex_unlock(g_leCharacteristicMutex);
892 return CA_STATUS_FAILED;
895 oc_mutex_unlock(g_leCharacteristicMutex);
897 OIC_LOG(DEBUG, TAG, "OUT");
901 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
903 OIC_LOG(DEBUG, TAG, "IN");
905 oc_mutex_lock(g_leReqRespCbMutex);
906 g_leServerDataReceivedCallback = callback;
907 oc_mutex_unlock(g_leReqRespCbMutex);
909 OIC_LOG(DEBUG, TAG, "OUT");
912 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
914 g_serverErrorCallback = callback;
917 bool CALEServerIsConnected(const char* address)
923 uint16_t CALEServerGetMtuSize(const char* address)
925 OIC_LOG(DEBUG, TAG, "IN");
926 VERIFY_NON_NULL_RET(address, TAG, "address is null",
927 CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE);
930 "bt_device_get_att_mtu is not supported");
931 return CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE;