diff --git a/src/adapter.c b/src/adapter.c
index a75a0c4..6e8552b 100644
--- a/src/adapter.c
+++ b/src/adapter.c
GSList *keys;
};
+static int str2buf(const char *str, uint8_t *buf, size_t blen)
+{
+ int i, dlen;
+
+ if (str == NULL)
+ return -EINVAL;
+
+ memset(buf, 0, blen);
+
+ dlen = MIN((strlen(str) / 2), blen);
+
+ for (i = 0; i < dlen; i++)
+ sscanf(str + (i * 2), "%02hhX", &buf[i]);
+
+ return 0;
+}
+
static struct link_key_info *get_key_info(const char *addr, const char *value)
{
struct link_key_info *info;
return info;
}
+static struct smp_ltk_info *get_ltk_info(const char *addr, const char *value)
+{
+ struct smp_ltk_info *ltk;
+ char *ptr;
+ int i, ret, total;
+
+ total = strlen(value);
+ if (total < 60) {
+ error("Unexpectedly short (%zu) LTK", strlen(value));
+ return NULL;
+ }
+
+ ltk = g_new0(struct smp_ltk_info, 1);
+
+ str2ba(addr, <k->bdaddr);
+
+ str2buf(value, ltk->val, sizeof(ltk->val));
+
+ ptr = (char *) value + 2 * sizeof(ltk->val) + 1;
+ total -= 2 * sizeof(ltk->val) + 1;
+
+ ret = sscanf(ptr, " %hhd %hhd %hhd %hhd %hd %n",
+ (uint8_t *) <k->addr_type,
+ <k->authenticated, <k->master,
+ <k->enc_size, <k->ediv, &i);
+ if (ret < 2) {
+ g_free(ltk);
+ return NULL;
+ }
+ ptr += i;
+ total -= i;
+
+ str2buf(ptr, ltk->rand, sizeof(ltk->rand));
+
+ return ltk;
+}
+
static void create_stored_device_from_linkkeys(char *key, char *value,
void *user_data)
{
}
}
+static void create_stored_device_from_ltks(char *key, char *value,
+ void *user_data)
+{
+ struct adapter_keys *keys = user_data;
+ struct btd_adapter *adapter = keys->adapter;
+ struct btd_device *device;
+ struct smp_ltk_info *info;
+ char srcaddr[18];
+ bdaddr_t src;
+
+ info = get_ltk_info(key, value);
+ if (info)
+ keys->keys = g_slist_append(keys->keys, info);
+
+ if (g_slist_find_custom(adapter->devices, key,
+ (GCompareFunc) device_address_cmp))
+ return;
+
+ adapter_get_address(adapter, &src);
+ ba2str(&src, srcaddr);
+
+ if (g_strcmp0(srcaddr, key) == 0)
+ return;
+
+ device = device_create(connection, adapter, key, info->addr_type);
+ if (device) {
+ device_set_temporary(device, FALSE);
+ adapter->devices = g_slist_append(adapter->devices, device);
+ }
+}
+
static void create_stored_device_from_blocked(char *key, char *value,
void *user_data)
{
g_slist_free(uuids);
}
+static void smp_key_free(void *data)
+{
+ struct smp_ltk_info *info = data;
+
+ g_free(info);
+}
+
static void load_devices(struct btd_adapter *adapter)
{
char filename[PATH_MAX + 1];
err = adapter_ops->load_keys(adapter->dev_id, keys.keys,
main_opts.debug_keys);
- if (err < 0) {
+ if (err < 0)
error("Unable to load keys to adapter_ops: %s (%d)",
strerror(-err), -err);
- g_slist_free_full(keys.keys, g_free);
- }
+
+ g_slist_free_full(keys.keys, g_free);
+ keys.keys = NULL;
+
+ create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "longtermkeys");
+ textfile_foreach(filename, create_stored_device_from_ltks, &keys);
+
+ err = adapter_ops->load_ltks(adapter->dev_id, keys.keys);
+ if (err < 0)
+ error("Unable to load keys to adapter_ops: %s (%d)",
+ strerror(-err), -err);
+ g_slist_free_full(keys.keys, smp_key_free);
+ keys.keys = NULL;
create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "blocked");
textfile_foreach(filename, create_stored_device_from_blocked, adapter);