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"
31 #include <bluetooth_internal.h>
35 * Logging tag for module name
37 //#define TAG "OIC_CA_LE_SERVER_MCD"
38 #define TAG BLE_SERVER_MCD_TAG
41 * The handle of the OIC server.
43 static bt_gatt_server_h g_gattServer = NULL;
46 * The handle of the OIC service.
48 static bt_gatt_h g_gattSvcPath = NULL;
51 * The handle of the OIC read characteristics.
53 static bt_gatt_h g_gattReadCharPath = NULL;
56 * The handle of the OIC write characteristics.
58 static bt_gatt_h g_gattWriteCharPath = NULL;
61 * The handle to control Bluetooth LE advertising.
63 static bt_advertiser_h g_hAdvertiser = NULL;
66 * Callback register with LE adapter. This callback is called on reception of any
67 * data from the remote device.
69 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
72 * Callback to notify any error in LE adapter.
74 static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
77 * To keep the state of GATT server if started or not.
79 static bool g_isLEGattServerStarted = false;
82 * Mutex to synchronize the calls to start and stop server.
84 static oc_mutex g_leServerStateMutex = NULL;
87 * Mutex to synchronize writing operations on the characteristics.
89 static oc_mutex g_leCharacteristicMutex = NULL;
92 * Mutex to synchronize to creation of OIC service.
94 static oc_mutex g_leServiceMutex = NULL;
97 * Mutex to synchronize access to the requestResponse callback to be called
98 * when the data needs to be sent from GATTClient.
100 static oc_mutex g_leReqRespCbMutex = NULL;
103 * Mutex to synchronize the task to be pushed to thread pool.
105 static oc_mutex g_leServerThreadPoolMutex = NULL;
108 * Reference to threadpool.
110 static ca_thread_pool_t g_leServerThreadPool = NULL;
113 * GmainLoop to manage the threads to receive the callback from the platfrom.
115 static GMainLoop *g_eventLoop = NULL;
118 * This contains the list of OIC clients connected to the server.
120 static LEClientInfoList *g_LEClientList = NULL;
123 * Mutex to synchronize access to LE ClientList.
125 static oc_mutex g_LEClientListMutex = NULL;
127 static const int samsung_code = 117;
129 static bool cutom_adv_flag = false;
130 static char *custom_adv_data = NULL;
131 static int custom_adv_data_length = 0;
133 static bool cutom_scanrsp_flag = false;
134 static char *custom_scanrsp_data = NULL;
135 static int custom_scanrsp_data_length = 0;
137 CAResult_t CAsetServerAdvertisementData(const char *data, int length)
140 CAResult_t ret = CA_STATUS_OK;
142 OIC_LOG(DEBUG, TAG, "IN");
144 if(!data || strlen(data) <= 0 || length <=0 )
146 OIC_LOG(ERROR, TAG, "Invalid param is passed");
147 return CA_STATUS_INVALID_PARAM;
150 oc_mutex_lock(g_leServerStateMutex);
152 cutom_adv_flag = true;
153 custom_adv_data = data;
154 custom_adv_data_length = length;
156 oc_mutex_unlock(g_leServerStateMutex);
158 OIC_LOG_V(DEBUG, TAG, "Custom advertise value has set as [%s]", custom_adv_data);
159 OIC_LOG(DEBUG, TAG, "OUT");
164 CAResult_t CAsetServerSanResponseData(const char *data, int length)
167 CAResult_t ret = CA_STATUS_OK;
169 OIC_LOG(DEBUG, TAG, "IN");
171 if(!data || strlen(data) <= 0 || length <=0 )
173 OIC_LOG(ERROR, TAG, "Invalid param is passed");
174 return CA_STATUS_INVALID_PARAM;
177 oc_mutex_lock(g_leServerStateMutex);
179 cutom_scanrsp_flag = true;
180 custom_scanrsp_data = data;
181 custom_scanrsp_data_length = length;
183 oc_mutex_unlock(g_leServerStateMutex);
185 OIC_LOG_V(DEBUG, TAG, "Custom scan response value has set as [%s]", custom_scanrsp_data);
186 OIC_LOG(DEBUG, TAG, "OUT");
191 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
193 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
195 CAResult_t res = CA_STATUS_OK;
198 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
199 char *addr = OICStrdup(remoteAddress);
200 oc_mutex_lock(g_LEClientListMutex);
201 res = CAAddLEClientInfoToList(&g_LEClientList, addr);
202 if (CA_STATUS_OK != res)
204 OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
205 oc_mutex_unlock(g_LEClientListMutex);
209 oc_mutex_unlock(g_LEClientListMutex);
211 res = CALEStopAdvertise();
212 if (CA_STATUS_OK != res)
214 OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
220 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
221 oc_mutex_lock(g_LEClientListMutex);
222 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
223 oc_mutex_unlock(g_LEClientListMutex);
225 res = CALEStartAdvertise();
226 if (CA_STATUS_OK != res)
228 OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
235 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
236 bt_gatt_h characteristic, bool completed, void *user_data)
238 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
239 bt_gatt_h characteristic, bool completed, void *user_data)
242 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
245 CAResult_t CAStartLEGattServer()
247 OIC_LOG(DEBUG, TAG, "IN");
249 oc_mutex_lock(g_leServerStateMutex);
250 if (true == g_isLEGattServerStarted)
252 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
253 oc_mutex_unlock(g_leServerStateMutex);
257 CAResult_t ret = CAInitLEGattServer();
258 if (CA_STATUS_OK != ret)
260 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
261 oc_mutex_unlock(g_leServerStateMutex);
262 CATerminateLEGattServer();
263 return CA_STATUS_FAILED;
266 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
267 if (CA_STATUS_OK != ret)
269 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
270 oc_mutex_unlock(g_leServerStateMutex);
271 CATerminateLEGattServer();
272 return CA_STATUS_FAILED;
275 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
276 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
278 // For Read Characteristics.
279 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
280 sizeof(charReadValue), true);
281 if (CA_STATUS_OK != ret)
283 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
284 oc_mutex_unlock(g_leServerStateMutex);
285 CATerminateLEGattServer();
286 return CA_STATUS_FAILED;
289 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
290 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
293 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
294 sizeof(charWriteValue), false); // For Write Characteristics.
295 if (CA_STATUS_OK != ret )
297 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
298 oc_mutex_unlock(g_leServerStateMutex);
299 CATerminateLEGattServer();
300 return CA_STATUS_FAILED;
303 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
304 if (CA_STATUS_OK != ret )
306 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
307 oc_mutex_unlock(g_leServerStateMutex);
308 CATerminateLEGattServer();
309 return CA_STATUS_FAILED;
312 ret = CALEStartAdvertise();
313 if (CA_STATUS_OK != ret)
315 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
316 oc_mutex_unlock(g_leServerStateMutex);
317 CATerminateLEGattServer();
318 return CA_STATUS_FAILED;
321 g_isLEGattServerStarted = true;
323 oc_mutex_unlock(g_leServerStateMutex);
325 OIC_LOG(DEBUG, TAG, "OUT");
329 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
332 OIC_LOG(DEBUG, TAG, "IN");
335 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
336 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
337 true, "notifyChar success");
341 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
342 false, "notifyChar failure");
344 OIC_LOG(DEBUG, TAG, "OUT");
347 CAResult_t CALEStartAdvertise()
349 OIC_LOG(DEBUG, TAG, "IN");
351 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
352 if (CA_STATUS_OK != res)
354 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
357 OIC_LOG(DEBUG, TAG, "OUT");
361 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
363 OIC_LOG(DEBUG, TAG, "IN");
367 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
368 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
370 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
371 return CA_STATUS_FAILED;
374 if (cutom_adv_flag == false) // Advertise with Default Service UUID
376 OIC_LOG(DEBUG, TAG, "Advertise with default Service UUID");
378 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
379 BT_ADAPTER_LE_PACKET_ADVERTISING,
381 if (BT_ERROR_NONE != res)
383 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
384 CALEGetErrorMsg(res));
385 return CA_STATUS_FAILED;
388 else // Advertise with custom advertise data
390 OIC_LOG(DEBUG, TAG, "Advertise with custom advertise data");
392 res = bt_adapter_le_add_advertising_manufacturer_data(g_hAdvertiser,BT_ADAPTER_LE_PACKET_ADVERTISING, samsung_code, custom_adv_data, custom_adv_data_length);
393 if (BT_ERROR_NONE != res)
395 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data failed(BT_ADAPTER_LE_PACKET_ADVERTISING) with ret[%s]",
396 CALEGetErrorMsg(res));
397 return CA_STATUS_FAILED;
402 if(cutom_scanrsp_flag == false)
404 OIC_LOG(DEBUG, TAG, "Advertise with default scan response data");
406 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
407 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
408 if (BT_ERROR_NONE != res)
410 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
411 CALEGetErrorMsg(res));
412 return CA_STATUS_FAILED;
415 else // Advertise with custom advertise data
417 OIC_LOG(DEBUG, TAG, "Advertise with custom scan response data");
419 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);
420 if (BT_ERROR_NONE != res)
422 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data(BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) failed with ret[%s]",
423 CALEGetErrorMsg(res));
424 return CA_STATUS_FAILED;
429 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
430 if (BT_ERROR_NONE != res)
432 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
433 CALEGetErrorMsg(res));
434 return CA_STATUS_FAILED;
437 OIC_LOG(DEBUG, TAG, "OUT");
441 CAResult_t CALEStopAdvertise()
443 OIC_LOG(DEBUG, TAG, "IN");
444 if (NULL != g_hAdvertiser)
446 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
449 OIC_LOG_V(ERROR, TAG,
450 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
453 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
456 OIC_LOG_V(ERROR, TAG,
457 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
459 g_hAdvertiser = NULL;
463 OIC_LOG(ERROR, TAG, "Advertising is not running");
464 return CA_STATUS_FAILED;
467 OIC_LOG(DEBUG, TAG, "OUT");
471 CAResult_t CAStopLEGattServer()
473 OIC_LOG(DEBUG, TAG, "IN");
475 oc_mutex_lock(g_leServerStateMutex);
477 if (false == g_isLEGattServerStarted)
479 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
480 oc_mutex_unlock(g_leServerStateMutex);
484 g_isLEGattServerStarted = false;
485 cutom_adv_flag = false;
486 custom_adv_data = NULL;
487 custom_adv_data_length = 0;
488 cutom_scanrsp_flag = false;
489 custom_scanrsp_data = NULL;
490 custom_scanrsp_data_length = 0;
492 oc_mutex_lock(g_LEClientListMutex);
493 CADisconnectAllClient(g_LEClientList);
494 g_LEClientList = NULL;
495 oc_mutex_unlock(g_LEClientListMutex);
497 CAResult_t res = CALEStopAdvertise();
499 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
502 res = CADeInitLEGattServer();
503 if (CA_STATUS_OK != res)
505 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
508 GMainContext *context_event_loop = NULL;
509 // Required for waking up the thread which is running in gmain loop
510 if (NULL != g_eventLoop)
512 context_event_loop = g_main_loop_get_context(g_eventLoop);
514 if (context_event_loop)
516 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
517 g_main_context_wakeup(context_event_loop);
519 // Kill g main loops and kill threads
520 g_main_loop_quit(g_eventLoop);
526 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
529 oc_mutex_unlock(g_leServerStateMutex);
531 OIC_LOG(DEBUG, TAG, "OUT");
535 CAResult_t CAInitializeLEGattServer()
537 OIC_LOG(DEBUG, TAG, "IN");
539 CAResult_t ret = CAInitGattServerMutexVariables();
540 if (CA_STATUS_OK != ret )
542 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
543 CATerminateGattServerMutexVariables();
544 return CA_SERVER_NOT_STARTED;
546 OIC_LOG(DEBUG, TAG, "OUT");
550 void CATerminateLEGattServer()
552 OIC_LOG(DEBUG, TAG, "IN");
554 // Service and characteristics path will be freed by the platform.
555 oc_mutex_lock(g_leServiceMutex);
556 g_gattSvcPath = NULL;
557 oc_mutex_unlock(g_leServiceMutex);
559 oc_mutex_lock(g_leCharacteristicMutex);
560 g_gattReadCharPath = NULL;
561 g_gattWriteCharPath = NULL;
562 oc_mutex_unlock(g_leCharacteristicMutex);
564 oc_mutex_lock(g_leServerThreadPoolMutex);
565 g_leServerThreadPool = NULL;
566 oc_mutex_unlock(g_leServerThreadPoolMutex);
568 // Terminating all mutex variables.
569 CATerminateGattServerMutexVariables();
570 OIC_LOG(DEBUG, TAG, "OUT");
573 CAResult_t CAInitGattServerMutexVariables()
575 OIC_LOG(DEBUG, TAG, "IN");
576 if (NULL == g_leServerStateMutex)
578 g_leServerStateMutex = oc_mutex_new();
579 if (NULL == g_leServerStateMutex)
581 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
582 return CA_STATUS_FAILED;
586 if (NULL == g_leServiceMutex)
588 g_leServiceMutex = oc_mutex_new();
589 if (NULL == g_leServiceMutex)
591 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
592 return CA_STATUS_FAILED;
596 if (NULL == g_leCharacteristicMutex)
598 g_leCharacteristicMutex = oc_mutex_new();
599 if (NULL == g_leCharacteristicMutex)
601 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
602 return CA_STATUS_FAILED;
606 if (NULL == g_leReqRespCbMutex)
608 g_leReqRespCbMutex = oc_mutex_new();
609 if (NULL == g_leReqRespCbMutex)
611 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
612 return CA_STATUS_FAILED;
616 if (NULL == g_leServerThreadPoolMutex)
618 g_leServerThreadPoolMutex = oc_mutex_new();
619 if (NULL == g_leServerThreadPoolMutex)
621 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
622 return CA_STATUS_FAILED;
626 if (NULL == g_LEClientListMutex)
628 g_LEClientListMutex = oc_mutex_new();
629 if (NULL == g_LEClientListMutex)
631 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
632 return CA_STATUS_FAILED;
636 OIC_LOG(DEBUG, TAG, "OUT");
640 void CATerminateGattServerMutexVariables()
642 OIC_LOG(DEBUG, TAG, "IN");
643 oc_mutex_free(g_leServerStateMutex);
644 g_leServerStateMutex = NULL;
646 oc_mutex_free(g_leServiceMutex);
647 g_leServiceMutex = NULL;
649 oc_mutex_free(g_leCharacteristicMutex);
650 g_leCharacteristicMutex = NULL;
652 oc_mutex_free(g_leReqRespCbMutex);
653 g_leReqRespCbMutex = NULL;
655 oc_mutex_free(g_leServerThreadPoolMutex);
656 g_leServerThreadPoolMutex = NULL;
658 oc_mutex_free(g_LEClientListMutex);
659 g_LEClientListMutex = NULL;
661 OIC_LOG(DEBUG, TAG, "OUT");
664 CAResult_t CAInitLEGattServer()
666 OIC_LOG(DEBUG, TAG, "IN");
668 int ret = bt_gatt_server_initialize();
671 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
672 CALEGetErrorMsg(ret));
673 return CA_STATUS_FAILED;
678 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
679 ret = bt_gatt_server_create(&g_gattServer);
682 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
683 CALEGetErrorMsg(ret));
684 bt_gatt_server_deinitialize();
685 return CA_STATUS_FAILED;
689 OIC_LOG(DEBUG, TAG, "OUT");
693 CAResult_t CADeInitLEGattServer()
695 OIC_LOG(DEBUG, TAG, "IN");
697 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
700 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
701 CALEGetErrorMsg(ret));
702 // CONPRO-1181 continue even bt API fails during DeInit
703 //return CA_STATUS_FAILED;
706 ret = bt_gatt_server_destroy(g_gattServer);
709 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
710 CALEGetErrorMsg(ret));
711 // CONPRO-1181 continue even bt API fails during DeInit
712 //return CA_STATUS_FAILED;
716 ret = bt_gatt_server_deinitialize();
719 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
720 CALEGetErrorMsg(ret));
721 // CONPRO-1181 continue even bt API fails during DeInit
722 //return CA_STATUS_FAILED;
725 OIC_LOG(DEBUG, TAG, "OUT");
729 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
731 OIC_LOG(DEBUG, TAG, "IN");
732 oc_mutex_lock(g_leServerThreadPoolMutex);
733 g_leServerThreadPool = handle;
734 oc_mutex_unlock(g_leServerThreadPoolMutex);
735 OIC_LOG(DEBUG, TAG, "OUT");
738 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
740 OIC_LOG(DEBUG, TAG, "IN");
742 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
744 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
746 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
748 oc_mutex_lock(g_leServiceMutex);
749 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
752 oc_mutex_unlock(g_leServiceMutex);
753 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
754 CALEGetErrorMsg(ret));
755 return CA_STATUS_FAILED;
757 oc_mutex_unlock(g_leServiceMutex);
761 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
764 OIC_LOG(DEBUG, TAG, "OUT");
769 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
770 bt_gatt_server_h server, bt_gatt_h gatt_handle,
771 bool response_needed, int offset, const char *charValue,
772 int charLen, void *userData)
774 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
775 bt_gatt_h gatt_handle, int offset, char *charValue,
776 int charLen, void *userData)
779 OIC_LOG(INFO, TAG, "IN - WriteCharCB");
781 if (NULL == charValue || NULL == remoteAddress)
783 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
787 OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
789 uint8_t *data = OICMalloc(charLen);
792 OIC_LOG(ERROR, TAG, "Malloc failed!");
796 memcpy(data, charValue, charLen);
798 oc_mutex_lock(g_leReqRespCbMutex);
799 if (NULL == g_leServerDataReceivedCallback)
801 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
802 oc_mutex_unlock(g_leReqRespCbMutex);
807 OIC_LOG(INFO, TAG, "Sending data up !");
808 uint32_t sentLength = 0;
809 g_leServerDataReceivedCallback(remoteAddress, data, charLen,
811 oc_mutex_unlock(g_leReqRespCbMutex);
816 OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
819 OIC_LOG(INFO, TAG, "send response to remote client");
820 bt_gatt_server_send_response(request_id,
821 BT_GATT_REQUEST_TYPE_WRITE, offset,
822 BT_ERROR_NONE, NULL, 0);
826 OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
829 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
831 OIC_LOG(DEBUG, TAG, "IN");
833 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
835 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
837 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
840 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
841 CALEGetErrorMsg(ret));
842 return CA_STATUS_FAILED;
845 ret = bt_gatt_server_start();
848 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
849 CALEGetErrorMsg(ret));
850 return CA_STATUS_FAILED;
854 ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
856 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
858 CALEGattRemoteCharacteristicWriteCb, NULL);
862 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
863 CALEGetErrorMsg(ret));
864 return CA_STATUS_FAILED;
867 OIC_LOG(DEBUG, TAG, "OUT");
871 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
872 const char *charValue, int charValueLen, bool read)
875 OIC_LOG(DEBUG, TAG, "IN");
877 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
881 properties = BT_GATT_PROPERTY_INDICATE;
885 properties = BT_GATT_PROPERTY_WRITE;
888 bt_gatt_h charPath = NULL;
890 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
891 charValueLen, &charPath);
893 if (0 != ret || NULL == charPath)
895 OIC_LOG_V(ERROR, TAG,
896 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
897 return CA_STATUS_FAILED;
900 OIC_LOG_V(DEBUG, TAG,
901 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
906 ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
910 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
914 OIC_LOG_V(ERROR, TAG,
916 "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
918 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
920 CALEGetErrorMsg(ret));
921 return CA_STATUS_FAILED;
925 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
928 OIC_LOG_V(ERROR, TAG,
929 "bt_gatt_service_add_characteristic failed with ret[%s]",
930 CALEGetErrorMsg(ret));
931 return CA_STATUS_FAILED;
934 oc_mutex_lock(g_leCharacteristicMutex);
938 char desc_value[2] = {1, 0}; // Notification enabled.
939 bt_gatt_h descriptor = NULL;
940 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
941 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
942 desc_value, sizeof(desc_value),
946 oc_mutex_unlock(g_leCharacteristicMutex);
947 OIC_LOG_V(ERROR, TAG,
948 "bt_gatt_descriptor_create failed with ret[%s]",
949 CALEGetErrorMsg(ret));
950 return CA_STATUS_FAILED;
953 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
956 oc_mutex_unlock(g_leCharacteristicMutex);
957 OIC_LOG_V(ERROR, TAG,
958 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
959 CALEGetErrorMsg(ret));
960 return CA_STATUS_FAILED;
963 g_gattReadCharPath = charPath;
967 g_gattWriteCharPath = charPath;
970 oc_mutex_unlock(g_leCharacteristicMutex);
972 OIC_LOG(DEBUG, TAG, "OUT");
976 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
977 uint32_t charValueLen)
979 OIC_LOG(DEBUG, TAG, "IN");
981 VERIFY_NON_NULL(charValue, TAG, "charValue");
982 VERIFY_NON_NULL(address, TAG, "address");
984 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
986 oc_mutex_lock(g_leCharacteristicMutex);
988 if (NULL == g_gattReadCharPath)
990 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
991 oc_mutex_unlock(g_leCharacteristicMutex);
992 return CA_STATUS_FAILED;
995 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
998 OIC_LOG_V(ERROR, TAG,
999 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
1000 oc_mutex_unlock(g_leCharacteristicMutex);
1001 return CA_STATUS_FAILED;
1005 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
1006 CALEServerNotificationSentCB,
1009 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1015 OIC_LOG_V(ERROR, TAG,
1017 "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
1019 "bt_gatt_server_notify failed with return [%s]",
1021 CALEGetErrorMsg(ret));
1022 oc_mutex_unlock(g_leCharacteristicMutex);
1023 return CA_STATUS_FAILED;
1026 oc_mutex_unlock(g_leCharacteristicMutex);
1028 OIC_LOG(DEBUG, TAG, "OUT");
1029 return CA_STATUS_OK;
1032 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
1034 OIC_LOG(DEBUG, TAG, "IN");
1036 VERIFY_NON_NULL(charValue, TAG, "charValue");
1038 oc_mutex_lock(g_leCharacteristicMutex);
1040 if (NULL == g_gattReadCharPath)
1042 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
1043 oc_mutex_unlock(g_leCharacteristicMutex);
1044 return CA_STATUS_FAILED;
1047 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
1050 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
1051 oc_mutex_unlock(g_leCharacteristicMutex);
1052 return CA_STATUS_FAILED;
1056 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
1057 CALEServerNotificationSentCB,
1060 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1065 OIC_LOG_V(ERROR, TAG,
1067 "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
1069 "bt_gatt_server_notify failed with return[%s]",
1071 CALEGetErrorMsg(ret));
1072 oc_mutex_unlock(g_leCharacteristicMutex);
1073 return CA_STATUS_FAILED;
1076 oc_mutex_unlock(g_leCharacteristicMutex);
1078 OIC_LOG(DEBUG, TAG, "OUT");
1079 return CA_STATUS_OK;
1082 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1084 OIC_LOG(DEBUG, TAG, "IN");
1086 oc_mutex_lock(g_leReqRespCbMutex);
1087 g_leServerDataReceivedCallback = callback;
1088 oc_mutex_unlock(g_leReqRespCbMutex);
1090 OIC_LOG(DEBUG, TAG, "OUT");
1093 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1095 g_serverErrorCallback = callback;
1098 bool CALEServerIsConnected(const char* address)
1104 uint16_t CALEServerGetMtuSize(const char* address)
1106 OIC_LOG(DEBUG, TAG, "IN");
1107 VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1109 unsigned int mtu = CA_DEFAULT_BLE_MTU_SIZE;
1113 bt_gatt_client_h client = NULL;
1114 ret = bt_gatt_client_create(address, &client);
1117 OIC_LOG_V(ERROR, TAG,
1118 "bt_gatt_client_create failed with return [%s]", CALEGetErrorMsg(ret));
1119 return CA_DEFAULT_BLE_MTU_SIZE;
1122 ret = bt_gatt_client_get_att_mtu(client, &mtu);
1125 OIC_LOG_V(ERROR, TAG,
1126 "bt_gatt_client_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1127 return CA_DEFAULT_BLE_MTU_SIZE;
1130 ret = bt_gatt_client_destroy(client);
1133 OIC_LOG_V(ERROR, TAG,
1134 "bt_gatt_client_destroy failed with return [%s]", CALEGetErrorMsg(ret));
1135 return CA_DEFAULT_BLE_MTU_SIZE;
1138 ret = bt_device_get_att_mtu(address, &mtu);
1141 OIC_LOG_V(ERROR, TAG,
1142 "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1143 return CA_DEFAULT_BLE_MTU_SIZE;
1147 OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1148 OIC_LOG(DEBUG, TAG, "OUT");
1149 return mtu - CA_BLE_MTU_HEADER_SIZE;