public inbox for iwd@lists.linux.dev
 help / color / mirror / Atom feed
From: James Prestwood <prestwoj@gmail.com>
To: iwd@lists.linux.dev
Cc: James Prestwood <prestwoj@gmail.com>
Subject: [PATCH v3 03/13] station: use network_bss_{start,stop}_update
Date: Mon, 12 Aug 2024 08:46:03 -0700	[thread overview]
Message-ID: <20240812154613.126522-3-prestwoj@gmail.com> (raw)
In-Reply-To: <20240812154613.126522-1-prestwoj@gmail.com>

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.
---
 src/station.c | 37 ++++++++++++++++++++++++++++++-------
 1 file changed, 30 insertions(+), 7 deletions(-)

v3:
 * Update use of stop_update() to provide the scan_freq_set. This
   also required using a new struct to pass to process_network()

diff --git a/src/station.c b/src/station.c
index e373b03b..c45b849b 100644
--- a/src/station.c
+++ b/src/station.c
@@ -339,10 +339,18 @@ static void network_free(void *data)
 	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)
 {
 	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)) {
 		bool connected = network == station->connected_network;
@@ -532,6 +540,7 @@ struct bss_expiration_data {
 	struct scan_bss *connected_bss;
 	uint64_t now;
 	const struct scan_freq_set *freqs;
+	struct l_queue *free_list;
 };
 
 #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))
 		return false;
 
-	bss_free(bss);
+	l_queue_push_head(expiration_data->free_list, bss);
 
 	return true;
 }
 
 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 = {
 		.now = l_time_now(),
 		.connected_bss = station->connected_bss,
 		.freqs = freqs,
+		.free_list = free_list,
 	};
 
 	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;
 	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);
 
 	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_destroy(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;
 						bss_entry = bss_entry->next) {
@@ -962,7 +975,12 @@ void station_set_scan_results(struct station *station,
 			if (old_bss == station->connected_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;
 		}
@@ -994,7 +1012,12 @@ void station_set_scan_results(struct station *station,
 
 	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_start(station);
-- 
2.34.1


  parent reply	other threads:[~2024-08-12 15:46 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
2024-08-12 15:46 ` [PATCH v3 02/13] network: Add BasicServiceSet object James Prestwood
2024-08-12 15:46 ` James Prestwood [this message]
2024-08-12 15:46 ` [PATCH v3 04/13] network: add ExtendedServiceSet DBus property James Prestwood
2024-08-12 15:46 ` [PATCH v3 05/13] network: remove network_bss_list_clear James Prestwood
2024-08-12 15:46 ` [PATCH v3 06/13] station: add ConnectedAccessPoint property James Prestwood
2024-08-12 15:46 ` [PATCH v3 07/13] doc: document BasicServiceSet API James Prestwood
2024-08-12 15:46 ` [PATCH v3 08/13] client: separate property header and values into two functions James Prestwood
2024-08-12 15:46 ` [PATCH v3 09/13] client: add net.connman.iwd.BasicServiceSet definition James Prestwood
2024-08-12 15:46 ` [PATCH v3 10/13] client: Add BasicServiceSets property to network James Prestwood
2024-08-12 15:46 ` [PATCH v3 11/13] client: add BasicServiceSet interface James Prestwood
2024-08-12 15:46 ` [PATCH v3 12/13] client: refactor cmd_connect() and add find_network() James Prestwood
2024-08-12 15:46 ` [PATCH v3 13/13] client: add station command "get-bsses" James Prestwood
2024-08-12 17:11 ` [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface Denis Kenzior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240812154613.126522-3-prestwoj@gmail.com \
    --to=prestwoj@gmail.com \
    --cc=iwd@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox