From 2f34c87820921098f89ec292ff9a38b48f89d4c7 Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Mon, 23 Jan 2017 12:38:39 +0100 Subject: [PATCH] device: Transition to selected BSS if FT supported With this patch an actual fast transition should happen when the signal strength goes low but there are still various details to be fixed before this becomes useful: * the kernel tends to return cached scan results and won't update the rssi values, * there's no timer to prevent too frequent transition attempts or to retry after some time if the signal is still low, * no candidate other than the top ranked BSS is tried. With FT it may be impossible to try another BSS anyway although there isn't anything in the spec to imply this. It would require keeping the handshake_state around after netdev gives up on the transition attempt. --- src/device.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/device.c b/src/device.c index bc6301ea..680124d6 100644 --- a/src/device.c +++ b/src/device.c @@ -580,8 +580,61 @@ static void device_roam_failed(struct device *device) device_disassociated(device); } +static void device_fast_transition_cb(struct netdev *netdev, + enum netdev_result result, + void *user_data) +{ + struct device *device = user_data; + + l_debug("%d, result: %d", device->index, result); + + if (device->state != DEVICE_STATE_ROAMING) + return; + + if (result == NETDEV_RESULT_OK) + device_enter_state(device, DEVICE_STATE_CONNECTED); + else + device_roam_failed(device); +} + static void device_transition_start(struct device *device, struct scan_bss *bss) { + struct handshake_state *hs = netdev_get_handshake(device->netdev); + uint16_t mdid; + + l_debug("%d, target %s", device->index, + util_address_to_string(bss->addr)); + + if (hs->mde) + ie_parse_mobility_domain_from_data(hs->mde, hs->mde[1] + 2, + &mdid, NULL, NULL); + + /* Can we use Fast Transition? */ + if (hs->mde && bss->mde_present && l_get_le16(bss->mde) == mdid) { + /* + * There's no need to regenerate the RSNE because neither + * the AKM nor cipher suite can change: + * + * 12.5.2: "If the FTO selects a pairwise cipher suite in + * the RSNE that is different from the ones used in the + * Initial mobility domain association, then the AP shall + * reject the Authentication Request with status code 19 + * (i.e., Invalid Pairwise Cipher)." + */ + if (netdev_fast_transition(device->netdev, bss, + device_fast_transition_cb) < 0) { + device_roam_failed(device); + return; + } + + device->connected_bss = bss; + device->preparing_roam = false; + device_enter_state(device, DEVICE_STATE_ROAMING); + + return; + } + + /* Non-FT transition not supported yet */ device_roam_failed(device); }