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);