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 "cautilinterface.h"
32 #include <bluetooth_internal.h>
36 * Logging tag for module name
38 //#define TAG "OIC_CA_LE_SERVER_MCD"
39 #define TAG BLE_SERVER_MCD_TAG
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 * Function called just before starting advertising
68 * provided data are used to setServerAdvertisementData
70 static CAAdvertisementDataGetterCB g_leServerAdvertisementDataGetter = NULL;
73 * Control if advertise will start automatically
75 static bool g_leServerAutoAdvertisement = true;
78 * Callback register with LE adapter. This callback is called on reception of any
79 * data from the remote device.
81 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
84 * Callback to notify any error in LE adapter.
86 static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
89 * To keep the state of GATT server if started or not.
91 static bool g_isLEGattServerStarted = false;
94 * Mutex to synchronize the calls to start and stop server.
96 static oc_mutex g_leServerStateMutex = NULL;
99 * Mutex to synchronize writing operations on the characteristics.
101 static oc_mutex g_leCharacteristicMutex = NULL;
104 * Mutex to synchronize to creation of OIC service.
106 static oc_mutex g_leServiceMutex = NULL;
109 * Mutex to synchronize access to the requestResponse callback to be called
110 * when the data needs to be sent from GATTClient.
112 static oc_mutex g_leReqRespCbMutex = NULL;
115 * Mutex to synchronize the task to be pushed to thread pool.
117 static oc_mutex g_leServerThreadPoolMutex = NULL;
120 * Reference to threadpool.
122 static ca_thread_pool_t g_leServerThreadPool = NULL;
125 * GmainLoop to manage the threads to receive the callback from the platfrom.
127 static GMainLoop *g_eventLoop = NULL;
130 * This contains the list of OIC clients connected to the server.
132 static LEClientInfoList *g_LEClientList = NULL;
135 * Mutex to synchronize access to LE ClientList.
137 static oc_mutex g_LEClientListMutex = NULL;
139 static const int samsung_code = 117;
141 static bool cutom_adv_flag = false;
142 static char *custom_adv_data = NULL;
143 static int custom_adv_data_length = 0;
145 static bool cutom_scanrsp_flag = false;
146 static char *custom_scanrsp_data = NULL;
147 static int custom_scanrsp_data_length = 0;
150 * Maximum length of BLE advertisement packet data size is acctually 24 bytes,
151 * but for safety reason 1 additional byte is allocated.
153 const int g_leAdvPacketDataSizeMax = 25;
156 CAResult_t CAsetServerAdvertisementData(const char *data, int length)
158 CAResult_t ret = CA_STATUS_OK;
160 OIC_LOG(DEBUG, TAG, "IN");
162 if(!data || strlen(data) <= 0 || length <=0 )
164 OIC_LOG(ERROR, TAG, "Invalid param is passed");
165 return CA_STATUS_INVALID_PARAM;
168 oc_mutex_lock(g_leServerStateMutex);
169 CAsetServerAdvertisementDataImpl(data, length);
170 oc_mutex_unlock(g_leServerStateMutex);
172 OIC_LOG(DEBUG, TAG, "OUT");
176 void CAsetServerAdvertisementDataImpl(const char *data, int length)
178 cutom_adv_flag = true;
179 custom_adv_data = data;
180 custom_adv_data_length = length;
182 OIC_LOG_V(DEBUG, TAG, "Custom advertise value has set as [%s]", custom_adv_data);
185 void CAsetServerAdvertisementDataGetter(CAAdvertisementDataGetterCB getter)
187 OIC_LOG(DEBUG, TAG, "IN");
189 oc_mutex_lock(g_leServerStateMutex);
190 g_leServerAdvertisementDataGetter = getter;
191 oc_mutex_unlock(g_leServerStateMutex);
193 OIC_LOG(DEBUG, TAG, "OUT");
196 void CAsetServerAutoAdvertisement(bool autoAdvertisement)
198 OIC_LOG(DEBUG, TAG, "IN");
200 oc_mutex_lock(g_leServerStateMutex);
201 g_leServerAutoAdvertisement = autoAdvertisement;
202 oc_mutex_unlock(g_leServerStateMutex);
204 OIC_LOG(DEBUG, TAG, "OUT");
207 CAResult_t CAsetServerScanResponseData(const char *data, int length)
210 CAResult_t ret = CA_STATUS_OK;
212 OIC_LOG(DEBUG, TAG, "IN");
214 if(!data || strlen(data) <= 0 || length <=0 )
216 OIC_LOG(ERROR, TAG, "Invalid param is passed");
217 return CA_STATUS_INVALID_PARAM;
220 oc_mutex_lock(g_leServerStateMutex);
222 cutom_scanrsp_flag = true;
223 custom_scanrsp_data = data;
224 custom_scanrsp_data_length = length;
226 oc_mutex_unlock(g_leServerStateMutex);
228 OIC_LOG_V(DEBUG, TAG, "Custom scan response value has set as [%s]", custom_scanrsp_data);
229 OIC_LOG(DEBUG, TAG, "OUT");
234 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
236 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
238 CAResult_t res = CA_STATUS_OK;
241 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
242 char *addr = OICStrdup(remoteAddress);
243 oc_mutex_lock(g_LEClientListMutex);
244 res = CAAddLEClientInfoToList(&g_LEClientList, addr);
245 if (CA_STATUS_OK != res)
247 OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
248 oc_mutex_unlock(g_LEClientListMutex);
252 oc_mutex_unlock(g_LEClientListMutex);
254 res = CALEStopAdvertise();
255 if (CA_STATUS_OK != res)
257 OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
263 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
264 oc_mutex_lock(g_LEClientListMutex);
265 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
266 oc_mutex_unlock(g_LEClientListMutex);
268 if(g_leServerAutoAdvertisement)
270 res = CALEStartAdvertise();
271 if (CA_STATUS_OK != res)
273 OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
279 OIC_LOG(WARNING, TAG, "Auto advertisement is DISABLED. Advertising is not started.");
285 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
286 bt_gatt_h characteristic, bool completed, void *user_data)
288 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
289 bt_gatt_h characteristic, bool completed, void *user_data)
292 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
295 CAResult_t CAStartLEGattServer()
297 OIC_LOG(DEBUG, TAG, "IN");
299 oc_mutex_lock(g_leServerStateMutex);
300 if (true == g_isLEGattServerStarted)
302 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
303 oc_mutex_unlock(g_leServerStateMutex);
307 CAResult_t ret = CAInitLEGattServer();
308 if (CA_STATUS_OK != ret)
310 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
311 oc_mutex_unlock(g_leServerStateMutex);
312 CATerminateLEGattServer();
313 return CA_STATUS_FAILED;
316 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
317 if (CA_STATUS_OK != ret)
319 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
320 oc_mutex_unlock(g_leServerStateMutex);
321 CATerminateLEGattServer();
322 return CA_STATUS_FAILED;
325 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
326 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
328 // For Read Characteristics.
329 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
330 sizeof(charReadValue), true);
331 if (CA_STATUS_OK != ret)
333 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
334 oc_mutex_unlock(g_leServerStateMutex);
335 CATerminateLEGattServer();
336 return CA_STATUS_FAILED;
339 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
340 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
343 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
344 sizeof(charWriteValue), false); // For Write Characteristics.
345 if (CA_STATUS_OK != ret )
347 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
348 oc_mutex_unlock(g_leServerStateMutex);
349 CATerminateLEGattServer();
350 return CA_STATUS_FAILED;
353 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
354 if (CA_STATUS_OK != ret )
356 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
357 oc_mutex_unlock(g_leServerStateMutex);
358 CATerminateLEGattServer();
359 return CA_STATUS_FAILED;
362 if(g_leServerAutoAdvertisement)
364 ret = CALEStartAdvertise();
365 if (CA_STATUS_OK != ret)
367 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
368 oc_mutex_unlock(g_leServerStateMutex);
369 CATerminateLEGattServer();
370 return CA_STATUS_FAILED;
375 OIC_LOG(WARNING, TAG, "Auto advertisement is DISABLED. Advertising is not started.");
378 g_isLEGattServerStarted = true;
380 oc_mutex_unlock(g_leServerStateMutex);
382 OIC_LOG(DEBUG, TAG, "OUT");
386 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
389 OIC_LOG(DEBUG, TAG, "IN");
392 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
393 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
394 true, "notifyChar success");
398 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
399 false, "notifyChar failure");
401 OIC_LOG(DEBUG, TAG, "OUT");
404 CAResult_t CALEStartAdvertise()
406 OIC_LOG(DEBUG, TAG, "IN");
409 if(g_leServerAdvertisementDataGetter)
412 data = (char*) malloc(g_leAdvPacketDataSizeMax);
413 g_leServerAdvertisementDataGetter(g_leAdvPacketDataSizeMax, data, &length);
414 if(!data || length <= 0)
416 OIC_LOG(WARNING, TAG, "Invalid data. Custom advertisement data will not be set.");
420 CAsetServerAdvertisementDataImpl(data, length);
424 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
425 if (CA_STATUS_OK != res)
427 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
430 //This array is freed here because it's used in CALEStartAdvertiseImpl() method (freeing earlier causes bluetooth to crash)
433 OIC_LOG(DEBUG, TAG, "OUT");
437 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
439 OIC_LOG(DEBUG, TAG, "IN");
443 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
444 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
446 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
447 return CA_STATUS_FAILED;
450 if (cutom_adv_flag == false) // Advertise with Default Service UUID
452 OIC_LOG(DEBUG, TAG, "Advertise with default Service UUID");
454 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
455 BT_ADAPTER_LE_PACKET_ADVERTISING,
457 if (BT_ERROR_NONE != res)
459 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
460 CALEGetErrorMsg(res));
461 return CA_STATUS_FAILED;
464 else // Advertise with custom advertise data
466 OIC_LOG(DEBUG, TAG, "Advertise with custom advertise data");
468 res = bt_adapter_le_add_advertising_manufacturer_data(g_hAdvertiser,BT_ADAPTER_LE_PACKET_ADVERTISING, samsung_code, custom_adv_data, custom_adv_data_length);
469 if (BT_ERROR_NONE != res)
471 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data failed(BT_ADAPTER_LE_PACKET_ADVERTISING) with ret[%s]",
472 CALEGetErrorMsg(res));
473 return CA_STATUS_FAILED;
478 if(cutom_scanrsp_flag == false)
480 OIC_LOG(DEBUG, TAG, "Advertise with default scan response data");
482 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
483 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
484 if (BT_ERROR_NONE != res)
486 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
487 CALEGetErrorMsg(res));
488 return CA_STATUS_FAILED;
491 else // Advertise with custom advertise data
493 OIC_LOG(DEBUG, TAG, "Advertise with custom scan response data");
495 res = bt_adapter_le_add_advertising_manufacturer_data(g_hAdvertiser,BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, samsung_code, custom_scanrsp_data, custom_scanrsp_data_length);
496 if (BT_ERROR_NONE != res)
498 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data(BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) failed with ret[%s]",
499 CALEGetErrorMsg(res));
500 return CA_STATUS_FAILED;
505 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
506 if (BT_ERROR_NONE != res)
508 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
509 CALEGetErrorMsg(res));
510 return CA_STATUS_FAILED;
513 OIC_LOG(DEBUG, TAG, "OUT");
517 CAResult_t CALEStopAdvertise()
519 OIC_LOG(DEBUG, TAG, "IN");
520 if (NULL != g_hAdvertiser)
522 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
525 OIC_LOG_V(ERROR, TAG,
526 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
529 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
532 OIC_LOG_V(ERROR, TAG,
533 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
535 g_hAdvertiser = NULL;
539 OIC_LOG(ERROR, TAG, "Advertising is not running");
540 return CA_STATUS_FAILED;
543 OIC_LOG(DEBUG, TAG, "OUT");
547 CAResult_t CAStopLEGattServer()
549 OIC_LOG(DEBUG, TAG, "IN");
551 oc_mutex_lock(g_leServerStateMutex);
553 if (false == g_isLEGattServerStarted)
555 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
556 oc_mutex_unlock(g_leServerStateMutex);
560 g_isLEGattServerStarted = false;
561 cutom_adv_flag = false;
562 custom_adv_data = NULL;
563 custom_adv_data_length = 0;
564 cutom_scanrsp_flag = false;
565 custom_scanrsp_data = NULL;
566 custom_scanrsp_data_length = 0;
568 oc_mutex_lock(g_LEClientListMutex);
569 CADisconnectAllClient(g_LEClientList);
570 g_LEClientList = NULL;
571 oc_mutex_unlock(g_LEClientListMutex);
573 CAResult_t res = CALEStopAdvertise();
575 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
578 res = CADeInitLEGattServer();
579 if (CA_STATUS_OK != res)
581 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
584 GMainContext *context_event_loop = NULL;
585 // Required for waking up the thread which is running in gmain loop
586 if (NULL != g_eventLoop)
588 context_event_loop = g_main_loop_get_context(g_eventLoop);
590 if (context_event_loop)
592 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
593 g_main_context_wakeup(context_event_loop);
595 // Kill g main loops and kill threads
596 g_main_loop_quit(g_eventLoop);
602 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
605 oc_mutex_unlock(g_leServerStateMutex);
607 OIC_LOG(DEBUG, TAG, "OUT");
611 CAResult_t CAInitializeLEGattServer()
613 OIC_LOG(DEBUG, TAG, "IN");
615 CAResult_t ret = CAInitGattServerMutexVariables();
616 if (CA_STATUS_OK != ret )
618 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
619 CATerminateGattServerMutexVariables();
620 return CA_SERVER_NOT_STARTED;
622 OIC_LOG(DEBUG, TAG, "OUT");
626 void CATerminateLEGattServer()
628 OIC_LOG(DEBUG, TAG, "IN");
630 // Service and characteristics path will be freed by the platform.
631 oc_mutex_lock(g_leServiceMutex);
632 g_gattSvcPath = NULL;
633 oc_mutex_unlock(g_leServiceMutex);
635 oc_mutex_lock(g_leCharacteristicMutex);
636 g_gattReadCharPath = NULL;
637 g_gattWriteCharPath = NULL;
638 oc_mutex_unlock(g_leCharacteristicMutex);
640 oc_mutex_lock(g_leServerThreadPoolMutex);
641 g_leServerThreadPool = NULL;
642 oc_mutex_unlock(g_leServerThreadPoolMutex);
644 // Terminating all mutex variables.
645 CATerminateGattServerMutexVariables();
646 OIC_LOG(DEBUG, TAG, "OUT");
649 CAResult_t CAInitGattServerMutexVariables()
651 OIC_LOG(DEBUG, TAG, "IN");
652 if (NULL == g_leServerStateMutex)
654 g_leServerStateMutex = oc_mutex_new();
655 if (NULL == g_leServerStateMutex)
657 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
658 return CA_STATUS_FAILED;
662 if (NULL == g_leServiceMutex)
664 g_leServiceMutex = oc_mutex_new();
665 if (NULL == g_leServiceMutex)
667 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
668 return CA_STATUS_FAILED;
672 if (NULL == g_leCharacteristicMutex)
674 g_leCharacteristicMutex = oc_mutex_new();
675 if (NULL == g_leCharacteristicMutex)
677 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
678 return CA_STATUS_FAILED;
682 if (NULL == g_leReqRespCbMutex)
684 g_leReqRespCbMutex = oc_mutex_new();
685 if (NULL == g_leReqRespCbMutex)
687 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
688 return CA_STATUS_FAILED;
692 if (NULL == g_leServerThreadPoolMutex)
694 g_leServerThreadPoolMutex = oc_mutex_new();
695 if (NULL == g_leServerThreadPoolMutex)
697 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
698 return CA_STATUS_FAILED;
702 if (NULL == g_LEClientListMutex)
704 g_LEClientListMutex = oc_mutex_new();
705 if (NULL == g_LEClientListMutex)
707 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
708 return CA_STATUS_FAILED;
712 OIC_LOG(DEBUG, TAG, "OUT");
716 void CATerminateGattServerMutexVariables()
718 OIC_LOG(DEBUG, TAG, "IN");
719 oc_mutex_free(g_leServerStateMutex);
720 g_leServerStateMutex = NULL;
722 oc_mutex_free(g_leServiceMutex);
723 g_leServiceMutex = NULL;
725 oc_mutex_free(g_leCharacteristicMutex);
726 g_leCharacteristicMutex = NULL;
728 oc_mutex_free(g_leReqRespCbMutex);
729 g_leReqRespCbMutex = NULL;
731 oc_mutex_free(g_leServerThreadPoolMutex);
732 g_leServerThreadPoolMutex = NULL;
734 oc_mutex_free(g_LEClientListMutex);
735 g_LEClientListMutex = NULL;
737 OIC_LOG(DEBUG, TAG, "OUT");
740 CAResult_t CAInitLEGattServer()
742 OIC_LOG(DEBUG, TAG, "IN");
744 int ret = bt_gatt_server_initialize();
747 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
748 CALEGetErrorMsg(ret));
749 return CA_STATUS_FAILED;
754 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
755 ret = bt_gatt_server_create(&g_gattServer);
758 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
759 CALEGetErrorMsg(ret));
760 bt_gatt_server_deinitialize();
761 return CA_STATUS_FAILED;
765 OIC_LOG(DEBUG, TAG, "OUT");
769 CAResult_t CADeInitLEGattServer()
771 OIC_LOG(DEBUG, TAG, "IN");
773 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
776 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
777 CALEGetErrorMsg(ret));
778 // CONPRO-1181 continue even bt API fails during DeInit
779 //return CA_STATUS_FAILED;
782 ret = bt_gatt_server_destroy(g_gattServer);
785 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
786 CALEGetErrorMsg(ret));
787 // CONPRO-1181 continue even bt API fails during DeInit
788 //return CA_STATUS_FAILED;
792 ret = bt_gatt_server_deinitialize();
795 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
796 CALEGetErrorMsg(ret));
797 // CONPRO-1181 continue even bt API fails during DeInit
798 //return CA_STATUS_FAILED;
801 OIC_LOG(DEBUG, TAG, "OUT");
805 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
807 OIC_LOG(DEBUG, TAG, "IN");
808 oc_mutex_lock(g_leServerThreadPoolMutex);
809 g_leServerThreadPool = handle;
810 oc_mutex_unlock(g_leServerThreadPoolMutex);
811 OIC_LOG(DEBUG, TAG, "OUT");
814 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
816 OIC_LOG(DEBUG, TAG, "IN");
818 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
820 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
822 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
824 oc_mutex_lock(g_leServiceMutex);
825 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
828 oc_mutex_unlock(g_leServiceMutex);
829 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
830 CALEGetErrorMsg(ret));
831 return CA_STATUS_FAILED;
833 oc_mutex_unlock(g_leServiceMutex);
837 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
840 OIC_LOG(DEBUG, TAG, "OUT");
845 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
846 bt_gatt_server_h server, bt_gatt_h gatt_handle,
847 bool response_needed, int offset, const char *charValue,
848 int charLen, void *userData)
850 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
851 bt_gatt_h gatt_handle, int offset, char *charValue,
852 int charLen, void *userData)
855 OIC_LOG(INFO, TAG, "IN - WriteCharCB");
857 if (NULL == charValue || NULL == remoteAddress)
859 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
863 OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
865 uint8_t *data = OICMalloc(charLen);
868 OIC_LOG(ERROR, TAG, "Malloc failed!");
872 memcpy(data, charValue, charLen);
874 oc_mutex_lock(g_leReqRespCbMutex);
875 if (NULL == g_leServerDataReceivedCallback)
877 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
878 oc_mutex_unlock(g_leReqRespCbMutex);
883 OIC_LOG(INFO, TAG, "Sending data up !");
884 uint32_t sentLength = 0;
885 g_leServerDataReceivedCallback(remoteAddress, data, charLen,
887 oc_mutex_unlock(g_leReqRespCbMutex);
892 OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
895 OIC_LOG(INFO, TAG, "send response to remote client");
896 bt_gatt_server_send_response(request_id,
897 BT_GATT_REQUEST_TYPE_WRITE, offset,
898 BT_ERROR_NONE, NULL, 0);
902 OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
905 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
907 OIC_LOG(DEBUG, TAG, "IN");
909 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
911 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
913 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
916 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
917 CALEGetErrorMsg(ret));
918 return CA_STATUS_FAILED;
921 ret = bt_gatt_server_start();
924 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
925 CALEGetErrorMsg(ret));
926 return CA_STATUS_FAILED;
930 ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
932 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
934 CALEGattRemoteCharacteristicWriteCb, NULL);
938 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
939 CALEGetErrorMsg(ret));
940 return CA_STATUS_FAILED;
943 OIC_LOG(DEBUG, TAG, "OUT");
947 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
948 const char *charValue, int charValueLen, bool read)
951 OIC_LOG(DEBUG, TAG, "IN");
953 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
957 properties = BT_GATT_PROPERTY_INDICATE;
961 properties = BT_GATT_PROPERTY_WRITE;
964 bt_gatt_h charPath = NULL;
966 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
967 charValueLen, &charPath);
969 if (0 != ret || NULL == charPath)
971 OIC_LOG_V(ERROR, TAG,
972 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
973 return CA_STATUS_FAILED;
976 OIC_LOG_V(DEBUG, TAG,
977 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
982 ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
986 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
990 OIC_LOG_V(ERROR, TAG,
992 "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
994 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
996 CALEGetErrorMsg(ret));
997 return CA_STATUS_FAILED;
1001 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
1004 OIC_LOG_V(ERROR, TAG,
1005 "bt_gatt_service_add_characteristic failed with ret[%s]",
1006 CALEGetErrorMsg(ret));
1007 return CA_STATUS_FAILED;
1010 oc_mutex_lock(g_leCharacteristicMutex);
1014 char desc_value[2] = {1, 0}; // Notification enabled.
1015 bt_gatt_h descriptor = NULL;
1016 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
1017 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
1018 desc_value, sizeof(desc_value),
1022 oc_mutex_unlock(g_leCharacteristicMutex);
1023 OIC_LOG_V(ERROR, TAG,
1024 "bt_gatt_descriptor_create failed with ret[%s]",
1025 CALEGetErrorMsg(ret));
1026 return CA_STATUS_FAILED;
1029 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
1032 oc_mutex_unlock(g_leCharacteristicMutex);
1033 OIC_LOG_V(ERROR, TAG,
1034 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
1035 CALEGetErrorMsg(ret));
1036 return CA_STATUS_FAILED;
1039 g_gattReadCharPath = charPath;
1043 g_gattWriteCharPath = charPath;
1046 oc_mutex_unlock(g_leCharacteristicMutex);
1048 OIC_LOG(DEBUG, TAG, "OUT");
1049 return CA_STATUS_OK;
1052 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
1053 uint32_t charValueLen)
1055 OIC_LOG(DEBUG, TAG, "IN");
1057 VERIFY_NON_NULL(charValue, TAG, "charValue");
1058 VERIFY_NON_NULL(address, TAG, "address");
1060 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
1062 oc_mutex_lock(g_leCharacteristicMutex);
1064 if (NULL == g_gattReadCharPath)
1066 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
1067 oc_mutex_unlock(g_leCharacteristicMutex);
1068 return CA_STATUS_FAILED;
1071 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
1074 OIC_LOG_V(ERROR, TAG,
1075 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
1076 oc_mutex_unlock(g_leCharacteristicMutex);
1077 return CA_STATUS_FAILED;
1081 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
1082 CALEServerNotificationSentCB,
1085 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1091 OIC_LOG_V(ERROR, TAG,
1093 "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
1095 "bt_gatt_server_notify failed with return [%s]",
1097 CALEGetErrorMsg(ret));
1098 oc_mutex_unlock(g_leCharacteristicMutex);
1099 return CA_STATUS_FAILED;
1102 oc_mutex_unlock(g_leCharacteristicMutex);
1104 OIC_LOG(DEBUG, TAG, "OUT");
1105 return CA_STATUS_OK;
1108 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
1110 OIC_LOG(DEBUG, TAG, "IN");
1112 VERIFY_NON_NULL(charValue, TAG, "charValue");
1114 oc_mutex_lock(g_leCharacteristicMutex);
1116 if (NULL == g_gattReadCharPath)
1118 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
1119 oc_mutex_unlock(g_leCharacteristicMutex);
1120 return CA_STATUS_FAILED;
1123 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
1126 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
1127 oc_mutex_unlock(g_leCharacteristicMutex);
1128 return CA_STATUS_FAILED;
1132 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
1133 CALEServerNotificationSentCB,
1136 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1141 OIC_LOG_V(ERROR, TAG,
1143 "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
1145 "bt_gatt_server_notify failed with return[%s]",
1147 CALEGetErrorMsg(ret));
1148 oc_mutex_unlock(g_leCharacteristicMutex);
1149 return CA_STATUS_FAILED;
1152 oc_mutex_unlock(g_leCharacteristicMutex);
1154 OIC_LOG(DEBUG, TAG, "OUT");
1155 return CA_STATUS_OK;
1158 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1160 OIC_LOG(DEBUG, TAG, "IN");
1162 oc_mutex_lock(g_leReqRespCbMutex);
1163 g_leServerDataReceivedCallback = callback;
1164 oc_mutex_unlock(g_leReqRespCbMutex);
1166 OIC_LOG(DEBUG, TAG, "OUT");
1169 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1171 g_serverErrorCallback = callback;
1174 bool CALEServerIsConnected(const char* address)
1180 uint16_t CALEServerGetMtuSize(const char* address)
1182 OIC_LOG(DEBUG, TAG, "IN");
1183 VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1185 unsigned int mtu = CA_DEFAULT_BLE_MTU_SIZE;
1189 bt_gatt_client_h client = NULL;
1190 ret = bt_gatt_client_create(address, &client);
1193 OIC_LOG_V(ERROR, TAG,
1194 "bt_gatt_client_create failed with return [%s]", CALEGetErrorMsg(ret));
1195 return CA_DEFAULT_BLE_MTU_SIZE;
1198 ret = bt_gatt_client_get_att_mtu(client, &mtu);
1201 OIC_LOG_V(ERROR, TAG,
1202 "bt_gatt_client_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1203 return CA_DEFAULT_BLE_MTU_SIZE;
1206 ret = bt_gatt_client_destroy(client);
1209 OIC_LOG_V(ERROR, TAG,
1210 "bt_gatt_client_destroy failed with return [%s]", CALEGetErrorMsg(ret));
1211 return CA_DEFAULT_BLE_MTU_SIZE;
1214 ret = bt_device_get_att_mtu(address, &mtu);
1217 OIC_LOG_V(ERROR, TAG,
1218 "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1219 return CA_DEFAULT_BLE_MTU_SIZE;
1223 OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1224 OIC_LOG(DEBUG, TAG, "OUT");
1225 return mtu - CA_BLE_MTU_HEADER_SIZE;