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_MCD"
35 #define TAG BLE_SERVER_MCD_TAG
37 * Initial buffer 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 static const int samsung_code = 117;
130 static bool cutom_adv_flag = false;
131 static char *custom_adv_data = NULL;
132 static int custom_adv_data_length = 0;
134 static bool cutom_scanrsp_flag = false;
135 static char *custom_scanrsp_data = NULL;
136 static int custom_scanrsp_data_length = 0;
138 CAResult_t CAsetServerAdvertisementData(const char *data, int length)
141 CAResult_t ret = CA_STATUS_OK;
143 OIC_LOG(DEBUG, TAG, "IN");
145 if(!data || strlen(data) <= 0 || length <=0 )
147 OIC_LOG(ERROR, TAG, "Invalid param is passed");
148 return CA_STATUS_INVALID_PARAM;
151 oc_mutex_lock(g_leServerStateMutex);
153 cutom_adv_flag = true;
154 custom_adv_data = data;
155 custom_adv_data_length = length;
157 oc_mutex_unlock(g_leServerStateMutex);
159 OIC_LOG_V(DEBUG, TAG, "Custom advertise value has set as [%s]", custom_adv_data);
160 OIC_LOG(DEBUG, TAG, "OUT");
165 CAResult_t CAsetServerSanResponseData(const char *data, int length)
168 CAResult_t ret = CA_STATUS_OK;
170 OIC_LOG(DEBUG, TAG, "IN");
172 if(!data || strlen(data) <= 0 || length <=0 )
174 OIC_LOG(ERROR, TAG, "Invalid param is passed");
175 return CA_STATUS_INVALID_PARAM;
178 oc_mutex_lock(g_leServerStateMutex);
180 cutom_scanrsp_flag = true;
181 custom_scanrsp_data = data;
182 custom_scanrsp_data_length = length;
184 oc_mutex_unlock(g_leServerStateMutex);
186 OIC_LOG_V(DEBUG, TAG, "Custom scan response value has set as [%s]", custom_scanrsp_data);
187 OIC_LOG(DEBUG, TAG, "OUT");
192 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
194 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
196 CAResult_t res = CA_STATUS_OK;
199 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
200 char *addr = OICStrdup(remoteAddress);
201 oc_mutex_lock(g_LEClientListMutex);
202 res = CAAddLEClientInfoToList(&g_LEClientList, addr);
203 if (CA_STATUS_OK != res)
205 OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
206 oc_mutex_unlock(g_LEClientListMutex);
210 oc_mutex_unlock(g_LEClientListMutex);
212 res = CALEStopAdvertise();
213 if (CA_STATUS_OK != res)
215 OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
221 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
222 oc_mutex_lock(g_LEClientListMutex);
223 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
224 oc_mutex_unlock(g_LEClientListMutex);
226 res = CALEStartAdvertise();
227 if (CA_STATUS_OK != res)
229 OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
236 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
237 bt_gatt_h characteristic, bool completed, void *user_data)
239 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
240 bt_gatt_h characteristic, bool completed, void *user_data)
243 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
246 CAResult_t CAStartLEGattServer()
248 OIC_LOG(DEBUG, TAG, "IN");
250 oc_mutex_lock(g_leServerStateMutex);
251 if (true == g_isLEGattServerStarted)
253 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
254 oc_mutex_unlock(g_leServerStateMutex);
258 CAResult_t ret = CAInitLEGattServer();
259 if (CA_STATUS_OK != ret)
261 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
262 oc_mutex_unlock(g_leServerStateMutex);
263 CATerminateLEGattServer();
264 return CA_STATUS_FAILED;
267 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
268 if (CA_STATUS_OK != ret)
270 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
271 oc_mutex_unlock(g_leServerStateMutex);
272 CATerminateLEGattServer();
273 return CA_STATUS_FAILED;
276 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
277 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
279 // For Read Characteristics.
280 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
281 CA_LE_INITIAL_BUF_SIZE, true);
282 if (CA_STATUS_OK != ret)
284 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
285 oc_mutex_unlock(g_leServerStateMutex);
286 CATerminateLEGattServer();
287 return CA_STATUS_FAILED;
290 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
291 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
294 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
295 CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
296 if (CA_STATUS_OK != ret )
298 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
299 oc_mutex_unlock(g_leServerStateMutex);
300 CATerminateLEGattServer();
301 return CA_STATUS_FAILED;
304 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
305 if (CA_STATUS_OK != ret )
307 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
308 oc_mutex_unlock(g_leServerStateMutex);
309 CATerminateLEGattServer();
310 return CA_STATUS_FAILED;
313 ret = CALEStartAdvertise();
314 if (CA_STATUS_OK != ret)
316 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
317 oc_mutex_unlock(g_leServerStateMutex);
318 CATerminateLEGattServer();
319 return CA_STATUS_FAILED;
322 g_isLEGattServerStarted = true;
324 oc_mutex_unlock(g_leServerStateMutex);
326 OIC_LOG(DEBUG, TAG, "OUT");
330 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
333 OIC_LOG(DEBUG, TAG, "IN");
336 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
337 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
338 true, "notifyChar success");
342 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
343 false, "notifyChar failure");
345 OIC_LOG(DEBUG, TAG, "OUT");
348 CAResult_t CALEStartAdvertise()
350 OIC_LOG(DEBUG, TAG, "IN");
352 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
353 if (CA_STATUS_OK != res)
355 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
358 OIC_LOG(DEBUG, TAG, "OUT");
362 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
364 OIC_LOG(DEBUG, TAG, "IN");
368 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
369 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
371 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
372 return CA_STATUS_FAILED;
375 if (cutom_adv_flag == false) // Advertise with Default Service UUID
377 OIC_LOG(DEBUG, TAG, "Advertise with default Service UUID");
379 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
380 BT_ADAPTER_LE_PACKET_ADVERTISING,
382 if (BT_ERROR_NONE != res)
384 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
385 CALEGetErrorMsg(res));
386 return CA_STATUS_FAILED;
389 else // Advertise with custom advertise data
391 OIC_LOG(DEBUG, TAG, "Advertise with custom advertise data");
393 res = bt_adapter_le_add_advertising_manufacturer_data(g_hAdvertiser,BT_ADAPTER_LE_PACKET_ADVERTISING, samsung_code, custom_adv_data, custom_adv_data_length);
394 if (BT_ERROR_NONE != res)
396 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data failed(BT_ADAPTER_LE_PACKET_ADVERTISING) with ret[%s]",
397 CALEGetErrorMsg(res));
398 return CA_STATUS_FAILED;
403 if(cutom_scanrsp_flag == false)
405 OIC_LOG(DEBUG, TAG, "Advertise with default scan response data");
407 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
408 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
409 if (BT_ERROR_NONE != res)
411 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
412 CALEGetErrorMsg(res));
413 return CA_STATUS_FAILED;
416 else // Advertise with custom advertise data
418 OIC_LOG(DEBUG, TAG, "Advertise with custom scan response data");
420 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);
421 if (BT_ERROR_NONE != res)
423 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data(BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) failed with ret[%s]",
424 CALEGetErrorMsg(res));
425 return CA_STATUS_FAILED;
430 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
431 if (BT_ERROR_NONE != res)
433 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
434 CALEGetErrorMsg(res));
435 return CA_STATUS_FAILED;
438 OIC_LOG(DEBUG, TAG, "OUT");
442 CAResult_t CALEStopAdvertise()
444 OIC_LOG(DEBUG, TAG, "IN");
445 if (NULL != g_hAdvertiser)
447 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
450 OIC_LOG_V(ERROR, TAG,
451 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
454 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
457 OIC_LOG_V(ERROR, TAG,
458 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
460 g_hAdvertiser = NULL;
464 OIC_LOG(ERROR, TAG, "Advertising is not running");
465 return CA_STATUS_FAILED;
468 OIC_LOG(DEBUG, TAG, "OUT");
472 CAResult_t CAStopLEGattServer()
474 OIC_LOG(DEBUG, TAG, "IN");
476 oc_mutex_lock(g_leServerStateMutex);
478 if (false == g_isLEGattServerStarted)
480 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
481 oc_mutex_unlock(g_leServerStateMutex);
485 g_isLEGattServerStarted = false;
486 cutom_adv_flag = false;
487 custom_adv_data = NULL;
488 custom_adv_data_length = 0;
489 cutom_scanrsp_flag = false;
490 custom_scanrsp_data = NULL;
491 custom_scanrsp_data_length = 0;
493 oc_mutex_lock(g_LEClientListMutex);
494 CADisconnectAllClient(g_LEClientList);
495 g_LEClientList = NULL;
496 oc_mutex_unlock(g_LEClientListMutex);
498 CAResult_t res = CALEStopAdvertise();
500 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
503 res = CADeInitLEGattServer();
504 if (CA_STATUS_OK != res)
506 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
509 GMainContext *context_event_loop = NULL;
510 // Required for waking up the thread which is running in gmain loop
511 if (NULL != g_eventLoop)
513 context_event_loop = g_main_loop_get_context(g_eventLoop);
515 if (context_event_loop)
517 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
518 g_main_context_wakeup(context_event_loop);
520 // Kill g main loops and kill threads
521 g_main_loop_quit(g_eventLoop);
527 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
530 oc_mutex_unlock(g_leServerStateMutex);
532 OIC_LOG(DEBUG, TAG, "OUT");
536 CAResult_t CAInitializeLEGattServer()
538 OIC_LOG(DEBUG, TAG, "IN");
540 CAResult_t ret = CAInitGattServerMutexVariables();
541 if (CA_STATUS_OK != ret )
543 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
544 CATerminateGattServerMutexVariables();
545 return CA_SERVER_NOT_STARTED;
547 OIC_LOG(DEBUG, TAG, "OUT");
551 void CATerminateLEGattServer()
553 OIC_LOG(DEBUG, TAG, "IN");
555 // Service and characteristics path will be freed by the platform.
556 oc_mutex_lock(g_leServiceMutex);
557 g_gattSvcPath = NULL;
558 oc_mutex_unlock(g_leServiceMutex);
560 oc_mutex_lock(g_leCharacteristicMutex);
561 g_gattReadCharPath = NULL;
562 g_gattWriteCharPath = NULL;
563 oc_mutex_unlock(g_leCharacteristicMutex);
565 oc_mutex_lock(g_leServerThreadPoolMutex);
566 g_leServerThreadPool = NULL;
567 oc_mutex_unlock(g_leServerThreadPoolMutex);
569 // Terminating all mutex variables.
570 CATerminateGattServerMutexVariables();
571 OIC_LOG(DEBUG, TAG, "OUT");
574 CAResult_t CAInitGattServerMutexVariables()
576 OIC_LOG(DEBUG, TAG, "IN");
577 if (NULL == g_leServerStateMutex)
579 g_leServerStateMutex = oc_mutex_new();
580 if (NULL == g_leServerStateMutex)
582 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
583 return CA_STATUS_FAILED;
587 if (NULL == g_leServiceMutex)
589 g_leServiceMutex = oc_mutex_new();
590 if (NULL == g_leServiceMutex)
592 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
593 return CA_STATUS_FAILED;
597 if (NULL == g_leCharacteristicMutex)
599 g_leCharacteristicMutex = oc_mutex_new();
600 if (NULL == g_leCharacteristicMutex)
602 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
603 return CA_STATUS_FAILED;
607 if (NULL == g_leReqRespCbMutex)
609 g_leReqRespCbMutex = oc_mutex_new();
610 if (NULL == g_leReqRespCbMutex)
612 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
613 return CA_STATUS_FAILED;
617 if (NULL == g_leServerThreadPoolMutex)
619 g_leServerThreadPoolMutex = oc_mutex_new();
620 if (NULL == g_leServerThreadPoolMutex)
622 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
623 return CA_STATUS_FAILED;
627 if (NULL == g_LEClientListMutex)
629 g_LEClientListMutex = oc_mutex_new();
630 if (NULL == g_LEClientListMutex)
632 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
633 return CA_STATUS_FAILED;
637 OIC_LOG(DEBUG, TAG, "OUT");
641 void CATerminateGattServerMutexVariables()
643 OIC_LOG(DEBUG, TAG, "IN");
644 oc_mutex_free(g_leServerStateMutex);
645 g_leServerStateMutex = NULL;
647 oc_mutex_free(g_leServiceMutex);
648 g_leServiceMutex = NULL;
650 oc_mutex_free(g_leCharacteristicMutex);
651 g_leCharacteristicMutex = NULL;
653 oc_mutex_free(g_leReqRespCbMutex);
654 g_leReqRespCbMutex = NULL;
656 oc_mutex_free(g_leServerThreadPoolMutex);
657 g_leServerThreadPoolMutex = NULL;
659 oc_mutex_free(g_LEClientListMutex);
660 g_LEClientListMutex = NULL;
662 OIC_LOG(DEBUG, TAG, "OUT");
665 CAResult_t CAInitLEGattServer()
667 OIC_LOG(DEBUG, TAG, "IN");
669 int ret = bt_gatt_server_initialize();
672 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
673 CALEGetErrorMsg(ret));
674 return CA_STATUS_FAILED;
679 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
680 ret = bt_gatt_server_create(&g_gattServer);
683 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
684 CALEGetErrorMsg(ret));
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 return CA_STATUS_FAILED;
705 ret = bt_gatt_server_destroy(g_gattServer);
708 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
709 CALEGetErrorMsg(ret));
710 return CA_STATUS_FAILED;
714 ret = bt_gatt_server_deinitialize();
717 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
718 CALEGetErrorMsg(ret));
719 return CA_STATUS_FAILED;
722 OIC_LOG(DEBUG, TAG, "OUT");
726 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
728 OIC_LOG(DEBUG, TAG, "IN");
729 oc_mutex_lock(g_leServerThreadPoolMutex);
730 g_leServerThreadPool = handle;
731 oc_mutex_unlock(g_leServerThreadPoolMutex);
732 OIC_LOG(DEBUG, TAG, "OUT");
735 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
737 OIC_LOG(DEBUG, TAG, "IN");
739 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
741 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
743 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
745 oc_mutex_lock(g_leServiceMutex);
746 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
749 oc_mutex_unlock(g_leServiceMutex);
750 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
751 CALEGetErrorMsg(ret));
752 return CA_STATUS_FAILED;
754 oc_mutex_unlock(g_leServiceMutex);
758 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
761 OIC_LOG(DEBUG, TAG, "OUT");
766 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
767 bt_gatt_server_h server, bt_gatt_h gatt_handle,
768 bool response_needed, int offset, const char *charValue,
769 int charLen, void *userData)
771 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
772 bt_gatt_h gatt_handle, int offset, char *charValue,
773 int charLen, void *userData)
776 OIC_LOG(INFO, TAG, "IN - WriteCharCB");
778 if (NULL == charValue || NULL == remoteAddress)
780 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
784 OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
786 uint8_t *data = OICMalloc(charLen);
789 OIC_LOG(ERROR, TAG, "Malloc failed!");
793 memcpy(data, charValue, charLen);
795 oc_mutex_lock(g_leReqRespCbMutex);
796 if (NULL == g_leServerDataReceivedCallback)
798 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
799 oc_mutex_unlock(g_leReqRespCbMutex);
804 OIC_LOG(INFO, TAG, "Sending data up !");
805 uint32_t sentLength = 0;
806 g_leServerDataReceivedCallback(remoteAddress, data, charLen,
808 oc_mutex_unlock(g_leReqRespCbMutex);
813 OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
816 OIC_LOG(INFO, TAG, "send response to remote client");
817 bt_gatt_server_send_response(request_id,
818 BT_GATT_REQUEST_TYPE_WRITE, offset,
819 BT_ERROR_NONE, NULL, 0);
823 OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
826 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
828 OIC_LOG(DEBUG, TAG, "IN");
830 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
832 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
834 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
837 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
838 CALEGetErrorMsg(ret));
839 return CA_STATUS_FAILED;
842 ret = bt_gatt_server_start();
845 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
846 CALEGetErrorMsg(ret));
847 return CA_STATUS_FAILED;
851 ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
853 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
855 CALEGattRemoteCharacteristicWriteCb, NULL);
859 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
860 CALEGetErrorMsg(ret));
861 return CA_STATUS_FAILED;
864 OIC_LOG(DEBUG, TAG, "OUT");
868 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
869 const char *charValue, int charValueLen, bool read)
872 OIC_LOG(DEBUG, TAG, "IN");
874 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
878 properties = BT_GATT_PROPERTY_INDICATE;
882 properties = BT_GATT_PROPERTY_WRITE;
885 bt_gatt_h charPath = NULL;
887 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
888 charValueLen, &charPath);
890 if (0 != ret || NULL == charPath)
892 OIC_LOG_V(ERROR, TAG,
893 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
894 return CA_STATUS_FAILED;
897 OIC_LOG_V(DEBUG, TAG,
898 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
903 ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
907 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
911 OIC_LOG_V(ERROR, TAG,
913 "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
915 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
917 CALEGetErrorMsg(ret));
918 return CA_STATUS_FAILED;
922 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
925 OIC_LOG_V(ERROR, TAG,
926 "bt_gatt_service_add_characteristic failed with ret[%s]",
927 CALEGetErrorMsg(ret));
928 return CA_STATUS_FAILED;
931 oc_mutex_lock(g_leCharacteristicMutex);
935 char desc_value[2] = {1, 0}; // Notification enabled.
936 bt_gatt_h descriptor = NULL;
937 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
938 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
939 desc_value, sizeof(desc_value),
943 oc_mutex_unlock(g_leCharacteristicMutex);
944 OIC_LOG_V(ERROR, TAG,
945 "bt_gatt_descriptor_create failed with ret[%s]",
946 CALEGetErrorMsg(ret));
947 return CA_STATUS_FAILED;
950 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
953 oc_mutex_unlock(g_leCharacteristicMutex);
954 OIC_LOG_V(ERROR, TAG,
955 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
956 CALEGetErrorMsg(ret));
957 return CA_STATUS_FAILED;
960 g_gattReadCharPath = charPath;
964 g_gattWriteCharPath = charPath;
967 oc_mutex_unlock(g_leCharacteristicMutex);
969 OIC_LOG(DEBUG, TAG, "OUT");
973 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
974 uint32_t charValueLen)
976 OIC_LOG(DEBUG, TAG, "IN");
978 VERIFY_NON_NULL(charValue, TAG, "charValue");
979 VERIFY_NON_NULL(address, TAG, "address");
981 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
983 oc_mutex_lock(g_leCharacteristicMutex);
985 if (NULL == g_gattReadCharPath)
987 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
988 oc_mutex_unlock(g_leCharacteristicMutex);
989 return CA_STATUS_FAILED;
992 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
995 OIC_LOG_V(ERROR, TAG,
996 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
997 oc_mutex_unlock(g_leCharacteristicMutex);
998 return CA_STATUS_FAILED;
1002 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
1003 CALEServerNotificationSentCB,
1006 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1012 OIC_LOG_V(ERROR, TAG,
1014 "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
1016 "bt_gatt_server_notify failed with return [%s]",
1018 CALEGetErrorMsg(ret));
1019 oc_mutex_unlock(g_leCharacteristicMutex);
1020 return CA_STATUS_FAILED;
1023 oc_mutex_unlock(g_leCharacteristicMutex);
1025 OIC_LOG(DEBUG, TAG, "OUT");
1026 return CA_STATUS_OK;
1029 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
1031 OIC_LOG(DEBUG, TAG, "IN");
1033 VERIFY_NON_NULL(charValue, TAG, "charValue");
1035 oc_mutex_lock(g_leCharacteristicMutex);
1037 if (NULL == g_gattReadCharPath)
1039 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
1040 oc_mutex_unlock(g_leCharacteristicMutex);
1041 return CA_STATUS_FAILED;
1044 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
1047 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
1048 oc_mutex_unlock(g_leCharacteristicMutex);
1049 return CA_STATUS_FAILED;
1053 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
1054 CALEServerNotificationSentCB,
1057 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1062 OIC_LOG_V(ERROR, TAG,
1064 "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
1066 "bt_gatt_server_notify failed with return[%s]",
1068 CALEGetErrorMsg(ret));
1069 oc_mutex_unlock(g_leCharacteristicMutex);
1070 return CA_STATUS_FAILED;
1073 oc_mutex_unlock(g_leCharacteristicMutex);
1075 OIC_LOG(DEBUG, TAG, "OUT");
1076 return CA_STATUS_OK;
1079 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1081 OIC_LOG(DEBUG, TAG, "IN");
1083 oc_mutex_lock(g_leReqRespCbMutex);
1084 g_leServerDataReceivedCallback = callback;
1085 oc_mutex_unlock(g_leReqRespCbMutex);
1087 OIC_LOG(DEBUG, TAG, "OUT");
1090 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1092 g_serverErrorCallback = callback;
1095 bool CALEServerIsConnected(const char* address)
1101 uint16_t CALEServerGetMtuSize(const char* address)
1103 OIC_LOG(DEBUG, TAG, "IN");
1104 VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1107 int ret = bt_device_get_att_mtu(address, &mtu);
1110 OIC_LOG_V(ERROR, TAG,
1111 "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1112 return CA_DEFAULT_BLE_MTU_SIZE;
1114 OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1115 OIC_LOG(DEBUG, TAG, "OUT");
1116 return mtu - CA_BLE_MTU_HEADER_SIZE;