All of lore.kernel.org
 help / color / mirror / Atom feed
From: James Prestwood <prestwoj@gmail.com>
To: iwd@lists.01.org
Subject: [PATCH v2 2/4] station: add ConnectBssid() developer method
Date: Mon, 09 Aug 2021 10:16:14 -0700	[thread overview]
Message-ID: <20210809171616.535514-2-prestwoj@gmail.com> (raw)
In-Reply-To: <20210809171616.535514-1-prestwoj@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 6262 bytes --]

This method will initiate a connection to a specific BSS rather
than relying on a network based connection (which the user has
no control over which specific BSS is selected).
---
 src/station.c | 129 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 111 insertions(+), 18 deletions(-)

diff --git a/src/station.c b/src/station.c
index bc4e7539..9a053c85 100644
--- a/src/station.c
+++ b/src/station.c
@@ -286,6 +286,34 @@ static int bss_signal_strength_compare(const void *a, const void *b, void *user)
 	return (bss->signal_strength > new_bss->signal_strength) ? 1 : -1;
 }
 
+static int station_parse_bss(struct station *station,
+				struct scan_bss *bss, char *ssid_out,
+				enum security *security_out,
+				char *path_out)
+{
+	struct ie_rsn_info info;
+	const char *path;
+	int r;
+
+	r = scan_bss_get_rsn_info(bss, &info);
+	if (r < 0) {
+		if (r != -ENOENT)
+			return r;
+
+		*security_out = security_determine(bss->capability, NULL);
+	} else
+		*security_out = security_determine(bss->capability, &info);
+
+	memcpy(ssid_out, bss->ssid, bss->ssid_len);
+	ssid_out[bss->ssid_len] = '\0';
+
+	path = iwd_network_get_path(station, ssid_out, *security_out);
+
+	strcpy(path_out, path);
+
+	return 0;
+}
+
 /*
  * Returns the network object the BSS was added to or NULL if ignored.
  */
