From: Archie Pusaka <apusaka@xxxxxxxxxxxx> When Remote Name Resolve ends with failure, record this occurrence and prevent remote name resolving for the same device for some time. Reviewed-by: Miao-chen Chou <mcchou@xxxxxxxxxxxx> --- Changes in v4: * Use CLOCK_MONOTONIC for timekeeping. * Constant waiting time between retries instead of increasing. * Fix conflict merge with adv_monitor.c Changes in v3: * Rename MGMT const to align with the doc. Changes in v2: * Stay silent instead of sending MGMT_OP_CONFIRM_NAME with DONT_CARE flag. src/adapter.c | 16 +++++++++++++--- src/adapter.h | 1 + src/adv_monitor.c | 7 +++++-- src/device.c | 27 +++++++++++++++++++++++++++ src/device.h | 2 ++ 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/adapter.c b/src/adapter.c index 98616f17d2..c49f42cfbb 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -6979,6 +6979,7 @@ void btd_adapter_update_found_device(struct btd_adapter *adapter, uint8_t bdaddr_type, int8_t rssi, bool confirm, bool legacy, bool not_connectable, + bool name_resolve_failed, const uint8_t *data, uint8_t data_len, bool monitoring) { @@ -7076,6 +7077,9 @@ void btd_adapter_update_found_device(struct btd_adapter *adapter, device_set_legacy(dev, legacy); + if (name_resolve_failed) + device_name_resolve_fail(dev); + if (adapter->filtered_discovery) device_set_rssi_with_delta(dev, rssi, 0); else @@ -7146,7 +7150,10 @@ void btd_adapter_update_found_device(struct btd_adapter *adapter, if (g_slist_find(adapter->discovery_found, dev)) return; - if (confirm) + /* If name is unknown but it's not allowed to resolve, don't send + * MGMT_OP_CONFIRM_NAME. + */ + if (confirm && (name_known || device_is_name_resolve_allowed(dev))) confirm_name(adapter, bdaddr, bdaddr_type, name_known); adapter->discovery_found = g_slist_prepend(adapter->discovery_found, @@ -7196,8 +7203,9 @@ static void device_found_callback(uint16_t index, uint16_t length, uint32_t flags; bool confirm_name; bool legacy; - char addr[18]; bool not_connectable; + bool name_resolve_failed; + char addr[18]; if (length < sizeof(*ev)) { btd_error(adapter->dev_id, @@ -7227,10 +7235,12 @@ static void device_found_callback(uint16_t index, uint16_t length, confirm_name = (flags & MGMT_DEV_FOUND_CONFIRM_NAME); legacy = (flags & MGMT_DEV_FOUND_LEGACY_PAIRING); not_connectable = (flags & MGMT_DEV_FOUND_NOT_CONNECTABLE); + name_resolve_failed = (flags & MGMT_DEV_FOUND_NAME_REQUEST_FAILED); btd_adapter_update_found_device(adapter, &ev->addr.bdaddr, ev->addr.type, ev->rssi, confirm_name, - legacy, not_connectable, eir, eir_len, + legacy, not_connectable, + name_resolve_failed, eir, eir_len, false); } diff --git a/src/adapter.h b/src/adapter.h index 2815d4613f..35deb1d117 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -92,6 +92,7 @@ void btd_adapter_update_found_device(struct btd_adapter *adapter, uint8_t bdaddr_type, int8_t rssi, bool confirm, bool legacy, bool not_connectable, + bool name_resolve_failed, const uint8_t *data, uint8_t data_len, bool monitored); diff --git a/src/adv_monitor.c b/src/adv_monitor.c index bf7f2bed3b..602830e30b 100644 --- a/src/adv_monitor.c +++ b/src/adv_monitor.c @@ -1585,8 +1585,9 @@ static void adv_monitor_device_found_callback(uint16_t index, uint16_t length, uint32_t flags; bool confirm_name; bool legacy; - char addr[18]; bool not_connectable; + bool name_resolve_failed; + char addr[18]; if (length < sizeof(*ev)) { btd_error(adapter_id, @@ -1613,10 +1614,12 @@ static void adv_monitor_device_found_callback(uint16_t index, uint16_t length, confirm_name = (flags & MGMT_DEV_FOUND_CONFIRM_NAME); legacy = (flags & MGMT_DEV_FOUND_LEGACY_PAIRING); not_connectable = (flags & MGMT_DEV_FOUND_NOT_CONNECTABLE); + name_resolve_failed = (flags & MGMT_DEV_FOUND_NAME_REQUEST_FAILED); btd_adapter_update_found_device(adapter, &ev->addr.bdaddr, ev->addr.type, ev->rssi, confirm_name, - legacy, not_connectable, ad_data, + legacy, not_connectable, + name_resolve_failed, ad_data, ad_data_len, true); if (handle) { diff --git a/src/device.c b/src/device.c index 6b398bd396..a83cb61f8c 100644 --- a/src/device.c +++ b/src/device.c @@ -79,6 +79,8 @@ #define GATT_INCLUDE_UUID_STR "2802" #define GATT_CHARAC_UUID_STR "2803" +#define NAME_RESOLVE_RETRY_DELAY 300 /* seconds */ + static DBusConnection *dbus_conn = NULL; static unsigned service_state_cb_id; @@ -272,6 +274,8 @@ struct btd_device { GIOChannel *att_io; guint store_id; + + time_t name_resolve_failed_time; }; static const uint16_t uuid_list[] = { @@ -4389,6 +4393,29 @@ bool device_name_known(struct btd_device *device) return device->name[0] != '\0'; } +bool device_is_name_resolve_allowed(struct btd_device *device) +{ + struct timespec now; + + if (!device) + return false; + + clock_gettime(CLOCK_MONOTONIC, &now); + return now.tv_sec >= device->name_resolve_failed_time + + NAME_RESOLVE_RETRY_DELAY; +} + +void device_name_resolve_fail(struct btd_device *device) +{ + struct timespec now; + + if (!device) + return; + + clock_gettime(CLOCK_MONOTONIC, &now); + device->name_resolve_failed_time = now.tv_sec; +} + void device_set_class(struct btd_device *device, uint32_t class) { if (device->class == class) diff --git a/src/device.h b/src/device.h index b37a0a3d21..071576d6b3 100644 --- a/src/device.h +++ b/src/device.h @@ -25,6 +25,8 @@ void btd_device_device_set_name(struct btd_device *device, const char *name); void device_store_cached_name(struct btd_device *dev, const char *name); void device_get_name(struct btd_device *device, char *name, size_t len); bool device_name_known(struct btd_device *device); +bool device_is_name_resolve_allowed(struct btd_device *device); +void device_name_resolve_fail(struct btd_device *device); void device_set_class(struct btd_device *device, uint32_t class); void device_update_addr(struct btd_device *device, const bdaddr_t *bdaddr, uint8_t bdaddr_type); -- 2.34.0.rc2.393.gf8c9666880-goog