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>
27 #include "bt-internal-types.h"
28 #include "bt-service-common.h"
29 #include "bt-service-event.h"
30 #include "bt-service-adapter.h"
31 #include "bt-service-adapter-le.h"
32 #include "bt-service-util.h"
35 #define BT_ADV_INTERVAL_MIN 20 /* msec */
36 #define BT_ADV_INTERVAL_MAX 10240
37 #define BT_ADV_INTERVAL_SPLIT 0.625
38 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
39 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
40 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
41 #define BT_ADV_TYPE_DEFAULT 0x00
42 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
43 #define BT_ADV_MULTI_MAX 16
49 } bt_adapter_le_feature_info_t;
54 gboolean is_advertising;
56 } bt_adapter_le_adv_slot_t;
62 } bt_adapter_le_scanner_t;
64 static bluetooth_advertising_params_t adv_params = {
65 BT_DEFAULT_ADV_MIN_INTERVAL,
66 BT_DEFAULT_ADV_MAX_INTERVAL,
67 BT_ADV_FILTER_POLICY_DEFAULT,
69 static bluetooth_advertising_data_t adv_data = { {0} };
70 static int adv_data_len;
71 static bluetooth_scan_resp_data_t resp_data = { {0} };
72 static int resp_data_len;
74 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
75 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
77 GSList *scanner_list = NULL;
78 static gboolean is_le_set_scan_parameter = FALSE;
79 static gboolean is_le_scanning = FALSE;
80 static gboolean scan_filter_enabled = FALSE;
81 static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN;
83 static void __bt_free_le_adv_slot(void)
87 if (le_adv_slot == NULL)
90 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
91 if (le_adv_slot[i].sender)
92 g_free(le_adv_slot[i].sender);
98 int _bt_service_adapter_le_init(void)
100 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
102 return BLUETOOTH_ERROR_NONE;
105 void _bt_service_adapter_le_deinit(void)
107 __bt_free_le_adv_slot();
110 gboolean _bt_update_le_feature_support(const char *item, const char *value)
112 if (item == NULL || value == NULL)
115 if (g_strcmp0(item, "adv_inst_max") == 0) {
118 slot_num = atoi(value);
119 retv_if(slot_num < 0, FALSE);
120 retv_if(slot_num > BT_ADV_MULTI_MAX, FALSE);
122 if (slot_num != le_feature_info.adv_inst_max) {
123 __bt_free_le_adv_slot();
124 le_feature_info.adv_inst_max = slot_num;
125 BT_INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
126 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
128 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
129 le_feature_info.rpa_offloading = atoi(value);
130 BT_INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
131 } else if (g_strcmp0(item, "max_filter") == 0) {
132 le_feature_info.max_filter = atoi(value);
133 BT_INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
135 BT_DBG("No registered item");
142 static gboolean __bt_is_factory_test_mode(void)
146 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
147 BT_ERR("Get the DUT Mode fail");
152 BT_INFO("DUT Test Mode !!");
159 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
163 if (le_adv_slot == NULL) {
164 BT_ERR("le_adv_slot is NULL");
168 BT_DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
170 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
171 if (le_adv_slot[i].sender == NULL)
173 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
177 if (le_feature_info.adv_inst_max <= 2)
179 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
184 for (; i < le_feature_info.adv_inst_max; i++) {
185 if (le_adv_slot[i].sender == NULL)
192 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
194 if (le_adv_slot == NULL)
197 if (le_adv_slot[slot_id].sender == NULL) {
198 le_adv_slot[slot_id].sender = strdup(sender);
199 le_adv_slot[slot_id].adv_handle = adv_handle;
203 void _bt_unregister_adv_slot_owner(int slot_id)
205 if (le_adv_slot == NULL)
208 g_free(le_adv_slot[slot_id].sender);
209 le_adv_slot[slot_id].sender = NULL;
210 le_adv_slot[slot_id].adv_handle = 0;
213 const char* _bt_get_adv_slot_owner(int slot_id)
215 if (le_adv_slot == NULL)
218 return le_adv_slot[slot_id].sender;
221 int _bt_get_adv_slot_adv_handle(int slot_id)
223 if (le_adv_slot == NULL)
226 return le_adv_slot[slot_id].adv_handle;
229 void _bt_set_advertising_status(int slot_id, gboolean mode)
231 if (le_adv_slot == NULL)
234 le_adv_slot[slot_id].is_advertising = mode;
237 gboolean _bt_is_advertising(void)
239 gboolean status = FALSE;
242 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
243 if (le_adv_slot[i].is_advertising == TRUE)
250 gboolean _bt_is_multi_adv_supported(void)
252 return (le_feature_info.adv_inst_max > 1) ? TRUE : FALSE;
255 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
259 if (le_adv_slot == NULL)
262 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
263 if (le_adv_slot[i].sender != NULL) {
264 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
265 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
266 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
272 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
277 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
282 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
285 GError *error = NULL;
289 if (__bt_is_factory_test_mode()) {
290 BT_ERR("Unable to start advertising in factory binary !!");
291 return BLUETOOTH_ERROR_NOT_SUPPORT;
294 if (_bt_adapter_get_status() != BT_ACTIVATED &&
295 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
296 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
299 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
301 BT_ERR("There is NO available slot!!");
302 return BLUETOOTH_ERROR_NO_RESOURCES;
305 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
306 return BLUETOOTH_ERROR_IN_PROGRESS;
308 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
309 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
311 if (le_adv_slot[slot_id].hold_timer_id > 0) {
312 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
313 le_adv_slot[slot_id].hold_timer_id = 0;
316 proxy = _bt_get_adapter_proxy();
317 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
319 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
320 g_variant_new("(bi)", enable, slot_id),
321 G_DBUS_CALL_FLAGS_NONE,
327 BT_ERR("SetAdvertising Fail: %s", error->message);
328 g_clear_error(&error);
329 return BLUETOOTH_ERROR_INTERNAL;
333 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
335 le_adv_slot[slot_id].is_advertising = enable;
336 BT_INFO_C("### Set advertising [%d]", enable);
339 g_variant_unref(ret);
341 return BLUETOOTH_ERROR_NONE;
344 int _bt_set_custom_advertising(const char *sender, int adv_handle,
345 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
349 GError *error = NULL;
354 BT_CHECK_PARAMETER(params, return);
356 if (__bt_is_factory_test_mode()) {
357 BT_ERR("Unable to start advertising in factory binary !!");
358 return BLUETOOTH_ERROR_NOT_SUPPORT;
361 if (_bt_adapter_get_status() != BT_ACTIVATED &&
362 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
363 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
366 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
368 BT_ERR("There is NO available slot!!");
369 return BLUETOOTH_ERROR_NO_RESOURCES;
372 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
373 return BLUETOOTH_ERROR_IN_PROGRESS;
375 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
376 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
378 if (le_adv_slot[slot_id].hold_timer_id > 0) {
379 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
380 le_adv_slot[slot_id].hold_timer_id = 0;
383 proxy = _bt_get_adapter_proxy();
384 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
386 if (params->interval_min > params->interval_max ||
387 params->interval_min < BT_ADV_INTERVAL_MIN ||
388 params->interval_max > BT_ADV_INTERVAL_MAX)
389 return BLUETOOTH_ERROR_INVALID_PARAM;
391 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
392 return BLUETOOTH_ERROR_INVALID_PARAM;
394 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
395 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
396 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
397 return BLUETOOTH_ERROR_NOT_SUPPORT;
399 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
400 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
402 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
403 g_variant_new("(uuuui)", min, max,
404 params->filter_policy, params->type,
405 slot_id), G_DBUS_CALL_FLAGS_NONE,
409 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
410 g_clear_error(&error);
411 return BLUETOOTH_ERROR_INTERNAL;
414 adv_params.interval_min = params->interval_min;
415 adv_params.interval_max = params->interval_max;
416 adv_params.filter_policy = params->filter_policy;
417 adv_params.type = params->type;
420 g_variant_unref(ret);
422 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
423 g_variant_new("(bi)", enable, slot_id),
424 G_DBUS_CALL_FLAGS_NONE,
430 BT_ERR("SetAdvertising Fail: %s", error->message);
431 g_clear_error(&error);
432 return BLUETOOTH_ERROR_INTERNAL;
436 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
438 _bt_unregister_adv_slot_owner(slot_id);
440 le_adv_slot[slot_id].is_advertising = enable;
441 BT_INFO_C("### Set advertising [%d]", enable);
443 g_variant_unref(ret);
445 return BLUETOOTH_ERROR_NONE;
448 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
451 GError *error = NULL;
454 BT_INFO("Restart advertising stopped by bt-service");
456 le_adv_slot[0].hold_timer_id = 0;
458 proxy = _bt_get_adapter_proxy();
459 retv_if(proxy == NULL, FALSE);
461 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
462 g_variant_new("(bi)", TRUE, 0),
463 G_DBUS_CALL_FLAGS_NONE,
469 BT_ERR("SetAdvertising Fail: %s", error->message);
470 g_clear_error(&error);
475 g_variant_unref(ret);
480 int _bt_hold_current_advertising(void)
483 GError *error = NULL;
486 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
487 BT_INFO("Stop current advertising by bt-service");
489 proxy = _bt_get_adapter_proxy();
490 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
492 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
493 g_variant_new("(bi)", FALSE, 0),
494 G_DBUS_CALL_FLAGS_NONE,
500 BT_ERR("SetAdvertising Fail: %s", error->message);
501 g_clear_error(&error);
502 return BLUETOOTH_ERROR_INTERNAL;
506 g_variant_unref(ret);
508 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
509 __bt_hold_current_advertising_timeout_cb, NULL);
511 BT_ERR("It's NOT advertising");
512 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
515 return BLUETOOTH_ERROR_NONE;
518 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
519 char in_type, char **data, int *data_len)
521 if (in_data == NULL || data == NULL || data_len == NULL)
522 return BLUETOOTH_ERROR_INTERNAL;
525 return BLUETOOTH_ERROR_INTERNAL;
531 for (i = 0; i < in_len; i++) {
533 if (len <= 0 || i + 1 >= in_len) {
534 BT_ERR("Invalid advertising data");
535 return BLUETOOTH_ERROR_INTERNAL;
538 type = in_data[i + 1];
539 if (type == in_type) {
549 if (i + len > in_len) {
550 BT_ERR("Invalid advertising data");
551 return BLUETOOTH_ERROR_INTERNAL;
552 } else if (len == 0) {
553 BT_DBG("AD Type 0x%02x data is not set", in_type);
556 return BLUETOOTH_ERROR_NONE;
559 *data = g_memdup(&in_data[i], len);
561 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
564 return BLUETOOTH_ERROR_NONE;
567 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
569 BT_CHECK_PARAMETER(adv, return);
570 BT_CHECK_PARAMETER(length, return);
572 memcpy(adv, &adv_data, sizeof(adv_data));
573 *length = adv_data_len;
575 return BLUETOOTH_ERROR_NONE;
578 int _bt_set_advertising_data(const char *sender, int adv_handle,
579 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
582 GError *error = NULL;
583 GVariant *ret, *ad_data, *param = NULL;
584 GVariant *temp = NULL;
585 GVariantBuilder *builder;
587 char *old_mdata = NULL;
588 char *new_mdata = NULL;
593 if (__bt_is_factory_test_mode()) {
594 BT_ERR("Unable to set advertising data in factory binary !!");
595 return BLUETOOTH_ERROR_NOT_SUPPORT;
598 BT_CHECK_PARAMETER(adv, return);
600 if (_bt_adapter_get_status() != BT_ACTIVATED &&
601 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
602 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
605 proxy = _bt_get_adapter_proxy();
606 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
608 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
610 BT_ERR("There is NO available slot!!");
611 return BLUETOOTH_ERROR_NO_RESOURCES;
614 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
615 for (i = 0; i < length; i++)
616 g_variant_builder_add(builder, "y", adv->data[i]);
618 temp = g_variant_new("ay", builder);
619 g_variant_builder_unref(builder);
620 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
621 g_variant_new("(@ayi)", temp, slot_id),
622 G_DBUS_CALL_FLAGS_NONE,
626 BT_ERR("SetAdvertisingData Fail: %s", error->message);
627 g_clear_error(&error);
628 return BLUETOOTH_ERROR_INTERNAL;
631 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
633 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
634 &old_mdata, &old_len);
635 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
636 &new_mdata, &new_len);
637 if (old_len != new_len ||
638 (old_mdata && new_mdata &&
639 memcmp(old_mdata, new_mdata, new_len))) {
640 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
641 new_mdata, new_len, TRUE, NULL, NULL);
642 param = g_variant_new("(@ay)", ad_data);
643 _bt_send_event(BT_ADAPTER_EVENT,
644 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
650 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
651 memcpy(&adv_data, adv, length);
652 adv_data_len = length;
654 BT_INFO("Set advertising data");
656 g_variant_unref(ret);
658 return BLUETOOTH_ERROR_NONE;
661 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
663 BT_CHECK_PARAMETER(response, return);
664 BT_CHECK_PARAMETER(length, return);
666 memcpy(response, &resp_data, sizeof(resp_data));
667 *length = resp_data_len;
669 return BLUETOOTH_ERROR_NONE;
672 int _bt_set_scan_response_data(const char *sender, int adv_handle,
673 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
676 GError *error = NULL;
677 GVariant *ret, *scan_data, *param = NULL;
678 GVariant *temp = NULL;
679 GVariantBuilder *builder;
681 char *old_mdata = NULL;
682 char *new_mdata = NULL;
687 if (__bt_is_factory_test_mode()) {
688 BT_ERR("Unable to set scan response list in factory binary !!");
689 return BLUETOOTH_ERROR_NOT_SUPPORT;
692 BT_CHECK_PARAMETER(response, return);
694 if (_bt_adapter_get_status() != BT_ACTIVATED &&
695 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
696 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
699 proxy = _bt_get_adapter_proxy();
700 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
702 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
704 BT_ERR("There is NO available slot!!");
705 return BLUETOOTH_ERROR_NO_RESOURCES;
707 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
708 for (i = 0; i < length; i++)
709 g_variant_builder_add(builder, "y", response->data[i]);
711 temp = g_variant_new("ay", builder);
712 g_variant_builder_unref(builder);
713 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
714 g_variant_new("(@ayi)", temp, slot_id),
715 G_DBUS_CALL_FLAGS_NONE,
719 BT_ERR("SetScanRespData Fail: %s", error->message);
720 g_clear_error(&error);
721 return BLUETOOTH_ERROR_INTERNAL;
724 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
726 /* Compare with previous scan resp data */
727 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
728 &old_mdata, &old_len);
729 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
730 &new_mdata, &new_len);
731 if (old_len != new_len ||
732 (old_mdata && new_mdata &&
733 memcmp(old_mdata, new_mdata, new_len))) {
734 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
735 new_mdata, new_len, TRUE, NULL, NULL);
736 param = g_variant_new("(@ay)", scan_data);
737 _bt_send_event(BT_ADAPTER_EVENT,
738 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
744 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
745 memcpy(&resp_data, response, length);
746 resp_data_len = length;
749 g_variant_unref(ret);
750 BT_INFO("Set scan response data");
751 return BLUETOOTH_ERROR_NONE;
754 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
757 GError *error = NULL;
762 BT_CHECK_PARAMETER(params, return);
764 if (_bt_adapter_get_status() != BT_ACTIVATED &&
765 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
766 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
769 proxy = _bt_get_adapter_proxy();
770 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
772 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
773 return BLUETOOTH_ERROR_INVALID_PARAM;
775 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
776 return BLUETOOTH_ERROR_INVALID_PARAM;
778 if (params->window > params->interval)
779 return BLUETOOTH_ERROR_INVALID_PARAM;
781 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
782 win = params->window / BT_ADV_INTERVAL_SPLIT;
784 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
785 g_variant_new("(uuu)", params->type, itv, win),
786 G_DBUS_CALL_FLAGS_NONE, -1,
790 BT_ERR("SetScanParameters Fail: %s", error->message);
791 g_clear_error(&error);
792 return BLUETOOTH_ERROR_INTERNAL;
795 _bt_set_le_scan_type(params->type);
797 is_le_set_scan_parameter = TRUE;
800 g_variant_unref(ret);
801 BT_INFO("Set scan parameters");
802 return BLUETOOTH_ERROR_NONE;
805 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
808 bt_adapter_le_scanner_t *scanner;
810 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
812 if (g_strcmp0(scanner->sender, sender) == 0)
819 int __bt_get_available_scan_filter_slot_id(void)
822 bt_adapter_le_scanner_t *scanner;
824 bluetooth_le_scan_filter_t *filter_data;
825 gboolean *slot_check_list = NULL;
828 if (le_feature_info.max_filter == 0) {
829 BT_ERR("Scan filter is NOT Supported");
832 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
834 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
836 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
837 filter_data = fl->data;
838 if (filter_data->slot_id < le_feature_info.max_filter)
839 slot_check_list[filter_data->slot_id] = TRUE;
843 for (i = 0; i < le_feature_info.max_filter; i++) {
844 if (slot_check_list[i] == FALSE) {
845 g_free(slot_check_list);
850 BT_ERR("There is NO available slot for scan filter.");
851 g_free(slot_check_list);
855 gboolean _bt_is_scan_filter_supported(void)
857 if (le_feature_info.max_filter > 0)
863 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
866 GError *error = NULL;
867 GVariant *ret, *param;
868 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
869 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
870 GArray *arr_uuid = NULL;
871 GArray *arr_uuid_mask = NULL;
872 GArray *arr_data = NULL;
873 GArray *arr_data_mask = NULL;
874 bt_adapter_le_scanner_t *scanner = NULL;
875 bluetooth_le_scan_filter_t *filter_data = NULL;
876 int feature_selection = 0;
878 *slot_id = __bt_get_available_scan_filter_slot_id();
880 return BLUETOOTH_ERROR_NO_RESOURCES;
882 proxy = _bt_get_adapter_proxy();
883 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
885 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
886 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
887 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
889 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
891 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
892 NULL, 0, TRUE, NULL, NULL);
893 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
894 NULL, 0, TRUE, NULL, NULL);
895 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
896 NULL, 0, TRUE, NULL, NULL);
897 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
898 NULL, 0, TRUE, NULL, NULL);
900 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
902 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
903 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
904 *slot_id, // filter_index
906 0, // company_id_mask
907 arr_uuid_param, // p_uuid
908 arr_uuid_mask_param, // p_uuid_mask
911 arr_data_param, // p_data
912 arr_data_mask_param); // p_mask
914 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
915 param, G_DBUS_CALL_FLAGS_NONE,
919 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
920 g_clear_error(&error);
923 g_variant_unref(ret);
926 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
927 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
929 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
930 NULL, 0, TRUE, NULL, NULL);
931 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
932 NULL, 0, TRUE, NULL, NULL);
933 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
934 NULL, 0, TRUE, NULL, NULL);
935 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
936 NULL, 0, TRUE, NULL, NULL);
938 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
940 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
941 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
942 *slot_id, // filter_index
944 0, // company_id_mask
945 arr_uuid_param, // p_uuid
946 arr_uuid_mask_param, // p_uuid_mask
947 filter->device_name, // string
949 arr_data_param, // p_data
950 arr_data_mask_param);
952 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
953 param, G_DBUS_CALL_FLAGS_NONE,
957 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
958 g_clear_error(&error);
961 g_variant_unref(ret);
964 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
965 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
967 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
968 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
970 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
971 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
973 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
974 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
975 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
976 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
977 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
978 NULL, 0, TRUE, NULL, NULL);
979 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
980 NULL, 0, TRUE, NULL, NULL);
982 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
984 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
985 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
986 *slot_id, // filter_index
988 0, // company_id_mask
989 arr_uuid_param, // p_uuid
990 arr_uuid_mask_param, // p_uuid_mask
993 arr_data_param, // p_data
994 arr_data_mask_param);
996 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
997 param, G_DBUS_CALL_FLAGS_NONE,
1001 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1002 g_clear_error(&error);
1005 g_variant_unref(ret);
1007 g_array_free(arr_uuid, TRUE);
1008 g_array_free(arr_uuid_mask, TRUE);
1009 g_array_free(arr_data, TRUE);
1010 g_array_free(arr_data_mask, TRUE);
1013 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1014 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1016 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1017 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1019 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1020 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1022 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1023 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1024 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1025 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1026 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1027 NULL, 0, TRUE, NULL, NULL);
1028 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1029 NULL, 0, TRUE, NULL, NULL);
1031 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1033 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1034 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1035 *slot_id, // filter_index
1037 0, // company_id_mask
1038 arr_uuid_param, // p_uuid
1039 arr_uuid_mask_param, // p_uuid_mask
1042 arr_data_param, // p_data
1043 arr_data_mask_param);
1045 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1046 G_DBUS_CALL_FLAGS_NONE,
1050 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1051 g_clear_error(&error);
1054 g_variant_unref(ret);
1056 g_array_free(arr_uuid, TRUE);
1057 g_array_free(arr_uuid_mask, TRUE);
1060 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1061 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1063 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1064 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1066 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1067 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1069 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1070 NULL, 0, TRUE, NULL, NULL);
1071 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1072 NULL, 0, TRUE, NULL, NULL);
1073 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1074 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1075 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1076 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1078 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1080 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1081 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1082 *slot_id, // filter_index
1084 0, // company_id_mask
1085 arr_uuid_param, // p_uuid
1086 arr_uuid_mask_param, // p_uuid_mask
1089 arr_data_param, // p_data
1090 arr_data_mask_param);
1092 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1093 G_DBUS_CALL_FLAGS_NONE,
1097 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1098 g_clear_error(&error);
1101 g_variant_unref(ret);
1103 g_array_free(arr_data, TRUE);
1104 g_array_free(arr_data_mask, TRUE);
1107 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1108 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1110 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1111 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1113 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1114 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1116 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1117 NULL, 0, TRUE, NULL, NULL);
1118 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1119 NULL, 0, TRUE, NULL, NULL);
1120 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1121 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1122 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1123 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1125 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1127 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1128 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1129 *slot_id, // filter_index
1130 filter->manufacturer_id, // company_id
1131 0xFFFF, // company_id_mask
1132 arr_uuid_param, // p_uuid
1133 arr_uuid_mask_param, // p_uuid_mask
1136 arr_data_param, // p_data
1137 arr_data_mask_param);
1139 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1140 G_DBUS_CALL_FLAGS_NONE,
1144 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1145 g_clear_error(&error);
1148 g_variant_unref(ret);
1150 g_array_free(arr_data, TRUE);
1151 g_array_free(arr_data_mask, TRUE);
1154 BT_DBG("Filter selection %.2x", feature_selection);
1156 param = g_variant_new("(iiiiiiiiiiii)",
1158 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1159 *slot_id, // filter_index
1160 feature_selection, // feat_seln
1161 0, // list_logic_type (OR - 0x00, AND - 0x01)
1162 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1163 -127, // rssi_high_thres
1164 -127, // rssi_low_thres
1165 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1168 0); // found_timeout_cnt
1169 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1170 param, G_DBUS_CALL_FLAGS_NONE,
1174 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1175 g_clear_error(&error);
1178 scanner = __bt_find_scanner_from_list(sender);
1179 if (scanner == NULL) {
1180 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1181 scanner->sender = strdup(sender);
1182 scanner_list = g_slist_append(scanner_list, scanner);
1185 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1186 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1187 filter_data->slot_id = *slot_id;
1190 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1193 g_variant_unref(ret);
1194 return BLUETOOTH_ERROR_NONE;
1197 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1200 GError *error = NULL;
1202 bt_adapter_le_scanner_t *scanner = NULL;
1203 bluetooth_le_scan_filter_t *filter_data = NULL;
1205 gboolean is_slot_id_found = FALSE;
1207 scanner = __bt_find_scanner_from_list(sender);
1208 if (scanner == NULL) {
1209 BT_ERR("There is NO available scanner.");
1210 return BLUETOOTH_ERROR_NOT_FOUND;
1213 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1214 filter_data = l->data;
1215 if (filter_data->slot_id == slot_id) {
1216 is_slot_id_found = TRUE;
1220 if (is_slot_id_found == FALSE) {
1221 BT_ERR("There is NO registered slot.");
1222 return BLUETOOTH_ERROR_NOT_FOUND;
1225 proxy = _bt_get_adapter_proxy();
1226 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1228 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1229 g_variant_new("(ii)", 0, slot_id),
1230 G_DBUS_CALL_FLAGS_NONE,
1234 BT_ERR("scan_filter_clear Fail: %s", error->message);
1235 g_clear_error(&error);
1238 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1239 g_free(filter_data);
1242 g_variant_unref(ret);
1243 return BLUETOOTH_ERROR_NONE;
1246 int _bt_unregister_all_scan_filters(const char *sender)
1249 GError *error = NULL;
1251 bt_adapter_le_scanner_t *scanner = NULL;
1252 bluetooth_le_scan_filter_t *filter_data = NULL;
1255 scanner = __bt_find_scanner_from_list(sender);
1256 if (scanner == NULL) {
1257 BT_ERR("There is NO available scanner.");
1258 return BLUETOOTH_ERROR_NOT_FOUND;
1261 proxy = _bt_get_adapter_proxy();
1262 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1264 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1265 filter_data = l->data;
1267 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1268 g_variant_new("(ii)", 0, filter_data->slot_id),
1269 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1272 BT_ERR("scan_filter_clear Fail: %s", error->message);
1273 g_clear_error(&error);
1276 g_variant_unref(ret);
1279 g_slist_free_full(scanner->filter_list, g_free);
1280 scanner->filter_list = NULL;
1282 return BLUETOOTH_ERROR_NONE;
1285 int _bt_start_le_scan(const char *sender)
1288 GError *error = NULL;
1290 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1292 if (scanner == NULL) {
1293 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1294 scanner->sender = strdup(sender);
1295 scanner_list = g_slist_append(scanner_list, scanner);
1298 if (scanner->is_scanning == TRUE) {
1299 BT_ERR("BT is already in LE scanning");
1300 return BLUETOOTH_ERROR_IN_PROGRESS;
1302 scanner->is_scanning = TRUE;
1304 proxy = _bt_get_adapter_proxy();
1305 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1307 if (_bt_is_le_scanning()) {
1308 if (scan_filter_enabled == TRUE) {
1309 if (scanner->filter_list == NULL) {
1310 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1311 g_variant_new("(ib)", 0, FALSE),
1312 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1315 BT_ERR("scan_filter_clear Fail: %s", error->message);
1316 g_clear_error(&error);
1320 g_variant_unref(ret);
1321 BT_INFO("Disable LE Scan Filter");
1322 scan_filter_enabled = FALSE;
1324 BT_INFO("LE Filter Scan is continue");
1327 BT_INFO("LE Full Scan is already on progress");
1329 return BLUETOOTH_ERROR_NONE;
1331 if (is_le_set_scan_parameter == FALSE) {
1332 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1333 bluetooth_le_scan_params_t scan_params;
1334 scan_params.type = BT_LE_ACTIVE_SCAN;
1335 scan_params.interval = 5000;
1336 scan_params.window = 500;
1337 _bt_set_scan_parameters(&scan_params);
1340 if (scanner->filter_list == NULL) {
1341 BT_INFO("Start LE Full Scan");
1342 scan_filter_enabled = FALSE;
1344 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1345 g_variant_new("(ib)", 0, TRUE),
1346 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1349 BT_ERR("scan_filter_clear Fail: %s", error->message);
1350 g_clear_error(&error);
1354 g_variant_unref(ret);
1355 BT_INFO("Enable LE Scan Filter");
1356 scan_filter_enabled = TRUE;
1360 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1361 NULL, G_DBUS_CALL_FLAGS_NONE,
1365 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1366 g_clear_error(&error);
1367 return BLUETOOTH_ERROR_INTERNAL;
1371 g_variant_unref(ret);
1372 return BLUETOOTH_ERROR_NONE;
1375 int _bt_stop_le_scan(const char *sender)
1378 GError *error = NULL;
1380 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1382 gboolean next_scanning = FALSE;
1383 gboolean need_scan_filter = TRUE;
1385 if (scanner == NULL || scanner->is_scanning == FALSE)
1386 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1388 scanner->is_scanning = FALSE;
1390 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1392 if (scanner->is_scanning == TRUE) {
1393 next_scanning = TRUE;
1394 if (scanner->filter_list == NULL)
1395 need_scan_filter = FALSE;
1399 proxy = _bt_get_adapter_proxy();
1400 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1402 if (next_scanning == TRUE) {
1403 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1404 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1405 g_variant_new("(ib)", 0, TRUE),
1406 G_DBUS_CALL_FLAGS_NONE,
1410 BT_ERR("scan_filter_clear Fail: %s", error->message);
1411 g_clear_error(&error);
1415 g_variant_unref(ret);
1416 BT_INFO("Enable LE Scan Filter");
1417 scan_filter_enabled = TRUE;
1419 return BLUETOOTH_ERROR_NONE;
1421 if (scan_filter_enabled == TRUE) {
1422 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1423 g_variant_new("(ib)", 0, FALSE),
1424 G_DBUS_CALL_FLAGS_NONE,
1428 BT_ERR("scan_filter_clear Fail: %s", error->message);
1429 g_clear_error(&error);
1433 g_variant_unref(ret);
1434 BT_INFO("Disable LE Scan Filter");
1436 BT_INFO("Just stop LE scan");
1440 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1441 NULL, G_DBUS_CALL_FLAGS_NONE,
1444 BT_ERR("LE Scan stop failed");
1445 return BLUETOOTH_ERROR_INTERNAL;
1448 scan_filter_enabled = FALSE;
1449 is_le_set_scan_parameter = FALSE;
1451 g_variant_unref(ret);
1452 return BLUETOOTH_ERROR_NONE;
1455 void _bt_disable_all_scanner_status(void)
1458 bt_adapter_le_scanner_t *scanner;
1460 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1462 scanner->is_scanning = FALSE;
1466 void _bt_set_le_scan_status(gboolean mode)
1468 is_le_scanning = mode;
1471 gboolean _bt_is_le_scanning(void)
1473 return is_le_scanning;
1476 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1478 le_scan_type = type;
1481 bt_le_scan_type_t _bt_get_le_scan_type(void)
1483 return le_scan_type;
1486 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1487 int adv_data_len, const char *svc_uuid, int uuid_len,
1488 const char *uuid_mask, char ad_type)
1494 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1495 ad_type, &data, &data_len);
1497 for (i = 0; i < data_len; i += uuid_len) {
1498 if (uuid_len > (data_len - i))
1501 if (_bt_byte_arr_cmp_with_mask(data + i,
1502 svc_uuid, uuid_mask, uuid_len) == 0) {
1513 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1514 const char *adv_data, int adv_data_len,
1515 const char *scan_data, int scan_data_len,
1516 const bt_adapter_le_scanner_t *scanner)
1519 bluetooth_le_scan_filter_t *filter_data = NULL;
1522 gboolean is_matched = FALSE;
1524 if (scanner->filter_list == NULL) {
1525 BT_INFO("This scanner is on Full Scan.");
1529 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1530 filter_data = l->data;
1532 if (filter_data->added_features &
1533 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1534 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1536 _bt_convert_addr_type_to_string(address,
1537 filter_data->device_address.addr);
1538 if (strncmp(address, device_address,
1539 BT_ADDRESS_STRING_SIZE) != 0)
1543 if (filter_data->added_features &
1544 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1547 if (__bt_check_scan_result_uuid(adv_data,
1549 (char*)filter_data->service_uuid.data.data,
1550 filter_data->service_uuid.data_len,
1551 (char*)filter_data->service_uuid_mask.data.data,
1552 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1555 if (__bt_check_scan_result_uuid(adv_data,
1557 (char*)filter_data->service_uuid.data.data,
1558 filter_data->service_uuid.data_len,
1559 (char*)filter_data->service_uuid_mask.data.data,
1560 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1563 if (__bt_check_scan_result_uuid(adv_data,
1565 (char*)filter_data->service_uuid.data.data,
1566 filter_data->service_uuid.data_len,
1567 (char*)filter_data->service_uuid_mask.data.data,
1568 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1571 if (__bt_check_scan_result_uuid(adv_data,
1573 (char*)filter_data->service_uuid.data.data,
1574 filter_data->service_uuid.data_len,
1575 (char*)filter_data->service_uuid_mask.data.data,
1576 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1579 if (__bt_check_scan_result_uuid(scan_data,
1581 (char*)filter_data->service_uuid.data.data,
1582 filter_data->service_uuid.data_len,
1583 (char*)filter_data->service_uuid_mask.data.data,
1584 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1587 if (__bt_check_scan_result_uuid(scan_data,
1589 (char*)filter_data->service_uuid.data.data,
1590 filter_data->service_uuid.data_len,
1591 (char*)filter_data->service_uuid_mask.data.data,
1592 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1595 if (__bt_check_scan_result_uuid(scan_data,
1597 (char*)filter_data->service_uuid.data.data,
1598 filter_data->service_uuid.data_len,
1599 (char*)filter_data->service_uuid_mask.data.data,
1600 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1603 if (__bt_check_scan_result_uuid(scan_data,
1605 (char*)filter_data->service_uuid.data.data,
1606 filter_data->service_uuid.data_len,
1607 (char*)filter_data->service_uuid_mask.data.data,
1608 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1612 if (is_matched == FALSE)
1615 if (filter_data->added_features &
1616 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1619 if (__bt_check_scan_result_uuid(adv_data,
1621 (char*)filter_data->service_solicitation_uuid.data.data,
1622 filter_data->service_solicitation_uuid.data_len,
1623 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1624 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1627 if (__bt_check_scan_result_uuid(adv_data,
1629 (char*)filter_data->service_solicitation_uuid.data.data,
1630 filter_data->service_solicitation_uuid.data_len,
1631 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1632 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1635 if (__bt_check_scan_result_uuid(scan_data,
1637 (char*)filter_data->service_solicitation_uuid.data.data,
1638 filter_data->service_solicitation_uuid.data_len,
1639 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1640 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1643 if (__bt_check_scan_result_uuid(scan_data,
1645 (char*)filter_data->service_solicitation_uuid.data.data,
1646 filter_data->service_solicitation_uuid.data_len,
1647 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1648 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1652 if (is_matched == FALSE)
1655 if (filter_data->added_features &
1656 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1657 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1662 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1663 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1666 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1667 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1668 memcpy(name, data, data_len);
1669 name[data_len] = '\0';
1672 if (strncmp(filter_data->device_name,
1673 name, data_len) == 0)
1676 __bt_get_ad_data_by_type((char*)scan_data,
1678 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1681 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1682 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1683 memcpy(name, data, data_len);
1684 name[data_len] = '\0';
1687 if (strncmp(filter_data->device_name,
1688 name, data_len) == 0)
1692 if (is_matched == FALSE)
1695 if (filter_data->added_features &
1696 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1701 __bt_get_ad_data_by_type((char*)adv_data,
1703 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1707 int manufacturer_id;
1708 manufacturer_id = (data[1] << 8) + data[0];
1710 if (filter_data->manufacturer_id == manufacturer_id) {
1711 if (filter_data->manufacturer_data.data_len == 0) {
1714 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1715 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1716 if (_bt_byte_arr_cmp_with_mask(data + 2,
1717 (char*)filter_data->manufacturer_data.data.data,
1718 (char*)filter_data->manufacturer_data_mask.data.data,
1719 data_len - 2) == 0) {
1727 __bt_get_ad_data_by_type((char*)scan_data,
1729 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1733 int manufacturer_id;
1734 manufacturer_id = (data[1] << 8) + data[0];
1736 if (filter_data->manufacturer_id == manufacturer_id) {
1737 if (filter_data->manufacturer_data.data_len == 0) {
1740 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1741 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1742 if (_bt_byte_arr_cmp_with_mask(data + 2,
1743 (char*)filter_data->manufacturer_data.data.data,
1744 (char*)filter_data->manufacturer_data_mask.data.data,
1745 data_len - 2) == 0) {
1754 if (is_matched == FALSE)
1757 if (filter_data->added_features &
1758 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1763 __bt_get_ad_data_by_type((char*)adv_data,
1765 BT_LE_AD_TYPE_SERVICE_DATA,
1768 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1769 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1770 if (_bt_byte_arr_cmp_with_mask(data,
1771 (char*)filter_data->service_data.data.data,
1772 (char*)filter_data->service_data_mask.data.data,
1779 __bt_get_ad_data_by_type((char*)scan_data,
1781 BT_LE_AD_TYPE_SERVICE_DATA,
1784 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1785 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1786 if (_bt_byte_arr_cmp_with_mask(data,
1787 (char*)filter_data->service_data.data.data,
1788 (char*)filter_data->service_data_mask.data.data,
1796 if (is_matched == FALSE)
1800 BT_INFO("The scan result is conformable.");
1804 BT_INFO("The scan result is NOT conformable.");
1808 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1809 const bt_le_adv_info_t *adv_info)
1811 int result = BLUETOOTH_ERROR_NONE;
1813 GVariant *scan_data_param, *adv_data_param;
1815 bt_adapter_le_scanner_t *scanner = NULL;
1816 const char *adv_data = NULL;
1817 int adv_data_len = 0;
1818 const char *scan_data = NULL;
1819 int scan_data_len = 0;
1821 ret_if(le_dev_info == NULL);
1822 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1823 ret_if(adv_info == NULL);
1825 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1826 adv_data = le_dev_info->adv_data;
1827 adv_data_len = le_dev_info->adv_data_len;
1828 scan_data = le_dev_info->adv_data;
1831 adv_data = adv_info->data;
1832 adv_data_len = adv_info->data_len;
1833 scan_data = le_dev_info->adv_data;
1834 scan_data_len = le_dev_info->adv_data_len;
1837 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1839 if (scanner->is_scanning == FALSE)
1842 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1843 adv_data, adv_data_len, scan_data, scan_data_len,
1847 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1848 adv_data, adv_data_len, TRUE, NULL, NULL);
1849 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1850 scan_data, scan_data_len, TRUE, NULL, NULL);
1852 param = g_variant_new("(isnnn@ayn@ay)",
1854 le_dev_info->address,
1855 le_dev_info->addr_type,
1862 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1863 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1867 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1870 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1871 GError *error = NULL;
1874 if (__bt_is_factory_test_mode()) {
1875 BT_ERR("Unable to add white list in factory binary !!");
1876 return BLUETOOTH_ERROR_NOT_SUPPORT;
1879 BT_CHECK_PARAMETER(device_address, return);
1881 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1882 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1883 return BLUETOOTH_ERROR_INVALID_PARAM;
1885 _bt_convert_addr_type_to_string(address, device_address->addr);
1887 proxy = _bt_get_adapter_proxy();
1888 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1890 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1891 g_variant_new("(su)", address, address_type),
1892 G_DBUS_CALL_FLAGS_NONE, -1,
1896 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
1897 g_clear_error(&error);
1898 return BLUETOOTH_ERROR_INTERNAL;
1902 g_variant_unref(ret);
1903 BT_INFO("Add white list");
1905 return BLUETOOTH_ERROR_NONE;
1908 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1911 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1912 GError *error = NULL;
1915 if (__bt_is_factory_test_mode()) {
1916 BT_ERR("Unable to remove white list in factory binary !!");
1917 return BLUETOOTH_ERROR_NOT_SUPPORT;
1920 BT_CHECK_PARAMETER(device_address, return);
1922 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1923 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1924 return BLUETOOTH_ERROR_INVALID_PARAM;
1926 _bt_convert_addr_type_to_string(address, device_address->addr);
1928 proxy = _bt_get_adapter_proxy();
1929 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1931 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1932 g_variant_new("(su)", address, address_type),
1933 G_DBUS_CALL_FLAGS_NONE, -1,
1937 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
1938 g_clear_error(&error);
1939 return BLUETOOTH_ERROR_INTERNAL;
1943 g_variant_unref(ret);
1944 BT_INFO("Remove white list");
1946 return BLUETOOTH_ERROR_NONE;
1949 int _bt_clear_white_list(void)
1952 GError *error = NULL;
1955 if (__bt_is_factory_test_mode()) {
1956 BT_ERR("Unable to clear white list in factory binary !!");
1957 return BLUETOOTH_ERROR_NOT_SUPPORT;
1960 proxy = _bt_get_adapter_proxy();
1961 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1963 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
1964 NULL, G_DBUS_CALL_FLAGS_NONE,
1968 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
1969 g_clear_error(&error);
1970 return BLUETOOTH_ERROR_INTERNAL;
1973 g_variant_unref(ret);
1975 BT_INFO("Clear white list");
1977 return BLUETOOTH_ERROR_NONE;
1980 int _bt_initialize_ipsp(void)
1984 GError *error = NULL;
1987 if (_bt_adapter_get_status() != BT_ACTIVATED &&
1988 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
1989 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1992 proxy = _bt_get_adapter_proxy();
1993 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1995 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
1996 NULL, G_DBUS_CALL_FLAGS_NONE,
1999 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2000 g_clear_error(&error);
2001 return BLUETOOTH_ERROR_INTERNAL;
2004 g_variant_unref(ret);
2006 BT_INFO("IPSP initialization called successfully");
2008 return BLUETOOTH_ERROR_NONE;
2011 int _bt_deinitialize_ipsp(void)
2015 GError *error = NULL;
2018 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2019 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2020 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2023 proxy = _bt_get_adapter_proxy();
2024 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2026 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2027 NULL, G_DBUS_CALL_FLAGS_NONE,
2030 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2031 g_clear_error(&error);
2032 return BLUETOOTH_ERROR_INTERNAL;
2035 g_variant_unref(ret);
2037 BT_INFO("IPSP De-initialization called successfully");
2039 return BLUETOOTH_ERROR_NONE;
2042 int _bt_le_read_maximum_data_length(
2043 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2045 GError *error = NULL;
2047 GVariant *reply = NULL;
2048 guint16 max_tx_octets, max_tx_time;
2049 guint16 max_rx_octets, max_rx_time;
2051 proxy = _bt_get_adapter_proxy();
2052 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2054 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2055 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2057 g_object_unref(proxy);
2059 if (reply == NULL) {
2060 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2061 if (error != NULL) {
2062 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2063 error->code, error->message);
2064 g_clear_error(&error);
2066 return BLUETOOTH_ERROR_INTERNAL;
2069 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2070 &max_rx_octets, &max_rx_time);
2072 max_le_datalength->max_tx_octets = max_tx_octets;
2073 max_le_datalength->max_tx_time = max_tx_time;
2074 max_le_datalength->max_rx_octets = max_rx_octets;
2075 max_le_datalength->max_rx_time = max_rx_time;
2077 g_variant_unref(reply);
2079 return BLUETOOTH_ERROR_NONE;
2081 int _bt_le_write_host_suggested_default_data_length(
2082 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2084 GError *error = NULL;
2086 GVariant *reply = NULL;
2088 proxy = _bt_get_adapter_proxy();
2089 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2091 reply = g_dbus_proxy_call_sync(proxy,
2092 "LEWriteHostSuggestedDataLength",
2093 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2094 G_DBUS_CALL_FLAGS_NONE,
2099 g_object_unref(proxy);
2101 if (reply == NULL) {
2102 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2103 if (error != NULL) {
2104 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2105 error->code, error->message);
2106 g_clear_error(&error);
2108 return BLUETOOTH_ERROR_INTERNAL;
2111 g_variant_unref(reply);
2113 return BLUETOOTH_ERROR_NONE;
2116 int _bt_le_read_host_suggested_default_data_length(
2117 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2119 GError *error = NULL;
2121 GVariant *reply = NULL;
2122 guint16 def_tx_octets, def_tx_time;
2124 proxy = _bt_get_adapter_proxy();
2125 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2127 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2128 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2130 if (reply == NULL) {
2131 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2132 if (error != NULL) {
2133 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2134 error->code, error->message);
2135 g_clear_error(&error);
2137 return BLUETOOTH_ERROR_INTERNAL;
2140 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2142 def_data_length->def_tx_octets = def_tx_octets;
2143 def_data_length->def_tx_time = def_tx_time;
2145 g_variant_unref(reply);
2147 return BLUETOOTH_ERROR_NONE;
2150 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2151 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2153 GError *error = NULL;
2154 guint16 txOctets = max_tx_Octets;
2155 guint16 txTime = max_tx_Time;
2156 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2157 gchar *device_path = NULL;
2158 GDBusConnection *conn;
2159 GDBusProxy *device_proxy;
2161 _bt_convert_addr_type_to_string(address, device_address->addr);
2163 device_path = _bt_get_device_object_path(address);
2165 if (device_path == NULL) {
2166 BT_DBG("Device path is null");
2167 return BLUETOOTH_ERROR_INTERNAL;
2170 conn = _bt_gdbus_get_system_gconn();
2172 BT_ERR("conn == NULL");
2173 g_free(device_path);
2174 return BLUETOOTH_ERROR_INTERNAL;
2177 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2178 NULL, BT_BLUEZ_NAME,
2179 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2181 g_free(device_path);
2182 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2184 g_dbus_proxy_call_sync(device_proxy,
2186 g_variant_new("(qq)", txOctets, txTime),
2187 G_DBUS_CALL_FLAGS_NONE,
2192 g_object_unref(device_proxy);
2195 BT_ERR("LESetDataLength error: [%s]", error->message);
2196 g_error_free(error);
2197 return BLUETOOTH_ERROR_INTERNAL;
2200 return BLUETOOTH_ERROR_NONE;