@@ -8901,6 +8901,73 @@ static void store_irk(struct btd_adapter *adapter, const bdaddr_t *peer,
g_key_file_free(key_file);
}
+static void delete_existing_irk_from_directory(
+ struct btd_adapter *adapter,
+ const unsigned char *key)
+{
+ char dirname[PATH_MAX];
+ GError *gerr = NULL;
+ DIR *dir;
+ struct dirent *entry;
+
+ create_filename(dirname, PATH_MAX, "/%s",
+ btd_adapter_get_storage_dir(adapter));
+
+ dir = opendir(dirname);
+ if (!dir) {
+ btd_error(adapter->dev_id,
+ "Unable to open adapter storage directory: %s",
+ dirname);
+ return;
+ }
+
+ while ((entry = readdir(dir)) != NULL) {
+ struct btd_device *device;
+ char filename[PATH_MAX];
+ GKeyFile *key_file;
+ struct irk_info *irk_info;
+ uint8_t bdaddr_type;
+
+ if (entry->d_type == DT_UNKNOWN)
+ entry->d_type = util_get_dt(dirname, entry->d_name);
+
+ if (entry->d_type != DT_DIR || bachk(entry->d_name) < 0)
+ continue;
+
+ create_filename(filename, PATH_MAX, "/%s/%s/info",
+ btd_adapter_get_storage_dir(adapter),
+ entry->d_name);
+
+ key_file = g_key_file_new();
+ if (!g_key_file_load_from_file(key_file, filename,
+ 0, &gerr)) {
+ error("Unable to load key file from %s: (%s)",
+ filename, gerr->message);
+ g_clear_error(&gerr);
+ }
+
+ bdaddr_type = get_addr_type(key_file);
+
+ irk_info = get_irk_info(key_file, entry->d_name, bdaddr_type);
+
+ if (irk_info) {
+ if (!memcmp(irk_info->val, key, 16)) {
+ DBG("Has same irk, delete it");
+ device = btd_adapter_find_device(adapter,
+ &irk_info->bdaddr,
+ irk_info->bdaddr_type);
+ if (device)
+ btd_adapter_remove_device(adapter,
+ device);
+ }
+ }
+ g_key_file_free(key_file);
+ }
+
+ closedir(dir);
+
+}
+
static void new_irk_callback(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
@@ -8950,6 +9017,8 @@ static void new_irk_callback(uint16_t index, uint16_t length,
if (!persistent)
return;
+ delete_existing_irk_from_directory(adapter, irk->val);
+
store_irk(adapter, &addr->bdaddr, addr->type, irk->val);
btd_device_set_temporary(device, false);