From d56685d05706bd5ab97a92940cd0b3dcf22d0401 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 29 Apr 2013 14:02:34 +0300 Subject: [PATCH] core: Fix storing info for private addressed devices Devices with private addresses cannot persistently be identified by their address. Therefore it doesn't make sense to store any information about them as the information couldn't be looked up later once the remote address has changed. Once the kernel receives support for private address resolution we'll start getting the public address of such devices to user space. However, until then we just have to ignore such devices from a storage perspective. --- plugins/neard.c | 3 +-- src/adapter.c | 58 ++++++++++++++++++------------------------------- src/adapter.h | 2 -- src/device.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ src/device.h | 1 + 5 files changed, 80 insertions(+), 41 deletions(-) diff --git a/plugins/neard.c b/plugins/neard.c index c60c07682..f46e20e5e 100644 --- a/plugins/neard.c +++ b/plugins/neard.c @@ -636,8 +636,7 @@ static void store_params(struct btd_adapter *adapter, struct btd_device *device, device_set_class(device, params->class); if (params->name) { - adapter_store_cached_name(adapter_get_address(adapter), - ¶ms->address, params->name); + device_store_cached_name(device, params->name); device_set_name(device, params->name); } diff --git a/src/adapter.c b/src/adapter.c index 6255da6ca..0c0831c97 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -397,32 +397,6 @@ static void store_adapter_info(struct btd_adapter *adapter) g_key_file_free(key_file); } -void adapter_store_cached_name(const bdaddr_t *local, const bdaddr_t *peer, - const char *name) -{ - char filename[PATH_MAX + 1]; - char s_addr[18], d_addr[18]; - GKeyFile *key_file; - char *data; - gsize length = 0; - - ba2str(local, s_addr); - ba2str(peer, d_addr); - snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", s_addr, d_addr); - filename[PATH_MAX] = '\0'; - create_file(filename, S_IRUSR | S_IWUSR); - - key_file = g_key_file_new(); - g_key_file_load_from_file(key_file, filename, 0, NULL); - g_key_file_set_string(key_file, "General", "Name", name); - - data = g_key_file_to_data(key_file, &length, NULL); - g_file_set_contents(filename, data, length, NULL); - g_free(data); - - g_key_file_free(key_file); -} - static void trigger_pairable_timeout(struct btd_adapter *adapter); static void adapter_start(struct btd_adapter *adapter); static void adapter_stop(struct btd_adapter *adapter); @@ -2993,7 +2967,10 @@ static void convert_names_entry(char *key, char *value, void *user_data) { char *address = user_data; char *str = key; - bdaddr_t local, peer; + char filename[PATH_MAX + 1]; + GKeyFile *key_file; + char *data; + gsize length = 0; if (strchr(key, '#')) str[17] = '\0'; @@ -3001,9 +2978,19 @@ static void convert_names_entry(char *key, char *value, void *user_data) if (bachk(str) != 0) return; - str2ba(address, &local); - str2ba(str, &peer); - adapter_store_cached_name(&local, &peer, value); + snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", address, str); + filename[PATH_MAX] = '\0'; + create_file(filename, S_IRUSR | S_IWUSR); + + key_file = g_key_file_new(); + g_key_file_load_from_file(key_file, filename, 0, NULL); + g_key_file_set_string(key_file, "General", "Name", value); + + data = g_key_file_to_data(key_file, &length, NULL); + g_file_set_contents(filename, data, length, NULL); + g_free(data); + + g_key_file_free(key_file); } struct device_converter { @@ -4081,10 +4068,6 @@ static void update_found_devices(struct btd_adapter *adapter, return; } - if (eir_data.name != NULL && eir_data.name_complete) - adapter_store_cached_name(&adapter->bdaddr, bdaddr, - eir_data.name); - /* Avoid creating LE device if it's not discoverable */ if (bdaddr_type != BDADDR_BREDR && !(eir_data.flags & (EIR_LIM_DISC | EIR_GEN_DISC))) { @@ -4115,6 +4098,9 @@ static void update_found_devices(struct btd_adapter *adapter, return; } + if (eir_data.name != NULL && eir_data.name_complete) + device_store_cached_name(dev, eir_data.name); + /* * If no client has requested discovery, then only update * already paired devices (skip temporary ones). @@ -5612,9 +5598,7 @@ static void connected_callback(uint16_t index, uint16_t length, adapter_add_connection(adapter, device); if (eir_data.name != NULL) { - const bdaddr_t *bdaddr = adapter_get_address(adapter); - adapter_store_cached_name(bdaddr, &ev->addr.bdaddr, - eir_data.name); + device_store_cached_name(device, eir_data.name); device_set_name(device, eir_data.name); } diff --git a/src/adapter.h b/src/adapter.h index 8d23a645b..6b6515a8e 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -200,8 +200,6 @@ void adapter_connect_list_remove(struct btd_adapter *adapter, void btd_adapter_set_oob_handler(struct btd_adapter *adapter, struct oob_handler *handler); gboolean btd_adapter_check_oob_handler(struct btd_adapter *adapter); -void adapter_store_cached_name(const bdaddr_t *local, const bdaddr_t *peer, - const char *name); void btd_adapter_for_each_device(struct btd_adapter *adapter, void (*cb)(struct btd_device *device, void *data), diff --git a/src/device.c b/src/device.c index dd137edce..3c1d02d52 100644 --- a/src/device.c +++ b/src/device.c @@ -366,14 +366,65 @@ static gboolean store_device_info_cb(gpointer user_data) return FALSE; } +static bool device_address_is_private(struct btd_device *dev) +{ + if (dev->bdaddr_type != BDADDR_LE_RANDOM) + return false; + + switch (dev->bdaddr.b[5] >> 6) { + case 0x00: /* Private non-resolvable */ + case 0x01: /* Private resolvable */ + return true; + default: + return false; + } +} + static void store_device_info(struct btd_device *device) { if (device->temporary || device->store_id > 0) return; + if (device_address_is_private(device)) { + warn("Can't store info for private addressed device %s", + device->path); + return; + } + device->store_id = g_idle_add(store_device_info_cb, device); } +void device_store_cached_name(struct btd_device *dev, const char *name) +{ + char filename[PATH_MAX + 1]; + char s_addr[18], d_addr[18]; + GKeyFile *key_file; + char *data; + gsize length = 0; + + if (device_address_is_private(dev)) { + warn("Can't store name for private addressed device %s", + dev->path); + return; + } + + ba2str(adapter_get_address(dev->adapter), s_addr); + ba2str(&dev->bdaddr, d_addr); + snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", s_addr, d_addr); + filename[PATH_MAX] = '\0'; + create_file(filename, S_IRUSR | S_IWUSR); + + key_file = g_key_file_new(); + g_key_file_load_from_file(key_file, filename, 0, NULL); + g_key_file_set_string(key_file, "General", "Name", name); + + data = g_key_file_to_data(key_file, &length, NULL); + g_file_set_contents(filename, data, length, NULL); + g_free(data); + + g_key_file_free(key_file); +} + static void browse_request_free(struct browse_req *req) { if (req->listener_id) @@ -2885,6 +2936,12 @@ static void store_services(struct btd_device *device) char *data; gsize length = 0; + if (device_address_is_private(device)) { + warn("Can't store services for private addressed device %s", + device->path); + return; + } + sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID); prim_uuid = bt_uuid2string(&uuid); if (prim_uuid == NULL) diff --git a/src/device.h b/src/device.h index f467fa671..f4db3b9e6 100644 --- a/src/device.h +++ b/src/device.h @@ -34,6 +34,7 @@ char *btd_device_get_storage_path(struct btd_device *device, const char *filename); void 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); void device_set_class(struct btd_device *device, uint32_t class); -- 2.47.3