OSDN Git Service

core: Fix storing info for private addressed devices
authorJohan Hedberg <johan.hedberg@intel.com>
Mon, 29 Apr 2013 11:02:34 +0000 (14:02 +0300)
committerJohan Hedberg <johan.hedberg@intel.com>
Mon, 29 Apr 2013 11:02:34 +0000 (14:02 +0300)
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
src/adapter.c
src/adapter.h
src/device.c
src/device.h

index c60c076..f46e20e 100644 (file)
@@ -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),
-                                               &params->address, params->name);
+               device_store_cached_name(device, params->name);
                device_set_name(device, params->name);
        }
 
index 6255da6..0c0831c 100644 (file)
@@ -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);
        }
 
index 8d23a64..6b6515a 100644 (file)
@@ -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),
index dd137ed..3c1d02d 100644 (file)
@@ -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)
index f467fa6..f4db3b9 100644 (file)
@@ -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);