@@ -293,10 +321,8 @@ static struct network *station_add_seen_bss(struct station *station,
 						struct scan_bss *bss)
 {
 	struct network *network;
-	struct ie_rsn_info info;
-	int r;
 	enum security security;
-	const char *path;
+	char path[256];
 	char ssid[33];
 	uint32_t kbps100 = DIV_ROUND_CLOSEST(bss->data_rate, 100000);
 
@@ -315,25 +341,13 @@ static struct network *station_add_seen_bss(struct station *station,
 		return NULL;
 	}
 
-	memcpy(ssid, bss->ssid, bss->ssid_len);
-	ssid[bss->ssid_len] = '\0';
-
 	if (!(bss->capability & IE_BSS_CAP_ESS)) {
-		l_debug("Ignoring non-ESS BSS \"%s\"", ssid);
+		l_debug("Ignoring non-ESS BSS \"%.32s\"", ssid);
 		return NULL;
 	}
 
-	memset(&info, 0, sizeof(info));
-	r = scan_bss_get_rsn_info(bss, &info);
-	if (r < 0) {
-		if (r != -ENOENT)
-			return NULL;
-
-		security = security_determine(bss->capability, NULL);
-	} else
-		security = security_determine(bss->capability, &info);
-
-	path = iwd_network_get_path(station, ssid, security);
+	if (station_parse_bss(station, bss, ssid, &security, path) < 0)
+		return NULL;
 
 	network = l_hashmap_lookup(station->networks, path);
 	if (!network) {
@@ -3540,6 +3554,12 @@ static struct station *station_create(struct netdev *netdev)
 
 	station_fill_scan_freq_subsets(station);
 
+	if (iwd_is_developer_mode())
+		l_dbus_object_add_interface(dbus,
+					netdev_get_path(station->netdev),
+					IWD_STATION_DEBUG_INTERFACE,
+					station);
+
 	return station;
 }
 
@@ -3553,6 +3573,10 @@ static void station_free(struct station *station)
 	l_dbus_object_remove_interface(dbus_get_bus(),
 					netdev_get_path(station->netdev),
 					IWD_STATION_DIAGNOSTIC_INTERFACE);
+	if (iwd_is_developer_mode())
+		l_dbus_object_remove_interface(dbus_get_bus(),
+					netdev_get_path(station->netdev),
+					IWD_STATION_DEBUG_INTERFACE);
 
 	if (station->netconfig) {
 		netconfig_destroy(station->netconfig);
@@ -3761,6 +3785,19 @@ invalid_args:
 	return dbus_error_invalid_args(message);
 }
 
+static struct network *station_find_network_from_bss(struct station *station,
+						struct scan_bss *bss)
+{
+	enum security security;
+	static char path[256];
+	char ssid[33];
+
+	if (station_parse_bss(station, bss, ssid, &security, path) < 0)
+		return NULL;
+
+	return l_hashmap_lookup(station->networks, path);
+}
+
 static void station_setup_diagnostic_interface(
 					struct l_dbus_interface *interface)
 {
@@ -3777,6 +3814,53 @@ static void station_destroy_diagnostic_interface(void *user_data)
 {
 }
 
+static struct l_dbus_message *station_force_connect_bssid(struct l_dbus *dbus,
+						struct l_dbus_message *message,
+						void *user_data)
+{
+	struct station *station = user_data;
+	struct l_queue *bss_list;
+	struct scan_bss *target;
+	struct network *network;
+	struct l_dbus_message_iter iter;
+	uint8_t *mac;
+	uint32_t mac_len;
+
+	if (!l_dbus_message_get_arguments(message, "ay", &iter))
+		goto invalid_args;
+
+	if (!l_dbus_message_iter_get_fixed_array(&iter, &mac, &mac_len))
+		goto invalid_args;
+
+	if (mac_len != 6)
+		return dbus_error_invalid_args(message);
+
+	bss_list = station_get_bss_list(station);
+
+	target = l_queue_find(bss_list, bss_match_bssid, mac);
+	if (!target)
+		return dbus_error_invalid_args(message);
+
+	network = station_find_network_from_bss(station, target);
+	if (!network)
+		return dbus_error_invalid_args(message);
+
+	l_debug("Attempting forced connection to BSS "MAC, MAC_STR(mac));
+
+	return __network_connect(network, target, message);
+
+invalid_args:
+	return dbus_error_invalid_args(message);
+}
+
+static void station_setup_debug_interface(
+					struct l_dbus_interface *interface)
+{
+	l_dbus_interface_method(interface, "ConnectBssid", 0,
+					station_force_connect_bssid, "", "ay",
+					"mac");
+}
+
 static void ap_roam_frame_event(const struct mmpdu_header *hdr,
 					const void *body, size_t body_len,
 					int rssi, void *user_data)
@@ -3848,6 +3932,12 @@ static int station_init(void)
 					station_setup_diagnostic_interface,
 					station_destroy_diagnostic_interface,
 					false);
+	if (iwd_is_developer_mode())
+		l_dbus_register_interface(dbus_get_bus(),
+					IWD_STATION_DEBUG_INTERFACE,
+					station_setup_debug_interface,
+					NULL,
+					false);
 
 	if (!l_settings_get_uint(iwd_get_config(), "General",
 					"ManagementFrameProtection",
@@ -3889,6 +3979,9 @@ static void station_exit(void)
 {
 	l_dbus_unregister_interface(dbus_get_bus(),
 					IWD_STATION_DIAGNOSTIC_INTERFACE);
+	if (iwd_is_developer_mode())
+		l_dbus_unregister_interface(dbus_get_bus(),
+					IWD_STATION_DEBUG_INTERFACE);
 	l_dbus_unregister_interface(dbus_get_bus(), IWD_STATION_INTERFACE);
 	netdev_watch_remove(netdev_watch);
 	l_queue_destroy(station_list, NULL);
-- 
2.31.1

  reply	other threads:[~2021-08-09 17:16 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-09 17:16 [PATCH v2 1/4] netdev: move failure point out of netdev_connect_common James Prestwood
2021-08-09 17:16 ` James Prestwood [this message]
2021-08-09 17:16 ` [PATCH v2 3/4] station: move Roam() under station debug interface James Prestwood
2021-08-09 17:16 ` [PATCH v2 4/4] test: update force-roam to use Debug interface 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=20210809171616.535514-2-prestwoj@gmail.com \
    --to=prestwoj@gmail.com \
    --cc=iwd@lists.01.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.