In order to retry a bonding we need a timer that will perform the retry, we need to stash the status and capability of the bonding request so it can use them again. In the case of a retrying bonding attempt we need to not tear down the temporary D-Bus device object on the adapter. --- src/adapter.c | 2 +- src/device.c | 20 ++++++++++++++++++-- src/device.h | 1 + 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/adapter.c b/src/adapter.c index 8c00dc6..498bb49 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -4253,7 +4253,7 @@ static void adapter_remove_connection(struct btd_adapter *adapter, if (device_is_authenticating(device)) device_cancel_authentication(device, TRUE); - if (device_is_temporary(device)) { + if (device_is_temporary(device) && !device_is_retrying(device)) { const char *path = device_get_path(device); DBG("Removing temporary device %s", path); diff --git a/src/device.c b/src/device.c index 8c4b98a..0a39add 100644 --- a/src/device.c +++ b/src/device.c @@ -86,6 +86,9 @@ struct bonding_req { struct btd_device *device; struct agent *agent; struct pincb_iter *cb_iter; + uint8_t capability; + uint8_t status; + guint retry_timer; }; typedef enum { @@ -1400,7 +1403,8 @@ static void device_svc_resolved(struct btd_device *dev, int err) static struct bonding_req *bonding_request_new(DBusMessage *msg, struct btd_device *device, - struct agent *agent) + struct agent *agent, + uint8_t io_cap) { struct bonding_req *bonding; char addr[18]; @@ -1414,6 +1418,8 @@ static struct bonding_req *bonding_request_new(DBusMessage *msg, bonding->cb_iter = pincb_iter_new(device->adapter); + bonding->capability = io_cap; + if (agent) bonding->agent = agent_ref(agent); @@ -1467,7 +1473,7 @@ static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg, else io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT; - bonding = bonding_request_new(msg, device, agent); + bonding = bonding_request_new(msg, device, agent, io_cap); if (agent) agent_unref(agent); @@ -1548,6 +1554,9 @@ static void bonding_request_free(struct bonding_req *bonding) bonding->agent = NULL; } + if (bonding->retry_timer) + g_source_remove(bonding->retry_timer); + if (bonding->device) bonding->device->bonding = NULL; @@ -3594,6 +3603,13 @@ static void device_auth_req_free(struct btd_device *device) device->authr = NULL; } +gboolean device_is_retrying(struct btd_device *device) +{ + struct bonding_req *bonding = device->bonding; + + return bonding && bonding->retry_timer != 0; +} + void device_bonding_complete(struct btd_device *device, uint8_t status) { struct bonding_req *bonding = device->bonding; diff --git a/src/device.h b/src/device.h index 725bd7a..61a294b 100644 --- a/src/device.h +++ b/src/device.h @@ -73,6 +73,7 @@ void device_set_bonded(struct btd_device *device, gboolean bonded); void device_set_legacy(struct btd_device *device, bool legacy); void device_set_rssi(struct btd_device *device, int8_t rssi); gboolean device_is_connected(struct btd_device *device); +gboolean device_is_retrying(struct btd_device *device); void device_bonding_complete(struct btd_device *device, uint8_t status); gboolean device_is_bonding(struct btd_device *device, const char *sender); void device_bonding_failed(struct btd_device *device, uint8_t status); -- 1.8.1.3 -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html