diff --git a/src/device.c b/src/device.c index 680124d6..294efd40 100644 --- a/src/device.c +++ b/src/device.c @@ -794,7 +794,7 @@ static void device_roam_scan(struct device *device, device_roam_failed(device); } -static void device_neighbor_report_cb(struct netdev *netdev, +static void device_neighbor_report_cb(struct netdev *netdev, int err, const uint8_t *reports, size_t reports_len, void *user_data) { @@ -809,10 +809,10 @@ static void device_neighbor_report_cb(struct netdev *netdev, * Check if we're still attempting to roam -- if dbus Disconnect * had been called in the meantime we just abort the attempt. */ - if (!device->preparing_roam) + if (!device->preparing_roam || err == -ENODEV) return; - if (!reports) { + if (!reports || err) { /* Have to do a full scan */ device_roam_scan(device, NULL); diff --git a/src/netdev.c b/src/netdev.c index 7a69a711..7b1a18c6 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -293,11 +293,17 @@ static void netdev_connect_free(struct netdev *netdev) netdev->handshake = NULL; } + if (netdev->neighbor_report_cb) { + netdev->neighbor_report_cb(netdev, -ENOTCONN, NULL, 0, + netdev->user_data); + netdev->neighbor_report_cb = NULL; + l_timeout_remove(netdev->neighbor_report_timeout); + } + netdev->operational = false; netdev->connected = false; netdev->connect_cb = NULL; netdev->event_filter = NULL; - netdev->neighbor_report_cb = NULL; netdev->user_data = NULL; netdev->result = NETDEV_RESULT_OK; netdev->in_ft = false; @@ -358,6 +364,13 @@ static void netdev_free(void *data) l_debug("Freeing netdev %s[%d]", netdev->name, netdev->index); + if (netdev->neighbor_report_cb) { + netdev->neighbor_report_cb(netdev, -ENODEV, NULL, 0, + netdev->user_data); + netdev->neighbor_report_cb = NULL; + l_timeout_remove(netdev->neighbor_report_timeout); + } + if (netdev->connected) { netdev->result = NETDEV_RESULT_ABORTED; netdev_connect_failed(NULL, netdev); @@ -372,9 +385,6 @@ static void netdev_free(void *data) netdev->user_data = NULL; } - if (netdev->neighbor_report_cb) - l_timeout_remove(netdev->neighbor_report_timeout); - device_remove(netdev->device); l_queue_destroy(netdev->watches, l_free); @@ -2270,7 +2280,8 @@ static void netdev_neighbor_report_req_cb(struct l_genl_msg *msg, return; if (l_genl_msg_get_error(msg) < 0) { - netdev->neighbor_report_cb(netdev, NULL, 0, netdev->user_data); + netdev->neighbor_report_cb(netdev, l_genl_msg_get_error(msg), + NULL, 0, netdev->user_data); netdev->neighbor_report_cb = NULL; @@ -2283,9 +2294,12 @@ static void netdev_neighbor_report_timeout(struct l_timeout *timeout, { struct netdev *netdev = user_data; - netdev->neighbor_report_cb(netdev, NULL, 0, netdev->user_data); + netdev->neighbor_report_cb(netdev, -ETIMEDOUT, NULL, 0, + netdev->user_data); netdev->neighbor_report_cb = NULL; + + l_timeout_remove(netdev->neighbor_report_timeout); } int netdev_neighbor_report_req(struct netdev *netdev, @@ -2337,7 +2351,7 @@ static void netdev_radio_measurement_frame_event(struct netdev *netdev, * Report Response received. */ - netdev->neighbor_report_cb(netdev, data + 2, len - 2, + netdev->neighbor_report_cb(netdev, 0, data + 2, len - 2, netdev->user_data); netdev->neighbor_report_cb = NULL; diff --git a/src/netdev.h b/src/netdev.h index f4718dc8..20786988 100644 --- a/src/netdev.h +++ b/src/netdev.h @@ -72,7 +72,7 @@ typedef void (*netdev_destroy_func_t)(void *user_data); typedef void (*netdev_eapol_event_func_t)(unsigned int event, const void *event_data, void *user_data); -typedef void (*netdev_neighbor_report_cb_t)(struct netdev *netdev, +typedef void (*netdev_neighbor_report_cb_t)(struct netdev *netdev, int err, const uint8_t *reports, size_t reports_len, void *user_data);