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
38 * The handle of the OIC server.
40 static bt_gatt_server_h g_gattServer = NULL;
43 * The handle of the OIC service.
45 static bt_gatt_h g_gattSvcPath = NULL;
48 * The handle of the OIC read characteristics.
50 static bt_gatt_h g_gattReadCharPath = NULL;
53 * The handle of the OIC write characteristics.
55 static bt_gatt_h g_gattWriteCharPath = NULL;
58 * The handle to control Bluetooth LE advertising.
60 static bt_advertiser_h g_hAdvertiser = NULL;
63 * Callback register with LE adapter. This callback is called on reception of any
64 * data from the remote device.
66 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
69 * Callback to notify any error in LE adapter.
71 static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
74 * To keep the state of GATT server if started or not.
76 static bool g_isLEGattServerStarted = false;
79 * Mutex to synchronize the calls to start and stop server.
81 static oc_mutex g_leServerStateMutex = NULL;
84 * Mutex to synchronize writing operations on the characteristics.
86 static oc_mutex g_leCharacteristicMutex = NULL;
89 * Mutex to synchronize to creation of OIC service.
91 static oc_mutex g_leServiceMutex = NULL;
94 * Mutex to synchronize access to the requestResponse callback to be called
95 * when the data needs to be sent from GATTClient.
97 static oc_mutex g_leReqRespCbMutex = NULL;
100 * Mutex to synchronize the task to be pushed to thread pool.
102 static oc_mutex g_leServerThreadPoolMutex = NULL;
105 * Reference to threadpool.
107 static ca_thread_pool_t g_leServerThreadPool = NULL;
110 * GmainLoop to manage the threads to receive the callback from the platfrom.
112 static GMainLoop *g_eventLoop = NULL;
115 * This contains the list of OIC clients connected to the server.
117 static LEClientInfoList *g_LEClientList = NULL;
120 * Mutex to synchronize access to LE ClientList.
122 static oc_mutex g_LEClientListMutex = NULL;
124 static const int samsung_code = 117;
126 static bool cutom_adv_flag = false;
127 static char *custom_adv_data = NULL;
128 static int custom_adv_data_length = 0;
130 static bool cutom_scanrsp_flag = false;
131 static char *custom_scanrsp_data = NULL;
132 static int custom_scanrsp_data_length = 0;
134 CAResult_t CAsetServerAdvertisementData(const char *data, int length)
137 CAResult_t ret = CA_STATUS_OK;
139 OIC_LOG(DEBUG, TAG, "IN");
141 if(!data || strlen(data) <= 0 || length <=0 )
143 OIC_LOG(ERROR, TAG, "Invalid param is passed");
144 return CA_STATUS_INVALID_PARAM;
147 oc_mutex_lock(g_leServerStateMutex);
149 cutom_adv_flag = true;
150 custom_adv_data = data;
151 custom_adv_data_length = length;
153 oc_mutex_unlock(g_leServerStateMutex);
155 OIC_LOG_V(DEBUG, TAG, "Custom advertise value has set as [%s]", custom_adv_data);
156 OIC_LOG(DEBUG, TAG, "OUT");
161 CAResult_t CAsetServerSanResponseData(const char *data, int length)
164 CAResult_t ret = CA_STATUS_OK;
166 OIC_LOG(DEBUG, TAG, "IN");
168 if(!data || strlen(data) <= 0 || length <=0 )
170 OIC_LOG(ERROR, TAG, "Invalid param is passed");
171 return CA_STATUS_INVALID_PARAM;
174 oc_mutex_lock(g_leServerStateMutex);
176 cutom_scanrsp_flag = true;
177 custom_scanrsp_data = data;
178 custom_scanrsp_data_length = length;
180 oc_mutex_unlock(g_leServerStateMutex);
182 OIC_LOG_V(DEBUG, TAG, "Custom scan response value has set as [%s]", custom_scanrsp_data);
183 OIC_LOG(DEBUG, TAG, "OUT");
188 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
190 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
192 CAResult_t res = CA_STATUS_OK;
195 OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
196 char *addr = OICStrdup(remoteAddress);
197 oc_mutex_lock(g_LEClientListMutex);
198 res = CAAddLEClientInfoToList(&g_LEClientList, addr);
199 if (CA_STATUS_OK != res)
201 OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
202 oc_mutex_unlock(g_LEClientListMutex);
206 oc_mutex_unlock(g_LEClientListMutex);
208 res = CALEStopAdvertise();
209 if (CA_STATUS_OK != res)
211 OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
217 OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
218 oc_mutex_lock(g_LEClientListMutex);
219 CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
220 oc_mutex_unlock(g_LEClientListMutex);
222 res = CALEStartAdvertise();
223 if (CA_STATUS_OK != res)
225 OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
232 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
233 bt_gatt_h characteristic, bool completed, void *user_data)
235 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
236 bt_gatt_h characteristic, bool completed, void *user_data)
239 OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
242 CAResult_t CAStartLEGattServer()
244 OIC_LOG(DEBUG, TAG, "IN");
246 oc_mutex_lock(g_leServerStateMutex);
247 if (true == g_isLEGattServerStarted)
249 OIC_LOG(ERROR, TAG, "Gatt Server is already running");
250 oc_mutex_unlock(g_leServerStateMutex);
254 CAResult_t ret = CAInitLEGattServer();
255 if (CA_STATUS_OK != ret)
257 OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
258 oc_mutex_unlock(g_leServerStateMutex);
259 CATerminateLEGattServer();
260 return CA_STATUS_FAILED;
263 ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
264 if (CA_STATUS_OK != ret)
266 OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
267 oc_mutex_unlock(g_leServerStateMutex);
268 CATerminateLEGattServer();
269 return CA_STATUS_FAILED;
272 static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
273 char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
275 // For Read Characteristics.
276 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
277 sizeof(charReadValue), true);
278 if (CA_STATUS_OK != ret)
280 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
281 oc_mutex_unlock(g_leServerStateMutex);
282 CATerminateLEGattServer();
283 return CA_STATUS_FAILED;
286 static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
287 char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
290 ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
291 sizeof(charWriteValue), false); // For Write Characteristics.
292 if (CA_STATUS_OK != ret )
294 OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
295 oc_mutex_unlock(g_leServerStateMutex);
296 CATerminateLEGattServer();
297 return CA_STATUS_FAILED;
300 ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
301 if (CA_STATUS_OK != ret )
303 OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
304 oc_mutex_unlock(g_leServerStateMutex);
305 CATerminateLEGattServer();
306 return CA_STATUS_FAILED;
309 ret = CALEStartAdvertise();
310 if (CA_STATUS_OK != ret)
312 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
313 oc_mutex_unlock(g_leServerStateMutex);
314 CATerminateLEGattServer();
315 return CA_STATUS_FAILED;
318 g_isLEGattServerStarted = true;
320 oc_mutex_unlock(g_leServerStateMutex);
322 OIC_LOG(DEBUG, TAG, "OUT");
326 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
329 OIC_LOG(DEBUG, TAG, "IN");
332 OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
333 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
334 true, "notifyChar success");
338 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
339 false, "notifyChar failure");
341 OIC_LOG(DEBUG, TAG, "OUT");
344 CAResult_t CALEStartAdvertise()
346 OIC_LOG(DEBUG, TAG, "IN");
348 CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
349 if (CA_STATUS_OK != res)
351 OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
354 OIC_LOG(DEBUG, TAG, "OUT");
358 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
360 OIC_LOG(DEBUG, TAG, "IN");
364 int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
365 if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
367 OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
368 return CA_STATUS_FAILED;
371 if (cutom_adv_flag == false) // Advertise with Default Service UUID
373 OIC_LOG(DEBUG, TAG, "Advertise with default Service UUID");
375 res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
376 BT_ADAPTER_LE_PACKET_ADVERTISING,
378 if (BT_ERROR_NONE != res)
380 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
381 CALEGetErrorMsg(res));
382 return CA_STATUS_FAILED;
385 else // Advertise with custom advertise data
387 OIC_LOG(DEBUG, TAG, "Advertise with custom advertise data");
389 res = bt_adapter_le_add_advertising_manufacturer_data(g_hAdvertiser,BT_ADAPTER_LE_PACKET_ADVERTISING, samsung_code, custom_adv_data, custom_adv_data_length);
390 if (BT_ERROR_NONE != res)
392 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data failed(BT_ADAPTER_LE_PACKET_ADVERTISING) with ret[%s]",
393 CALEGetErrorMsg(res));
394 return CA_STATUS_FAILED;
399 if(cutom_scanrsp_flag == false)
401 OIC_LOG(DEBUG, TAG, "Advertise with default scan response data");
403 res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
404 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
405 if (BT_ERROR_NONE != res)
407 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
408 CALEGetErrorMsg(res));
409 return CA_STATUS_FAILED;
412 else // Advertise with custom advertise data
414 OIC_LOG(DEBUG, TAG, "Advertise with custom scan response data");
416 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);
417 if (BT_ERROR_NONE != res)
419 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data(BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) failed with ret[%s]",
420 CALEGetErrorMsg(res));
421 return CA_STATUS_FAILED;
426 res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
427 if (BT_ERROR_NONE != res)
429 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
430 CALEGetErrorMsg(res));
431 return CA_STATUS_FAILED;
434 OIC_LOG(DEBUG, TAG, "OUT");
438 CAResult_t CALEStopAdvertise()
440 OIC_LOG(DEBUG, TAG, "IN");
441 if (NULL != g_hAdvertiser)
443 int ret = bt_adapter_le_stop_advertising(g_hAdvertiser);
446 OIC_LOG_V(ERROR, TAG,
447 "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
450 ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
453 OIC_LOG_V(ERROR, TAG,
454 "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
456 g_hAdvertiser = NULL;
460 OIC_LOG(ERROR, TAG, "Advertising is not running");
461 return CA_STATUS_FAILED;
464 OIC_LOG(DEBUG, TAG, "OUT");
468 CAResult_t CAStopLEGattServer()
470 OIC_LOG(DEBUG, TAG, "IN");
472 oc_mutex_lock(g_leServerStateMutex);
474 if (false == g_isLEGattServerStarted)
476 OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
477 oc_mutex_unlock(g_leServerStateMutex);
481 g_isLEGattServerStarted = false;
482 cutom_adv_flag = false;
483 custom_adv_data = NULL;
484 custom_adv_data_length = 0;
485 cutom_scanrsp_flag = false;
486 custom_scanrsp_data = NULL;
487 custom_scanrsp_data_length = 0;
489 oc_mutex_lock(g_LEClientListMutex);
490 CADisconnectAllClient(g_LEClientList);
491 g_LEClientList = NULL;
492 oc_mutex_unlock(g_LEClientListMutex);
494 CAResult_t res = CALEStopAdvertise();
496 OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
499 res = CADeInitLEGattServer();
500 if (CA_STATUS_OK != res)
502 OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
505 GMainContext *context_event_loop = NULL;
506 // Required for waking up the thread which is running in gmain loop
507 if (NULL != g_eventLoop)
509 context_event_loop = g_main_loop_get_context(g_eventLoop);
511 if (context_event_loop)
513 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %x", context_event_loop);
514 g_main_context_wakeup(context_event_loop);
516 // Kill g main loops and kill threads
517 g_main_loop_quit(g_eventLoop);
523 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
526 oc_mutex_unlock(g_leServerStateMutex);
528 OIC_LOG(DEBUG, TAG, "OUT");
532 CAResult_t CAInitializeLEGattServer()
534 OIC_LOG(DEBUG, TAG, "IN");
536 CAResult_t ret = CAInitGattServerMutexVariables();
537 if (CA_STATUS_OK != ret )
539 OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
540 CATerminateGattServerMutexVariables();
541 return CA_SERVER_NOT_STARTED;
543 OIC_LOG(DEBUG, TAG, "OUT");
547 void CATerminateLEGattServer()
549 OIC_LOG(DEBUG, TAG, "IN");
551 // Service and characteristics path will be freed by the platform.
552 oc_mutex_lock(g_leServiceMutex);
553 g_gattSvcPath = NULL;
554 oc_mutex_unlock(g_leServiceMutex);
556 oc_mutex_lock(g_leCharacteristicMutex);
557 g_gattReadCharPath = NULL;
558 g_gattWriteCharPath = NULL;
559 oc_mutex_unlock(g_leCharacteristicMutex);
561 oc_mutex_lock(g_leServerThreadPoolMutex);
562 g_leServerThreadPool = NULL;
563 oc_mutex_unlock(g_leServerThreadPoolMutex);
565 // Terminating all mutex variables.
566 CATerminateGattServerMutexVariables();
567 OIC_LOG(DEBUG, TAG, "OUT");
570 CAResult_t CAInitGattServerMutexVariables()
572 OIC_LOG(DEBUG, TAG, "IN");
573 if (NULL == g_leServerStateMutex)
575 g_leServerStateMutex = oc_mutex_new();
576 if (NULL == g_leServerStateMutex)
578 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
579 return CA_STATUS_FAILED;
583 if (NULL == g_leServiceMutex)
585 g_leServiceMutex = oc_mutex_new();
586 if (NULL == g_leServiceMutex)
588 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
589 return CA_STATUS_FAILED;
593 if (NULL == g_leCharacteristicMutex)
595 g_leCharacteristicMutex = oc_mutex_new();
596 if (NULL == g_leCharacteristicMutex)
598 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
599 return CA_STATUS_FAILED;
603 if (NULL == g_leReqRespCbMutex)
605 g_leReqRespCbMutex = oc_mutex_new();
606 if (NULL == g_leReqRespCbMutex)
608 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
609 return CA_STATUS_FAILED;
613 if (NULL == g_leServerThreadPoolMutex)
615 g_leServerThreadPoolMutex = oc_mutex_new();
616 if (NULL == g_leServerThreadPoolMutex)
618 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
619 return CA_STATUS_FAILED;
623 if (NULL == g_LEClientListMutex)
625 g_LEClientListMutex = oc_mutex_new();
626 if (NULL == g_LEClientListMutex)
628 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
629 return CA_STATUS_FAILED;
633 OIC_LOG(DEBUG, TAG, "OUT");
637 void CATerminateGattServerMutexVariables()
639 OIC_LOG(DEBUG, TAG, "IN");
640 oc_mutex_free(g_leServerStateMutex);
641 g_leServerStateMutex = NULL;
643 oc_mutex_free(g_leServiceMutex);
644 g_leServiceMutex = NULL;
646 oc_mutex_free(g_leCharacteristicMutex);
647 g_leCharacteristicMutex = NULL;
649 oc_mutex_free(g_leReqRespCbMutex);
650 g_leReqRespCbMutex = NULL;
652 oc_mutex_free(g_leServerThreadPoolMutex);
653 g_leServerThreadPoolMutex = NULL;
655 oc_mutex_free(g_LEClientListMutex);
656 g_LEClientListMutex = NULL;
658 OIC_LOG(DEBUG, TAG, "OUT");
661 CAResult_t CAInitLEGattServer()
663 OIC_LOG(DEBUG, TAG, "IN");
665 int ret = bt_gatt_server_initialize();
668 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
669 CALEGetErrorMsg(ret));
670 return CA_STATUS_FAILED;
675 OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
676 ret = bt_gatt_server_create(&g_gattServer);
679 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
680 CALEGetErrorMsg(ret));
681 return CA_STATUS_FAILED;
685 OIC_LOG(DEBUG, TAG, "OUT");
689 CAResult_t CADeInitLEGattServer()
691 OIC_LOG(DEBUG, TAG, "IN");
693 int ret = bt_gatt_server_unregister_all_services(g_gattServer);
696 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
697 CALEGetErrorMsg(ret));
698 return CA_STATUS_FAILED;
701 ret = bt_gatt_server_destroy(g_gattServer);
704 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
705 CALEGetErrorMsg(ret));
706 return CA_STATUS_FAILED;
710 ret = bt_gatt_server_deinitialize();
713 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
714 CALEGetErrorMsg(ret));
715 return CA_STATUS_FAILED;
718 OIC_LOG(DEBUG, TAG, "OUT");
722 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
724 OIC_LOG(DEBUG, TAG, "IN");
725 oc_mutex_lock(g_leServerThreadPoolMutex);
726 g_leServerThreadPool = handle;
727 oc_mutex_unlock(g_leServerThreadPoolMutex);
728 OIC_LOG(DEBUG, TAG, "OUT");
731 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
733 OIC_LOG(DEBUG, TAG, "IN");
735 VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
737 OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
739 bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
741 oc_mutex_lock(g_leServiceMutex);
742 int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
745 oc_mutex_unlock(g_leServiceMutex);
746 OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
747 CALEGetErrorMsg(ret));
748 return CA_STATUS_FAILED;
750 oc_mutex_unlock(g_leServiceMutex);
754 OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
757 OIC_LOG(DEBUG, TAG, "OUT");
762 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
763 bt_gatt_server_h server, bt_gatt_h gatt_handle,
764 bool response_needed, int offset, const char *charValue,
765 int charLen, void *userData)
767 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
768 bt_gatt_h gatt_handle, int offset, char *charValue,
769 int charLen, void *userData)
772 OIC_LOG(INFO, TAG, "IN - WriteCharCB");
774 if (NULL == charValue || NULL == remoteAddress)
776 OIC_LOG(ERROR, TAG, "Param callback values are NULL");
780 OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
782 uint8_t *data = OICMalloc(charLen);
785 OIC_LOG(ERROR, TAG, "Malloc failed!");
789 memcpy(data, charValue, charLen);
791 oc_mutex_lock(g_leReqRespCbMutex);
792 if (NULL == g_leServerDataReceivedCallback)
794 OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
795 oc_mutex_unlock(g_leReqRespCbMutex);
800 OIC_LOG(INFO, TAG, "Sending data up !");
801 uint32_t sentLength = 0;
802 g_leServerDataReceivedCallback(remoteAddress, data, charLen,
804 oc_mutex_unlock(g_leReqRespCbMutex);
809 OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
812 OIC_LOG(INFO, TAG, "send response to remote client");
813 bt_gatt_server_send_response(request_id,
814 BT_GATT_REQUEST_TYPE_WRITE, offset,
815 BT_ERROR_NONE, NULL, 0);
819 OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
822 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
824 OIC_LOG(DEBUG, TAG, "IN");
826 VERIFY_NON_NULL(svcPath, TAG, "svcPath");
828 OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
830 int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
833 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
834 CALEGetErrorMsg(ret));
835 return CA_STATUS_FAILED;
838 ret = bt_gatt_server_start();
841 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
842 CALEGetErrorMsg(ret));
843 return CA_STATUS_FAILED;
847 ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
849 ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
851 CALEGattRemoteCharacteristicWriteCb, NULL);
855 OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
856 CALEGetErrorMsg(ret));
857 return CA_STATUS_FAILED;
860 OIC_LOG(DEBUG, TAG, "OUT");
864 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
865 const char *charValue, int charValueLen, bool read)
868 OIC_LOG(DEBUG, TAG, "IN");
870 int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
874 properties = BT_GATT_PROPERTY_INDICATE;
878 properties = BT_GATT_PROPERTY_WRITE;
881 bt_gatt_h charPath = NULL;
883 int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
884 charValueLen, &charPath);
886 if (0 != ret || NULL == charPath)
888 OIC_LOG_V(ERROR, TAG,
889 "bt_gatt_add_characteristic failed with ret [%s]", CALEGetErrorMsg(ret));
890 return CA_STATUS_FAILED;
893 OIC_LOG_V(DEBUG, TAG,
894 "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
899 ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
903 ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
907 OIC_LOG_V(ERROR, TAG,
909 "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
911 "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]",
913 CALEGetErrorMsg(ret));
914 return CA_STATUS_FAILED;
918 ret = bt_gatt_service_add_characteristic(svcPath, charPath);
921 OIC_LOG_V(ERROR, TAG,
922 "bt_gatt_service_add_characteristic failed with ret[%s]",
923 CALEGetErrorMsg(ret));
924 return CA_STATUS_FAILED;
927 oc_mutex_lock(g_leCharacteristicMutex);
931 char desc_value[2] = {1, 0}; // Notification enabled.
932 bt_gatt_h descriptor = NULL;
933 permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
934 ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
935 desc_value, sizeof(desc_value),
939 oc_mutex_unlock(g_leCharacteristicMutex);
940 OIC_LOG_V(ERROR, TAG,
941 "bt_gatt_descriptor_create failed with ret[%s]",
942 CALEGetErrorMsg(ret));
943 return CA_STATUS_FAILED;
946 ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
949 oc_mutex_unlock(g_leCharacteristicMutex);
950 OIC_LOG_V(ERROR, TAG,
951 "bt_gatt_characteristic_add_descriptor failed with ret[%s]",
952 CALEGetErrorMsg(ret));
953 return CA_STATUS_FAILED;
956 g_gattReadCharPath = charPath;
960 g_gattWriteCharPath = charPath;
963 oc_mutex_unlock(g_leCharacteristicMutex);
965 OIC_LOG(DEBUG, TAG, "OUT");
969 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
970 uint32_t charValueLen)
972 OIC_LOG(DEBUG, TAG, "IN");
974 VERIFY_NON_NULL(charValue, TAG, "charValue");
975 VERIFY_NON_NULL(address, TAG, "address");
977 OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
979 oc_mutex_lock(g_leCharacteristicMutex);
981 if (NULL == g_gattReadCharPath)
983 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
984 oc_mutex_unlock(g_leCharacteristicMutex);
985 return CA_STATUS_FAILED;
988 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
991 OIC_LOG_V(ERROR, TAG,
992 "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
993 oc_mutex_unlock(g_leCharacteristicMutex);
994 return CA_STATUS_FAILED;
998 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
999 CALEServerNotificationSentCB,
1002 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1008 OIC_LOG_V(ERROR, TAG,
1010 "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
1012 "bt_gatt_server_notify failed with return [%s]",
1014 CALEGetErrorMsg(ret));
1015 oc_mutex_unlock(g_leCharacteristicMutex);
1016 return CA_STATUS_FAILED;
1019 oc_mutex_unlock(g_leCharacteristicMutex);
1021 OIC_LOG(DEBUG, TAG, "OUT");
1022 return CA_STATUS_OK;
1025 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
1027 OIC_LOG(DEBUG, TAG, "IN");
1029 VERIFY_NON_NULL(charValue, TAG, "charValue");
1031 oc_mutex_lock(g_leCharacteristicMutex);
1033 if (NULL == g_gattReadCharPath)
1035 OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
1036 oc_mutex_unlock(g_leCharacteristicMutex);
1037 return CA_STATUS_FAILED;
1040 int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
1043 OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
1044 oc_mutex_unlock(g_leCharacteristicMutex);
1045 return CA_STATUS_FAILED;
1049 ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
1050 CALEServerNotificationSentCB,
1053 ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1058 OIC_LOG_V(ERROR, TAG,
1060 "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
1062 "bt_gatt_server_notify failed with return[%s]",
1064 CALEGetErrorMsg(ret));
1065 oc_mutex_unlock(g_leCharacteristicMutex);
1066 return CA_STATUS_FAILED;
1069 oc_mutex_unlock(g_leCharacteristicMutex);
1071 OIC_LOG(DEBUG, TAG, "OUT");
1072 return CA_STATUS_OK;
1075 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1077 OIC_LOG(DEBUG, TAG, "IN");
1079 oc_mutex_lock(g_leReqRespCbMutex);
1080 g_leServerDataReceivedCallback = callback;
1081 oc_mutex_unlock(g_leReqRespCbMutex);
1083 OIC_LOG(DEBUG, TAG, "OUT");
1086 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1088 g_serverErrorCallback = callback;
1091 bool CALEServerIsConnected(const char* address)
1097 uint16_t CALEServerGetMtuSize(const char* address)
1099 OIC_LOG(DEBUG, TAG, "IN");
1100 VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1103 int ret = bt_device_get_att_mtu(address, &mtu);
1106 OIC_LOG_V(ERROR, TAG,
1107 "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1108 return CA_DEFAULT_BLE_MTU_SIZE;
1110 OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1111 OIC_LOG(DEBUG, TAG, "OUT");
1112 return mtu - CA_BLE_MTU_HEADER_SIZE;