From 94aba17968a201b346d308f29e5fe163cab24e99 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Mon, 22 Jun 2015 18:33:55 -0500 Subject: [PATCH] wiphy: Add auto-connect logic --- src/wiphy.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/wiphy.c b/src/wiphy.c index 2d9f51ee..a4170003 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -932,6 +932,81 @@ static bool netdev_match(const void *a, const void *b) return (netdev->index == index); } +static bool netdev_try_autoconnect(struct netdev *netdev, + struct network *network, + struct scan_bss *bss) +{ + struct wiphy *wiphy = netdev->wiphy; + + switch (network->ssid_security) { + case SCAN_SSID_SECURITY_NONE: + break; + case SCAN_SSID_SECURITY_PSK: + { + uint16_t pairwise_ciphers, group_ciphers; + const char *psk; + size_t len; + + bss_get_supported_ciphers(bss, + &pairwise_ciphers, &group_ciphers); + + if (!wiphy_select_cipher(wiphy, pairwise_ciphers) || + !wiphy_select_cipher(wiphy, group_ciphers)) { + l_debug("Cipher mis-match"); + return false; + } + + if (network->ask_psk) + return false; + + network->settings = storage_network_open("psk", network->ssid); + psk = l_settings_get_value(network->settings, "Security", + "PreSharedKey"); + + /* TODO: Blacklist the network from auto-connect */ + if (!psk) + return false; + + l_free(network->psk); + network->psk = l_util_from_hexstring(psk, &len); + + if (network->psk && len != 32) { + l_free(network->psk); + network->psk = NULL; + return false; + } + + break; + } + default: + return false; + } + + mlme_authenticate_cmd(network, bss); + return true; +} + +static void netdev_autoconnect_next(struct netdev *netdev) +{ + struct autoconnect_entry *entry; + bool r; + + while ((entry = l_queue_pop_head(netdev->autoconnect_list))) { + l_debug("Considering autoconnecting to BSS '%s' with SSID: %s," + " freq: %u, rank: %u, strength: %i", + bss_address_to_string(entry->bss), + entry->network->ssid, + entry->bss->frequency, entry->rank, + entry->bss->signal_strength); + + r = netdev_try_autoconnect(netdev, entry->network, entry->bss); + l_free(entry); + + if (r) + return; + } +} + static void wiphy_free(void *data) { struct wiphy *wiphy = data; @@ -1725,6 +1800,9 @@ static bool new_scan_results(uint32_t wiphy_id, uint32_t ifindex, l_queue_destroy(netdev->old_bss_list, bss_free); netdev->old_bss_list = NULL; + if (netdev->state == NETDEV_STATE_AUTOCONNECT) + netdev_autoconnect_next(netdev); + return true; }