diff --git a/plugins/hciops.c b/plugins/hciops.c
index 3329d49..d4d219c 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
return 0;
}
+static int hciops_load_ltks(int index, GSList *keys)
+{
+ return -ENOSYS;
+}
+
static struct btd_adapter_ops hci_ops = {
.setup = hciops_setup,
.cleanup = hciops_cleanup,
.add_remote_oob_data = hciops_add_remote_oob_data,
.remove_remote_oob_data = hciops_remove_remote_oob_data,
.confirm_name = hciops_confirm_name,
+ .load_ltks = hciops_load_ltks,
};
static int hciops_init(void)
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index 25bff57..b409569 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
return 0;
}
+static int mgmtops_load_ltks(int index, GSList *keys)
+{
+ char *buf;
+ struct mgmt_hdr *hdr;
+ struct mgmt_cp_load_long_term_keys *cp;
+ struct mgmt_ltk_info *key;
+ size_t key_count, cp_size;
+ GSList *l;
+ int err;
+
+ key_count = g_slist_length(keys);
+
+ DBG("index %d keys %zu", index, key_count);
+
+ cp_size = sizeof(*cp) + (key_count * sizeof(*key));
+
+ buf = g_try_malloc0(sizeof(*hdr) + cp_size);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ memset(buf, 0, sizeof(buf));
+
+ hdr = (void *) buf;
+ hdr->opcode = htobs(MGMT_OP_LOAD_LONG_TERM_KEYS);
+ hdr->len = htobs(cp_size);
+ hdr->index = htobs(index);
+
+ cp = (void *) (buf + sizeof(*hdr));
+ cp->key_count = htobs(key_count);
+
+ for (l = keys, key = cp->keys; l != NULL; l = g_slist_next(l), key++) {
+ struct smp_ltk_info *info = l->data;
+
+ bacpy(&key->addr.bdaddr, &info->bdaddr);
+ key->addr.type = info->addr_type;
+ memcpy(key->val, info->val, sizeof(info->val));
+ memcpy(key->rand, info->rand, sizeof(info->rand));
+ memcpy(&key->ediv, &info->ediv, sizeof(key->ediv));
+ key->authenticated = info->authenticated;
+ key->master = info->master;
+ key->enc_size = info->enc_size;
+ }
+
+ if (write(mgmt_sock, buf, sizeof(*hdr) + cp_size) < 0)
+ err = -errno;
+ else
+ err = 0;
+
+ g_free(buf);
+
+ return err;
+}
+
static struct btd_adapter_ops mgmt_ops = {
.setup = mgmt_setup,
.cleanup = mgmt_cleanup,
.add_remote_oob_data = mgmt_add_remote_oob_data,
.remove_remote_oob_data = mgmt_remove_remote_oob_data,
.confirm_name = mgmt_confirm_name,
+ .load_ltks = mgmtops_load_ltks,
};
static int mgmt_init(void)
diff --git a/src/adapter.h b/src/adapter.h
index c17cf0c..c1f981a 100644
--- a/src/adapter.h
+++ b/src/adapter.h
uint8_t pin_len;
};
+struct smp_ltk_info {
+ bdaddr_t bdaddr;
+ addr_type_t addr_type;
+ uint8_t authenticated;
+ uint8_t master;
+ uint8_t enc_size;
+ uint16_t ediv;
+ uint8_t rand[8];
+ uint8_t val[16];
+};
+
struct remote_dev_info {
bdaddr_t bdaddr;
addr_type_t type;
uint8_t *randomizer);
int (*remove_remote_oob_data) (int index, bdaddr_t *bdaddr);
int (*confirm_name) (int index, bdaddr_t *bdaddr, gboolean name_known);
+ int (*load_ltks) (int index, GSList *keys);
};
int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority);