From 39b1f68e78706aa0feb63d63f08d400593f25bc0 Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Fri, 22 May 2026 11:40:25 -0700 Subject: [PATCH] main: make developer mode more configurable The developer mode (-E) option is used only for the autotest framework to start up IWD in a state where: - Autoconnect is disabled - The station debug interface is available For testing and development on real systems the debug interface is convenient to have available, the trouble is starting IWD in this mode loses the autoconnect functionality (unless you manually enable after starting). This patch aims to allow developer mode + autoconnect but making allowing the -E flag to take several options: -E (no args) - same behavior, debug interface + no autoconnect -Etest - same as -E with no args -Edebug - debug interface with autoconnect enabled --- src/iwd.h | 7 ++++++- src/main.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ src/station.c | 16 +++++++++------- 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/iwd.h b/src/iwd.h index a8e2c5db..ee7c8544 100644 --- a/src/iwd.h +++ b/src/iwd.h @@ -30,6 +30,11 @@ struct l_genl; struct l_genl_family; +enum iwd_mode { + IWD_MODE_NO_AUTOCONNECT = 1 << 0, + IWD_MODE_DEBUG_INTERFACE = 1 << 1, +}; + const struct l_settings *iwd_get_config(void); struct l_genl *iwd_get_genl(void); struct l_netlink *iwd_get_rtnl(void); @@ -41,7 +46,7 @@ const char *iwd_get_iface_blacklist(void); const char *iwd_get_phy_whitelist(void); const char *iwd_get_phy_blacklist(void); -bool iwd_is_developer_mode(void); +uint32_t iwd_get_developer_modes(void); #define IWD_NOTICE_STATE "state" #define IWD_NOTICE_CONNECT_INFO "connect-info" diff --git a/src/main.c b/src/main.c index 27b2ced2..babfd1ea 100644 --- a/src/main.c +++ b/src/main.c @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -64,7 +65,7 @@ static const char *phys; static const char *nophys; static const char *debugopt; static const char *logger; -static bool developeropt; +static uint32_t iwd_developer_mode; static bool terminating; static bool nl80211_complete; @@ -137,9 +138,23 @@ const char *iwd_get_phy_blacklist(void) return nophys; } -bool iwd_is_developer_mode(void) +uint32_t iwd_get_developer_modes(void) { - return developeropt; + return iwd_developer_mode; +} + +static const char *iwd_mode_to_string(uint32_t mode) +{ + static char str[PATH_MAX]; + int idx = 0; + + if (mode & IWD_MODE_NO_AUTOCONNECT) + idx = sprintf(str, "no-autoconnect "); + + if (mode & IWD_MODE_DEBUG_INTERFACE) + idx += sprintf(str + idx, "debug-interface "); + + return str; } static void usage(void) @@ -160,7 +175,7 @@ static void usage(void) } static const struct option main_options[] = { - { "developer", no_argument, NULL, 'E' }, + { "developer", optional_argument, NULL, 'E' }, { "version", no_argument, NULL, 'v' }, { "interfaces", required_argument, NULL, 'i' }, { "nointerfaces", required_argument, NULL, 'I' }, @@ -473,14 +488,31 @@ int main(int argc, char *argv[]) for (;;) { int opt; - opt = getopt_long(argc, argv, "Ei:I:p:P:d::vhl:", + opt = getopt_long(argc, argv, "E::i:I:p:P:d::vhl:", main_options, NULL); if (opt < 0) break; switch (opt) { case 'E': - developeropt = true; + if (optarg) + if (!strcmp(optarg, "test")) + iwd_developer_mode = + IWD_MODE_DEBUG_INTERFACE | + IWD_MODE_NO_AUTOCONNECT; + else if (!strcmp(optarg, "debug")) + iwd_developer_mode = + IWD_MODE_DEBUG_INTERFACE; + else { + fprintf(stderr, + "Invalid developer mode '%s'\n", + optarg); + return EXIT_FAILURE; + } + else + iwd_developer_mode = IWD_MODE_DEBUG_INTERFACE | + IWD_MODE_NO_AUTOCONNECT; + break; case 'i': interfaces = optarg; @@ -539,6 +571,10 @@ int main(int argc, char *argv[]) if (debugopt) l_debug_enable(debugopt); + if (iwd_developer_mode) + l_debug("Developer mode enabled: %s", + iwd_mode_to_string(iwd_developer_mode)); + #ifdef HAVE_BACKTRACE __iwd_backtrace_init(); #endif diff --git a/src/station.c b/src/station.c index 8fcf8c70..fc1ce040 100644 --- a/src/station.c +++ b/src/station.c @@ -279,7 +279,7 @@ static bool station_debug_event(struct station *station, const char *name) { struct l_dbus_message *signal; - if (!iwd_is_developer_mode()) + if (!(iwd_get_developer_modes() & IWD_MODE_DEBUG_INTERFACE)) return true; l_debug("StationDebug.Event(%s)", name); @@ -1921,7 +1921,7 @@ bool station_set_autoconnect(struct station *station, bool autoconnect) if (station_is_autoconnecting(station) && !autoconnect) station_enter_state(station, STATION_STATE_DISCONNECTED); - if (iwd_is_developer_mode()) + if (iwd_get_developer_modes() & IWD_MODE_DEBUG_INTERFACE) l_dbus_property_changed(dbus_get_bus(), netdev_get_path(station->netdev), IWD_STATION_DEBUG_INTERFACE, "AutoConnect"); @@ -5144,6 +5144,7 @@ static struct station *station_create(struct netdev *netdev) struct station *station; struct l_dbus *dbus = dbus_get_bus(); bool autoconnect = true; + uint32_t iwd_mode = iwd_get_developer_modes(); station = l_new(struct station, 1); watchlist_init(&station->state_watches, NULL); @@ -5175,13 +5176,14 @@ static struct station *station_create(struct netdev *netdev) station_fill_scan_freq_subsets(station); - if (iwd_is_developer_mode()) { + if (iwd_mode & IWD_MODE_DEBUG_INTERFACE) l_dbus_object_add_interface(dbus, netdev_get_path(station->netdev), IWD_STATION_DEBUG_INTERFACE, station); + + if (iwd_mode & IWD_MODE_NO_AUTOCONNECT) autoconnect = false; - } station_set_autoconnect(station, autoconnect); @@ -5201,7 +5203,7 @@ 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()) + if (iwd_get_developer_modes() & IWD_MODE_DEBUG_INTERFACE) l_dbus_object_remove_interface(dbus_get_bus(), netdev_get_path(station->netdev), IWD_STATION_DEBUG_INTERFACE); @@ -5995,7 +5997,7 @@ static int station_init(void) station_setup_diagnostic_interface, station_destroy_diagnostic_interface, false); - if (iwd_is_developer_mode()) + if (iwd_get_developer_modes() & IWD_MODE_DEBUG_INTERFACE) l_dbus_register_interface(dbus_get_bus(), IWD_STATION_DEBUG_INTERFACE, station_setup_debug_interface, @@ -6062,7 +6064,7 @@ static void station_exit(void) { l_dbus_unregister_interface(dbus_get_bus(), IWD_STATION_DIAGNOSTIC_INTERFACE); - if (iwd_is_developer_mode()) + if (iwd_get_developer_modes() & IWD_MODE_DEBUG_INTERFACE) l_dbus_unregister_interface(dbus_get_bus(), IWD_STATION_DEBUG_INTERFACE); l_dbus_unregister_interface(dbus_get_bus(), IWD_STATION_INTERFACE);