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 * Initial buffer size(attr value max size) for Gatt Server.
39 #define CA_LE_INITIAL_BUF_SIZE (512)
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);
148 res = CALEStopAdvertise();
149 if (CA_STATUS_OK != res)
151 OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
157 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
158 oc_mutex_lock(g_LEClientListMutex);
159 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
160 oc_mutex_unlock(g_LEClientListMutex);
162 res = CALEStartAdvertise();
163 if (CA_STATUS_OK != res)
165 OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
171 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
172 bt_gatt_h characteristic, bool completed, void *user_data)
174 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
177 CAResult_t CAStartLEGattServer()
179 OIC_LOG(DEBUG, TAG, "IN");
181 oc_mutex_lock(g_leServerStateMutex);
182 if (true == g_isLEGattServerStarted)
184 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
185 oc_mutex_unlock(g_leServerStateMutex);
189 CAResult_t ret = CAInitLEGattServer();
190 if (CA_STATUS_OK != ret)
192 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
193 oc_mutex_unlock(g_leServerStateMutex);
194 CATerminateLEGattServer();
195 return CA_STATUS_FAILED;
198 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
199 if (CA_STATUS_OK != ret)
201 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
202 oc_mutex_unlock(g_leServerStateMutex);
203 CATerminateLEGattServer();
204 return CA_STATUS_FAILED;
207 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
208 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
210 // For Read Characteristics.
211 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
212 CA_LE_INITIAL_BUF_SIZE, true);
213 if (CA_STATUS_OK != ret)
215 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
216 oc_mutex_unlock(g_leServerStateMutex);
217 CATerminateLEGattServer();
218 return CA_STATUS_FAILED;
221 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
222 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
225 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
226 CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
227 if (CA_STATUS_OK != ret )
229 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
230 oc_mutex_unlock(g_leServerStateMutex);
231 CATerminateLEGattServer();
232 return CA_STATUS_FAILED;
235 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
236 if (CA_STATUS_OK != ret )
238 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
239 oc_mutex_unlock(g_leServerStateMutex);
240 CATerminateLEGattServer();
241 return CA_STATUS_FAILED;
244 ret = CALEStartAdvertise();
245 if (CA_STATUS_OK != ret)
247 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
248 oc_mutex_unlock(g_leServerStateMutex);
249 CATerminateLEGattServer();
250 return CA_STATUS_FAILED;
253 g_isLEGattServerStarted = true;
255 oc_mutex_unlock(g_leServerStateMutex);
257 OIC_LOG(DEBUG, TAG, "OUT");
261 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
264 OIC_LOG(DEBUG, TAG, "IN");
267 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
269 OIC_LOG(DEBUG, TAG, "OUT");
272 CAResult_t CALEStartAdvertise()
274 OIC_LOG(DEBUG, TAG, "IN");
276 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
277 if (CA_STATUS_OK != res)
279 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
282 OIC_LOG(DEBUG, TAG, "OUT");
286 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
288 OIC_LOG(DEBUG, TAG, "IN");
290 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
291 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
293 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
294 return CA_STATUS_FAILED;
297 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
298 BT_ADAPTER_LE_PACKET_ADVERTISING,
300 if (BT_ERROR_NONE != res)
302 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
303 CALEGetErrorMsg(res));
304 return CA_STATUS_FAILED;
307 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
308 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
309 if (BT_ERROR_NONE != res)
311 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
312 CALEGetErrorMsg(res));
313 return CA_STATUS_FAILED;
316 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
317 if (BT_ERROR_NONE != res)
319 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
320 CALEGetErrorMsg(res));
321 return CA_STATUS_FAILED;
324 OIC_LOG(DEBUG, TAG, "OUT");
328 CAResult_t CALEStopAdvertise()
330 OIC_LOG(DEBUG, TAG, "IN");
331 if (NULL != g_hAdvertiser)
333 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
336 OIC_LOG_V(ERROR, TAG,
337 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
340 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
343 OIC_LOG_V(ERROR, TAG,
344 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
346 g_hAdvertiser = NULL;
350 OIC_LOG(ERROR, TAG, "Advertising is not running");
351 return CA_STATUS_FAILED;
354 OIC_LOG(DEBUG, TAG, "OUT");
358 CAResult_t CAStopLEGattServer()
360 OIC_LOG(DEBUG, TAG, "IN");
362 oc_mutex_lock(g_leServerStateMutex);
364 if (false == g_isLEGattServerStarted)
366 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
367 oc_mutex_unlock(g_leServerStateMutex);
371 g_isLEGattServerStarted = false;
373 oc_mutex_lock(g_LEClientListMutex);
374 CADisconnectAllClient(g_LEClientList);
375 g_LEClientList = NULL;
376 oc_mutex_unlock(g_LEClientListMutex);
378 CAResult_t res = CALEStopAdvertise();
380 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
383 res = CADeInitLEGattServer();
384 if (CA_STATUS_OK != res)
386 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
389 GMainContext *context_event_loop = NULL;
390 // Required for waking up the thread which is running in gmain loop
391 if (NULL != g_eventLoop)
393 context_event_loop = g_main_loop_get_context(g_eventLoop);
395 if (context_event_loop)
397 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
398 g_main_context_wakeup(context_event_loop);
400 // Kill g main loops and kill threads
401 g_main_loop_quit(g_eventLoop);
407 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
410 oc_mutex_unlock(g_leServerStateMutex);
412 OIC_LOG(DEBUG, TAG, "OUT");
416 CAResult_t CAInitializeLEGattServer()
418 OIC_LOG(DEBUG, TAG, "IN");
420 CAResult_t ret = CAInitGattServerMutexVariables();
421 if (CA_STATUS_OK != ret )
423 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
424 CATerminateGattServerMutexVariables();
425 return CA_SERVER_NOT_STARTED;
427 OIC_LOG(DEBUG, TAG, "OUT");
431 void CATerminateLEGattServer()
433 OIC_LOG(DEBUG, TAG, "IN");
435 // Service and characteristics path will be freed by the platform.
436 oc_mutex_lock(g_leServiceMutex);
437 g_gattSvcPath = NULL;
438 oc_mutex_unlock(g_leServiceMutex);
440 oc_mutex_lock(g_leCharacteristicMutex);
441 g_gattReadCharPath = NULL;
442 g_gattWriteCharPath = NULL;
443 oc_mutex_unlock(g_leCharacteristicMutex);
445 oc_mutex_lock(g_leServerThreadPoolMutex);
446 g_leServerThreadPool = NULL;
447 oc_mutex_unlock(g_leServerThreadPoolMutex);
449 // Terminating all mutex variables.
450 CATerminateGattServerMutexVariables();
451 OIC_LOG(DEBUG, TAG, "OUT");
454 CAResult_t CAInitGattServerMutexVariables()
456 OIC_LOG(DEBUG, TAG, "IN");
457 if (NULL == g_leServerStateMutex)
459 g_leServerStateMutex = oc_mutex_new();
460 if (NULL == g_leServerStateMutex)
462 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
463 return CA_STATUS_FAILED;
467 if (NULL == g_leServiceMutex)
469 g_leServiceMutex = oc_mutex_new();
470 if (NULL == g_leServiceMutex)
472 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
473 return CA_STATUS_FAILED;
477 if (NULL == g_leCharacteristicMutex)
479 g_leCharacteristicMutex = oc_mutex_new();
480 if (NULL == g_leCharacteristicMutex)
482 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
483 return CA_STATUS_FAILED;
487 if (NULL == g_leReqRespCbMutex)
489 g_leReqRespCbMutex = oc_mutex_new();
490 if (NULL == g_leReqRespCbMutex)
492 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
493 return CA_STATUS_FAILED;
497 if (NULL == g_leServerThreadPoolMutex)
499 g_leServerThreadPoolMutex = oc_mutex_new();
500 if (NULL == g_leServerThreadPoolMutex)
502 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
503 return CA_STATUS_FAILED;
507 if (NULL == g_LEClientListMutex)
509 g_LEClientListMutex = oc_mutex_new();
510 if (NULL == g_LEClientListMutex)
512 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
513 return CA_STATUS_FAILED;
517 OIC_LOG(DEBUG, TAG, "OUT");
521 void CATerminateGattServerMutexVariables()
523 OIC_LOG(DEBUG, TAG, "IN");
524 oc_mutex_free(g_leServerStateMutex);
525 g_leServerStateMutex = NULL;
527 oc_mutex_free(g_leServiceMutex);
528 g_leServiceMutex = NULL;
530 oc_mutex_free(g_leCharacteristicMutex);
531 g_leCharacteristicMutex = NULL;
533 oc_mutex_free(g_leReqRespCbMutex);
534 g_leReqRespCbMutex = NULL;
536 oc_mutex_free(g_leServerThreadPoolMutex);
537 g_leServerThreadPoolMutex = NULL;
539 oc_mutex_free(g_LEClientListMutex);
540 g_LEClientListMutex = NULL;
542 OIC_LOG(DEBUG, TAG, "OUT");
545 CAResult_t CAInitLEGattServer()
547 OIC_LOG(DEBUG, TAG, "IN");
549 int ret = bt_gatt_server_initialize();
552 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
553 CALEGetErrorMsg(ret));
554 return CA_STATUS_FAILED;
559 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
560 ret = bt_gatt_server_create(&g_gattServer);
563 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
564 CALEGetErrorMsg(ret));
565 return CA_STATUS_FAILED;
569 OIC_LOG(DEBUG, TAG, "OUT");
573 CAResult_t CADeInitLEGattServer()
575 OIC_LOG(DEBUG, TAG, "IN");
577 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
580 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
581 CALEGetErrorMsg(ret));
582 return CA_STATUS_FAILED;
585 ret = bt_gatt_server_destroy(g_gattServer);
588 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
589 CALEGetErrorMsg(ret));
590 return CA_STATUS_FAILED;
594 ret = bt_gatt_server_deinitialize();
597 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
598 CALEGetErrorMsg(ret));
599 return CA_STATUS_FAILED;
602 OIC_LOG(DEBUG, TAG, "OUT");
606 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
608 OIC_LOG(DEBUG, TAG, "IN");
609 oc_mutex_lock(g_leServerThreadPoolMutex);
610 g_leServerThreadPool = handle;
611 oc_mutex_unlock(g_leServerThreadPoolMutex);
612 OIC_LOG(DEBUG, TAG, "OUT");
615 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
617 OIC_LOG(DEBUG, TAG, "IN");
619 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
621 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
623 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
625 oc_mutex_lock(g_leServiceMutex);
626 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
629 oc_mutex_unlock(g_leServiceMutex);
630 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
631 CALEGetErrorMsg(ret));
632 return CA_STATUS_FAILED;
634 oc_mutex_unlock(g_leServiceMutex);
638 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
641 OIC_LOG(DEBUG, TAG, "OUT");
645 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
646 bt_gatt_h charPath, int offset, char *charValue,
647 int charValueLen, void *userData)
649 OIC_LOG(DEBUG, TAG, "IN");
651 if (NULL == charValue || NULL == remoteAddress)
653 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
657 OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
658 charValue, charValueLen);
660 uint8_t *data = OICMalloc(charValueLen);
663 OIC_LOG(ERROR, TAG, "Malloc failed!");
667 memcpy(data, charValue, charValueLen);
669 oc_mutex_lock(g_leReqRespCbMutex);
670 if (NULL == g_leServerDataReceivedCallback)
672 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
673 oc_mutex_unlock(g_leReqRespCbMutex);
678 OIC_LOG(DEBUG, TAG, "Sending data up !");
679 uint32_t sentLength = 0;
680 g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
682 oc_mutex_unlock(g_leReqRespCbMutex);
684 OIC_LOG(DEBUG, TAG, "OUT");
687 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
689 OIC_LOG(DEBUG, TAG, "IN");
691 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
693 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
695 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
698 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
699 CALEGetErrorMsg(ret));
700 return CA_STATUS_FAILED;
703 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
704 CALEGattRemoteCharacteristicWriteCb, NULL);
708 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
709 CALEGetErrorMsg(ret));
710 return CA_STATUS_FAILED;
713 OIC_LOG(DEBUG, TAG, "OUT");
717 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
718 const char *charValue, int charValueLen, bool read)
721 OIC_LOG(DEBUG, TAG, "IN");
723 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
727 properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
731 properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
734 bt_gatt_h charPath = NULL;
736 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
737 charValueLen, &charPath);
739 if (0 != ret || NULL == charPath)
741 OIC_LOG_V(ERROR, TAG,
742 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
743 return CA_STATUS_FAILED;
746 OIC_LOG_V(DEBUG, TAG,
747 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
751 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
754 OIC_LOG_V(ERROR, TAG,
755 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
756 CALEGetErrorMsg(ret));
757 return CA_STATUS_FAILED;
761 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
764 OIC_LOG_V(ERROR, TAG,
765 "bt_gatt_service_add_characteristic failed with ret[%s]",
766 CALEGetErrorMsg(ret));
767 return CA_STATUS_FAILED;
770 oc_mutex_lock(g_leCharacteristicMutex);
774 char desc_value[2] = {1, 0}; // Notification enabled.
775 bt_gatt_h descriptor = NULL;
776 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
777 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
778 desc_value, sizeof(desc_value),
782 oc_mutex_unlock(g_leCharacteristicMutex);
783 OIC_LOG_V(ERROR, TAG,
784 "bt_gatt_descriptor_create failed with ret[%s]",
785 CALEGetErrorMsg(ret));
786 return CA_STATUS_FAILED;
789 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
792 oc_mutex_unlock(g_leCharacteristicMutex);
793 OIC_LOG_V(ERROR, TAG,
794 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
795 CALEGetErrorMsg(ret));
796 return CA_STATUS_FAILED;
799 g_gattReadCharPath = charPath;
803 g_gattWriteCharPath = charPath;
806 oc_mutex_unlock(g_leCharacteristicMutex);
808 OIC_LOG(DEBUG, TAG, "OUT");
812 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
813 uint32_t charValueLen)
815 OIC_LOG(DEBUG, TAG, "IN");
817 VERIFY_NON_NULL(charValue, TAG, "charValue");
818 VERIFY_NON_NULL(address, TAG, "address");
820 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
822 oc_mutex_lock(g_leCharacteristicMutex);
824 if (NULL == g_gattReadCharPath)
826 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
827 oc_mutex_unlock(g_leCharacteristicMutex);
828 return CA_STATUS_FAILED;
831 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
834 OIC_LOG_V(ERROR, TAG,
835 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
836 oc_mutex_unlock(g_leCharacteristicMutex);
837 return CA_STATUS_FAILED;
840 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
844 OIC_LOG_V(ERROR, TAG,
845 "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
846 oc_mutex_unlock(g_leCharacteristicMutex);
847 return CA_STATUS_FAILED;
850 oc_mutex_unlock(g_leCharacteristicMutex);
852 OIC_LOG(DEBUG, TAG, "OUT");
856 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
858 OIC_LOG(DEBUG, TAG, "IN");
860 VERIFY_NON_NULL(charValue, TAG, "charValue");
862 oc_mutex_lock(g_leCharacteristicMutex);
864 if (NULL == g_gattReadCharPath)
866 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
867 oc_mutex_unlock(g_leCharacteristicMutex);
868 return CA_STATUS_FAILED;
871 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
874 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
875 oc_mutex_unlock(g_leCharacteristicMutex);
876 return CA_STATUS_FAILED;
879 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
883 OIC_LOG_V(ERROR, TAG,
884 "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
885 oc_mutex_unlock(g_leCharacteristicMutex);
886 return CA_STATUS_FAILED;
889 oc_mutex_unlock(g_leCharacteristicMutex);
891 OIC_LOG(DEBUG, TAG, "OUT");
895 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
897 OIC_LOG(DEBUG, TAG, "IN");
899 oc_mutex_lock(g_leReqRespCbMutex);
900 g_leServerDataReceivedCallback = callback;
901 oc_mutex_unlock(g_leReqRespCbMutex);
903 OIC_LOG(DEBUG, TAG, "OUT");
906 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
908 g_serverErrorCallback = callback;
911 bool CALEServerIsConnected(const char* address)
917 uint16_t CALEServerGetMtuSize(const char* address)
919 OIC_LOG(DEBUG, TAG, "IN");
920 VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
922 unsigned int mtu = CA_DEFAULT_BLE_MTU_SIZE + CA_BLE_MTU_HEADER_SIZE;
923 int ret = bt_device_get_att_mtu(address, &mtu);
926 OIC_LOG_V(ERROR, TAG,
927 "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
928 return CA_DEFAULT_BLE_MTU_SIZE;
930 OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
931 OIC_LOG(DEBUG, TAG, "OUT");
932 return mtu - CA_BLE_MTU_HEADER_SIZE;