From: James Prestwood <prestwoj@gmail.com>
To: iwd@lists.linux.dev
Cc: James Prestwood <prestwoj@gmail.com>
Subject: [PATCH 2/6] station: move BasicServiceSet DBus management into station
Date: Fri, 16 Aug 2024 05:52:10 -0700 [thread overview]
Message-ID: <20240816125214.1162415-2-prestwoj@gmail.com> (raw)
In-Reply-To: <20240816125214.1162415-1-prestwoj@gmail.com>
Due to an unnoticed bug after adding the BasicServiceSet object into
network, it became clear that since station already owns the scan_bss
objects it makes sense for it to manage the associated DBus objects
as well. This way network doesn't have to jump through hoops to
determine if the scan_bss object was remove, added, or updated. It
can just manage its list as it did prior.
From the station side this makes things very easy. When scan results
come in we either update or add a new DBus object. And any time a
scan_bss is freed we remove the DBus object.
---
src/station.c | 89 +++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 72 insertions(+), 17 deletions(-)
diff --git a/src/station.c b/src/station.c
index 06b19db3..25ddce43 100644
--- a/src/station.c
+++ b/src/station.c
@@ -350,8 +350,6 @@ static bool process_network(const void *key, void *data, void *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;
@@ -431,6 +429,65 @@ static void station_print_scan_bss(const struct scan_bss *bss)
optional);
}
+static const char *station_get_bss_path(struct station *station,
+ struct scan_bss *bss)
+{
+ enum security security;
+ char ssid[33];
+ const char *network_path;
+
+ memcpy(ssid, bss->ssid, bss->ssid_len);
+ ssid[bss->ssid_len] = '\0';
+
+ if (scan_bss_get_security(bss, &security) < 0)
+ return NULL;
+
+ network_path = iwd_network_get_path(station, ssid, security);
+ if (!network_path)
+ return NULL;
+
+ return __network_path_append_bss(network_path, bss);
+}
+
+static bool station_unregister_bss(struct station *station,
+ struct scan_bss *bss)
+{
+ const char *path = station_get_bss_path(station, bss);
+
+ if (L_WARN_ON(!path))
+ return false;
+
+ return l_dbus_unregister_object(dbus_get_bus(), path);
+}
+
+static bool station_register_bss(struct station *station, struct scan_bss *bss)
+{
+ struct scan_bss *old;
+ const char *path = station_get_bss_path(station, bss);
+
+ if (L_WARN_ON(!path))
+ return false;
+
+ /*
+ * If we find this path in the object tree update the data to the new
+ * scan_bss pointer, as this one will be freed soon.
+ */
+ old = l_dbus_object_get_data(dbus_get_bus(), path, IWD_BSS_INTERFACE);
+ if (old)
+ return l_dbus_object_set_data(dbus_get_bus(), path,
+ IWD_BSS_INTERFACE, bss);
+
+ if (!l_dbus_object_add_interface(dbus_get_bus(), path,
+ IWD_BSS_INTERFACE, bss))
+ return false;
+
+ if (!l_dbus_object_add_interface(dbus_get_bus(), path,
+ L_DBUS_INTERFACE_PROPERTIES, bss))
+ return false;
+
+ return true;
+}
+
/*
* Returns the network object the BSS was added to or NULL if ignored.
*/
@@ -518,6 +575,7 @@ static struct network *station_add_seen_bss(struct station *station,
}
network_bss_add(network, bss);
+ station_register_bss(station, bss);
return network;
}
@@ -540,7 +598,7 @@ struct bss_expiration_data {
struct scan_bss *connected_bss;
uint64_t now;
const struct scan_freq_set *freqs;
- struct l_queue *free_list;
+ struct station *station;
};
#define SCAN_RESULT_BSS_RETENTION_TIME (30 * 1000000)
@@ -562,20 +620,21 @@ static bool bss_free_if_expired(void *data, void *user_data)
bss->time_stamp + SCAN_RESULT_BSS_RETENTION_TIME))
return false;
- l_queue_push_head(expiration_data->free_list, bss);
+ station_unregister_bss(expiration_data->station, bss);
+
+ scan_bss_free(bss);
return true;
}
static void station_bss_list_remove_expired_bsses(struct station *station,
- const struct scan_freq_set *freqs,
- struct l_queue *free_list)
+ const struct scan_freq_set *freqs)
{
struct bss_expiration_data data = {
.now = l_time_now(),
.connected_bss = station->connected_bss,
.freqs = freqs,
- .free_list = free_list,
+ .station = station,
};
l_queue_foreach_remove(station->bss_list, bss_free_if_expired, &data);
@@ -823,6 +882,7 @@ static bool station_owe_transition_results(int err, struct l_queue *bss_list,
l_queue_push_tail(station->bss_list, bss);
network_bss_add(network, bss);
+ station_register_bss(station, bss);
continue;
@@ -951,7 +1011,6 @@ 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);
@@ -963,7 +1022,7 @@ void station_set_scan_results(struct station *station,
l_queue_destroy(station->autoconnect_list, NULL);
station->autoconnect_list = NULL;
- station_bss_list_remove_expired_bsses(station, freqs, free_list);
+ station_bss_list_remove_expired_bsses(station, freqs);
for (bss_entry = l_queue_get_entries(station->bss_list); bss_entry;
bss_entry = bss_entry->next) {
@@ -975,12 +1034,8 @@ void station_set_scan_results(struct station *station,
if (old_bss == station->connected_bss)
station->connected_bss = new_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);
+ station_register_bss(station, new_bss);
+ scan_bss_free(old_bss);
continue;
}
@@ -1017,8 +1072,6 @@ void station_set_scan_results(struct station *station,
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);
}
@@ -2652,6 +2705,7 @@ static void station_update_roam_bss(struct station *station,
l_queue_remove_if(station->bss_list, bss_match, bss);
network_bss_update(network, bss);
+ station_register_bss(station, bss);
l_queue_push_tail(station->bss_list, bss);
if (old)
@@ -3160,6 +3214,7 @@ static void station_event_roamed(struct station *station, struct scan_bss *new)
struct scan_bss *stale;
network_bss_update(station->connected_network, new);
+ station_register_bss(station, new);
/* Remove new BSS if it exists in past scan results */
stale = l_queue_remove_if(station->bss_list, bss_match, new);
--
2.34.1
next prev parent reply other threads:[~2024-08-16 12:52 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-16 12:52 [PATCH 1/6] network: add __network_path_append_bss James Prestwood
2024-08-16 12:52 ` James Prestwood [this message]
2024-08-19 15:22 ` [PATCH 2/6] station: move BasicServiceSet DBus management into station Denis Kenzior
2024-08-16 12:52 ` [PATCH 3/6] network: remove BasicServiceSet DBus registration code James Prestwood
2024-08-16 12:52 ` [PATCH 4/6] network: add back network_bss_list_clear James Prestwood
2024-08-16 12:52 ` [PATCH 5/6] auto-t: Add ExtendedServiceSet property James Prestwood
2024-08-16 12:52 ` [PATCH 6/6] auto-t: Add test for BasicServiceSets James Prestwood
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=20240816125214.1162415-2-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