From: Denis Kenzior <denkenz@gmail.com>
To: James Prestwood <prestwoj@gmail.com>, iwd@lists.linux.dev
Subject: Re: [PATCH v4 5/8] station: add Affinities DBus property
Date: Tue, 27 Aug 2024 21:57:10 -0500 [thread overview]
Message-ID: <cf53e0e8-4ec4-48ce-8abd-b0c2f2b39d9c@gmail.com> (raw)
In-Reply-To: <20240823222339.328006-5-prestwoj@gmail.com>
Hi James,
On 8/23/24 5:23 PM, James Prestwood wrote:
> This property will hold an array of object paths for
> BasicServiceSet (BSS) objects. For the purpose of this patch
> only the setter/getter and client watch is implemented. The
> purpose of this array is to guide or loosly lock IWD to certain
typo: 'loosely'
> BSS's provided that some external client has more information
> about the environment than what IWD takes into account for its
> roaming decisions.
>
> For the time being, the array is limited to only the connected
> BSS path, and any roams or disconnects will clear the array.
>
> The intended use case for this is if the device is stationary
> an external client could reduce the likelihood of roaming by
> setting the affinity to the current BSS.
> ---
> src/station.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 145 insertions(+)
>
> diff --git a/src/station.c b/src/station.c
> index 30a1232a..c72d42ae 100644
> --- a/src/station.c
> +++ b/src/station.c
> @@ -128,6 +128,10 @@ struct station {
>
> uint64_t last_roam_scan;
>
> + struct l_queue *affinities;
> + unsigned int affinity_watch;
> + char *affinity_client;
> +
> bool preparing_roam : 1;
> bool roam_scan_full : 1;
> bool signal_low : 1;
> @@ -449,6 +453,14 @@ static const char *station_get_bss_path(struct station *station,
> return __network_path_append_bss(network_path, bss);
> }
>
> +static bool match_bss_path(const void *data, const void *user_data)
> +{
> + const char *path1 = data;
> + const char *path2 = user_data;
> +
> + return !strcmp(path1, path2);
> +}
> +
> static bool station_unregister_bss(struct station *station,
> struct scan_bss *bss)
> {
> @@ -457,6 +469,8 @@ static bool station_unregister_bss(struct station *station,
> if (L_WARN_ON(!path))
> return false;
>
> + l_queue_remove_if(station->affinities, match_bss_path, path);
> +
> return l_dbus_unregister_object(dbus_get_bus(), path);
> }
>
> @@ -1740,6 +1754,13 @@ static void station_enter_state(struct station *station,
> station_set_evict_nocarrier(station, true);
> station_set_drop_neighbor_discovery(station, false);
> station_set_drop_unicast_l2_multicast(station, false);
> +
> + if (station->affinity_watch) {
> + l_dbus_remove_watch(dbus_get_bus(),
> + station->affinity_watch);
> + station->affinity_watch = 0;
> + }
> +
Hmm, but not resetting affinities?
> break;
> case STATION_STATE_DISCONNECTING:
> case STATION_STATE_NETCONFIG:
> @@ -1747,6 +1768,12 @@ static void station_enter_state(struct station *station,
> case STATION_STATE_ROAMING:
> case STATION_STATE_FT_ROAMING:
> case STATION_STATE_FW_ROAMING:
> + if (station->affinity_watch) {
> + l_dbus_remove_watch(dbus_get_bus(),
> + station->affinity_watch);
> + station->affinity_watch = 0;
Okay. This reminds me that for hardware supporting FW roaming we may want to
return NotCapable when setting Affinities.
> + }
> +
> station_set_evict_nocarrier(station, false);
> break;
> }
<snip>
> +static void station_affinity_watch_destroy(void *user_data)
> +{
> + struct station *station = user_data;
> +
> + l_free(station->affinity_client);
> + station->affinity_client = NULL;
> +
> + l_queue_destroy(station->affinities, l_free);
> + station->affinities = NULL;
> +
> + l_dbus_property_changed(dbus_get_bus(),
> + netdev_get_path(station->netdev),
> + IWD_STATION_INTERFACE, "Affinities");
What if the list was empty?
> +}
> +
> +static struct l_dbus_message *station_property_set_affinities(
> + struct l_dbus *dbus,
> + struct l_dbus_message *message,
> + struct l_dbus_message_iter *new_value,
> + l_dbus_property_complete_cb_t complete,
> + void *user_data)
> +{
> + struct station *station = user_data;
> + struct l_dbus_message_iter array;
> + const char *sender = l_dbus_message_get_sender(message);
> + const char *path;
> + struct l_queue *new_affinities;
> +
> + if (!station->connected_network)
> + return dbus_error_not_connected(message);
> +
> + if (!station->affinity_watch) {
> + station->affinity_client = l_strdup(sender);
> + station->affinity_watch = l_dbus_add_disconnect_watch(dbus,
> + sender,
> + station_affinity_disconnected_cb,
> + station,
> + station_affinity_watch_destroy);
> + } else if (strcmp(station->affinity_client, sender)) {
> + l_warn("Only one client may manage Affinities property");
> + return dbus_error_not_available(message);
Hmm, we probably need a new error for 'permission denied or something'
> + }
> +
> + if (!l_dbus_message_iter_get_variant(new_value, "ao", &array))
> + return dbus_error_invalid_args(message);
So what happens to affinity_client / affinity_watch above?
> +
> + new_affinities = l_queue_new();
> +
> + while (l_dbus_message_iter_next_entry(&array, &path)) {
> + struct scan_bss *bss = l_dbus_object_get_data(dbus_get_bus(),
> + path,
> + IWD_BSS_INTERFACE);
> +
> + /*
> + * TODO: For now only allow the affinities array to contain the
> + * connected BSS path. Any other values will be rejected.
> + * This could change in the future.
> + */
> + if (bss != station->connected_bss) {
> + l_queue_destroy(new_affinities, l_free);
> + return dbus_error_invalid_args(message);
same as above?
You may want to make your life easier by just looking for an empty list or list
of size 1 with the connected bss.
> + }
> +
> + l_queue_push_head(new_affinities, l_strdup(path));
> + }
> +
> + l_queue_destroy(station->affinities, l_free);
> + station->affinities = new_affinities;
If the list is empty, should you unregister the watch?
> +
> + l_dbus_property_changed(dbus, netdev_get_path(station->netdev),
> + IWD_STATION_INTERFACE, "Affinities");
> +
> + complete(dbus, message, NULL);
It is the other way around, we send the 'message_return' first, then the signal.
Do you want to spuriously emit if the two lists are the same?
> +
> + return NULL;
> +}
> +
> void station_foreach(station_foreach_func_t func, void *user_data)
> {
> const struct l_queue_entry *entry;
Regards,
-Denis
next prev parent reply other threads:[~2024-08-28 2:57 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-23 22:23 [PATCH v4 1/8] doc: Document station Affinities property James Prestwood
2024-08-23 22:23 ` [PATCH v4 2/8] netdev: define netdev settings in netdev.h James Prestwood
2024-08-28 2:44 ` Denis Kenzior
2024-08-23 22:23 ` [PATCH v4 3/8] netdev: store signal threshold in netdev object, not globally James Prestwood
2024-08-23 22:23 ` [PATCH v4 4/8] netdev: add critical signal threshold level James Prestwood
2024-08-23 22:23 ` [PATCH v4 5/8] station: add Affinities DBus property James Prestwood
2024-08-28 2:57 ` Denis Kenzior [this message]
2024-08-23 22:23 ` [PATCH v4 6/8] station: Use Affinities property to change roaming threshold James Prestwood
2024-08-23 22:23 ` [PATCH v4 7/8] auto-t: add affinities property for station, and extended_service_set James Prestwood
2024-08-23 22:23 ` [PATCH v4 8/8] auto-t: add tests for Affinities behavior James Prestwood
2024-08-28 2:39 ` [PATCH v4 1/8] doc: Document station Affinities property 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=cf53e0e8-4ec4-48ce-8abd-b0c2f2b39d9c@gmail.com \
--to=denkenz@gmail.com \
--cc=iwd@lists.linux.dev \
--cc=prestwoj@gmail.com \
/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