OSDN Git Service

Check for cached remote host features during discovery
authorJohan Hedberg <johan.hedberg@nokia.com>
Wed, 3 Feb 2010 20:02:42 +0000 (12:02 -0800)
committerJohan Hedberg <johan.hedberg@nokia.com>
Wed, 3 Feb 2010 20:07:51 +0000 (12:07 -0800)
If a remote name is cached and we didn't got a non-EIR event we should
check for cached remote host features for SSP support to behave
correctly with SSP & non-EIR devices.

src/dbus-hci.c
src/storage.c
src/storage.h

index a943b9b..176e27b 100644 (file)
@@ -472,6 +472,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
        name_status_t name_status;
        int state;
        dbus_bool_t legacy;
+       unsigned char features[8];
 
        ba2str(local, local_addr);
        ba2str(peer, peer_addr);
@@ -497,8 +498,6 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
                adapter_set_state(adapter, state);
        }
 
-       legacy = (data == NULL);
-
        memset(&match, 0, sizeof(struct remote_dev_info));
        bacpy(&match.bdaddr, peer);
        match.name_status = NAME_SENT;
@@ -506,7 +505,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
        dev = adapter_search_found_devices(adapter, &match);
        if (dev) {
                adapter_update_found_devices(adapter, peer, rssi, class,
-                                               NULL, NULL, legacy,
+                                               NULL, NULL, dev->legacy,
                                                NAME_NOT_REQUIRED);
                return;
        }
@@ -523,6 +522,18 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
        create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "names");
        name = textfile_get(filename, peer_addr);
 
+       if (data)
+               legacy = FALSE;
+       else if (name == NULL)
+               legacy = TRUE;
+       else if (read_remote_features(local, peer, NULL, features) == 0) {
+               if (features[0] & 0x01)
+                       legacy = FALSE;
+               else
+                       legacy = TRUE;
+       } else
+               legacy = TRUE;
+
        tmp_name = extract_eir_name(data, &name_type);
        if (tmp_name) {
                if (name_type == 0x09) {
@@ -541,7 +552,6 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
                }
        }
 
-
        if (name && name_type != 0x08)
                name_status = NAME_SENT;
 
index 1a1deb7..981c744 100644 (file)
@@ -515,6 +515,51 @@ int write_features_info(bdaddr_t *local, bdaddr_t *peer,
        return textfile_put(filename, addr, str);
 }
 
+static int decode_bytes(const char *str, unsigned char *bytes, size_t len)
+{
+       unsigned int i;
+
+       for (i = 0; i < len; i++) {
+               if (sscanf(str + (i * 2), "%02hhX", &bytes[i]) != 1)
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
+int read_remote_features(bdaddr_t *local, bdaddr_t *peer,
+                               unsigned char *page1, unsigned char *page2)
+{
+       char filename[PATH_MAX + 1], addr[18], *str;
+       size_t len;
+       int err;
+
+       if (page1 == NULL && page2 == NULL)
+               return -EINVAL;
+
+       create_filename(filename, PATH_MAX, local, "features");
+
+       ba2str(peer, addr);
+
+       str = textfile_get(filename, addr);
+       if (!str)
+               return -ENOENT;
+
+       len = strlen(str);
+
+       err = -ENOENT;
+
+       if (page1 && len >= 16)
+               err = decode_bytes(str, page1, 8);
+
+       if (page2 && len >= 33)
+               err = decode_bytes(str + 17, page2, 8);
+
+       free(str);
+
+       return err;
+}
+
 int write_lastseen_info(bdaddr_t *local, bdaddr_t *peer, struct tm *tm)
 {
        char filename[PATH_MAX + 1], addr[18], str[24];
index d4542d4..ed50734 100644 (file)
@@ -48,6 +48,7 @@ int read_l2cap_info(bdaddr_t *local, bdaddr_t *peer,
                        uint16_t *mask_result, uint32_t *mask);
 int write_version_info(bdaddr_t *local, bdaddr_t *peer, uint16_t manufacturer, uint8_t lmp_ver, uint16_t lmp_subver);
 int write_features_info(bdaddr_t *local, bdaddr_t *peer, unsigned char *page1, unsigned char *page2);
+int read_remote_features(bdaddr_t *local, bdaddr_t *peer, unsigned char *page1, unsigned char *page2);
 int write_lastseen_info(bdaddr_t *local, bdaddr_t *peer, struct tm *tm);
 int write_lastused_info(bdaddr_t *local, bdaddr_t *peer, struct tm *tm);
 int write_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, uint8_t type, int length);