Implement caching of remote host features
Devices with SSP but no EIR requires looking at the remote host features
to get a correct value for the LegacyPairing property. Requesting a
remote name gives these features for free but if the name is already
cached we don't get them. This patch implements the caching part for the
features and a subsequent patch will actually make use of the cached
value for the device discovery process.
diff --git a/src/security.c b/src/security.c
index ce32846..acb5a1f 100644
--- a/src/security.c
+++ b/src/security.c
@@ -661,6 +661,8 @@
hcid_dbus_set_legacy_pairing(sba, &evt->bdaddr, FALSE);
else
hcid_dbus_set_legacy_pairing(sba, &evt->bdaddr, TRUE);
+
+ write_features_info(sba, &evt->bdaddr, NULL, evt->features);
}
static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr)
@@ -833,7 +835,7 @@
if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0)
return;
- write_features_info(sba, &dba, evt->features);
+ write_features_info(sba, &dba, evt->features, NULL);
}
static inline void conn_complete(int dev, int dev_id, bdaddr_t *sba, void *ptr)
diff --git a/src/storage.c b/src/storage.c
index aa66232..1a1deb7 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -483,20 +483,35 @@
return textfile_put(filename, addr, str);
}
-int write_features_info(bdaddr_t *local, bdaddr_t *peer, unsigned char *features)
+int write_features_info(bdaddr_t *local, bdaddr_t *peer,
+ unsigned char *page1, unsigned char *page2)
{
- char filename[PATH_MAX + 1], addr[18], str[17];
+ char filename[PATH_MAX + 1], addr[18];
+ char str[] = "0000000000000000 0000000000000000";
+ char *old_value;
int i;
- memset(str, 0, sizeof(str));
- for (i = 0; i < 8; i++)
- sprintf(str + (i * 2), "%2.2X", features[i]);
+ ba2str(peer, addr);
create_filename(filename, PATH_MAX, local, "features");
-
create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- ba2str(peer, addr);
+ old_value = textfile_get(filename, addr);
+
+ if (page1)
+ for (i = 0; i < 8; i++)
+ sprintf(str + (i * 2), "%2.2X", page1[i]);
+ else if (old_value && strlen(old_value) >= 16)
+ strncpy(str, old_value, 16);
+
+ if (page2)
+ for (i = 0; i < 8; i++)
+ sprintf(str + 17 + (i * 2), "%2.2X", page2[i]);
+ else if (old_value && strlen(old_value) >= 33)
+ strncpy(str + 17, old_value + 17, 16);
+
+ free(old_value);
+
return textfile_put(filename, addr, str);
}
diff --git a/src/storage.h b/src/storage.h
index ae244c7..d4542d4 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -47,7 +47,7 @@
uint16_t *mtu_result, uint16_t *mtu,
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 *features);
+int write_features_info(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);