mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-21 22:09:23 +01:00
station: use network_bss_{start,stop}_update
This will tell network the BSS list is being updated and it can act accordingly as far as the BSS DBus registrations/unregistration. In addition any scan_bss object needing to be freed has to wait until after network_bss_stop_update() because network has to be able to iterate its old list and unregister any BSS's that were not seen in the scan results. This is done by pushing each BSS needing to be freed into a queue, then destroying them after the BSS's are all added.
This commit is contained in:
parent
fe2a91ae11
commit
560ad581ad
@ -339,10 +339,18 @@ static void network_free(void *data)
|
|||||||
network_remove(network, -ESHUTDOWN);
|
network_remove(network, -ESHUTDOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct process_network_data {
|
||||||
|
struct station *station;
|
||||||
|
const struct scan_freq_set *freqs;
|
||||||
|
};
|
||||||
|
|
||||||
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;
|
||||||
struct station *station = user_data;
|
struct process_network_data *process_data = user_data;
|
||||||
|
struct station *station = process_data->station;
|
||||||
|
|
||||||
|
network_bss_stop_update(network, process_data->freqs);
|
||||||
|
|
||||||
if (!network_bss_list_isempty(network)) {
|
if (!network_bss_list_isempty(network)) {
|
||||||
bool connected = network == station->connected_network;
|
bool connected = network == station->connected_network;
|
||||||
@ -532,6 +540,7 @@ struct bss_expiration_data {
|
|||||||
struct scan_bss *connected_bss;
|
struct scan_bss *connected_bss;
|
||||||
uint64_t now;
|
uint64_t now;
|
||||||
const struct scan_freq_set *freqs;
|
const struct scan_freq_set *freqs;
|
||||||
|
struct l_queue *free_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCAN_RESULT_BSS_RETENTION_TIME (30 * 1000000)
|
#define SCAN_RESULT_BSS_RETENTION_TIME (30 * 1000000)
|
||||||
@ -553,18 +562,20 @@ static bool bss_free_if_expired(void *data, void *user_data)
|
|||||||
bss->time_stamp + SCAN_RESULT_BSS_RETENTION_TIME))
|
bss->time_stamp + SCAN_RESULT_BSS_RETENTION_TIME))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bss_free(bss);
|
l_queue_push_head(expiration_data->free_list, bss);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void station_bss_list_remove_expired_bsses(struct station *station,
|
static void station_bss_list_remove_expired_bsses(struct station *station,
|
||||||
const struct scan_freq_set *freqs)
|
const struct scan_freq_set *freqs,
|
||||||
|
struct l_queue *free_list)
|
||||||
{
|
{
|
||||||
struct bss_expiration_data data = {
|
struct bss_expiration_data data = {
|
||||||
.now = l_time_now(),
|
.now = l_time_now(),
|
||||||
.connected_bss = station->connected_bss,
|
.connected_bss = station->connected_bss,
|
||||||
.freqs = freqs,
|
.freqs = freqs,
|
||||||
|
.free_list = free_list,
|
||||||
};
|
};
|
||||||
|
|
||||||
l_queue_foreach_remove(station->bss_list, bss_free_if_expired, &data);
|
l_queue_foreach_remove(station->bss_list, bss_free_if_expired, &data);
|
||||||
@ -939,18 +950,20 @@ void station_set_scan_results(struct station *station,
|
|||||||
{
|
{
|
||||||
const struct l_queue_entry *bss_entry;
|
const struct l_queue_entry *bss_entry;
|
||||||
struct network *network;
|
struct network *network;
|
||||||
|
struct process_network_data data;
|
||||||
|
struct l_queue *free_list = l_queue_new();
|
||||||
|
|
||||||
l_queue_foreach_remove(new_bss_list, bss_free_if_ssid_not_utf8, NULL);
|
l_queue_foreach_remove(new_bss_list, bss_free_if_ssid_not_utf8, NULL);
|
||||||
|
|
||||||
while ((network = l_queue_pop_head(station->networks_sorted)))
|
while ((network = l_queue_pop_head(station->networks_sorted)))
|
||||||
network_bss_list_clear(network);
|
network_bss_start_update(network);
|
||||||
|
|
||||||
l_queue_clear(station->hidden_bss_list_sorted, NULL);
|
l_queue_clear(station->hidden_bss_list_sorted, NULL);
|
||||||
|
|
||||||
l_queue_destroy(station->autoconnect_list, NULL);
|
l_queue_destroy(station->autoconnect_list, NULL);
|
||||||
station->autoconnect_list = NULL;
|
station->autoconnect_list = NULL;
|
||||||
|
|
||||||
station_bss_list_remove_expired_bsses(station, freqs);
|
station_bss_list_remove_expired_bsses(station, freqs, free_list);
|
||||||
|
|
||||||
for (bss_entry = l_queue_get_entries(station->bss_list); bss_entry;
|
for (bss_entry = l_queue_get_entries(station->bss_list); bss_entry;
|
||||||
bss_entry = bss_entry->next) {
|
bss_entry = bss_entry->next) {
|
||||||
@ -962,7 +975,12 @@ void station_set_scan_results(struct station *station,
|
|||||||
if (old_bss == station->connected_bss)
|
if (old_bss == station->connected_bss)
|
||||||
station->connected_bss = new_bss;
|
station->connected_bss = new_bss;
|
||||||
|
|
||||||
bss_free(old_bss);
|
/*
|
||||||
|
* The network object is still holding a reference to
|
||||||
|
* the BSS. Until we tell network to replace the BSS
|
||||||
|
* with a new object, don't free it.
|
||||||
|
*/
|
||||||
|
l_queue_push_head(free_list, old_bss);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -994,7 +1012,12 @@ void station_set_scan_results(struct station *station,
|
|||||||
|
|
||||||
station->bss_list = new_bss_list;
|
station->bss_list = new_bss_list;
|
||||||
|
|
||||||
l_hashmap_foreach_remove(station->networks, process_network, station);
|
data.station = station;
|
||||||
|
data.freqs = freqs;
|
||||||
|
|
||||||
|
l_hashmap_foreach_remove(station->networks, process_network, &data);
|
||||||
|
|
||||||
|
l_queue_destroy(free_list, bss_free);
|
||||||
|
|
||||||
station->autoconnect_can_start = trigger_autoconnect;
|
station->autoconnect_can_start = trigger_autoconnect;
|
||||||
station_autoconnect_start(station);
|
station_autoconnect_start(station);
|
||||||
|
Loading…
Reference in New Issue
Block a user