mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-26 18:49:43 +01:00
station: Move autoconnect logic from device
This commit is contained in:
parent
977b817f3c
commit
9b574b5931
68
src/device.c
68
src/device.c
@ -48,12 +48,6 @@
|
|||||||
#include "src/adhoc.h"
|
#include "src/adhoc.h"
|
||||||
#include "src/station.h"
|
#include "src/station.h"
|
||||||
|
|
||||||
struct autoconnect_entry {
|
|
||||||
uint16_t rank;
|
|
||||||
struct network *network;
|
|
||||||
struct scan_bss *bss;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct device {
|
struct device {
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
enum device_state state;
|
enum device_state state;
|
||||||
@ -64,7 +58,6 @@ struct device {
|
|||||||
struct l_queue *networks_sorted;
|
struct l_queue *networks_sorted;
|
||||||
struct scan_bss *connected_bss;
|
struct scan_bss *connected_bss;
|
||||||
struct network *connected_network;
|
struct network *connected_network;
|
||||||
struct l_queue *autoconnect_list;
|
|
||||||
struct l_dbus_message *connect_pending;
|
struct l_dbus_message *connect_pending;
|
||||||
struct l_dbus_message *disconnect_pending;
|
struct l_dbus_message *disconnect_pending;
|
||||||
struct watchlist state_watches;
|
struct watchlist state_watches;
|
||||||
@ -156,28 +149,6 @@ static const char *device_state_to_string(enum device_state state)
|
|||||||
return "invalid";
|
return "invalid";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_autoconnect_next(struct device *device)
|
|
||||||
{
|
|
||||||
struct autoconnect_entry *entry;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
while ((entry = l_queue_pop_head(device->autoconnect_list))) {
|
|
||||||
l_debug("Considering autoconnecting to BSS '%s' with SSID: %s,"
|
|
||||||
" freq: %u, rank: %u, strength: %i",
|
|
||||||
util_address_to_string(entry->bss->addr),
|
|
||||||
network_get_ssid(entry->network),
|
|
||||||
entry->bss->frequency, entry->rank,
|
|
||||||
entry->bss->signal_strength);
|
|
||||||
|
|
||||||
/* TODO: Blacklist the network from auto-connect */
|
|
||||||
r = network_autoconnect(entry->network, entry->bss);
|
|
||||||
l_free(entry);
|
|
||||||
|
|
||||||
if (!r)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bss_free(void *data)
|
static void bss_free(void *data)
|
||||||
{
|
{
|
||||||
struct scan_bss *bss = data;
|
struct scan_bss *bss = data;
|
||||||
@ -196,14 +167,6 @@ static void network_free(void *data)
|
|||||||
network_remove(network, -ESHUTDOWN);
|
network_remove(network, -ESHUTDOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int autoconnect_rank_compare(const void *a, const void *b, void *user)
|
|
||||||
{
|
|
||||||
const struct autoconnect_entry *new_ae = a;
|
|
||||||
const struct autoconnect_entry *ae = b;
|
|
||||||
|
|
||||||
return ae->rank - new_ae->rank;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool process_network(const void *key, void *data, void *user_data)
|
static bool process_network(const void *key, void *data, void *user_data)
|
||||||
{
|
{
|
||||||
struct network *network = data;
|
struct network *network = data;
|
||||||
@ -227,24 +190,6 @@ static bool process_network(const void *key, void *data, void *user_data)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_autoconnect_bss(struct device *device, struct network *network,
|
|
||||||
struct scan_bss *bss)
|
|
||||||
{
|
|
||||||
double rankmod;
|
|
||||||
struct autoconnect_entry *entry;
|
|
||||||
|
|
||||||
/* See if network is autoconnectable (is a known network) */
|
|
||||||
if (!network_rankmod(network, &rankmod))
|
|
||||||
return;
|
|
||||||
|
|
||||||
entry = l_new(struct autoconnect_entry, 1);
|
|
||||||
entry->network = network;
|
|
||||||
entry->bss = bss;
|
|
||||||
entry->rank = bss->rank * rankmod;
|
|
||||||
l_queue_insert(device->autoconnect_list, entry,
|
|
||||||
autoconnect_rank_compare, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the network object the BSS was added to or NULL if ignored.
|
* Returns the network object the BSS was added to or NULL if ignored.
|
||||||
*/
|
*/
|
||||||
@ -335,8 +280,8 @@ void device_set_scan_results(struct device *device, struct l_queue *bss_list,
|
|||||||
while ((network = l_queue_pop_head(device->networks_sorted)))
|
while ((network = l_queue_pop_head(device->networks_sorted)))
|
||||||
network_bss_list_clear(network);
|
network_bss_list_clear(network);
|
||||||
|
|
||||||
l_queue_destroy(device->autoconnect_list, l_free);
|
l_queue_destroy(device->station->autoconnect_list, l_free);
|
||||||
device->autoconnect_list = l_queue_new();
|
device->station->autoconnect_list = l_queue_new();
|
||||||
|
|
||||||
for (bss_entry = l_queue_get_entries(bss_list); bss_entry;
|
for (bss_entry = l_queue_get_entries(bss_list); bss_entry;
|
||||||
bss_entry = bss_entry->next) {
|
bss_entry = bss_entry->next) {
|
||||||
@ -344,7 +289,8 @@ void device_set_scan_results(struct device *device, struct l_queue *bss_list,
|
|||||||
struct network *network = add_seen_bss(device, bss);
|
struct network *network = add_seen_bss(device, bss);
|
||||||
|
|
||||||
if (network && add_to_autoconnect)
|
if (network && add_to_autoconnect)
|
||||||
add_autoconnect_bss(device, network, bss);
|
station_add_autoconnect_bss(device->station,
|
||||||
|
network, bss);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->connected_bss) {
|
if (device->connected_bss) {
|
||||||
@ -395,7 +341,7 @@ static bool new_scan_results(uint32_t wiphy_id, uint32_t ifindex, int err,
|
|||||||
device_set_scan_results(device, bss_list, autoconnect);
|
device_set_scan_results(device, bss_list, autoconnect);
|
||||||
|
|
||||||
if (autoconnect)
|
if (autoconnect)
|
||||||
device_autoconnect_next(device);
|
station_autoconnect_next(device->station);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2381,9 +2327,6 @@ static void device_netdev_notify(struct netdev *netdev,
|
|||||||
l_hashmap_foreach_remove(device->networks,
|
l_hashmap_foreach_remove(device->networks,
|
||||||
device_remove_network, device);
|
device_remove_network, device);
|
||||||
|
|
||||||
l_queue_destroy(device->autoconnect_list, l_free);
|
|
||||||
device->autoconnect_list = l_queue_new();
|
|
||||||
|
|
||||||
l_queue_destroy(device->bss_list, bss_free);
|
l_queue_destroy(device->bss_list, bss_free);
|
||||||
device->bss_list = l_queue_new();
|
device->bss_list = l_queue_new();
|
||||||
|
|
||||||
@ -2487,7 +2430,6 @@ static void device_free(void *user)
|
|||||||
|
|
||||||
l_queue_destroy(device->bss_list, bss_free);
|
l_queue_destroy(device->bss_list, bss_free);
|
||||||
l_queue_destroy(device->old_bss_list, bss_free);
|
l_queue_destroy(device->old_bss_list, bss_free);
|
||||||
l_queue_destroy(device->autoconnect_list, l_free);
|
|
||||||
|
|
||||||
l_timeout_remove(device->roam_trigger_timeout);
|
l_timeout_remove(device->roam_trigger_timeout);
|
||||||
|
|
||||||
|
@ -41,6 +41,61 @@
|
|||||||
|
|
||||||
static struct l_queue *station_list;
|
static struct l_queue *station_list;
|
||||||
|
|
||||||
|
struct autoconnect_entry {
|
||||||
|
uint16_t rank;
|
||||||
|
struct network *network;
|
||||||
|
struct scan_bss *bss;
|
||||||
|
};
|
||||||
|
|
||||||
|
void station_autoconnect_next(struct station *station)
|
||||||
|
{
|
||||||
|
struct autoconnect_entry *entry;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
while ((entry = l_queue_pop_head(station->autoconnect_list))) {
|
||||||
|
l_debug("Considering autoconnecting to BSS '%s' with SSID: %s,"
|
||||||
|
" freq: %u, rank: %u, strength: %i",
|
||||||
|
util_address_to_string(entry->bss->addr),
|
||||||
|
network_get_ssid(entry->network),
|
||||||
|
entry->bss->frequency, entry->rank,
|
||||||
|
entry->bss->signal_strength);
|
||||||
|
|
||||||
|
/* TODO: Blacklist the network from auto-connect */
|
||||||
|
r = network_autoconnect(entry->network, entry->bss);
|
||||||
|
l_free(entry);
|
||||||
|
|
||||||
|
if (!r)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int autoconnect_rank_compare(const void *a, const void *b, void *user)
|
||||||
|
{
|
||||||
|
const struct autoconnect_entry *new_ae = a;
|
||||||
|
const struct autoconnect_entry *ae = b;
|
||||||
|
|
||||||
|
return ae->rank - new_ae->rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
void station_add_autoconnect_bss(struct station *station,
|
||||||
|
struct network *network,
|
||||||
|
struct scan_bss *bss)
|
||||||
|
{
|
||||||
|
double rankmod;
|
||||||
|
struct autoconnect_entry *entry;
|
||||||
|
|
||||||
|
/* See if network is autoconnectable (is a known network) */
|
||||||
|
if (!network_rankmod(network, &rankmod))
|
||||||
|
return;
|
||||||
|
|
||||||
|
entry = l_new(struct autoconnect_entry, 1);
|
||||||
|
entry->network = network;
|
||||||
|
entry->bss = bss;
|
||||||
|
entry->rank = bss->rank * rankmod;
|
||||||
|
l_queue_insert(station->autoconnect_list, entry,
|
||||||
|
autoconnect_rank_compare, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static enum ie_rsn_akm_suite select_akm_suite(struct network *network,
|
static enum ie_rsn_akm_suite select_akm_suite(struct network *network,
|
||||||
struct scan_bss *bss,
|
struct scan_bss *bss,
|
||||||
struct ie_rsn_info *info)
|
struct ie_rsn_info *info)
|
||||||
@ -264,6 +319,8 @@ void station_free(struct station *station)
|
|||||||
if (!l_queue_remove(station_list, station))
|
if (!l_queue_remove(station_list, station))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
l_queue_destroy(station->autoconnect_list, l_free);
|
||||||
|
|
||||||
l_free(station);
|
l_free(station);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,11 +30,17 @@ struct network;
|
|||||||
|
|
||||||
struct station {
|
struct station {
|
||||||
struct network *connected_network;
|
struct network *connected_network;
|
||||||
|
struct l_queue *autoconnect_list;
|
||||||
|
|
||||||
struct wiphy *wiphy;
|
struct wiphy *wiphy;
|
||||||
struct netdev *netdev;
|
struct netdev *netdev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void station_autoconnect_next(struct station *station);
|
||||||
|
void station_add_autoconnect_bss(struct station *station,
|
||||||
|
struct network *network,
|
||||||
|
struct scan_bss *bss);
|
||||||
|
|
||||||
struct handshake_state *station_handshake_setup(struct station *station,
|
struct handshake_state *station_handshake_setup(struct station *station,
|
||||||
struct network *network,
|
struct network *network,
|
||||||
struct scan_bss *bss);
|
struct scan_bss *bss);
|
||||||
|
Loading…
Reference in New Issue
Block a user