From 23435f56c190cf2c833dfea601d5aa0a65c39e01 Mon Sep 17 00:00:00 2001 From: Timo Kokkonen Date: Wed, 25 Dec 2024 18:45:44 -0800 Subject: [PATCH] Support selecting WiFi authentication mode (#136) * New commands to select WiFi authentication mode: - SYS:WIFI:AUTHmode - SYS:WIFI:AUTHmode? --- commands.md | 36 +++++++++++++++++++++++++ src/command.c | 20 ++++++++++++++ src/config.c | 8 ++++++ src/fanpico.h | 5 +++- src/network.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 138 insertions(+), 6 deletions(-) diff --git a/commands.md b/commands.md index 46803b2..213a119 100644 --- a/commands.md +++ b/commands.md @@ -228,6 +228,8 @@ Fanpico supports following commands: * [SYStem:VREFadc?](#systemvrefadc-1) * [SYStem:VSENSORS?](#systemvsensors) * [SYStem:WIFI?](#systemwifi) +* [SYStem:WIFI:AUTHmode](#systemwifiauthmode) +* [SYStem:WIFI:AUTHmode?](#systemwifiauthmode-1) * [SYStem:WIFI:COUntry](#systemwificountry) * [SYStem:WIFI:COUntry?](#systemwificountry-1) * [SYStem:WIFI:HOSTname](#systemwifihostname) @@ -3279,6 +3281,40 @@ SYS:WIFI? 1 ``` +#### SYStem:WIFI:AUTHmode +Set Wi-Fi Authentication mode. + +Following modes are currently supported: + + +Mode|Description|Notes +----|-----------|----- +default|Use system default|Currently default is WPA2 +WPA3_WPA2|Use WPA3/WPA2 (mixed) mode| +WPA3|Use WPA3 only| +WPA2|Use WPA2 only| +WPA2_WPA|Use WPA2/WPA (mixed) mode|Not recommended. +WPA|Use WPA only|Not recommended. +OPEN|Use "Open" mode|No authentication. + + +Example: +``` +SYS:WIFI:AUTH WPA3_WPA2 +``` + + +#### SYStem:WIFI:AUTHmode? +Return currently configured Authentication mode for the WiFi interface. + +Example: + +``` +SYS:WIFI:AUTH? +default +``` + + #### SYStem:WIFI:COUntry Set Wi-Fi Country code. By default, the country setting for the wireless adapter is unset. This means driver will use default world-wide safe setting, which can mean that some channels diff --git a/src/command.c b/src/command.c index 3d9a038..dea1990 100644 --- a/src/command.c +++ b/src/command.c @@ -2234,6 +2234,25 @@ int cmd_wifi_hostname(const char *cmd, const char *args, int query, struct prev_ "WiFi Hostname", valid_hostname); } +int cmd_wifi_auth_mode(const char *cmd, const char *args, int query, struct prev_cmd_t *prev_cmd) +{ + uint32_t type; + + if (query) { + printf("%s\n", conf->wifi_auth_mode); + } else { + if (!wifi_get_auth_type(args, &type)) + return 1; + if (strncmp(conf->wifi_auth_mode, args, sizeof(conf->wifi_auth_mode))) { + log_msg(LOG_NOTICE, "WiFi Auth Type change %s --> %s", + conf->wifi_auth_mode, args); + strncopy(conf->wifi_auth_mode, args, sizeof(conf->wifi_auth_mode)); + } + } + + return 0; +} + int cmd_wifi_mode(const char *cmd, const char *args, int query, struct prev_cmd_t *prev_cmd) { return uint8_setting(cmd, args, query, prev_cmd, @@ -2893,6 +2912,7 @@ const struct cmd_t lfs_commands[] = { const struct cmd_t wifi_commands[] = { #ifdef WIFI_SUPPORT + { "AUTHmode", 4, NULL, cmd_wifi_auth_mode }, { "COUntry", 3, NULL, cmd_wifi_country }, { "GATEway", 4, NULL, cmd_wifi_gateway }, { "HOSTname", 4, NULL, cmd_wifi_hostname }, diff --git a/src/config.c b/src/config.c index 378afc6..ee242e6 100644 --- a/src/config.c +++ b/src/config.c @@ -538,6 +538,7 @@ void clear_config(struct fanpico_config *cfg) #ifdef WIFI_SUPPORT cfg->wifi_ssid[0] = 0; cfg->wifi_passwd[0] = 0; + strncopy(cfg->wifi_auth_mode, "default", sizeof(cfg->wifi_auth_mode)); cfg->wifi_mode = 0; cfg->hostname[0] = 0; strncopy(cfg->wifi_country, "XX", sizeof(cfg->wifi_country)); @@ -636,6 +637,9 @@ cJSON *config_to_json(const struct fanpico_config *cfg) free(p); } } + if (strlen(cfg->wifi_auth_mode) > 0) { + cJSON_AddItemToObject(config, "wifi_auth_mode", cJSON_CreateString(cfg->wifi_auth_mode)); + } if (cfg->wifi_mode != 0) { cJSON_AddItemToObject(config, "wifi_mode", cJSON_CreateNumber(cfg->wifi_mode)); } @@ -986,6 +990,10 @@ int json_to_config(cJSON *config, struct fanpico_config *cfg) } } } + if ((ref = cJSON_GetObjectItem(config, "wifi_auth_mode"))) { + if ((val = cJSON_GetStringValue(ref))) + strncopy(cfg->wifi_auth_mode, val, sizeof(cfg->wifi_auth_mode)); + } if ((ref = cJSON_GetObjectItem(config, "wifi_mode"))) { cfg->wifi_mode = cJSON_GetNumberValue(ref); } diff --git a/src/fanpico.h b/src/fanpico.h index 8b50436..8af9a67 100644 --- a/src/fanpico.h +++ b/src/fanpico.h @@ -238,6 +238,7 @@ struct fanpico_config { char wifi_ssid[WIFI_SSID_MAX_LEN + 1]; char wifi_passwd[WIFI_PASSWD_MAX_LEN + 1]; char wifi_country[WIFI_COUNTRY_MAX_LEN + 1]; + char wifi_auth_mode[16]; uint8_t wifi_mode; char hostname[32]; ip_addr_t syslog_server; @@ -412,11 +413,13 @@ const char *network_ip(); const char *network_hostname(); #if WIFI_SUPPORT +bool wifi_get_auth_type(const char *name, uint32_t *type); +const char* wifi_auth_type_name(uint32_t type); + /* httpd.c */ u16_t fanpico_ssi_handler(const char *tag, char *insert, int insertlen, u16_t current_tag_part, u16_t *next_tag_part); - /* mqtt.c */ void fanpico_setup_mqtt_client(); int fanpico_mqtt_client_active(); diff --git a/src/network.c b/src/network.c index 58484f1..9038bbf 100644 --- a/src/network.c +++ b/src/network.c @@ -50,6 +50,64 @@ static char wifi_hostname[32]; static ip_addr_t syslog_server; static ip_addr_t current_ip; +struct wifi_auth_type { + char *name; + uint32_t type; +}; + +static struct wifi_auth_type auth_types[] = { + { "default", CYW43_AUTH_WPA2_AES_PSK }, + + { "WPA3_WPA2", CYW43_AUTH_WPA3_WPA2_AES_PSK }, + { "WPA3", CYW43_AUTH_WPA3_SAE_AES_PSK }, + { "WPA2", CYW43_AUTH_WPA2_AES_PSK }, + { "WPA2_WPA", CYW43_AUTH_WPA2_MIXED_PSK }, + { "WPA", CYW43_AUTH_WPA_TKIP_PSK }, + { "OPEN", CYW43_AUTH_OPEN }, + + { NULL, 0 } +}; + + +bool wifi_get_auth_type(const char *name, uint32_t *type) +{ + int len, i; + + if (!name || !type) + return false; + + /* Return default type if no match... */ + *type = auth_types[0].type; + + if ((len = strlen(name)) < 1) + return false; + + i = 0; + while (auth_types[i].name) { + if (!strncasecmp(name, auth_types[i].name, len + 1)) { + *type = auth_types[i].type; + return true; + } + i++; + } + + return false; +} + +const char* wifi_auth_type_name(uint32_t type) +{ + int i = 1; + + while (auth_types[i].name) { + if (auth_types[i].type == type) { + return auth_types[i].name; + } + i++; + } + + return "Unknown"; +} + void wifi_mac() { printf("%s\n", mac_address_str(cyw43_mac)); @@ -81,11 +139,13 @@ void wifi_init() { uint32_t country_code = CYW43_COUNTRY_WORLDWIDE; struct netif *n = &cyw43_state.netif[CYW43_ITF_STA]; + uint32_t wifi_auth_mode; int res; memset(cyw43_mac, 0, sizeof(cyw43_mac)); ip_addr_set_zero(&syslog_server); ip_addr_set_zero(¤t_ip); + wifi_hostname[0] = 0; log_msg(LOG_NOTICE, "Initializing WiFi..."); @@ -147,15 +207,21 @@ void wifi_init() return; } log_msg(LOG_NOTICE, "WiFi MAC: %s", mac_address_str(cyw43_mac)); + wifi_get_auth_type(cfg->wifi_auth_mode, &wifi_auth_mode); + log_msg(LOG_INFO, "WiFi Authentication mode: %s", + wifi_auth_type_name(wifi_auth_mode)); /* Attempt to connect to a WiFi network... */ - if (strlen(cfg->wifi_ssid) > 0 && strlen(cfg->wifi_passwd) > 0) { + if (strlen(cfg->wifi_ssid) > 0) { + if (strlen(cfg->wifi_passwd) < 1 && wifi_auth_mode != CYW43_AUTH_OPEN) { + log_msg(LOG_ERR, "No WiFi Password configured."); + return; + } log_msg(LOG_NOTICE, "WiFi connecting to network: %s", cfg->wifi_ssid); if (cfg->wifi_mode == 0) { /* Default is to initiate asynchronous connection. */ res = cyw43_arch_wifi_connect_async(cfg->wifi_ssid, - cfg->wifi_passwd, - CYW43_AUTH_WPA3_WPA2_AES_PSK); + cfg->wifi_passwd, wifi_auth_mode); } else { /* If "SYS:WIFI:MODE 1" has been used, attempt synchronous connection as connection to some buggy(?) APs don't seem to always work with @@ -165,8 +231,7 @@ void wifi_init() do { res = cyw43_arch_wifi_connect_timeout_ms(cfg->wifi_ssid, cfg->wifi_passwd, - CYW43_AUTH_WPA3_WPA2_AES_PSK, - 30000); + wifi_auth_mode, 30000); log_msg(LOG_INFO, "cyw43_arch_wifi_connect_timeout_ms(): %d", res); } while (res != 0 && --retries > 0); }