2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <syspopup_caller.h>
26 #include "bt-internal-types.h"
27 #include "bt-service-common.h"
28 #include "bt-service-event.h"
29 #include "bt-service-adapter.h"
30 #include "bt-service-adapter-le.h"
31 #include "bt-service-util.h"
34 #define BT_ADV_INTERVAL_MIN 20 /* msec */
35 #define BT_ADV_INTERVAL_MAX 10240
36 #define BT_ADV_INTERVAL_SPLIT 0.625
37 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
38 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
39 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
40 #define BT_ADV_TYPE_DEFAULT 0x00
41 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
42 #define BT_ADV_MULTI_MAX 16
48 } bt_adapter_le_feature_info_t;
53 gboolean is_advertising;
55 } bt_adapter_le_adv_slot_t;
61 } bt_adapter_le_scanner_t;
63 static bluetooth_advertising_params_t adv_params = {
64 BT_DEFAULT_ADV_MIN_INTERVAL,
65 BT_DEFAULT_ADV_MAX_INTERVAL,
66 BT_ADV_FILTER_POLICY_DEFAULT,
68 static bluetooth_advertising_data_t adv_data = { {0} };
69 static int adv_data_len;
70 static bluetooth_scan_resp_data_t resp_data = { {0} };
71 static int resp_data_len;
73 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
74 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
76 GSList *scanner_list = NULL;
77 static gboolean is_le_set_scan_parameter = FALSE;
78 static gboolean is_le_scanning = FALSE;
79 static gboolean scan_filter_enabled = FALSE;
80 static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN;
82 static void __bt_free_le_adv_slot(void)
86 if (le_adv_slot == NULL)
89 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
90 if (le_adv_slot[i].sender)
91 g_free(le_adv_slot[i].sender);
97 int _bt_service_adapter_le_init(void)
99 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
101 return BLUETOOTH_ERROR_NONE;
104 void _bt_service_adapter_le_deinit(void)
106 __bt_free_le_adv_slot();
109 gboolean _bt_update_le_feature_support(const char *item, const char *value)
111 if (item == NULL || value == NULL)
114 if (g_strcmp0(item, "adv_inst_max") == 0) {
117 slot_num = atoi(value);
118 retv_if(slot_num < 0, FALSE);
119 retv_if(slot_num > BT_ADV_MULTI_MAX, FALSE);
121 if (slot_num != le_feature_info.adv_inst_max) {
122 __bt_free_le_adv_slot();
123 le_feature_info.adv_inst_max = slot_num;
124 BT_INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
125 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
127 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
128 le_feature_info.rpa_offloading = atoi(value);
129 BT_INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
130 } else if (g_strcmp0(item, "max_filter") == 0) {
131 le_feature_info.max_filter = atoi(value);
132 BT_INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
134 BT_DBG("No registered item");
141 static gboolean __bt_is_factory_test_mode(void)
145 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
146 BT_ERR("Get the DUT Mode fail");
151 BT_INFO("DUT Test Mode !!");
158 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
162 if (le_adv_slot == NULL) {
163 BT_ERR("le_adv_slot is NULL");
167 BT_DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
169 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
170 if (le_adv_slot[i].sender == NULL)
172 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
176 if (le_feature_info.adv_inst_max <= 2)
178 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
183 for (; i < le_feature_info.adv_inst_max; i++) {
184 if (le_adv_slot[i].sender == NULL)
191 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
193 if (le_adv_slot == NULL)
196 if (le_adv_slot[slot_id].sender == NULL) {
197 le_adv_slot[slot_id].sender = strdup(sender);
198 le_adv_slot[slot_id].adv_handle = adv_handle;
202 void _bt_unregister_adv_slot_owner(int slot_id)
204 if (le_adv_slot == NULL)
207 g_free(le_adv_slot[slot_id].sender);
208 le_adv_slot[slot_id].sender = NULL;
209 le_adv_slot[slot_id].adv_handle = 0;
212 const char* _bt_get_adv_slot_owner(int slot_id)
214 if (le_adv_slot == NULL)
217 return le_adv_slot[slot_id].sender;
220 int _bt_get_adv_slot_adv_handle(int slot_id)
222 if (le_adv_slot == NULL)
225 return le_adv_slot[slot_id].adv_handle;
228 void _bt_set_advertising_status(int slot_id, gboolean mode)
230 if (le_adv_slot == NULL)
233 le_adv_slot[slot_id].is_advertising = mode;
236 gboolean _bt_is_advertising(void)
238 gboolean status = FALSE;
241 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
242 if (le_adv_slot[i].is_advertising == TRUE)
249 gboolean _bt_is_multi_adv_supported(void)
251 return (le_feature_info.adv_inst_max > 1) ? TRUE : FALSE;
254 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
258 if (le_adv_slot == NULL)
261 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
262 if (le_adv_slot[i].sender != NULL) {
263 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
264 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
265 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
271 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
276 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
281 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
284 GError *error = NULL;
288 if (__bt_is_factory_test_mode()) {
289 BT_ERR("Unable to start advertising in factory binary !!");
290 return BLUETOOTH_ERROR_NOT_SUPPORT;
293 if (_bt_adapter_get_status() != BT_ACTIVATED &&
294 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
295 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
298 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
300 BT_ERR("There is NO available slot!!");
301 return BLUETOOTH_ERROR_NO_RESOURCES;
304 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
305 return BLUETOOTH_ERROR_IN_PROGRESS;
307 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
308 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
310 if (le_adv_slot[slot_id].hold_timer_id > 0) {
311 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
312 le_adv_slot[slot_id].hold_timer_id = 0;
315 proxy = _bt_get_adapter_proxy();
316 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
318 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
319 g_variant_new("(bi)", enable, slot_id),
320 G_DBUS_CALL_FLAGS_NONE,
326 BT_ERR("SetAdvertising Fail: %s", error->message);
327 g_clear_error(&error);
328 return BLUETOOTH_ERROR_INTERNAL;
332 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
334 le_adv_slot[slot_id].is_advertising = enable;
335 BT_INFO_C("### Set advertising [%d]", enable);
338 g_variant_unref(ret);
340 return BLUETOOTH_ERROR_NONE;
343 int _bt_set_custom_advertising(const char *sender, int adv_handle,
344 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
348 GError *error = NULL;
353 BT_CHECK_PARAMETER(params, return);
355 if (__bt_is_factory_test_mode()) {
356 BT_ERR("Unable to start advertising in factory binary !!");
357 return BLUETOOTH_ERROR_NOT_SUPPORT;
360 if (_bt_adapter_get_status() != BT_ACTIVATED &&
361 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
362 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
365 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
367 BT_ERR("There is NO available slot!!");
368 return BLUETOOTH_ERROR_NO_RESOURCES;
371 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
372 return BLUETOOTH_ERROR_IN_PROGRESS;
374 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
375 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
377 if (le_adv_slot[slot_id].hold_timer_id > 0) {
378 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
379 le_adv_slot[slot_id].hold_timer_id = 0;
382 proxy = _bt_get_adapter_proxy();
383 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
385 if (params->interval_min > params->interval_max ||
386 params->interval_min < BT_ADV_INTERVAL_MIN ||
387 params->interval_max > BT_ADV_INTERVAL_MAX)
388 return BLUETOOTH_ERROR_INVALID_PARAM;
390 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
391 return BLUETOOTH_ERROR_INVALID_PARAM;
393 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
394 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
395 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
396 return BLUETOOTH_ERROR_NOT_SUPPORT;
398 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
399 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
401 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
402 g_variant_new("(uuuui)", min, max,
403 params->filter_policy, params->type,
404 slot_id), G_DBUS_CALL_FLAGS_NONE,
408 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
409 g_clear_error(&error);
410 return BLUETOOTH_ERROR_INTERNAL;
413 adv_params.interval_min = params->interval_min;
414 adv_params.interval_max = params->interval_max;
415 adv_params.filter_policy = params->filter_policy;
416 adv_params.type = params->type;
419 g_variant_unref(ret);
421 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
422 g_variant_new("(bi)", enable, slot_id),
423 G_DBUS_CALL_FLAGS_NONE,
429 BT_ERR("SetAdvertising Fail: %s", error->message);
430 g_clear_error(&error);
431 return BLUETOOTH_ERROR_INTERNAL;
435 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
437 _bt_unregister_adv_slot_owner(slot_id);
439 le_adv_slot[slot_id].is_advertising = enable;
440 BT_INFO_C("### Set advertising [%d]", enable);
442 g_variant_unref(ret);
444 return BLUETOOTH_ERROR_NONE;
447 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
450 GError *error = NULL;
453 BT_INFO("Restart advertising stopped by bt-service");
455 le_adv_slot[0].hold_timer_id = 0;
457 proxy = _bt_get_adapter_proxy();
458 retv_if(proxy == NULL, FALSE);
460 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
461 g_variant_new("(bi)", TRUE, 0),
462 G_DBUS_CALL_FLAGS_NONE,
468 BT_ERR("SetAdvertising Fail: %s", error->message);
469 g_clear_error(&error);
474 g_variant_unref(ret);
479 int _bt_hold_current_advertising(void)
482 GError *error = NULL;
485 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
486 BT_INFO("Stop current advertising by bt-service");
488 proxy = _bt_get_adapter_proxy();
489 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
491 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
492 g_variant_new("(bi)", FALSE, 0),
493 G_DBUS_CALL_FLAGS_NONE,
499 BT_ERR("SetAdvertising Fail: %s", error->message);
500 g_clear_error(&error);
501 return BLUETOOTH_ERROR_INTERNAL;
505 g_variant_unref(ret);
507 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
508 __bt_hold_current_advertising_timeout_cb, NULL);
510 BT_ERR("It's NOT advertising");
511 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
514 return BLUETOOTH_ERROR_NONE;
517 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
518 char in_type, char **data, int *data_len)
520 if (in_data == NULL || data == NULL || data_len == NULL)
521 return BLUETOOTH_ERROR_INTERNAL;
524 return BLUETOOTH_ERROR_INTERNAL;
530 for (i = 0; i < in_len; i++) {
532 if (len <= 0 || i + 1 >= in_len) {
533 BT_ERR("Invalid advertising data");
534 return BLUETOOTH_ERROR_INTERNAL;
537 type = in_data[i + 1];
538 if (type == in_type) {
548 if (i + len > in_len) {
549 BT_ERR("Invalid advertising data");
550 return BLUETOOTH_ERROR_INTERNAL;
551 } else if (len == 0) {
552 BT_DBG("AD Type 0x%02x data is not set", in_type);
555 return BLUETOOTH_ERROR_NONE;
558 *data = g_memdup(&in_data[i], len);
560 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
563 return BLUETOOTH_ERROR_NONE;
566 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
568 BT_CHECK_PARAMETER(adv, return);
569 BT_CHECK_PARAMETER(length, return);
571 memcpy(adv, &adv_data, sizeof(adv_data));
572 *length = adv_data_len;
574 return BLUETOOTH_ERROR_NONE;
577 int _bt_set_advertising_data(const char *sender, int adv_handle,
578 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
581 GError *error = NULL;
582 GVariant *ret, *ad_data, *param = NULL;
583 GVariant *temp = NULL;
584 GVariantBuilder *builder;
586 char *old_mdata = NULL;
587 char *new_mdata = NULL;
592 if (__bt_is_factory_test_mode()) {
593 BT_ERR("Unable to set advertising data in factory binary !!");
594 return BLUETOOTH_ERROR_NOT_SUPPORT;
597 BT_CHECK_PARAMETER(adv, return);
599 if (_bt_adapter_get_status() != BT_ACTIVATED &&
600 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
601 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
604 proxy = _bt_get_adapter_proxy();
605 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
607 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
609 BT_ERR("There is NO available slot!!");
610 return BLUETOOTH_ERROR_NO_RESOURCES;
613 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
614 for (i = 0; i < length; i++)
615 g_variant_builder_add(builder, "y", adv->data[i]);
617 temp = g_variant_new("ay", builder);
618 g_variant_builder_unref(builder);
619 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
620 g_variant_new("(@ayi)", temp, slot_id),
621 G_DBUS_CALL_FLAGS_NONE,
625 BT_ERR("SetAdvertisingData Fail: %s", error->message);
626 g_clear_error(&error);
627 return BLUETOOTH_ERROR_INTERNAL;
630 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
632 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
633 &old_mdata, &old_len);
634 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
635 &new_mdata, &new_len);
636 if (old_len != new_len ||
637 (old_mdata && new_mdata &&
638 memcmp(old_mdata, new_mdata, new_len))) {
639 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
640 new_mdata, new_len, TRUE, NULL, NULL);
641 param = g_variant_new("(@ay)", ad_data);
642 _bt_send_event(BT_ADAPTER_EVENT,
643 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
649 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
650 memcpy(&adv_data, adv, length);
651 adv_data_len = length;
653 BT_INFO("Set advertising data");
655 g_variant_unref(ret);
657 return BLUETOOTH_ERROR_NONE;
660 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
662 BT_CHECK_PARAMETER(response, return);
663 BT_CHECK_PARAMETER(length, return);
665 memcpy(response, &resp_data, sizeof(resp_data));
666 *length = resp_data_len;
668 return BLUETOOTH_ERROR_NONE;
671 int _bt_set_scan_response_data(const char *sender, int adv_handle,
672 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
675 GError *error = NULL;
676 GVariant *ret, *scan_data, *param = NULL;
677 GVariant *temp = NULL;
678 GVariantBuilder *builder;
680 char *old_mdata = NULL;
681 char *new_mdata = NULL;
686 if (__bt_is_factory_test_mode()) {
687 BT_ERR("Unable to set scan response list in factory binary !!");
688 return BLUETOOTH_ERROR_NOT_SUPPORT;
691 BT_CHECK_PARAMETER(response, return);
693 if (_bt_adapter_get_status() != BT_ACTIVATED &&
694 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
695 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
698 proxy = _bt_get_adapter_proxy();
699 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
701 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
703 BT_ERR("There is NO available slot!!");
704 return BLUETOOTH_ERROR_NO_RESOURCES;
706 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
707 for (i = 0; i < length; i++)
708 g_variant_builder_add(builder, "y", response->data[i]);
710 temp = g_variant_new("ay", builder);
711 g_variant_builder_unref(builder);
712 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
713 g_variant_new("(@ayi)", temp, slot_id),
714 G_DBUS_CALL_FLAGS_NONE,
718 BT_ERR("SetScanRespData Fail: %s", error->message);
719 g_clear_error(&error);
720 return BLUETOOTH_ERROR_INTERNAL;
723 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
725 /* Compare with previous scan resp data */
726 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
727 &old_mdata, &old_len);
728 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
729 &new_mdata, &new_len);
730 if (old_len != new_len ||
731 (old_mdata && new_mdata &&
732 memcmp(old_mdata, new_mdata, new_len))) {
733 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
734 new_mdata, new_len, TRUE, NULL, NULL);
735 param = g_variant_new("(@ay)", scan_data);
736 _bt_send_event(BT_ADAPTER_EVENT,
737 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
743 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
744 memcpy(&resp_data, response, length);
745 resp_data_len = length;
748 g_variant_unref(ret);
749 BT_INFO("Set scan response data");
750 return BLUETOOTH_ERROR_NONE;
753 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
756 GError *error = NULL;
761 BT_CHECK_PARAMETER(params, return);
763 if (_bt_adapter_get_status() != BT_ACTIVATED &&
764 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
765 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
768 proxy = _bt_get_adapter_proxy();
769 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
771 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
772 return BLUETOOTH_ERROR_INVALID_PARAM;
774 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
775 return BLUETOOTH_ERROR_INVALID_PARAM;
777 if (params->window > params->interval)
778 return BLUETOOTH_ERROR_INVALID_PARAM;
780 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
781 win = params->window / BT_ADV_INTERVAL_SPLIT;
783 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
784 g_variant_new("(uuu)", params->type, itv, win),
785 G_DBUS_CALL_FLAGS_NONE, -1,
789 BT_ERR("SetScanParameters Fail: %s", error->message);
790 g_clear_error(&error);
791 return BLUETOOTH_ERROR_INTERNAL;
794 _bt_set_le_scan_type(params->type);
796 is_le_set_scan_parameter = TRUE;
799 g_variant_unref(ret);
800 BT_INFO("Set scan parameters");
801 return BLUETOOTH_ERROR_NONE;
804 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
807 bt_adapter_le_scanner_t *scanner;
809 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
811 if (g_strcmp0(scanner->sender, sender) == 0)
818 int __bt_get_available_scan_filter_slot_id(void)
821 bt_adapter_le_scanner_t *scanner;
823 bluetooth_le_scan_filter_t *filter_data;
824 gboolean *slot_check_list = NULL;
827 if (le_feature_info.max_filter == 0) {
828 BT_ERR("Scan filter is NOT Supported");
831 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
833 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
835 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
836 filter_data = fl->data;
837 if (filter_data->slot_id < le_feature_info.max_filter)
838 slot_check_list[filter_data->slot_id] = TRUE;
842 for (i = 0; i < le_feature_info.max_filter; i++) {
843 if (slot_check_list[i] == FALSE) {
844 g_free(slot_check_list);
849 BT_ERR("There is NO available slot for scan filter.");
850 g_free(slot_check_list);
854 gboolean _bt_is_scan_filter_supported(void)
856 if (le_feature_info.max_filter > 0)
862 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
865 GError *error = NULL;
866 GVariant *ret, *param;
867 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
868 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
869 GArray *arr_uuid = NULL;
870 GArray *arr_uuid_mask = NULL;
871 GArray *arr_data = NULL;
872 GArray *arr_data_mask = NULL;
873 bt_adapter_le_scanner_t *scanner = NULL;
874 bluetooth_le_scan_filter_t *filter_data = NULL;
875 int feature_selection = 0;
877 *slot_id = __bt_get_available_scan_filter_slot_id();
879 return BLUETOOTH_ERROR_NO_RESOURCES;
881 proxy = _bt_get_adapter_proxy();
882 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
884 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
885 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
886 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
888 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
890 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
891 NULL, 0, TRUE, NULL, NULL);
892 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
893 NULL, 0, TRUE, NULL, NULL);
894 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
895 NULL, 0, TRUE, NULL, NULL);
896 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
897 NULL, 0, TRUE, NULL, NULL);
899 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
901 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
902 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
903 *slot_id, // filter_index
905 0, // company_id_mask
906 arr_uuid_param, // p_uuid
907 arr_uuid_mask_param, // p_uuid_mask
910 arr_data_param, // p_data
911 arr_data_mask_param); // p_mask
913 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
914 param, G_DBUS_CALL_FLAGS_NONE,
918 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
919 g_clear_error(&error);
922 g_variant_unref(ret);
925 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
926 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
928 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
929 NULL, 0, TRUE, NULL, NULL);
930 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
931 NULL, 0, TRUE, NULL, NULL);
932 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
933 NULL, 0, TRUE, NULL, NULL);
934 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
935 NULL, 0, TRUE, NULL, NULL);
937 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
939 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
940 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
941 *slot_id, // filter_index
943 0, // company_id_mask
944 arr_uuid_param, // p_uuid
945 arr_uuid_mask_param, // p_uuid_mask
946 filter->device_name, // string
948 arr_data_param, // p_data
949 arr_data_mask_param);
951 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
952 param, G_DBUS_CALL_FLAGS_NONE,
956 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
957 g_clear_error(&error);
960 g_variant_unref(ret);
963 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
964 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
966 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
967 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
969 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
970 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
972 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
973 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
974 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
975 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
976 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
977 NULL, 0, TRUE, NULL, NULL);
978 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
979 NULL, 0, TRUE, NULL, NULL);
981 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
983 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
984 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
985 *slot_id, // filter_index
987 0, // company_id_mask
988 arr_uuid_param, // p_uuid
989 arr_uuid_mask_param, // p_uuid_mask
992 arr_data_param, // p_data
993 arr_data_mask_param);
995 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
996 param, G_DBUS_CALL_FLAGS_NONE,
1000 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1001 g_clear_error(&error);
1004 g_variant_unref(ret);
1006 g_array_free(arr_uuid, TRUE);
1007 g_array_free(arr_uuid_mask, TRUE);
1008 g_array_free(arr_data, TRUE);
1009 g_array_free(arr_data_mask, TRUE);
1012 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1013 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1015 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1016 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1018 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1019 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1021 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1022 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1023 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1024 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1025 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1026 NULL, 0, TRUE, NULL, NULL);
1027 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1028 NULL, 0, TRUE, NULL, NULL);
1030 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1032 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1033 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1034 *slot_id, // filter_index
1036 0, // company_id_mask
1037 arr_uuid_param, // p_uuid
1038 arr_uuid_mask_param, // p_uuid_mask
1041 arr_data_param, // p_data
1042 arr_data_mask_param);
1044 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1045 G_DBUS_CALL_FLAGS_NONE,
1049 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1050 g_clear_error(&error);
1053 g_variant_unref(ret);
1055 g_array_free(arr_uuid, TRUE);
1056 g_array_free(arr_uuid_mask, TRUE);
1059 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1060 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1062 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1063 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1065 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1066 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1068 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1069 NULL, 0, TRUE, NULL, NULL);
1070 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1071 NULL, 0, TRUE, NULL, NULL);
1072 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1073 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1074 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1075 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1077 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1079 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1080 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1081 *slot_id, // filter_index
1083 0, // company_id_mask
1084 arr_uuid_param, // p_uuid
1085 arr_uuid_mask_param, // p_uuid_mask
1088 arr_data_param, // p_data
1089 arr_data_mask_param);
1091 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1092 G_DBUS_CALL_FLAGS_NONE,
1096 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1097 g_clear_error(&error);
1100 g_variant_unref(ret);
1102 g_array_free(arr_data, TRUE);
1103 g_array_free(arr_data_mask, TRUE);
1106 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1107 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1109 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1110 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1112 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1113 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1115 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1116 NULL, 0, TRUE, NULL, NULL);
1117 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1118 NULL, 0, TRUE, NULL, NULL);
1119 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1120 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1121 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1122 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1124 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1126 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1127 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1128 *slot_id, // filter_index
1129 filter->manufacturer_id, // company_id
1130 0xFFFF, // company_id_mask
1131 arr_uuid_param, // p_uuid
1132 arr_uuid_mask_param, // p_uuid_mask
1135 arr_data_param, // p_data
1136 arr_data_mask_param);
1138 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1139 G_DBUS_CALL_FLAGS_NONE,
1143 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1144 g_clear_error(&error);
1147 g_variant_unref(ret);
1149 g_array_free(arr_data, TRUE);
1150 g_array_free(arr_data_mask, TRUE);
1153 BT_DBG("Filter selection %.2x", feature_selection);
1155 param = g_variant_new("(iiiiiiiiiiii)",
1157 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1158 *slot_id, // filter_index
1159 feature_selection, // feat_seln
1160 0, // list_logic_type (OR - 0x00, AND - 0x01)
1161 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1162 -127, // rssi_high_thres
1163 -127, // rssi_low_thres
1164 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1167 0); // found_timeout_cnt
1168 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1169 param, G_DBUS_CALL_FLAGS_NONE,
1173 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1174 g_clear_error(&error);
1177 scanner = __bt_find_scanner_from_list(sender);
1178 if (scanner == NULL) {
1179 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1180 scanner->sender = strdup(sender);
1181 scanner_list = g_slist_append(scanner_list, scanner);
1184 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1185 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1186 filter_data->slot_id = *slot_id;
1189 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1192 g_variant_unref(ret);
1193 return BLUETOOTH_ERROR_NONE;
1196 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1199 GError *error = NULL;
1201 bt_adapter_le_scanner_t *scanner = NULL;
1202 bluetooth_le_scan_filter_t *filter_data = NULL;
1204 gboolean is_slot_id_found = FALSE;
1206 scanner = __bt_find_scanner_from_list(sender);
1207 if (scanner == NULL) {
1208 BT_ERR("There is NO available scanner.");
1209 return BLUETOOTH_ERROR_NOT_FOUND;
1212 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1213 filter_data = l->data;
1214 if (filter_data->slot_id == slot_id) {
1215 is_slot_id_found = TRUE;
1219 if (is_slot_id_found == FALSE) {
1220 BT_ERR("There is NO registered slot.");
1221 return BLUETOOTH_ERROR_NOT_FOUND;
1224 proxy = _bt_get_adapter_proxy();
1225 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1227 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1228 g_variant_new("(ii)", 0, slot_id),
1229 G_DBUS_CALL_FLAGS_NONE,
1233 BT_ERR("scan_filter_clear Fail: %s", error->message);
1234 g_clear_error(&error);
1237 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1238 g_free(filter_data);
1241 g_variant_unref(ret);
1242 return BLUETOOTH_ERROR_NONE;
1245 int _bt_unregister_all_scan_filters(const char *sender)
1248 GError *error = NULL;
1250 bt_adapter_le_scanner_t *scanner = NULL;
1251 bluetooth_le_scan_filter_t *filter_data = NULL;
1254 scanner = __bt_find_scanner_from_list(sender);
1255 if (scanner == NULL) {
1256 BT_ERR("There is NO available scanner.");
1257 return BLUETOOTH_ERROR_NOT_FOUND;
1260 proxy = _bt_get_adapter_proxy();
1261 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1263 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1264 filter_data = l->data;
1266 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1267 g_variant_new("(ii)", 0, filter_data->slot_id),
1268 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1271 BT_ERR("scan_filter_clear Fail: %s", error->message);
1272 g_clear_error(&error);
1275 g_variant_unref(ret);
1278 g_slist_free_full(scanner->filter_list, g_free);
1279 scanner->filter_list = NULL;
1281 return BLUETOOTH_ERROR_NONE;
1284 int _bt_start_le_scan(const char *sender)
1287 GError *error = NULL;
1289 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1291 if (scanner == NULL) {
1292 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1293 scanner->sender = strdup(sender);
1294 scanner_list = g_slist_append(scanner_list, scanner);
1297 if (scanner->is_scanning == TRUE) {
1298 BT_ERR("BT is already in LE scanning");
1299 return BLUETOOTH_ERROR_IN_PROGRESS;
1301 scanner->is_scanning = TRUE;
1303 proxy = _bt_get_adapter_proxy();
1304 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1306 if (_bt_is_le_scanning()) {
1307 if (scan_filter_enabled == TRUE) {
1308 if (scanner->filter_list == NULL) {
1309 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1310 g_variant_new("(ib)", 0, FALSE),
1311 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1314 BT_ERR("scan_filter_clear Fail: %s", error->message);
1315 g_clear_error(&error);
1319 g_variant_unref(ret);
1320 BT_INFO("Disable LE Scan Filter");
1321 scan_filter_enabled = FALSE;
1323 BT_INFO("LE Filter Scan is continue");
1326 BT_INFO("LE Full Scan is already on progress");
1328 return BLUETOOTH_ERROR_NONE;
1330 if (is_le_set_scan_parameter == FALSE) {
1331 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1332 bluetooth_le_scan_params_t scan_params;
1333 scan_params.type = BT_LE_ACTIVE_SCAN;
1334 scan_params.interval = 5000;
1335 scan_params.window = 500;
1336 _bt_set_scan_parameters(&scan_params);
1339 if (scanner->filter_list == NULL) {
1340 BT_INFO("Start LE Full Scan");
1341 scan_filter_enabled = FALSE;
1343 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1344 g_variant_new("(ib)", 0, TRUE),
1345 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1348 BT_ERR("scan_filter_clear Fail: %s", error->message);
1349 g_clear_error(&error);
1353 g_variant_unref(ret);
1354 BT_INFO("Enable LE Scan Filter");
1355 scan_filter_enabled = TRUE;
1359 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1360 NULL, G_DBUS_CALL_FLAGS_NONE,
1364 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1365 g_clear_error(&error);
1366 return BLUETOOTH_ERROR_INTERNAL;
1370 g_variant_unref(ret);
1371 return BLUETOOTH_ERROR_NONE;
1374 int _bt_stop_le_scan(const char *sender)
1377 GError *error = NULL;
1379 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1381 gboolean next_scanning = FALSE;
1382 gboolean need_scan_filter = TRUE;
1384 if (scanner == NULL || scanner->is_scanning == FALSE)
1385 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1387 scanner->is_scanning = FALSE;
1389 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1391 if (scanner->is_scanning == TRUE) {
1392 next_scanning = TRUE;
1393 if (scanner->filter_list == NULL)
1394 need_scan_filter = FALSE;
1398 proxy = _bt_get_adapter_proxy();
1399 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1401 if (next_scanning == TRUE) {
1402 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1403 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1404 g_variant_new("(ib)", 0, TRUE),
1405 G_DBUS_CALL_FLAGS_NONE,
1409 BT_ERR("scan_filter_clear Fail: %s", error->message);
1410 g_clear_error(&error);
1414 g_variant_unref(ret);
1415 BT_INFO("Enable LE Scan Filter");
1416 scan_filter_enabled = TRUE;
1418 return BLUETOOTH_ERROR_NONE;
1420 if (scan_filter_enabled == TRUE) {
1421 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1422 g_variant_new("(ib)", 0, FALSE),
1423 G_DBUS_CALL_FLAGS_NONE,
1427 BT_ERR("scan_filter_clear Fail: %s", error->message);
1428 g_clear_error(&error);
1432 g_variant_unref(ret);
1433 BT_INFO("Disable LE Scan Filter");
1435 BT_INFO("Just stop LE scan");
1439 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1440 NULL, G_DBUS_CALL_FLAGS_NONE,
1443 BT_ERR("LE Scan stop failed");
1444 return BLUETOOTH_ERROR_INTERNAL;
1447 scan_filter_enabled = FALSE;
1448 is_le_set_scan_parameter = FALSE;
1450 g_variant_unref(ret);
1451 return BLUETOOTH_ERROR_NONE;
1454 void _bt_disable_all_scanner_status(void)
1457 bt_adapter_le_scanner_t *scanner;
1459 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1461 scanner->is_scanning = FALSE;
1465 void _bt_set_le_scan_status(gboolean mode)
1467 is_le_scanning = mode;
1470 gboolean _bt_is_le_scanning(void)
1472 return is_le_scanning;
1475 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1477 le_scan_type = type;
1480 bt_le_scan_type_t _bt_get_le_scan_type(void)
1482 return le_scan_type;
1485 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1486 int adv_data_len, const char *svc_uuid, int uuid_len,
1487 const char *uuid_mask, char ad_type)
1493 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1494 ad_type, &data, &data_len);
1496 for (i = 0; i < data_len; i += uuid_len) {
1497 if (uuid_len > (data_len - i))
1500 if (_bt_byte_arr_cmp_with_mask(data + i,
1501 svc_uuid, uuid_mask, uuid_len) == 0) {
1512 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1513 const char *adv_data, int adv_data_len,
1514 const char *scan_data, int scan_data_len,
1515 const bt_adapter_le_scanner_t *scanner)
1518 bluetooth_le_scan_filter_t *filter_data = NULL;
1521 gboolean is_matched = FALSE;
1523 if (scanner->filter_list == NULL) {
1524 BT_INFO("This scanner is on Full Scan.");
1528 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1529 filter_data = l->data;
1531 if (filter_data->added_features &
1532 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1533 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1535 _bt_convert_addr_type_to_string(address,
1536 filter_data->device_address.addr);
1537 if (strncmp(address, device_address,
1538 BT_ADDRESS_STRING_SIZE) != 0)
1542 if (filter_data->added_features &
1543 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1546 if (__bt_check_scan_result_uuid(adv_data,
1548 (char*)filter_data->service_uuid.data.data,
1549 filter_data->service_uuid.data_len,
1550 (char*)filter_data->service_uuid_mask.data.data,
1551 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1554 if (__bt_check_scan_result_uuid(adv_data,
1556 (char*)filter_data->service_uuid.data.data,
1557 filter_data->service_uuid.data_len,
1558 (char*)filter_data->service_uuid_mask.data.data,
1559 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1562 if (__bt_check_scan_result_uuid(adv_data,
1564 (char*)filter_data->service_uuid.data.data,
1565 filter_data->service_uuid.data_len,
1566 (char*)filter_data->service_uuid_mask.data.data,
1567 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1570 if (__bt_check_scan_result_uuid(adv_data,
1572 (char*)filter_data->service_uuid.data.data,
1573 filter_data->service_uuid.data_len,
1574 (char*)filter_data->service_uuid_mask.data.data,
1575 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1578 if (__bt_check_scan_result_uuid(scan_data,
1580 (char*)filter_data->service_uuid.data.data,
1581 filter_data->service_uuid.data_len,
1582 (char*)filter_data->service_uuid_mask.data.data,
1583 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1586 if (__bt_check_scan_result_uuid(scan_data,
1588 (char*)filter_data->service_uuid.data.data,
1589 filter_data->service_uuid.data_len,
1590 (char*)filter_data->service_uuid_mask.data.data,
1591 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1594 if (__bt_check_scan_result_uuid(scan_data,
1596 (char*)filter_data->service_uuid.data.data,
1597 filter_data->service_uuid.data_len,
1598 (char*)filter_data->service_uuid_mask.data.data,
1599 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1602 if (__bt_check_scan_result_uuid(scan_data,
1604 (char*)filter_data->service_uuid.data.data,
1605 filter_data->service_uuid.data_len,
1606 (char*)filter_data->service_uuid_mask.data.data,
1607 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1611 if (is_matched == FALSE)
1614 if (filter_data->added_features &
1615 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1618 if (__bt_check_scan_result_uuid(adv_data,
1620 (char*)filter_data->service_solicitation_uuid.data.data,
1621 filter_data->service_solicitation_uuid.data_len,
1622 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1623 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1626 if (__bt_check_scan_result_uuid(adv_data,
1628 (char*)filter_data->service_solicitation_uuid.data.data,
1629 filter_data->service_solicitation_uuid.data_len,
1630 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1631 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1634 if (__bt_check_scan_result_uuid(scan_data,
1636 (char*)filter_data->service_solicitation_uuid.data.data,
1637 filter_data->service_solicitation_uuid.data_len,
1638 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1639 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1642 if (__bt_check_scan_result_uuid(scan_data,
1644 (char*)filter_data->service_solicitation_uuid.data.data,
1645 filter_data->service_solicitation_uuid.data_len,
1646 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1647 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1651 if (is_matched == FALSE)
1654 if (filter_data->added_features &
1655 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1656 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1661 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1662 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1665 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1666 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1667 memcpy(name, data, data_len);
1668 name[data_len] = '\0';
1671 if (strncmp(filter_data->device_name,
1672 name, data_len) == 0)
1675 __bt_get_ad_data_by_type((char*)scan_data,
1677 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1680 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1681 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1682 memcpy(name, data, data_len);
1683 name[data_len] = '\0';
1686 if (strncmp(filter_data->device_name,
1687 name, data_len) == 0)
1691 if (is_matched == FALSE)
1694 if (filter_data->added_features &
1695 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1700 __bt_get_ad_data_by_type((char*)adv_data,
1702 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1706 int manufacturer_id;
1707 manufacturer_id = (data[1] << 8) + data[0];
1709 if (filter_data->manufacturer_id == manufacturer_id) {
1710 if (filter_data->manufacturer_data.data_len == 0) {
1713 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1714 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1715 if (_bt_byte_arr_cmp_with_mask(data + 2,
1716 (char*)filter_data->manufacturer_data.data.data,
1717 (char*)filter_data->manufacturer_data_mask.data.data,
1718 data_len - 2) == 0) {
1726 __bt_get_ad_data_by_type((char*)scan_data,
1728 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1732 int manufacturer_id;
1733 manufacturer_id = (data[1] << 8) + data[0];
1735 if (filter_data->manufacturer_id == manufacturer_id) {
1736 if (filter_data->manufacturer_data.data_len == 0) {
1739 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1740 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1741 if (_bt_byte_arr_cmp_with_mask(data + 2,
1742 (char*)filter_data->manufacturer_data.data.data,
1743 (char*)filter_data->manufacturer_data_mask.data.data,
1744 data_len - 2) == 0) {
1753 if (is_matched == FALSE)
1756 if (filter_data->added_features &
1757 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1762 __bt_get_ad_data_by_type((char*)adv_data,
1764 BT_LE_AD_TYPE_SERVICE_DATA,
1767 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1768 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1769 if (_bt_byte_arr_cmp_with_mask(data,
1770 (char*)filter_data->service_data.data.data,
1771 (char*)filter_data->service_data_mask.data.data,
1778 __bt_get_ad_data_by_type((char*)scan_data,
1780 BT_LE_AD_TYPE_SERVICE_DATA,
1783 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1784 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1785 if (_bt_byte_arr_cmp_with_mask(data,
1786 (char*)filter_data->service_data.data.data,
1787 (char*)filter_data->service_data_mask.data.data,
1795 if (is_matched == FALSE)
1799 BT_INFO("The scan result is conformable.");
1803 BT_INFO("The scan result is NOT conformable.");
1807 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1808 const bt_le_adv_info_t *adv_info)
1810 int result = BLUETOOTH_ERROR_NONE;
1812 GVariant *scan_data_param, *adv_data_param;
1814 bt_adapter_le_scanner_t *scanner = NULL;
1815 const char *adv_data = NULL;
1816 int adv_data_len = 0;
1817 const char *scan_data = NULL;
1818 int scan_data_len = 0;
1820 ret_if(le_dev_info == NULL);
1821 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1822 ret_if(adv_info == NULL);
1824 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1825 adv_data = le_dev_info->adv_data;
1826 adv_data_len = le_dev_info->adv_data_len;
1827 scan_data = le_dev_info->adv_data;
1830 adv_data = adv_info->data;
1831 adv_data_len = adv_info->data_len;
1832 scan_data = le_dev_info->adv_data;
1833 scan_data_len = le_dev_info->adv_data_len;
1836 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1838 if (scanner->is_scanning == FALSE)
1841 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1842 adv_data, adv_data_len, scan_data, scan_data_len,
1846 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1847 adv_data, adv_data_len, TRUE, NULL, NULL);
1848 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1849 scan_data, scan_data_len, TRUE, NULL, NULL);
1851 param = g_variant_new("(isnnn@ayn@ay)",
1853 le_dev_info->address,
1854 le_dev_info->addr_type,
1861 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1862 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1866 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1869 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1870 GError *error = NULL;
1873 if (__bt_is_factory_test_mode()) {
1874 BT_ERR("Unable to add white list in factory binary !!");
1875 return BLUETOOTH_ERROR_NOT_SUPPORT;
1878 BT_CHECK_PARAMETER(device_address, return);
1880 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1881 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1882 return BLUETOOTH_ERROR_INVALID_PARAM;
1884 _bt_convert_addr_type_to_string(address, device_address->addr);
1886 proxy = _bt_get_adapter_proxy();
1887 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1889 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1890 g_variant_new("(su)", address, address_type),
1891 G_DBUS_CALL_FLAGS_NONE, -1,
1895 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
1896 g_clear_error(&error);
1897 return BLUETOOTH_ERROR_INTERNAL;
1901 g_variant_unref(ret);
1902 BT_INFO("Add white list");
1904 return BLUETOOTH_ERROR_NONE;
1907 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1910 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1911 GError *error = NULL;
1914 if (__bt_is_factory_test_mode()) {
1915 BT_ERR("Unable to remove white list in factory binary !!");
1916 return BLUETOOTH_ERROR_NOT_SUPPORT;
1919 BT_CHECK_PARAMETER(device_address, return);
1921 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1922 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1923 return BLUETOOTH_ERROR_INVALID_PARAM;
1925 _bt_convert_addr_type_to_string(address, device_address->addr);
1927 proxy = _bt_get_adapter_proxy();
1928 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1930 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1931 g_variant_new("(su)", address, address_type),
1932 G_DBUS_CALL_FLAGS_NONE, -1,
1936 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
1937 g_clear_error(&error);
1938 return BLUETOOTH_ERROR_INTERNAL;
1942 g_variant_unref(ret);
1943 BT_INFO("Remove white list");
1945 return BLUETOOTH_ERROR_NONE;
1948 int _bt_clear_white_list(void)
1951 GError *error = NULL;
1954 if (__bt_is_factory_test_mode()) {
1955 BT_ERR("Unable to clear white list in factory binary !!");
1956 return BLUETOOTH_ERROR_NOT_SUPPORT;
1959 proxy = _bt_get_adapter_proxy();
1960 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1962 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
1963 NULL, G_DBUS_CALL_FLAGS_NONE,
1967 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
1968 g_clear_error(&error);
1969 return BLUETOOTH_ERROR_INTERNAL;
1972 g_variant_unref(ret);
1974 BT_INFO("Clear white list");
1976 return BLUETOOTH_ERROR_NONE;
1979 int _bt_initialize_ipsp(void)
1983 GError *error = NULL;
1986 if (_bt_adapter_get_status() != BT_ACTIVATED &&
1987 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
1988 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1991 proxy = _bt_get_adapter_proxy();
1992 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1994 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
1995 NULL, G_DBUS_CALL_FLAGS_NONE,
1998 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
1999 g_clear_error(&error);
2000 return BLUETOOTH_ERROR_INTERNAL;
2003 g_variant_unref(ret);
2005 BT_INFO("IPSP initialization called successfully");
2007 return BLUETOOTH_ERROR_NONE;
2010 int _bt_deinitialize_ipsp(void)
2014 GError *error = NULL;
2017 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2018 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2019 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2022 proxy = _bt_get_adapter_proxy();
2023 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2025 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2026 NULL, G_DBUS_CALL_FLAGS_NONE,
2029 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2030 g_clear_error(&error);
2031 return BLUETOOTH_ERROR_INTERNAL;
2034 g_variant_unref(ret);
2036 BT_INFO("IPSP De-initialization called successfully");
2038 return BLUETOOTH_ERROR_NONE;
2041 int _bt_le_read_maximum_data_length(
2042 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2044 GError *error = NULL;
2046 GVariant *reply = NULL;
2047 guint16 max_tx_octets, max_tx_time;
2048 guint16 max_rx_octets, max_rx_time;
2050 proxy = _bt_get_adapter_proxy();
2051 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2053 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2054 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2056 g_object_unref(proxy);
2058 if (reply == NULL) {
2059 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2060 if (error != NULL) {
2061 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2062 error->code, error->message);
2063 g_clear_error(&error);
2065 return BLUETOOTH_ERROR_INTERNAL;
2068 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2069 &max_rx_octets, &max_rx_time);
2071 max_le_datalength->max_tx_octets = max_tx_octets;
2072 max_le_datalength->max_tx_time = max_tx_time;
2073 max_le_datalength->max_rx_octets = max_rx_octets;
2074 max_le_datalength->max_rx_time = max_rx_time;
2076 g_variant_unref(reply);
2078 return BLUETOOTH_ERROR_NONE;
2080 int _bt_le_write_host_suggested_default_data_length(
2081 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2083 GError *error = NULL;
2085 GVariant *reply = NULL;
2087 proxy = _bt_get_adapter_proxy();
2088 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2090 reply = g_dbus_proxy_call_sync(proxy,
2091 "LEWriteHostSuggestedDataLength",
2092 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2093 G_DBUS_CALL_FLAGS_NONE,
2098 g_object_unref(proxy);
2100 if (reply == NULL) {
2101 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2102 if (error != NULL) {
2103 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2104 error->code, error->message);
2105 g_clear_error(&error);
2107 return BLUETOOTH_ERROR_INTERNAL;
2110 g_variant_unref(reply);
2112 return BLUETOOTH_ERROR_NONE;
2115 int _bt_le_read_host_suggested_default_data_length(
2116 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2118 GError *error = NULL;
2120 GVariant *reply = NULL;
2121 guint16 def_tx_octets, def_tx_time;
2123 proxy = _bt_get_adapter_proxy();
2124 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2126 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2127 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2129 if (reply == NULL) {
2130 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2131 if (error != NULL) {
2132 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2133 error->code, error->message);
2134 g_clear_error(&error);
2136 return BLUETOOTH_ERROR_INTERNAL;
2139 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2141 def_data_length->def_tx_octets = def_tx_octets;
2142 def_data_length->def_tx_time = def_tx_time;
2144 g_variant_unref(reply);
2146 return BLUETOOTH_ERROR_NONE;
2149 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2150 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2152 GError *error = NULL;
2153 guint16 txOctets = max_tx_Octets;
2154 guint16 txTime = max_tx_Time;
2155 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2156 gchar *device_path = NULL;
2157 GDBusConnection *conn;
2158 GDBusProxy *device_proxy;
2160 _bt_convert_addr_type_to_string(address, device_address->addr);
2162 device_path = _bt_get_device_object_path(address);
2164 if (device_path == NULL) {
2165 BT_DBG("Device path is null");
2166 return BLUETOOTH_ERROR_INTERNAL;
2169 conn = _bt_gdbus_get_system_gconn();
2171 BT_ERR("conn == NULL");
2172 g_free(device_path);
2173 return BLUETOOTH_ERROR_INTERNAL;
2176 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2177 NULL, BT_BLUEZ_NAME,
2178 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2180 g_free(device_path);
2181 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2183 g_dbus_proxy_call_sync(device_proxy,
2185 g_variant_new("(qq)", txOctets, txTime),
2186 G_DBUS_CALL_FLAGS_NONE,
2191 g_object_unref(device_proxy);
2194 BT_ERR("LESetDataLength error: [%s]", error->message);
2195 g_error_free(error);
2196 return BLUETOOTH_ERROR_INTERNAL;
2199 return BLUETOOTH_ERROR_NONE;