public inbox for iwd@lists.linux.dev
 help / color / mirror / Atom feed
* [PATCH] device: Improve errors when station not present
@ 2025-12-05  7:03 Chris Down
  0 siblings, 0 replies; only message in thread
From: Chris Down @ 2025-12-05  7:03 UTC (permalink / raw)
  To: iwd; +Cc: kernel-team

When a user attempts to use station commands (scan, get-networks,
connect, disconnect, show) on a device that does not have a station
interface available, iwctl currently displays the generic error message
"No station on device: 'wlan0'". This message is quite broad and does
not really help users understand why the station interface is
unavailable.

The station interface can be unavailable for several distinct reasons:

1. The device does not exist (invalid device name)
2. The device is not in station mode (device is in AP mode or ad-hoc
   mode instead)
3. The device is rfkilled (either hardware rfkill via physical button or
   software rfkill via rfkill utility)
4. The device is not powered for other reasons (manual ifdown, driver
   issues, etc.)

The current implementation simply checks if the station interface exists
and displays the same generic message for all of these cases, which is
particularly confusing when the device is rfkilled, as users may not
immediately understand that "No station on device" means the device is
rfkilled.

This commit improves the error messages by checking the device state and
providing specific error messages for each scenario.
---
 client/adapter.c | 12 ++++++++++++
 client/adapter.h | 25 +++++++++++++++++++++++++
 client/device.c  | 31 +++++++++++++++++++++++++++++++
 client/device.h  |  2 ++
 client/station.c | 18 +++++++++++++-----
 5 files changed, 83 insertions(+), 5 deletions(-)
 create mode 100644 client/adapter.h

diff --git a/client/adapter.c b/client/adapter.c
index 1719b97..7091a22 100644
--- a/client/adapter.c
+++ b/client/adapter.c
@@ -28,6 +28,7 @@
 
 #include "client/command.h"
 #include "client/dbus-proxy.h"
+#include "client/adapter.h"
 #include "client/display.h"
 #include "client/properties.h"
 
@@ -410,5 +411,16 @@ static void adapter_interface_exit(void)
 	proxy_interface_type_unregister(&adapter_interface_type);
 }
 
+bool adapter_is_powered(const struct proxy_interface *adapter_i)
+{
+	const struct adapter *adapter;
+
+	if (!adapter_i)
+		return false;
+
+	adapter = proxy_interface_get_data(adapter_i);
+	return adapter->powered;
+}
+
 INTERFACE_TYPE(adapter_interface_type, adapter_interface_init,
 						adapter_interface_exit)
diff --git a/client/adapter.h b/client/adapter.h
new file mode 100644
index 0000000..c3886d2
--- /dev/null
+++ b/client/adapter.h
@@ -0,0 +1,25 @@
+/*
+ *
+ *  Wireless daemon for Linux
+ *
+ *  Copyright (C) 2017-2019  Intel Corporation. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+struct proxy_interface;
+
+bool adapter_is_powered(const struct proxy_interface *adapter_i);
diff --git a/client/device.c b/client/device.c
index ce2afc8..94e9262 100644
--- a/client/device.c
+++ b/client/device.c
@@ -29,6 +29,7 @@
 #include "client/command.h"
 #include "client/dbus-proxy.h"
 #include "client/device.h"
+#include "client/adapter.h"
 #include "client/display.h"
 #include "client/network.h"
 #include "client/properties.h"
@@ -433,6 +434,36 @@ static void device_command_family_exit(void)
 COMMAND_FAMILY(device_command_family, device_command_family_init,
 						device_command_family_exit)
 
+void device_check_station_error(const struct proxy_interface *device_i,
+					const char *device_name)
+{
+	const struct device *device;
+
+	if (!device_i) {
+		/* device_proxy_find_by_name already displays "Device %s not found" */
+		return;
+	}
+
+	device = proxy_interface_get_data(device_i);
+
+	if (!device->mode || strcmp(device->mode, "station") != 0) {
+		display("Device '%s' is not in station mode.\n", device_name);
+		return;
+	}
+
+	if (!device->powered) {
+		if (device->adapter && !adapter_is_powered(device->adapter)) {
+			display("Device '%s' is rfkilled.\n", device_name);
+		} else {
+			display("Device '%s' is not powered.\n", device_name);
+		}
+		return;
+	}
+
+	/* Fallback for other cases */
+	display("No station on device: '%s'\n", device_name);
+}
+
 static int device_interface_init(void)
 {
 	proxy_interface_type_register(&device_interface_type);
diff --git a/client/device.h b/client/device.h
index f8481ef..9965948 100644
--- a/client/device.h
+++ b/client/device.h
@@ -30,3 +30,5 @@ const struct proxy_interface *device_proxy_find_by_name(const char *name);
 const struct proxy_interface *device_proxy_find(const char *device_name,
 							const char *interface);
 const struct proxy_interface *device_get_default(void);
+void device_check_station_error(const struct proxy_interface *device_i,
+					const char *device_name);
diff --git a/client/station.c b/client/station.c
index 5066a9f..3d1c09b 100644
--- a/client/station.c
+++ b/client/station.c
@@ -242,6 +242,14 @@ static void display_station_inline(const char *margin, const void *data)
 				8, station->scanning ? "scanning" : "");
 }
 
+static void display_station_error(const char *device_name)
+{
+	const struct proxy_interface *device_i =
+					device_proxy_find_by_name(device_name);
+
+	device_check_station_error(device_i, device_name);
+}
+
 static enum cmd_status cmd_list(const char *device_name, char **argv, int argc)
 {
 	const struct l_queue_entry *entry;
@@ -351,7 +359,7 @@ static enum cmd_status cmd_connect_hidden_network(const char *device_name,
 
 	station_i = device_proxy_find(device_name, IWD_STATION_INTERFACE);
 	if (!station_i) {
-		display("No station on device: '%s'\n", device_name);
+		display_station_error(device_name);
 		return CMD_STATUS_INVALID_VALUE;
 	}
 
@@ -369,7 +377,7 @@ static enum cmd_status cmd_disconnect(const char *device_name,
 			device_proxy_find(device_name, IWD_STATION_INTERFACE);
 
 	if (!station_i) {
-		display("No station on device: '%s'\n", device_name);
+		display_station_error(device_name);
 		return CMD_STATUS_INVALID_VALUE;
 	}
 
@@ -527,7 +535,7 @@ static enum cmd_status cmd_get_networks(const char *device_name,
 			device_proxy_find(device_name, IWD_STATION_INTERFACE);
 
 	if (!station_i) {
-		display("No station on device: '%s'\n", device_name);
+		display_station_error(device_name);
 		return CMD_STATUS_INVALID_VALUE;
 	}
 
@@ -661,7 +669,7 @@ static enum cmd_status cmd_scan(const char *device_name,
 			device_proxy_find(device_name, IWD_STATION_INTERFACE);
 
 	if (!station_i) {
-		display("No station on device: '%s'\n", device_name);
+		display_station_error(device_name);
 		return CMD_STATUS_INVALID_VALUE;
 	}
 
@@ -701,7 +709,7 @@ static enum cmd_status cmd_show(const char *device_name,
 					IWD_STATION_DIAGNOSTIC_INTERFACE);
 
 	if (!station) {
-		display("No station on device: '%s'\n", device_name);
+		display_station_error(device_name);
 		return CMD_STATUS_INVALID_VALUE;
 	}
 
-- 
2.52.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2025-12-05  7:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-05  7:03 [PATCH] device: Improve errors when station not present Chris Down

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox