diff --git a/src/adapter.c b/src/adapter.c
index c7c0ce0..629732b 100644
--- a/src/adapter.c
+++ b/src/adapter.c
GSList *profiles;
struct oob_handler *oob_handler;
+
+ unsigned int load_ltks_id;
+ guint load_ltks_timeout;
};
static struct btd_adapter *btd_adapter_lookup(uint16_t index)
DBG("link keys loaded for hci%u", adapter->dev_id);
}
-static int load_link_keys(struct btd_adapter *adapter, GSList *keys,
+static void load_link_keys(struct btd_adapter *adapter, GSList *keys,
bool debug_keys)
{
struct mgmt_cp_load_link_keys *cp;
cp_size = sizeof(*cp) + (key_count * sizeof(*key));
cp = g_try_malloc0(cp_size);
- if (cp == NULL)
- return -ENOMEM;
+ if (cp == NULL) {
+ error("No memory for link keys for hci%u", adapter->dev_id);
+ return;
+ }
cp->debug_keys = debug_keys;
cp->key_count = htobs(key_count);
g_free(cp);
- if (id == 0) {
+ if (id == 0)
error("Failed to load link keys for hci%u", adapter->dev_id);
- return -EIO;
- }
+}
- return 0;
+static gboolean load_ltks_timeout(gpointer user_data)
+{
+ struct btd_adapter *adapter = user_data;
+
+ error("Loading LTKs timed out for hci%u", adapter->dev_id);
+
+ adapter->load_ltks_timeout = 0;
+
+ mgmt_cancel(adapter->mgmt, adapter->load_ltks_id);
+ adapter->load_ltks_id = 0;
+
+ return FALSE;
}
-#if 0
static void load_ltks_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
if (status != MGMT_STATUS_SUCCESS) {
error("Failed to load LTKs for hci%u: %s (0x%02x)",
adapter->dev_id, mgmt_errstr(status), status);
- return;
}
+ adapter->load_ltks_id = 0;
+
+ g_source_remove(adapter->load_ltks_timeout);
+ adapter->load_ltks_timeout = 0;
+
DBG("LTKs loaded for hci%u", adapter->dev_id);
}
-static int load_ltks(struct btd_adapter *adapter, GSList *keys)
+static void load_ltks(struct btd_adapter *adapter, GSList *keys)
{
struct mgmt_cp_load_long_term_keys *cp;
struct mgmt_ltk_info *key;
size_t key_count, cp_size;
- unsigned int id;
GSList *l;
key_count = g_slist_length(keys);
cp_size = sizeof(*cp) + (key_count * sizeof(*key));
cp = g_try_malloc0(cp_size);
- if (cp == NULL)
- return -ENOMEM;
+ if (cp == NULL) {
+ error("No memory for LTKs for hci%u", adapter->dev_id);
+ return;
+ }
cp->key_count = htobs(key_count);
key->enc_size = info->enc_size;
}
- id = mgmt_send(adapter->mgmt, MGMT_OP_LOAD_LONG_TERM_KEYS,
- adapter->dev_id, cp_size, cp,
- load_ltks_complete, adapter, NULL);
+ adapter->load_ltks_id = mgmt_send(adapter->mgmt,
+ MGMT_OP_LOAD_LONG_TERM_KEYS,
+ adapter->dev_id, cp_size, cp,
+ load_ltks_complete, adapter, NULL);
g_free(cp);
- if (id == 0) {
+ if (adapter->load_ltks_id == 0) {
error("Failed to load LTKs for hci%u", adapter->dev_id);
- return -EIO;
+ return;
}
- return 0;
+ /*
+ * This timeout handling is needed since the kernel is stupid
+ * and forgets to send a command complete response. However in
+ * case of failures it does send a command status.
+ */
+ adapter->load_ltks_timeout = g_timeout_add_seconds(2,
+ load_ltks_timeout, adapter);
}
-#endif
static void load_devices(struct btd_adapter *adapter)
{
char srcaddr[18];
struct adapter_keys keys = { adapter, NULL };
struct adapter_keys ltks = { adapter, NULL };
- int err;
DIR *dir;
struct dirent *entry;
closedir(dir);
- err = load_link_keys(adapter, keys.keys, main_opts.debug_keys);
- if (err < 0)
- error("Unable to load link keys: %s (%d)",
- strerror(-err), -err);
-
+ load_link_keys(adapter, keys.keys, main_opts.debug_keys);
g_slist_free_full(keys.keys, g_free);
-#if 0
- err = load_ltks(adapter, ltks.keys);
- if (err < 0)
- error("Unable to load ltks: %s (%d)", strerror(-err), -err);
-#endif
-
+ load_ltks(adapter, ltks.keys);
g_slist_free_full(ltks.keys, g_free);
}
DBG("%p", adapter);
+ if (adapter->load_ltks_timeout > 0)
+ g_source_remove(adapter->load_ltks_timeout);
+
if (adapter->auth_idle_id)
g_source_remove(adapter->auth_idle_id);