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 GSList *gatt_client_senders = NULL;
86 gboolean _bt_is_set_scan_parameter(void)
88 return is_le_set_scan_parameter;
91 void _bt_init_gatt_client_senders(void)
93 _bt_clear_request_list();
96 int _bt_insert_gatt_client_sender(char *sender)
100 retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
102 info = g_strdup(sender);
103 retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
105 gatt_client_senders = g_slist_append(gatt_client_senders, info);
107 BT_DBG("insert sender: %s", sender);
109 return BLUETOOTH_ERROR_NONE;
112 int _bt_delete_gatt_client_sender(char *sender)
117 BT_DBG("remove sender: %s", sender);
119 for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) {
124 if (g_strcmp0(info, sender) == 0) {
125 BT_DBG("remove info");
126 gatt_client_senders = g_slist_remove(gatt_client_senders, info);
128 return BLUETOOTH_ERROR_NONE;
132 return BLUETOOTH_ERROR_NOT_FOUND;
135 void _bt_clear_gatt_client_senders(void)
137 if (gatt_client_senders) {
138 g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL);
139 g_slist_free(gatt_client_senders);
140 gatt_client_senders = NULL;
144 static void __bt_send_foreach_event(gpointer data, gpointer user_data)
147 GVariant *param = user_data;
149 _bt_send_event_to_dest(sender, BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
153 void _bt_send_char_value_changed_event(void *param)
156 g_slist_foreach(gatt_client_senders, __bt_send_foreach_event,
159 _bt_send_event(BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED, param);
163 void __bt_free_le_adv_slot(void)
167 if (le_adv_slot == NULL)
170 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
171 if (le_adv_slot[i].sender)
172 g_free(le_adv_slot[i].sender);
178 int _bt_service_adapter_le_init(void)
180 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
182 return BLUETOOTH_ERROR_NONE;
185 void _bt_service_adapter_le_deinit(void)
187 __bt_free_le_adv_slot();
190 gboolean _bt_update_le_feature_support(const char *item, const char *value)
192 if (item == NULL || value == NULL)
195 if (g_strcmp0(item, "adv_inst_max") == 0) {
198 slot_num = atoi(value);
199 retv_if(slot_num < 0, FALSE);
200 retv_if(slot_num > BT_ADV_MULTI_MAX, FALSE);
202 if (slot_num != le_feature_info.adv_inst_max) {
203 __bt_free_le_adv_slot();
204 le_feature_info.adv_inst_max = slot_num;
205 BT_INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
206 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
208 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
209 le_feature_info.rpa_offloading = atoi(value);
210 BT_INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
211 } else if (g_strcmp0(item, "max_filter") == 0) {
212 le_feature_info.max_filter = atoi(value);
213 BT_INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
215 BT_DBG("No registered item");
222 static gboolean __bt_is_factory_test_mode(void)
226 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
227 BT_ERR("Get the DUT Mode fail");
232 BT_INFO("DUT Test Mode !!");
239 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
243 if (le_adv_slot == NULL) {
244 BT_ERR("le_adv_slot is NULL");
248 BT_DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
250 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
251 if (le_adv_slot[i].sender == NULL)
253 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
257 if (le_feature_info.adv_inst_max <= 2)
259 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
264 for (; i < le_feature_info.adv_inst_max; i++) {
265 if (le_adv_slot[i].sender == NULL)
272 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
274 if (le_adv_slot[slot_id].sender == NULL) {
275 le_adv_slot[slot_id].sender = strdup(sender);
276 le_adv_slot[slot_id].adv_handle = adv_handle;
280 void _bt_unregister_adv_slot_owner(int slot_id)
282 g_free(le_adv_slot[slot_id].sender);
283 le_adv_slot[slot_id].sender = NULL;
284 le_adv_slot[slot_id].adv_handle = 0;
287 const char* _bt_get_adv_slot_owner(int slot_id)
289 if (le_adv_slot == NULL)
292 return le_adv_slot[slot_id].sender;
295 int _bt_get_adv_slot_adv_handle(int slot_id)
297 if (le_adv_slot == NULL)
300 return le_adv_slot[slot_id].adv_handle;
303 void _bt_set_advertising_status(int slot_id, gboolean mode)
305 le_adv_slot[slot_id].is_advertising = mode;
308 gboolean _bt_is_advertising(void)
310 gboolean status = FALSE;
313 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
314 if (le_adv_slot[i].is_advertising == TRUE)
321 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
325 if (le_adv_slot == NULL)
328 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
329 if (le_adv_slot[i].sender != NULL) {
330 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
331 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
332 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
338 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
343 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
348 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
351 GError *error = NULL;
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 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
386 g_variant_new("(bi)", enable, slot_id),
387 G_DBUS_CALL_FLAGS_NONE,
393 BT_ERR("SetAdvertising Fail: %s", error->message);
394 g_clear_error(&error);
395 return BLUETOOTH_ERROR_INTERNAL;
399 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
401 le_adv_slot[slot_id].is_advertising = enable;
402 BT_INFO_C("### Set advertising [%d]", enable);
405 g_variant_unref(ret);
407 return BLUETOOTH_ERROR_NONE;
410 int _bt_set_custom_advertising(const char *sender, int adv_handle,
411 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
415 GError *error = NULL;
420 BT_CHECK_PARAMETER(params, return);
422 if (__bt_is_factory_test_mode()) {
423 BT_ERR("Unable to start advertising in factory binary !!");
424 return BLUETOOTH_ERROR_NOT_SUPPORT;
427 if (_bt_adapter_get_status() != BT_ACTIVATED &&
428 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
429 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
432 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
434 BT_ERR("There is NO available slot!!");
435 return BLUETOOTH_ERROR_NO_RESOURCES;
438 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
439 return BLUETOOTH_ERROR_IN_PROGRESS;
441 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
442 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
444 if (le_adv_slot[slot_id].hold_timer_id > 0) {
445 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
446 le_adv_slot[slot_id].hold_timer_id = 0;
449 proxy = _bt_get_adapter_proxy();
450 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
452 if (params->interval_min > params->interval_max ||
453 params->interval_min < BT_ADV_INTERVAL_MIN ||
454 params->interval_max > BT_ADV_INTERVAL_MAX)
455 return BLUETOOTH_ERROR_INVALID_PARAM;
457 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
458 return BLUETOOTH_ERROR_INVALID_PARAM;
460 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
461 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
462 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
463 return BLUETOOTH_ERROR_NOT_SUPPORT;
465 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
466 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
468 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
469 g_variant_new("(uuuui)", min, max,
470 params->filter_policy, params->type,
471 slot_id), G_DBUS_CALL_FLAGS_NONE,
475 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
476 g_clear_error(&error);
477 return BLUETOOTH_ERROR_INTERNAL;
480 adv_params.interval_min = params->interval_min;
481 adv_params.interval_max = params->interval_max;
482 adv_params.filter_policy = params->filter_policy;
483 adv_params.type = params->type;
486 g_variant_unref(ret);
488 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
489 g_variant_new("(bi)", enable, slot_id),
490 G_DBUS_CALL_FLAGS_NONE,
496 BT_ERR("SetAdvertising Fail: %s", error->message);
497 g_clear_error(&error);
498 return BLUETOOTH_ERROR_INTERNAL;
502 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
504 _bt_unregister_adv_slot_owner(slot_id);
506 le_adv_slot[slot_id].is_advertising = enable;
507 BT_INFO_C("### Set advertising [%d]", enable);
509 g_variant_unref(ret);
511 return BLUETOOTH_ERROR_NONE;
514 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
517 GError *error = NULL;
520 BT_INFO("Restart advertising stopped by bt-service");
522 le_adv_slot[0].hold_timer_id = 0;
524 proxy = _bt_get_adapter_proxy();
525 retv_if(proxy == NULL, FALSE);
527 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
528 g_variant_new("(bi)", TRUE, 0),
529 G_DBUS_CALL_FLAGS_NONE,
535 BT_ERR("SetAdvertising Fail: %s", error->message);
536 g_clear_error(&error);
541 g_variant_unref(ret);
546 int _bt_hold_current_advertising(void)
549 GError *error = NULL;
552 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
553 BT_INFO("Stop current advertising by bt-service");
555 proxy = _bt_get_adapter_proxy();
556 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
558 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
559 g_variant_new("(bi)", FALSE, 0),
560 G_DBUS_CALL_FLAGS_NONE,
566 BT_ERR("SetAdvertising Fail: %s", error->message);
567 g_clear_error(&error);
568 return BLUETOOTH_ERROR_INTERNAL;
572 g_variant_unref(ret);
574 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
575 __bt_hold_current_advertising_timeout_cb, NULL);
577 BT_ERR("It's NOT advertising");
578 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
581 return BLUETOOTH_ERROR_NONE;
584 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
585 char in_type, char **data, int *data_len)
587 if (in_data == NULL || data == NULL || data_len == NULL)
588 return BLUETOOTH_ERROR_INTERNAL;
591 return BLUETOOTH_ERROR_INTERNAL;
597 for (i = 0; i < in_len; i++) {
599 if (len <= 0 || i + 1 >= in_len) {
600 BT_ERR("Invalid advertising data");
601 return BLUETOOTH_ERROR_INTERNAL;
604 type = in_data[i + 1];
605 if (type == in_type) {
615 if (i + len > in_len) {
616 BT_ERR("Invalid advertising data");
617 return BLUETOOTH_ERROR_INTERNAL;
618 } else if (len == 0) {
619 BT_DBG("AD Type 0x%02x data is not set", in_type);
622 return BLUETOOTH_ERROR_NONE;
625 *data = g_memdup(&in_data[i], len);
627 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
630 return BLUETOOTH_ERROR_NONE;
633 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
635 BT_CHECK_PARAMETER(adv, return);
636 BT_CHECK_PARAMETER(length, return);
638 memcpy(adv, &adv_data, sizeof(adv_data));
639 *length = adv_data_len;
641 return BLUETOOTH_ERROR_NONE;
644 int _bt_set_advertising_data(const char *sender, int adv_handle,
645 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
648 GError *error = NULL;
649 GVariant *ret, *ad_data, *param = NULL;
650 GVariant *temp = NULL;
651 GVariantBuilder *builder;
653 char *old_mdata = NULL;
654 char *new_mdata = NULL;
659 if (__bt_is_factory_test_mode()) {
660 BT_ERR("Unable to set advertising data in factory binary !!");
661 return BLUETOOTH_ERROR_NOT_SUPPORT;
664 BT_CHECK_PARAMETER(adv, return);
666 if (_bt_adapter_get_status() != BT_ACTIVATED &&
667 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
668 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
671 proxy = _bt_get_adapter_proxy();
672 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
674 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
676 BT_ERR("There is NO available slot!!");
677 return BLUETOOTH_ERROR_NO_RESOURCES;
680 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
681 for (i = 0; i < length; i++)
682 g_variant_builder_add(builder, "y", adv->data[i]);
684 temp = g_variant_new("ay", builder);
685 g_variant_builder_unref(builder);
686 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
687 g_variant_new("(@ayi)", temp, slot_id),
688 G_DBUS_CALL_FLAGS_NONE,
692 BT_ERR("SetAdvertisingData Fail: %s", error->message);
693 g_clear_error(&error);
694 return BLUETOOTH_ERROR_INTERNAL;
697 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
699 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
700 &old_mdata, &old_len);
701 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
702 &new_mdata, &new_len);
703 if (old_len != new_len ||
704 (old_mdata && new_mdata &&
705 memcmp(old_mdata, new_mdata, new_len))) {
706 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
707 new_mdata, new_len, TRUE, NULL, NULL);
708 param = g_variant_new("(@ay)", ad_data);
709 _bt_send_event(BT_ADAPTER_EVENT,
710 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
716 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
717 memcpy(&adv_data, adv, length);
718 adv_data_len = length;
720 BT_INFO("Set advertising data");
722 g_variant_unref(ret);
724 return BLUETOOTH_ERROR_NONE;
727 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
729 BT_CHECK_PARAMETER(response, return);
730 BT_CHECK_PARAMETER(length, return);
732 memcpy(response, &resp_data, sizeof(resp_data));
733 *length = resp_data_len;
735 return BLUETOOTH_ERROR_NONE;
738 int _bt_set_scan_response_data(const char *sender, int adv_handle,
739 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
742 GError *error = NULL;
743 GVariant *ret, *scan_data, *param = NULL;
744 GVariant *temp = NULL;
745 GVariantBuilder *builder;
747 char *old_mdata = NULL;
748 char *new_mdata = NULL;
753 if (__bt_is_factory_test_mode()) {
754 BT_ERR("Unable to set scan response list in factory binary !!");
755 return BLUETOOTH_ERROR_NOT_SUPPORT;
758 BT_CHECK_PARAMETER(response, return);
760 if (_bt_adapter_get_status() != BT_ACTIVATED &&
761 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
762 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
765 proxy = _bt_get_adapter_proxy();
766 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
768 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
770 BT_ERR("There is NO available slot!!");
771 return BLUETOOTH_ERROR_NO_RESOURCES;
773 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
774 for (i = 0; i < length; i++)
775 g_variant_builder_add(builder, "y", response->data[i]);
777 temp = g_variant_new("ay", builder);
778 g_variant_builder_unref(builder);
779 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
780 g_variant_new("(@ayi)", temp, slot_id),
781 G_DBUS_CALL_FLAGS_NONE,
785 BT_ERR("SetScanRespData Fail: %s", error->message);
786 g_clear_error(&error);
787 return BLUETOOTH_ERROR_INTERNAL;
790 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
792 /* Compare with previous scan resp data */
793 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
794 &old_mdata, &old_len);
795 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
796 &new_mdata, &new_len);
797 if (old_len != new_len ||
798 (old_mdata && new_mdata &&
799 memcmp(old_mdata, new_mdata, new_len))) {
800 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
801 new_mdata, new_len, TRUE, NULL, NULL);
802 param = g_variant_new("(@ay)", scan_data);
803 _bt_send_event(BT_ADAPTER_EVENT,
804 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
810 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
811 memcpy(&resp_data, response, length);
812 resp_data_len = length;
815 g_variant_unref(ret);
816 BT_INFO("Set scan response data");
817 return BLUETOOTH_ERROR_NONE;
820 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
823 GError *error = NULL;
828 BT_CHECK_PARAMETER(params, return);
830 if (_bt_adapter_get_status() != BT_ACTIVATED &&
831 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
832 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
835 proxy = _bt_get_adapter_proxy();
836 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
838 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
839 return BLUETOOTH_ERROR_INVALID_PARAM;
841 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
842 return BLUETOOTH_ERROR_INVALID_PARAM;
844 if (params->window > params->interval)
845 return BLUETOOTH_ERROR_INVALID_PARAM;
847 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
848 win = params->window / BT_ADV_INTERVAL_SPLIT;
850 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
851 g_variant_new("(uuu)", params->type, itv, win),
852 G_DBUS_CALL_FLAGS_NONE, -1,
856 BT_ERR("SetScanParameters Fail: %s", error->message);
857 g_clear_error(&error);
858 return BLUETOOTH_ERROR_INTERNAL;
861 _bt_set_le_scan_type(params->type);
863 is_le_set_scan_parameter = TRUE;
866 g_variant_unref(ret);
867 BT_INFO("Set scan parameters");
868 return BLUETOOTH_ERROR_NONE;
871 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
874 bt_adapter_le_scanner_t *scanner;
876 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
878 if (g_strcmp0(scanner->sender, sender) == 0)
885 int __bt_get_available_scan_filter_slot_id(void)
888 bt_adapter_le_scanner_t *scanner;
890 bluetooth_le_scan_filter_t *filter_data;
891 gboolean *slot_check_list = NULL;
894 if (le_feature_info.max_filter == 0) {
895 BT_ERR("Scan filter is NOT Supported");
898 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
900 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
902 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
903 filter_data = fl->data;
904 if (filter_data->slot_id < le_feature_info.max_filter)
905 slot_check_list[filter_data->slot_id] = TRUE;
909 for (i = 0; i < le_feature_info.max_filter; i++) {
910 if (slot_check_list[i] == FALSE) {
911 g_free(slot_check_list);
916 BT_ERR("There is NO available slot for scan filter.");
917 g_free(slot_check_list);
921 gboolean _bt_is_scan_filter_supported(void)
923 if (le_feature_info.max_filter > 0)
929 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
932 GError *error = NULL;
933 GVariant *ret, *param;
934 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
935 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
936 GArray *arr_uuid = NULL;
937 GArray *arr_uuid_mask = NULL;
938 GArray *arr_data = NULL;
939 GArray *arr_data_mask = NULL;
940 bt_adapter_le_scanner_t *scanner = NULL;
941 bluetooth_le_scan_filter_t *filter_data = NULL;
942 int feature_selection = 0;
944 *slot_id = __bt_get_available_scan_filter_slot_id();
946 return BLUETOOTH_ERROR_NO_RESOURCES;
948 proxy = _bt_get_adapter_proxy();
949 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
951 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
952 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
953 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
955 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
957 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
958 NULL, 0, TRUE, NULL, NULL);
959 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
960 NULL, 0, TRUE, NULL, NULL);
961 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
962 NULL, 0, TRUE, NULL, NULL);
963 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
964 NULL, 0, TRUE, NULL, NULL);
966 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
968 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
969 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
970 *slot_id, // filter_index
972 0, // company_id_mask
973 arr_uuid_param, // p_uuid
974 arr_uuid_mask_param, // p_uuid_mask
977 arr_data_param, // p_data
978 arr_data_mask_param); // p_mask
980 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
981 param, G_DBUS_CALL_FLAGS_NONE,
985 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
986 g_clear_error(&error);
989 g_variant_unref(ret);
992 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
993 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
995 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
996 NULL, 0, TRUE, NULL, NULL);
997 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
998 NULL, 0, TRUE, NULL, NULL);
999 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1000 NULL, 0, TRUE, NULL, NULL);
1001 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1002 NULL, 0, TRUE, NULL, NULL);
1004 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1006 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1007 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1008 *slot_id, // filter_index
1010 0, // company_id_mask
1011 arr_uuid_param, // p_uuid
1012 arr_uuid_mask_param, // p_uuid_mask
1013 filter->device_name, // string
1015 arr_data_param, // p_data
1016 arr_data_mask_param);
1018 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1019 param, G_DBUS_CALL_FLAGS_NONE,
1023 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1024 g_clear_error(&error);
1027 g_variant_unref(ret);
1030 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1031 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1033 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1034 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1036 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1037 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1039 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1040 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1041 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1042 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1043 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1044 NULL, 0, TRUE, NULL, NULL);
1045 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1046 NULL, 0, TRUE, NULL, NULL);
1048 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1050 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1051 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1052 *slot_id, // filter_index
1054 0, // company_id_mask
1055 arr_uuid_param, // p_uuid
1056 arr_uuid_mask_param, // p_uuid_mask
1059 arr_data_param, // p_data
1060 arr_data_mask_param);
1062 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1063 param, G_DBUS_CALL_FLAGS_NONE,
1067 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1068 g_clear_error(&error);
1071 g_variant_unref(ret);
1073 g_array_free(arr_uuid, TRUE);
1074 g_array_free(arr_uuid_mask, TRUE);
1075 g_array_free(arr_data, TRUE);
1076 g_array_free(arr_data_mask, TRUE);
1079 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1080 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1082 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1083 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1085 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1086 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1088 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1089 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1090 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1091 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1092 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1093 NULL, 0, TRUE, NULL, NULL);
1094 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1095 NULL, 0, TRUE, NULL, NULL);
1097 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1099 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1100 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1101 *slot_id, // filter_index
1103 0, // company_id_mask
1104 arr_uuid_param, // p_uuid
1105 arr_uuid_mask_param, // p_uuid_mask
1108 arr_data_param, // p_data
1109 arr_data_mask_param);
1111 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1112 G_DBUS_CALL_FLAGS_NONE,
1116 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1117 g_clear_error(&error);
1120 g_variant_unref(ret);
1122 g_array_free(arr_uuid, TRUE);
1123 g_array_free(arr_uuid_mask, TRUE);
1126 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1127 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1129 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1130 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1132 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1133 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1135 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1136 NULL, 0, TRUE, NULL, NULL);
1137 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1138 NULL, 0, TRUE, NULL, NULL);
1139 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1140 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1141 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1142 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1144 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1146 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1147 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1148 *slot_id, // filter_index
1150 0, // company_id_mask
1151 arr_uuid_param, // p_uuid
1152 arr_uuid_mask_param, // p_uuid_mask
1155 arr_data_param, // p_data
1156 arr_data_mask_param);
1158 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1159 G_DBUS_CALL_FLAGS_NONE,
1163 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1164 g_clear_error(&error);
1167 g_variant_unref(ret);
1169 g_array_free(arr_data, TRUE);
1170 g_array_free(arr_data_mask, TRUE);
1173 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1174 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1176 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1177 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1179 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1180 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1182 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1183 NULL, 0, TRUE, NULL, NULL);
1184 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1185 NULL, 0, TRUE, NULL, NULL);
1186 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1187 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1188 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1189 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1191 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1193 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1194 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1195 *slot_id, // filter_index
1196 filter->manufacturer_id, // company_id
1197 0xFFFF, // company_id_mask
1198 arr_uuid_param, // p_uuid
1199 arr_uuid_mask_param, // p_uuid_mask
1202 arr_data_param, // p_data
1203 arr_data_mask_param);
1205 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1206 G_DBUS_CALL_FLAGS_NONE,
1210 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1211 g_clear_error(&error);
1214 g_variant_unref(ret);
1216 g_array_free(arr_data, TRUE);
1217 g_array_free(arr_data_mask, TRUE);
1220 BT_DBG("Filter selection %.2x", feature_selection);
1222 param = g_variant_new("(iiiiiiiiiiii)",
1224 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1225 *slot_id, // filter_index
1226 feature_selection, // feat_seln
1227 0, // list_logic_type (OR - 0x00, AND - 0x01)
1228 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1229 -127, // rssi_high_thres
1230 -127, // rssi_low_thres
1231 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1234 0); // found_timeout_cnt
1235 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1236 param, G_DBUS_CALL_FLAGS_NONE,
1240 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1241 g_clear_error(&error);
1244 scanner = __bt_find_scanner_from_list(sender);
1245 if (scanner == NULL) {
1246 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1247 scanner->sender = strdup(sender);
1248 scanner_list = g_slist_append(scanner_list, scanner);
1251 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1252 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1253 filter_data->slot_id = *slot_id;
1256 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1259 g_variant_unref(ret);
1260 return BLUETOOTH_ERROR_NONE;
1263 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1266 GError *error = NULL;
1268 bt_adapter_le_scanner_t *scanner = NULL;
1269 bluetooth_le_scan_filter_t *filter_data = NULL;
1271 gboolean is_slot_id_found = FALSE;
1273 scanner = __bt_find_scanner_from_list(sender);
1274 if (scanner == NULL) {
1275 BT_ERR("There is NO available scanner.");
1276 return BLUETOOTH_ERROR_NOT_FOUND;
1279 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1280 filter_data = l->data;
1281 if (filter_data->slot_id == slot_id) {
1282 is_slot_id_found = TRUE;
1286 if (is_slot_id_found == FALSE) {
1287 BT_ERR("There is NO registered slot.");
1288 return BLUETOOTH_ERROR_NOT_FOUND;
1291 proxy = _bt_get_adapter_proxy();
1292 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1294 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1295 g_variant_new("(ii)", 0, slot_id),
1296 G_DBUS_CALL_FLAGS_NONE,
1300 BT_ERR("scan_filter_clear Fail: %s", error->message);
1301 g_clear_error(&error);
1304 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1305 g_free(filter_data);
1308 g_variant_unref(ret);
1309 return BLUETOOTH_ERROR_NONE;
1312 int _bt_unregister_all_scan_filters(const char *sender)
1315 GError *error = NULL;
1317 bt_adapter_le_scanner_t *scanner = NULL;
1318 bluetooth_le_scan_filter_t *filter_data = NULL;
1321 scanner = __bt_find_scanner_from_list(sender);
1322 if (scanner == NULL) {
1323 BT_ERR("There is NO available scanner.");
1324 return BLUETOOTH_ERROR_NOT_FOUND;
1327 proxy = _bt_get_adapter_proxy();
1328 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1330 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1331 filter_data = l->data;
1333 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1334 g_variant_new("(ii)", 0, filter_data->slot_id),
1335 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1338 BT_ERR("scan_filter_clear Fail: %s", error->message);
1339 g_clear_error(&error);
1342 g_variant_unref(ret);
1345 g_slist_free_full(scanner->filter_list, g_free);
1346 scanner->filter_list = NULL;
1348 return BLUETOOTH_ERROR_NONE;
1351 int _bt_start_le_scan(const char *sender)
1354 GError *error = NULL;
1356 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1358 if (scanner == NULL) {
1359 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1360 scanner->sender = strdup(sender);
1361 scanner_list = g_slist_append(scanner_list, scanner);
1364 if (scanner->is_scanning == TRUE) {
1365 BT_ERR("BT is already in LE scanning");
1366 return BLUETOOTH_ERROR_IN_PROGRESS;
1368 scanner->is_scanning = TRUE;
1370 proxy = _bt_get_adapter_proxy();
1371 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1373 if (_bt_is_le_scanning()) {
1374 if (scan_filter_enabled == TRUE) {
1375 if (scanner->filter_list == NULL) {
1376 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1377 g_variant_new("(ib)", 0, FALSE),
1378 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1381 BT_ERR("scan_filter_clear Fail: %s", error->message);
1382 g_clear_error(&error);
1386 g_variant_unref(ret);
1387 BT_INFO("Disable LE Scan Filter");
1388 scan_filter_enabled = FALSE;
1390 BT_INFO("LE Filter Scan is continue");
1393 BT_INFO("LE Full Scan is already on progress");
1395 return BLUETOOTH_ERROR_NONE;
1397 if (is_le_set_scan_parameter == FALSE) {
1398 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1399 bluetooth_le_scan_params_t scan_params;
1400 scan_params.type = BT_LE_ACTIVE_SCAN;
1401 scan_params.interval = 5000;
1402 scan_params.window = 500;
1403 _bt_set_scan_parameters(&scan_params);
1406 if (scanner->filter_list == NULL) {
1407 BT_INFO("Start LE Full Scan");
1408 scan_filter_enabled = FALSE;
1410 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1411 g_variant_new("(ib)", 0, TRUE),
1412 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1415 BT_ERR("scan_filter_clear Fail: %s", error->message);
1416 g_clear_error(&error);
1420 g_variant_unref(ret);
1421 BT_INFO("Enable LE Scan Filter");
1422 scan_filter_enabled = TRUE;
1426 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1427 NULL, G_DBUS_CALL_FLAGS_NONE,
1431 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1432 g_clear_error(&error);
1433 return BLUETOOTH_ERROR_INTERNAL;
1437 g_variant_unref(ret);
1438 return BLUETOOTH_ERROR_NONE;
1441 int _bt_stop_le_scan(const char *sender)
1444 GError *error = NULL;
1446 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1448 gboolean next_scanning = FALSE;
1449 gboolean need_scan_filter = TRUE;
1451 if (scanner == NULL || scanner->is_scanning == FALSE)
1452 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1454 scanner->is_scanning = FALSE;
1456 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1458 if (scanner->is_scanning == TRUE) {
1459 next_scanning = TRUE;
1460 if (scanner->filter_list == NULL)
1461 need_scan_filter = FALSE;
1465 proxy = _bt_get_adapter_proxy();
1466 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1468 if (next_scanning == TRUE) {
1469 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1470 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1471 g_variant_new("(ib)", 0, TRUE),
1472 G_DBUS_CALL_FLAGS_NONE,
1476 BT_ERR("scan_filter_clear Fail: %s", error->message);
1477 g_clear_error(&error);
1481 g_variant_unref(ret);
1482 BT_INFO("Enable LE Scan Filter");
1483 scan_filter_enabled = TRUE;
1485 return BLUETOOTH_ERROR_NONE;
1487 if (scan_filter_enabled == TRUE) {
1488 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1489 g_variant_new("(ib)", 0, FALSE),
1490 G_DBUS_CALL_FLAGS_NONE,
1494 BT_ERR("scan_filter_clear Fail: %s", error->message);
1495 g_clear_error(&error);
1499 g_variant_unref(ret);
1500 BT_INFO("Disable LE Scan Filter");
1502 BT_INFO("Just stop LE scan");
1506 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1507 NULL, G_DBUS_CALL_FLAGS_NONE,
1510 BT_ERR("LE Scan stop failed");
1511 return BLUETOOTH_ERROR_INTERNAL;
1514 scan_filter_enabled = FALSE;
1515 is_le_set_scan_parameter = FALSE;
1517 g_variant_unref(ret);
1518 return BLUETOOTH_ERROR_NONE;
1521 void _bt_disable_all_scanner_status(void)
1524 bt_adapter_le_scanner_t *scanner;
1526 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1528 scanner->is_scanning = FALSE;
1532 void _bt_set_le_scan_status(gboolean mode)
1534 is_le_scanning = mode;
1537 gboolean _bt_is_le_scanning(void)
1539 return is_le_scanning;
1542 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1544 le_scan_type = type;
1547 bt_le_scan_type_t _bt_get_le_scan_type(void)
1549 return le_scan_type;
1552 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1553 int adv_data_len, const char *svc_uuid, int uuid_len,
1554 const char *uuid_mask, char ad_type)
1560 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1561 ad_type, &data, &data_len);
1563 for (i = 0; i < data_len; i += uuid_len) {
1564 if (uuid_len > (data_len - i))
1567 if (_bt_byte_arr_cmp_with_mask(data + i,
1568 svc_uuid, uuid_mask, uuid_len) == 0) {
1579 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1580 const char *adv_data, int adv_data_len,
1581 const char *scan_data, int scan_data_len,
1582 const bt_adapter_le_scanner_t *scanner)
1585 bluetooth_le_scan_filter_t *filter_data = NULL;
1588 gboolean is_matched = FALSE;
1590 if (scanner->filter_list == NULL) {
1591 BT_INFO("This scanner is on Full Scan.");
1595 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1596 filter_data = l->data;
1598 if (filter_data->added_features &
1599 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1600 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1602 _bt_convert_addr_type_to_string(address,
1603 filter_data->device_address.addr);
1604 if (strncmp(address, device_address,
1605 BT_ADDRESS_STRING_SIZE) != 0)
1609 if (filter_data->added_features &
1610 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1613 if (__bt_check_scan_result_uuid(adv_data,
1615 (char*)filter_data->service_uuid.data.data,
1616 filter_data->service_uuid.data_len,
1617 (char*)filter_data->service_uuid_mask.data.data,
1618 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1621 if (__bt_check_scan_result_uuid(adv_data,
1623 (char*)filter_data->service_uuid.data.data,
1624 filter_data->service_uuid.data_len,
1625 (char*)filter_data->service_uuid_mask.data.data,
1626 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1629 if (__bt_check_scan_result_uuid(adv_data,
1631 (char*)filter_data->service_uuid.data.data,
1632 filter_data->service_uuid.data_len,
1633 (char*)filter_data->service_uuid_mask.data.data,
1634 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1637 if (__bt_check_scan_result_uuid(adv_data,
1639 (char*)filter_data->service_uuid.data.data,
1640 filter_data->service_uuid.data_len,
1641 (char*)filter_data->service_uuid_mask.data.data,
1642 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1645 if (__bt_check_scan_result_uuid(scan_data,
1647 (char*)filter_data->service_uuid.data.data,
1648 filter_data->service_uuid.data_len,
1649 (char*)filter_data->service_uuid_mask.data.data,
1650 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1653 if (__bt_check_scan_result_uuid(scan_data,
1655 (char*)filter_data->service_uuid.data.data,
1656 filter_data->service_uuid.data_len,
1657 (char*)filter_data->service_uuid_mask.data.data,
1658 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1661 if (__bt_check_scan_result_uuid(scan_data,
1663 (char*)filter_data->service_uuid.data.data,
1664 filter_data->service_uuid.data_len,
1665 (char*)filter_data->service_uuid_mask.data.data,
1666 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1669 if (__bt_check_scan_result_uuid(scan_data,
1671 (char*)filter_data->service_uuid.data.data,
1672 filter_data->service_uuid.data_len,
1673 (char*)filter_data->service_uuid_mask.data.data,
1674 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1678 if (is_matched == FALSE)
1681 if (filter_data->added_features &
1682 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1685 if (__bt_check_scan_result_uuid(adv_data,
1687 (char*)filter_data->service_solicitation_uuid.data.data,
1688 filter_data->service_solicitation_uuid.data_len,
1689 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1690 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1693 if (__bt_check_scan_result_uuid(adv_data,
1695 (char*)filter_data->service_solicitation_uuid.data.data,
1696 filter_data->service_solicitation_uuid.data_len,
1697 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1698 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1701 if (__bt_check_scan_result_uuid(scan_data,
1703 (char*)filter_data->service_solicitation_uuid.data.data,
1704 filter_data->service_solicitation_uuid.data_len,
1705 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1706 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1709 if (__bt_check_scan_result_uuid(scan_data,
1711 (char*)filter_data->service_solicitation_uuid.data.data,
1712 filter_data->service_solicitation_uuid.data_len,
1713 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1714 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1718 if (is_matched == FALSE)
1721 if (filter_data->added_features &
1722 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1723 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1728 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1729 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1732 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1733 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1734 memcpy(name, data, data_len);
1735 name[data_len] = '\0';
1738 if (strncmp(filter_data->device_name,
1739 name, data_len) == 0)
1742 __bt_get_ad_data_by_type((char*)scan_data,
1744 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1747 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1748 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1749 memcpy(name, data, data_len);
1750 name[data_len] = '\0';
1753 if (strncmp(filter_data->device_name,
1754 name, data_len) == 0)
1758 if (is_matched == FALSE)
1761 if (filter_data->added_features &
1762 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1767 __bt_get_ad_data_by_type((char*)adv_data,
1769 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1773 int manufacturer_id;
1774 manufacturer_id = (data[1] << 8) + data[0];
1776 if (filter_data->manufacturer_id == manufacturer_id) {
1777 if (filter_data->manufacturer_data.data_len == 0) {
1780 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1781 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1782 if (_bt_byte_arr_cmp_with_mask(data + 2,
1783 (char*)filter_data->manufacturer_data.data.data,
1784 (char*)filter_data->manufacturer_data_mask.data.data,
1785 data_len - 2) == 0) {
1793 __bt_get_ad_data_by_type((char*)scan_data,
1795 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1799 int manufacturer_id;
1800 manufacturer_id = (data[1] << 8) + data[0];
1802 if (filter_data->manufacturer_id == manufacturer_id) {
1803 if (filter_data->manufacturer_data.data_len == 0) {
1806 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1807 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1808 if (_bt_byte_arr_cmp_with_mask(data + 2,
1809 (char*)filter_data->manufacturer_data.data.data,
1810 (char*)filter_data->manufacturer_data_mask.data.data,
1811 data_len - 2) == 0) {
1820 if (is_matched == FALSE)
1823 if (filter_data->added_features &
1824 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1829 __bt_get_ad_data_by_type((char*)adv_data,
1831 BT_LE_AD_TYPE_SERVICE_DATA,
1834 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1835 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1836 if (_bt_byte_arr_cmp_with_mask(data,
1837 (char*)filter_data->service_data.data.data,
1838 (char*)filter_data->service_data_mask.data.data,
1845 __bt_get_ad_data_by_type((char*)scan_data,
1847 BT_LE_AD_TYPE_SERVICE_DATA,
1850 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1851 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1852 if (_bt_byte_arr_cmp_with_mask(data,
1853 (char*)filter_data->service_data.data.data,
1854 (char*)filter_data->service_data_mask.data.data,
1862 if (is_matched == FALSE)
1866 BT_INFO("The scan result is conformable.");
1870 BT_INFO("The scan result is NOT conformable.");
1874 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1875 const bt_le_adv_info_t *adv_info)
1877 int result = BLUETOOTH_ERROR_NONE;
1879 GVariant *scan_data_param, *adv_data_param;
1881 bt_adapter_le_scanner_t *scanner = NULL;
1882 const char *adv_data = NULL;
1883 int adv_data_len = 0;
1884 const char *scan_data = NULL;
1885 int scan_data_len = 0;
1887 ret_if(le_dev_info == NULL);
1888 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1889 ret_if(adv_info == NULL);
1891 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1892 adv_data = le_dev_info->adv_data;
1893 adv_data_len = le_dev_info->adv_data_len;
1894 scan_data = le_dev_info->adv_data;
1897 adv_data = adv_info->data;
1898 adv_data_len = adv_info->data_len;
1899 scan_data = le_dev_info->adv_data;
1900 scan_data_len = le_dev_info->adv_data_len;
1903 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1905 if (scanner->is_scanning == FALSE)
1908 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1909 adv_data, adv_data_len, scan_data, scan_data_len,
1913 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1914 adv_data, adv_data_len, TRUE, NULL, NULL);
1915 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1916 scan_data, scan_data_len, TRUE, NULL, NULL);
1918 param = g_variant_new("(isnnn@ayn@ay)",
1920 le_dev_info->address,
1921 le_dev_info->addr_type,
1929 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1930 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1932 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1937 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1940 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1941 GError *error = NULL;
1944 if (__bt_is_factory_test_mode()) {
1945 BT_ERR("Unable to add white list in factory binary !!");
1946 return BLUETOOTH_ERROR_NOT_SUPPORT;
1949 BT_CHECK_PARAMETER(device_address, return);
1951 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1952 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1953 return BLUETOOTH_ERROR_INVALID_PARAM;
1955 _bt_convert_addr_type_to_string(address, device_address->addr);
1957 proxy = _bt_get_adapter_proxy();
1958 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1960 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1961 g_variant_new("(su)", address, address_type),
1962 G_DBUS_CALL_FLAGS_NONE, -1,
1966 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
1967 g_clear_error(&error);
1968 return BLUETOOTH_ERROR_INTERNAL;
1972 g_variant_unref(ret);
1973 BT_INFO("Add white list");
1975 return BLUETOOTH_ERROR_NONE;
1978 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1981 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1982 GError *error = NULL;
1985 if (__bt_is_factory_test_mode()) {
1986 BT_ERR("Unable to remove white list in factory binary !!");
1987 return BLUETOOTH_ERROR_NOT_SUPPORT;
1990 BT_CHECK_PARAMETER(device_address, return);
1992 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1993 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1994 return BLUETOOTH_ERROR_INVALID_PARAM;
1996 _bt_convert_addr_type_to_string(address, device_address->addr);
1998 proxy = _bt_get_adapter_proxy();
1999 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2001 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
2002 g_variant_new("(su)", address, address_type),
2003 G_DBUS_CALL_FLAGS_NONE, -1,
2007 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2008 g_clear_error(&error);
2009 return BLUETOOTH_ERROR_INTERNAL;
2013 g_variant_unref(ret);
2014 BT_INFO("Remove white list");
2016 return BLUETOOTH_ERROR_NONE;
2019 int _bt_clear_white_list(void)
2022 GError *error = NULL;
2025 if (__bt_is_factory_test_mode()) {
2026 BT_ERR("Unable to clear white list in factory binary !!");
2027 return BLUETOOTH_ERROR_NOT_SUPPORT;
2030 proxy = _bt_get_adapter_proxy();
2031 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2033 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2034 NULL, G_DBUS_CALL_FLAGS_NONE,
2038 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2039 g_clear_error(&error);
2040 return BLUETOOTH_ERROR_INTERNAL;
2043 g_variant_unref(ret);
2045 BT_INFO("Clear white list");
2047 return BLUETOOTH_ERROR_NONE;
2050 int _bt_initialize_ipsp(void)
2054 GError *error = NULL;
2057 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2058 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2059 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2062 proxy = _bt_get_adapter_proxy();
2063 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2065 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2066 NULL, G_DBUS_CALL_FLAGS_NONE,
2069 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2070 g_clear_error(&error);
2071 return BLUETOOTH_ERROR_INTERNAL;
2074 g_variant_unref(ret);
2076 BT_INFO("IPSP initialization called successfully");
2078 return BLUETOOTH_ERROR_NONE;
2081 int _bt_deinitialize_ipsp(void)
2085 GError *error = NULL;
2088 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2089 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2090 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2093 proxy = _bt_get_adapter_proxy();
2094 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2096 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2097 NULL, G_DBUS_CALL_FLAGS_NONE,
2100 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2101 g_clear_error(&error);
2102 return BLUETOOTH_ERROR_INTERNAL;
2105 g_variant_unref(ret);
2107 BT_INFO("IPSP De-initialization called successfully");
2109 return BLUETOOTH_ERROR_NONE;
2112 int _bt_le_read_maximum_data_length(
2113 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2115 GError *error = NULL;
2117 GVariant *reply = NULL;
2118 guint16 max_tx_octets, max_tx_time;
2119 guint16 max_rx_octets, max_rx_time;
2121 proxy = _bt_get_adapter_proxy();
2122 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2124 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2125 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2127 g_object_unref(proxy);
2129 if (reply == NULL) {
2130 BT_ERR("LEReadMaximumDataLength 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, "(qqqq)", &max_tx_octets, &max_tx_time,
2140 &max_rx_octets, &max_rx_time);
2142 max_le_datalength->max_tx_octets = max_tx_octets;
2143 max_le_datalength->max_tx_time = max_tx_time;
2144 max_le_datalength->max_rx_octets = max_rx_octets;
2145 max_le_datalength->max_rx_time = max_rx_time;
2147 g_variant_unref(reply);
2149 return BLUETOOTH_ERROR_NONE;
2151 int _bt_le_write_host_suggested_default_data_length(
2152 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2154 GError *error = NULL;
2156 GVariant *reply = NULL;
2158 proxy = _bt_get_adapter_proxy();
2159 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2161 reply = g_dbus_proxy_call_sync(proxy,
2162 "LEWriteHostSuggestedDataLength",
2163 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2164 G_DBUS_CALL_FLAGS_NONE,
2169 g_object_unref(proxy);
2171 if (reply == NULL) {
2172 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2173 if (error != NULL) {
2174 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2175 error->code, error->message);
2176 g_clear_error(&error);
2178 return BLUETOOTH_ERROR_INTERNAL;
2181 g_variant_unref(reply);
2183 return BLUETOOTH_ERROR_NONE;
2186 int _bt_le_read_host_suggested_default_data_length(
2187 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2189 GError *error = NULL;
2191 GVariant *reply = NULL;
2192 guint16 def_tx_octets, def_tx_time;
2194 proxy = _bt_get_adapter_proxy();
2195 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2197 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2198 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2200 if (reply == NULL) {
2201 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2202 if (error != NULL) {
2203 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2204 error->code, error->message);
2205 g_clear_error(&error);
2207 return BLUETOOTH_ERROR_INTERNAL;
2210 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2212 def_data_length->def_tx_octets = def_tx_octets;
2213 def_data_length->def_tx_time = def_tx_time;
2215 g_variant_unref(reply);
2217 return BLUETOOTH_ERROR_NONE;
2220 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2221 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2223 GError *error = NULL;
2224 guint16 txOctets = max_tx_Octets;
2225 guint16 txTime = max_tx_Time;
2226 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2227 gchar *device_path = NULL;
2228 GDBusConnection *conn;
2229 GDBusProxy *device_proxy;
2231 _bt_convert_addr_type_to_string(address, device_address->addr);
2233 device_path = _bt_get_device_object_path(address);
2235 if (device_path == NULL) {
2236 BT_DBG("Device path is null");
2237 return BLUETOOTH_ERROR_INTERNAL;
2240 conn = _bt_gdbus_get_system_gconn();
2242 BT_ERR("conn == NULL");
2243 g_free(device_path);
2244 return BLUETOOTH_ERROR_INTERNAL;
2247 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2248 NULL, BT_BLUEZ_NAME,
2249 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2251 g_free(device_path);
2252 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2254 g_dbus_proxy_call_sync(device_proxy,
2256 g_variant_new("(qq)", txOctets, txTime),
2257 G_DBUS_CALL_FLAGS_NONE,
2262 g_object_unref(device_proxy);
2265 BT_ERR("LESetDataLength error: [%s]", error->message);
2266 g_error_free(error);
2267 return BLUETOOTH_ERROR_INTERNAL;
2270 return BLUETOOTH_ERROR_NONE;