station: Hide forgotten hidden networks

If we forget a hidden network, then make sure to remove it from the
network list completely.  Otherwise it would be possible to still
issue a Network.Connect to that particular object, but the fact that the
network is hidden would be lost.
This commit is contained in:
Denis Kenzior 2021-02-01 22:43:34 -06:00
parent 68303ae485
commit 06ca8e20a9
4 changed files with 41 additions and 1 deletions

View File

@ -681,6 +681,11 @@ void network_bss_list_clear(struct network *network)
network->bss_list = l_queue_new(); network->bss_list = l_queue_new();
} }
struct scan_bss *network_bss_list_pop(struct network *network)
{
return l_queue_pop_head(network->bss_list);
}
struct scan_bss *network_bss_find_by_addr(struct network *network, struct scan_bss *network_bss_find_by_addr(struct network *network,
const uint8_t *addr) const uint8_t *addr)
{ {
@ -1440,8 +1445,9 @@ static void network_unset_hotspot(struct network *network, void *user_data)
static void emit_known_network_removed(struct station *station, void *user_data) static void emit_known_network_removed(struct station *station, void *user_data)
{ {
struct network_info *info = user_data; struct network_info *info = user_data;
bool was_hidden = info->is_hidden;
struct network *connected_network; struct network *connected_network;
struct network *network; struct network *network = NULL;
/* Clear network info, as this network is no longer known */ /* Clear network info, as this network is no longer known */
if (info->is_hotspot) if (info->is_hotspot)
@ -1457,6 +1463,9 @@ static void emit_known_network_removed(struct station *station, void *user_data)
connected_network = station_get_connected_network(station); connected_network = station_get_connected_network(station);
if (connected_network && connected_network->info == NULL) if (connected_network && connected_network->info == NULL)
station_disconnect(station); station_disconnect(station);
if (network && was_hidden)
station_hide_network(station, network);
} }
static void network_update_hotspot(struct network *network, void *user_data) static void network_update_hotspot(struct network *network, void *user_data)

View File

@ -57,6 +57,7 @@ void network_connect_failed(struct network *network, bool in_handshake);
bool network_bss_add(struct network *network, struct scan_bss *bss); bool network_bss_add(struct network *network, struct scan_bss *bss);
bool network_bss_list_isempty(struct network *network); bool network_bss_list_isempty(struct network *network);
void network_bss_list_clear(struct network *network); void network_bss_list_clear(struct network *network);
struct scan_bss *network_bss_list_pop(struct network *network);
struct scan_bss *network_bss_find_by_addr(struct network *network, struct scan_bss *network_bss_find_by_addr(struct network *network,
const uint8_t *addr); const uint8_t *addr);
struct scan_bss *network_bss_select(struct network *network, struct scan_bss *network_bss_select(struct network *network,

View File

@ -3317,6 +3317,34 @@ struct scan_bss *station_get_connected_bss(struct station *station)
return station->connected_bss; return station->connected_bss;
} }
int station_hide_network(struct station *station, struct network *network)
{
const char *path = network_get_path(network);
struct scan_bss *bss;
l_debug("%s", path);
if (station->connected_network == network)
return -EBUSY;
if (!l_hashmap_lookup(station->networks, path))
return -ENOENT;
l_queue_remove(station->networks_sorted, network);
l_hashmap_remove(station->networks, path);
while ((bss = network_bss_list_pop(network))) {
l_queue_remove_if(station->hidden_bss_list_sorted,
bss_match_bssid, bss->addr);
l_queue_insert(station->hidden_bss_list_sorted, bss,
bss_signal_strength_compare, NULL);
}
network_remove(network, -ESRCH);
return 0;
}
static void station_add_one_freq(uint32_t freq, void *user_data) static void station_add_one_freq(uint32_t freq, void *user_data)
{ {
struct station *station = user_data; struct station *station = user_data;

View File

@ -100,3 +100,5 @@ void station_network_foreach(struct station *station,
void *user_data); void *user_data);
struct l_queue *station_get_bss_list(struct station *station); struct l_queue *station_get_bss_list(struct station *station);
struct scan_bss *station_get_connected_bss(struct station *station); struct scan_bss *station_get_connected_bss(struct station *station);
int station_hide_network(struct station *station, struct network *network);