base of xmarco-based config, used for wifi and network

work
Ondřej Hruška 7 years ago
parent fbd4693035
commit cabd42f2b4
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 2
      CMakeLists.txt
  2. 2
      front-end
  3. 3
      prepro.sh
  4. 172
      user/cgi_network.c
  5. 199
      user/cgi_wifi.c
  6. 99
      user/config_xmacros.c
  7. 85
      user/config_xmacros.h
  8. 172
      user/wifimgr.c
  9. 72
      user/wifimgr.h

@ -148,7 +148,7 @@ set(SOURCE_FILES
user/character_sets.h user/character_sets.h
user/utf8.h user/utf8.h
user/utf8.c user/utf8.c
user/cgi_logging.h) user/cgi_logging.h user/config_xmacros.h user/config_xmacros.c)
include_directories(include) include_directories(include)
include_directories(libesphttpd/esphttpclient) include_directories(libesphttpd/esphttpclient)

@ -1 +1 @@
Subproject commit d2fabc40f1874cabd7f7ceca690a5874887c3c5d Subproject commit 32c889b714dae859f51e6b46829fd85be59d9ed0

@ -0,0 +1,3 @@
#!/usr/bin/env bash
xtensa-lx106-elf-gcc -E -Iuser -Ilibesphttpd/include -Iesp_iot_sdk_v1.5.2/include -Iinclude $@

@ -9,6 +9,7 @@ configuring the network settings
#include "persist.h" #include "persist.h"
#include "helpers.h" #include "helpers.h"
#include "cgi_logging.h" #include "cgi_logging.h"
#include "config_xmacros.h"
#define SET_REDIR_SUC "/cfg/network" #define SET_REDIR_SUC "/cfg/network"
#define SET_REDIR_ERR SET_REDIR_SUC"?err=" #define SET_REDIR_ERR SET_REDIR_SUC"?err="
@ -48,138 +49,9 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
// ---- AP DHCP server lease time ---- // ---- AP DHCP server lease time ----
if (GET_ARG("ap_dhcp_time")) { #define X XSET_CGI_FUNC
cgi_dbg("Setting DHCP lease time to: %s min.", buff); XTABLE_WIFI
int min = atoi(buff); #undef X
if (min >= 1 && min <= 2880) {
if (wificonf->ap_dhcp_time != min) {
wificonf->ap_dhcp_time = (u16) min;
wifi_change_flags.ap = true;
}
} else {
cgi_warn("Lease time %s out of allowed range 1-2880.", buff);
redir_url += sprintf(redir_url, "ap_dhcp_time,");
}
}
// ---- AP DHCP start and end IP ----
if (GET_ARG("ap_dhcp_start")) {
cgi_dbg("Setting DHCP range start IP to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff);
if (ip != 0) {
if (wificonf->ap_dhcp_range.start_ip.addr != ip) {
wificonf->ap_dhcp_range.start_ip.addr = ip;
wifi_change_flags.ap = true;
}
} else {
cgi_warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_dhcp_start,");
}
}
if (GET_ARG("ap_dhcp_end")) {
cgi_dbg("Setting DHCP range end IP to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff);
if (ip != 0) {
if (wificonf->ap_dhcp_range.end_ip.addr != ip) {
wificonf->ap_dhcp_range.end_ip.addr = ip;
wifi_change_flags.ap = true;
}
} else {
cgi_warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_dhcp_end,");
}
}
// ---- AP local address & config ----
if (GET_ARG("ap_addr_ip")) {
cgi_dbg("Setting AP local IP to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff);
if (ip != 0) {
if (wificonf->ap_addr.ip.addr != ip) {
wificonf->ap_addr.ip.addr = ip;
wificonf->ap_addr.gw.addr = ip; // always the same, we're the router here
wifi_change_flags.ap = true;
}
} else {
cgi_warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_addr_ip,");
}
}
if (GET_ARG("ap_addr_mask")) {
cgi_dbg("Setting AP local IP netmask to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff);
if (ip != 0) {
if (wificonf->ap_addr.netmask.addr != ip) {
// ideally this should be checked to match the IP.
// Let's hope users know what they're doing
wificonf->ap_addr.netmask.addr = ip;
wifi_change_flags.ap = true;
}
} else {
cgi_warn("Bad IP mask: %s", buff);
redir_url += sprintf(redir_url, "ap_addr_mask,");
}
}
// ---- Station enable/disable DHCP ----
// DHCP enable / disable (disable means static IP is enabled)
if (GET_ARG("sta_dhcp_enable")) {
cgi_dbg("DHCP enable = %s", buff);
int enable = atoi(buff);
if (wificonf->sta_dhcp_enable != enable) {
wificonf->sta_dhcp_enable = (bool)enable;
wifi_change_flags.sta = true;
}
}
// ---- Station IP config (Static IP) ----
if (GET_ARG("sta_addr_ip")) {
cgi_dbg("Setting Station mode static IP to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff);
if (ip != 0) {
if (wificonf->sta_addr.ip.addr != ip) {
wificonf->sta_addr.ip.addr = ip;
wifi_change_flags.sta = true;
}
} else {
cgi_warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_ip,");
}
}
if (GET_ARG("sta_addr_mask")) {
cgi_dbg("Setting Station mode static IP netmask to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff);
if (ip != 0 && ip != 0xFFFFFFFFUL) {
if (wificonf->sta_addr.netmask.addr != ip) {
wificonf->sta_addr.netmask.addr = ip;
wifi_change_flags.sta = true;
}
} else {
cgi_warn("Bad IP mask: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_mask,");
}
}
if (GET_ARG("sta_addr_gw")) {
cgi_dbg("Setting Station mode static IP default gateway to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff);
if (ip != 0) {
if (wificonf->sta_addr.gw.addr != ip) {
wificonf->sta_addr.gw.addr = ip;
wifi_change_flags.sta = true;
}
} else {
cgi_warn("Bad gw IP: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_gw,");
}
}
(void) redir_url; (void) redir_url;
@ -216,7 +88,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
//Template code for the WLAN page. //Template code for the WLAN page.
httpd_cgi_state ICACHE_FLASH_ATTR tplNetwork(HttpdConnData *connData, char *token, void **arg) httpd_cgi_state ICACHE_FLASH_ATTR tplNetwork(HttpdConnData *connData, char *token, void **arg)
{ {
char buff[20]; char buff[64];
u8 mac[6]; u8 mac[6];
if (token == NULL) { if (token == NULL) {
@ -226,34 +98,12 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplNetwork(HttpdConnData *connData, char *toke
strcpy(buff, ""); // fallback strcpy(buff, ""); // fallback
if (streq(token, "ap_dhcp_time")) { #define X XGET_CGI_FUNC
sprintf(buff, "%d", wificonf->ap_dhcp_time); XTABLE_WIFI
} #undef X
else if (streq(token, "ap_dhcp_start")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.start_ip.addr)); // non-config
} if (streq(token, "sta_mac")) {
else if (streq(token, "ap_dhcp_end")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.end_ip.addr));
}
else if (streq(token, "ap_addr_ip")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->ap_addr.ip.addr));
}
else if (streq(token, "ap_addr_mask")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->ap_addr.netmask.addr));
}
else if (streq(token, "sta_dhcp_enable")) {
sprintf(buff, "%d", wificonf->sta_dhcp_enable);
}
else if (streq(token, "sta_addr_ip")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.ip.addr));
}
else if (streq(token, "sta_addr_mask")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.netmask.addr));
}
else if (streq(token, "sta_addr_gw")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.gw.addr));
}
else if (streq(token, "sta_mac")) {
wifi_get_macaddr(STATION_IF, mac); wifi_get_macaddr(STATION_IF, mac);
sprintf(buff, MACSTR, MAC2STR(mac)); sprintf(buff, MACSTR, MAC2STR(mac));
} }

@ -19,6 +19,7 @@ Cgi/template routines for the /wifi url.
#include "wifimgr.h" #include "wifimgr.h"
#include "persist.h" #include "persist.h"
#include "helpers.h" #include "helpers.h"
#include "config_xmacros.h"
#include "cgi_logging.h" #include "cgi_logging.h"
#define SET_REDIR_SUC "/cfg/wifi" #define SET_REDIR_SUC "/cfg/wifi"
@ -66,46 +67,6 @@ int ICACHE_FLASH_ATTR rssi2perc(int rssi)
return r; return r;
} }
/**
* Convert Auth type to string
*/
const ICACHE_FLASH_ATTR char *auth2str(AUTH_MODE auth)
{
switch (auth) {
case AUTH_OPEN:
return "Open";
case AUTH_WEP:
return "WEP";
case AUTH_WPA_PSK:
return "WPA";
case AUTH_WPA2_PSK:
return "WPA2";
case AUTH_WPA_WPA2_PSK:
return "WPA/WPA2";
default:
return "Unknown";
}
}
/**
* Convert WiFi opmode to string
*/
const ICACHE_FLASH_ATTR char *opmode2str(WIFI_MODE opmode)
{
switch (opmode) {
case NULL_MODE:
return "Disabled";
case STATION_MODE:
return "Client";
case SOFTAP_MODE:
return "AP only";
case STATIONAP_MODE:
return "Client+AP";
default:
return "Unknown";
}
}
/** /**
* Callback the code calls when a wlan ap scan is done. Basically stores the result in * Callback the code calls when a wlan ap scan is done. Basically stores the result in
* the static cgiWifiAps struct. * the static cgiWifiAps struct.
@ -363,18 +324,13 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
bool sta_turned_on = false; bool sta_turned_on = false;
bool sta_ssid_pw_changed = false; bool sta_ssid_pw_changed = false;
#define X XSET_CGI_FUNC
XTABLE_WIFI
#undef X
// ---- WiFi opmode ---- // ---- WiFi opmode ----
if (GET_ARG("opmode")) { // those are helpers, not a real prop
cgi_dbg("Setting WiFi opmode to: %s", buff);
int mode = atoi(buff);
if (mode > NULL_MODE && mode < MAX_MODE) {
wificonf->opmode = (WIFI_MODE) mode;
} else {
cgi_warn("Bad opmode value \"%s\"", buff);
redir_url += sprintf(redir_url, "opmode,");
}
}
if (GET_ARG("ap_enable")) { if (GET_ARG("ap_enable")) {
cgi_dbg("Enable AP: %s", buff); cgi_dbg("Enable AP: %s", buff);
@ -399,114 +355,6 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
} }
} }
// ---- AP transmit power ----
if (GET_ARG("tpw")) {
cgi_dbg("Setting AP power to: %s", buff);
int tpw = atoi(buff);
if (tpw >= 0 && tpw <= 82) { // 0 actually isn't 0 but quite low. 82 is very strong
if (wificonf->tpw != tpw) {
wificonf->tpw = (u8) tpw;
wifi_change_flags.ap = true;
}
} else {
cgi_warn("tpw %s out of allowed range 0-82.", buff);
redir_url += sprintf(redir_url, "tpw,");
}
}
// ---- AP channel (applies in AP-only mode) ----
if (GET_ARG("ap_channel")) {
cgi_info("ap_channel = %s", buff);
int channel = atoi(buff);
if (channel > 0 && channel < 15) {
if (wificonf->ap_channel != channel) {
wificonf->ap_channel = (u8) channel;
wifi_change_flags.ap = true;
}
} else {
cgi_warn("Bad channel value \"%s\", allowed 1-14", buff);
redir_url += sprintf(redir_url, "ap_channel,");
}
}
// ---- SSID name in AP mode ----
if (GET_ARG("ap_ssid")) {
// Replace all invalid ASCII with underscores
int i;
for (i = 0; i < 32; i++) {
char c = buff[i];
if (c == 0) break;
if (c < 32 || c >= 127) buff[i] = '_';
}
buff[i] = 0;
if (strlen(buff) > 0) {
if (!streq(wificonf->ap_ssid, buff)) {
cgi_info("Setting SSID to \"%s\"", buff);
strncpy_safe(wificonf->ap_ssid, buff, SSID_LEN);
wifi_change_flags.ap = true;
}
} else {
cgi_warn("Bad SSID len.");
redir_url += sprintf(redir_url, "ap_ssid,");
}
}
// ---- AP password ----
if (GET_ARG("ap_password")) {
// Users are free to use any stupid shit in ther password,
// but it may lock them out.
if (strlen(buff) == 0 || (strlen(buff) >= 8 && strlen(buff) < PASSWORD_LEN-1)) {
if (!streq(wificonf->ap_password, buff)) {
cgi_info("Setting AP password to \"%s\"", buff);
strncpy_safe(wificonf->ap_password, buff, PASSWORD_LEN);
wifi_change_flags.ap = true;
}
} else {
cgi_warn("Bad password len.");
redir_url += sprintf(redir_url, "ap_password,");
}
}
// ---- Hide AP network (do not announce) ----
if (GET_ARG("ap_hidden")) {
cgi_dbg("AP hidden = %s", buff);
int hidden = atoi(buff);
if (hidden != wificonf->ap_hidden) {
wificonf->ap_hidden = (hidden != 0);
wifi_change_flags.ap = true;
}
}
// ---- Station SSID (to connect to) ----
if (GET_ARG("sta_ssid")) {
if (!streq(wificonf->sta_ssid, buff)) {
// No verification needed, at worst it fails to connect
cgi_info("Setting station SSID to: \"%s\"", buff);
strncpy_safe(wificonf->sta_ssid, buff, SSID_LEN);
wifi_change_flags.sta = true;
sta_ssid_pw_changed = true;
}
}
// ---- Station password (empty for none is allowed) ----
if (GET_ARG("sta_password")) {
if (!streq(wificonf->sta_password, buff)) {
// No verification needed, at worst it fails to connect
cgi_info("Setting station password to: \"%s\"", buff);
strncpy_safe(wificonf->sta_password, buff, PASSWORD_LEN);
wifi_change_flags.sta = true;
sta_ssid_pw_changed = true;
}
}
(void)redir_url; (void)redir_url;
if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) { if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) {
@ -552,7 +400,6 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
//Template code for the WLAN page. //Template code for the WLAN page.
httpd_cgi_state ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg) httpd_cgi_state ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg)
{ {
@ -567,39 +414,17 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token,
strcpy(buff, ""); // fallback strcpy(buff, ""); // fallback
if (streq(token, "opmode_name")) { #define X XGET_CGI_FUNC
strcpy(buff, opmode2str(wificonf->opmode)); XTABLE_WIFI
} #undef X
else if (streq(token, "opmode")) {
sprintf(buff, "%d", wificonf->opmode); // non-config
} if (streq(token, "sta_enable")) {
else if (streq(token, "sta_enable")) {
sprintf(buff, "%d", (wificonf->opmode & STATION_MODE) != 0); sprintf(buff, "%d", (wificonf->opmode & STATION_MODE) != 0);
} }
else if (streq(token, "ap_enable")) { else if (streq(token, "ap_enable")) {
sprintf(buff, "%d", (wificonf->opmode & SOFTAP_MODE) != 0); sprintf(buff, "%d", (wificonf->opmode & SOFTAP_MODE) != 0);
} }
else if (streq(token, "tpw")) {
sprintf(buff, "%d", wificonf->tpw);
}
else if (streq(token, "ap_channel")) {
sprintf(buff, "%d", wificonf->ap_channel);
}
else if (streq(token, "ap_ssid")) {
sprintf(buff, "%s", wificonf->ap_ssid);
}
else if (streq(token, "ap_password")) {
sprintf(buff, "%s", wificonf->ap_password);
}
else if (streq(token, "ap_hidden")) {
sprintf(buff, "%d", wificonf->ap_hidden);
}
else if (streq(token, "sta_ssid")) {
sprintf(buff, "%s", wificonf->sta_ssid);
}
else if (streq(token, "sta_password")) {
sprintf(buff, "%s", wificonf->sta_password);
}
else if (streq(token, "sta_rssi")) { else if (streq(token, "sta_rssi")) {
sprintf(buff, "%d", wifi_station_get_rssi()); sprintf(buff, "%d", wifi_station_get_rssi());
} }

@ -0,0 +1,99 @@
//
// Created by MightyPork on 2017/10/22.
//
#include "config_xmacros.h"
#include "cgi_logging.h"
void ICACHE_FLASH_ATTR xget_dec(char *buff, u32 value)
{
sprintf(buff, "%d", value);
}
void ICACHE_FLASH_ATTR xget_bool(char *buff, bool value)
{
sprintf(buff, "%d", value?1:0);
}
void ICACHE_FLASH_ATTR xget_ustring(char *buff, const u8 *value)
{
sprintf(buff, "%s", (const char *) value);
}
void ICACHE_FLASH_ATTR xget_string(char *buff, const char *value)
{
sprintf(buff, "%s", value);
}
void ICACHE_FLASH_ATTR xget_ip(char *buff, const struct ip_addr *value)
{
sprintf(buff, IPSTR, GOOD_IP2STR(value->addr));
}
// ------------- XSET -------------
enum xset_result ICACHE_FLASH_ATTR
xset_ip(const char *name, struct ip_addr *field, const char *buff, const void *arg)
{
cgi_dbg("Setting %s = %s", name, buff);
u32 ip = ipaddr_addr(buff);
if (ip != 0 && ip != 0xFFFFFFFFUL) {
if (field->addr != ip) {
field->addr = ip;
return XSET_SET;
}
return XSET_UNCHANGED;
} else {
cgi_warn("Bad IP: %s", buff);
return XSET_FAIL;
}
}
enum xset_result ICACHE_FLASH_ATTR
xset_bool(const char *name, bool *field, const char *buff, const void *arg)
{
cgi_dbg("Setting %s = %s", name, buff);
bool enable = (atoi(buff) != 0);
if (*field != enable) {
*field = enable;
return XSET_SET;
}
return XSET_UNCHANGED;
}
enum xset_result ICACHE_FLASH_ATTR
xset_u8(const char *name, u8 *field, const char *buff, const void *arg)
{
cgi_dbg("Setting %s = %s", name, buff);
u32 val = (u32) atoi(buff);
if (val <= 255) {
if (*field != val) {
*field = (u8) val;
return XSET_SET;
}
return XSET_UNCHANGED;
} else {
cgi_warn("Bad value, max 255: %s", buff);
return XSET_FAIL;
}
}
enum xset_result ICACHE_FLASH_ATTR
xset_string(const char *name, char *field, const char *buff, const void *arg)
{
cgi_dbg("Setting %s = %s", name, buff);
u32 maxlen = (u32) arg;
if (arg > 0 && (u32)strlen(buff) > maxlen) {
cgi_warn("String too long, max %d", maxlen);
return XSET_FAIL;
}
if (!streq(field, buff)) {
strncpy_safe(field, buff, (u32)arg);
return XSET_SET;
}
return XSET_UNCHANGED;
}

@ -0,0 +1,85 @@
//
// Created by MightyPork on 2017/10/22.
//
#ifndef ESPTERM_CONFIG_XMACROS_H
#define ESPTERM_CONFIG_XMACROS_H
#include <esp8266.h>
#include <helpers.h>
#define XJOIN(a, b) a##b
/**Do nothing xnotify */
#define xnoop()
/**
* XGET interface
*
* @param buff - buffer where the value should be printed
* @param value - value to render to the buffer
*/
static inline bool xget_dummy(char *buff, u32 value)
{
sprintf(buff, "unused %d", value);
return false;
}
void xget_dec(char *buff, u32 value);
void xget_bool(char *buff, bool value);
void xget_ustring(char *buff, const u8 *value);
void xget_string(char *buff, const char *value);
void xget_ip(char *buff, const struct ip_addr *value);
void xget_dhcp(char *buff, const struct dhcps_lease *value);
/**
* XSET interface
*
* @param name - field name (for debug)
* @param field - pointer to the target field
* @param buff - field with the value to be set
* @param arg - arbitrary argument, used to modify behavior
*
* @return xset_result
*/
enum xset_result {
XSET_FAIL = 0,
XSET_SET = 1,
XSET_UNCHANGED = 2
};
// Dummy for unimplemented setters
static inline enum xset_result xset_dummy(const char *name, void *field, const char *buff, const void *arg)
{
return XSET_UNCHANGED;
}
enum xset_result xset_ip(const char *name, struct ip_addr *field, const char *buff, const void *arg);
enum xset_result xset_bool(const char *name, bool *field, const char *buff, const void *arg);
enum xset_result xset_u8(const char *name, u8 *field, const char *buff, const void *arg);
/**
* @param arg - max string length
*/
enum xset_result xset_string(const char *name, char *field, const char *buff, const void *arg);
/**
* Helper template macro for CGI functions that load GET args to structs using XTABLE
*
* If 'name' is found in connData->getArgs, xset() is called.
* If the result is SET, xnotify() is fired. Else, 'name,' is appended to the redir_url buffer.
*/
#define XSET_CGI_FUNC(type, name, suffix, deref, xget, cast, xset, xsarg, xnotify) \
if (GET_ARG(#name)) { \
enum xset_result res = xset(#name, cast &wificonf->name, buff, (const void*) (xsarg)); \
if (res == XSET_SET) { xnotify(); } \
else if (res == XSET_FAIL) { redir_url += sprintf(redir_url, #name","); } \
}
#define XGET_CGI_FUNC(type, name, suffix, deref, xget, cast, xset, xsarg, xnotify) \
if (streq(token, #name)) xget(buff, deref wificonf->name);
#endif //ESPTERM_CONFIG_XMACROS_H

@ -4,10 +4,127 @@
#include "wifimgr.h" #include "wifimgr.h"
#include "persist.h" #include "persist.h"
#include "cgi_logging.h"
#include "config_xmacros.h"
WiFiConfigBundle * const wificonf = &persist.current.wificonf; WiFiConfigBundle * const wificonf = &persist.current.wificonf;
WiFiConfChangeFlags wifi_change_flags; WiFiConfChangeFlags wifi_change_flags;
enum xset_result ICACHE_FLASH_ATTR
xset_wifi_lease_time(const char *name, u16 *field, const char *buff, const void *arg)
{
cgi_dbg("Setting %s = %s min", name, buff);
int min = atoi(buff);
if (min >= 1 && min <= 2880) {
if (*field != min) {
*field = (u16) min;
return XSET_SET;
}
return XSET_UNCHANGED;
} else {
cgi_warn("Lease time %s out of allowed range 1-2880.", buff);
return XSET_FAIL;
}
}
enum xset_result ICACHE_FLASH_ATTR
xset_wifi_opmode(const char *name, u8 *field, const char *buff, const void *arg)
{
cgi_dbg("Setting %s = %s", name, buff);
int mode = atoi(buff);
if (mode > NULL_MODE && mode < MAX_MODE) {
if (*field != mode) {
*field = (WIFI_MODE) mode;
return XSET_SET;
}
return XSET_UNCHANGED; // opmode does not use flags
} else {
cgi_warn("Bad opmode value \"%s\"", buff);
return XSET_FAIL;
}
}
enum xset_result ICACHE_FLASH_ATTR
xset_wifi_tpw(const char *name, u8 *field, const char *buff, const void *arg)
{
cgi_dbg("Setting %s = %s", name, buff);
int tpw = atoi(buff);
if (tpw >= 0 && tpw <= 82) { // 0 actually isn't 0 but quite low. 82 is very strong
if (*field != tpw) {
*field = (u8) tpw;
return XSET_SET;
}
return XSET_UNCHANGED;
} else {
cgi_warn("tpw %s out of allowed range 0-82.", buff);
return XSET_FAIL;
}
}
enum xset_result ICACHE_FLASH_ATTR
xset_wifi_ap_channel(const char *name, u8 *field, const char *buff, const void *arg)
{
cgi_dbg("Setting %s = %s", name, buff);
int channel = atoi(buff);
if (channel > 0 && channel < 15) {
if (*field != channel) {
*field = (u8) channel;
return XSET_SET;
}
return XSET_UNCHANGED;
} else {
cgi_warn("Bad channel value \"%s\", allowed 1-14", buff);
return XSET_FAIL;
}
}
enum xset_result ICACHE_FLASH_ATTR
xset_wifi_ssid(const char *name, u8 **field, const char *buff, const void *arg)
{
u8 buff2[SSID_LEN];
bool want_subs = arg!=0;
int i;
for (i = 0; i < SSID_LEN; i++) {
char c = buff[i];
if (c == 0) break;
if (want_subs && (c < 32 || c >= 127)) c = '_';
buff2[i] = (u8) c;
}
buff2[i] = 0;
cgi_dbg("Setting %s = %s", name, buff);
if (strlen((char *)buff2) > 0) {
if (!streq(*field, buff2)) {
strncpy_safe(*field, buff2, SSID_LEN);
return XSET_SET;
}
return XSET_UNCHANGED;
} else {
cgi_warn("Bad SSID len.");
return XSET_FAIL;
}
}
/** Set PW - allow len 0 or 8-64 */
enum xset_result ICACHE_FLASH_ATTR
xset_wifi_pwd(const char *name, u8 **field, const char *buff, const void *arg)
{
cgi_dbg("Setting %s = %s", name, buff);
if (strlen(buff) == 0 || (strlen(buff) >= 8 && strlen(buff) < PASSWORD_LEN-1)) {
if (!streq(*field, buff)) {
strncpy_safe(*field, buff, PASSWORD_LEN);
return XSET_SET;
}
return XSET_UNCHANGED;
} else {
cgi_warn("Bad password len.");
return XSET_FAIL;
}
}
int ICACHE_FLASH_ATTR getStaIpAsString(char *buffer) int ICACHE_FLASH_ATTR getStaIpAsString(char *buffer)
{ {
WIFI_MODE x = wifi_get_opmode(); WIFI_MODE x = wifi_get_opmode();
@ -42,13 +159,11 @@ wifimgr_restore_defaults(void)
wificonf->ap_password[0] = 0; // PSK2 always if password is not null. wificonf->ap_password[0] = 0; // PSK2 always if password is not null.
wificonf->ap_hidden = false; wificonf->ap_hidden = false;
IP4_ADDR(&wificonf->ap_addr.ip, 192, 168, 4, 1); IP4_ADDR(&wificonf->ap_addr_ip, 192, 168, 4, 1);
IP4_ADDR(&wificonf->ap_addr.netmask, 255, 255, 255, 0); IP4_ADDR(&wificonf->ap_addr_mask, 255, 255, 255, 0);
wificonf->ap_addr.gw.addr = wificonf->ap_addr.gw.addr;
IP4_ADDR(&wificonf->ap_dhcp_range.start_ip, 192, 168, 4, 100); IP4_ADDR(&wificonf->ap_dhcp_start, 192, 168, 4, 100);
IP4_ADDR(&wificonf->ap_dhcp_range.end_ip, 192, 168, 4, 200); IP4_ADDR(&wificonf->ap_dhcp_end, 192, 168, 4, 200);
wificonf->ap_dhcp_range.enable = 1; // this will never get changed, idk why it's even there
wificonf->ap_dhcp_time = 120; wificonf->ap_dhcp_time = 120;
// --- Client config --- // --- Client config ---
@ -56,9 +171,9 @@ wifimgr_restore_defaults(void)
wificonf->sta_password[0] = 0; wificonf->sta_password[0] = 0;
wificonf->sta_dhcp_enable = true; wificonf->sta_dhcp_enable = true;
IP4_ADDR(&wificonf->sta_addr.ip, 192, 168, 0, (mac[5] == 1 ? 2 : mac[5])); // avoid being the same as "default gw" IP4_ADDR(&wificonf->sta_addr_ip, 192, 168, 0, (mac[5] == 1 ? 2 : mac[5])); // avoid being the same as "default gw"
IP4_ADDR(&wificonf->sta_addr.netmask, 255, 255, 255, 0); IP4_ADDR(&wificonf->sta_addr_mask, 255, 255, 255, 0);
IP4_ADDR(&wificonf->sta_addr.gw, 192, 168, 0, 1); IP4_ADDR(&wificonf->sta_addr_gw, 192, 168, 0, 1); // a common default...
} }
static void ICACHE_FLASH_ATTR static void ICACHE_FLASH_ATTR
@ -83,13 +198,18 @@ configure_station(void)
} }
else { else {
wifi_info("[WiFi] Setting up static IP..."); wifi_info("[WiFi] Setting up static IP...");
wifi_dbg("[WiFi] Client.ip = "IPSTR, GOOD_IP2STR(wificonf->sta_addr.ip.addr)); wifi_dbg("[WiFi] Client.ip = "IPSTR, GOOD_IP2STR(wificonf->sta_addr_ip.addr));
wifi_dbg("[WiFi] Client.mask = "IPSTR, GOOD_IP2STR(wificonf->sta_addr.netmask.addr)); wifi_dbg("[WiFi] Client.mask = "IPSTR, GOOD_IP2STR(wificonf->sta_addr_mask.addr));
wifi_dbg("[WiFi] Client.gw = "IPSTR, GOOD_IP2STR(wificonf->sta_addr.gw.addr)); wifi_dbg("[WiFi] Client.gw = "IPSTR, GOOD_IP2STR(wificonf->sta_addr_gw.addr));
wifi_station_dhcpc_stop(); wifi_station_dhcpc_stop();
// Load static IP config // Load static IP config
if (!wifi_set_ip_info(STATION_IF, &wificonf->sta_addr)) { struct ip_info ipstruct;
ipstruct.ip.addr = wificonf->sta_addr_ip.addr;
ipstruct.netmask.addr = wificonf->sta_addr_mask.addr;
ipstruct.gw.addr = wificonf->sta_addr_gw.addr;
if (!wifi_set_ip_info(STATION_IF, &ipstruct)) {
error("[WiFi] Error setting static IP!"); error("[WiFi] Error setting static IP!");
return; return;
} }
@ -112,7 +232,7 @@ configure_ap(void)
strcpy((char *) conf.password, (char *) wificonf->ap_password); strcpy((char *) conf.password, (char *) wificonf->ap_password);
conf.authmode = (wificonf->ap_password[0] == 0 ? AUTH_OPEN : AUTH_WPA2_PSK); conf.authmode = (wificonf->ap_password[0] == 0 ? AUTH_OPEN : AUTH_WPA2_PSK);
conf.ssid_len = (uint8_t) strlen((char *) conf.ssid); conf.ssid_len = (uint8_t) strlen((char *) conf.ssid);
conf.ssid_hidden = wificonf->ap_hidden; conf.ssid_hidden = (uint8) wificonf->ap_hidden;
conf.max_connection = 4; // default 4 (max possible) conf.max_connection = 4; // default 4 (max possible)
conf.beacon_interval = 100; // default 100 ms conf.beacon_interval = 100; // default 100 ms
@ -127,24 +247,32 @@ configure_ap(void)
// Set IP // Set IP
wifi_info("[WiFi] Configuring SoftAP local IP..."); wifi_info("[WiFi] Configuring SoftAP local IP...");
wifi_dbg("[WiFi] SoftAP.ip = "IPSTR, GOOD_IP2STR(wificonf->ap_addr.ip.addr)); wifi_dbg("[WiFi] SoftAP.ip = "IPSTR, GOOD_IP2STR(wificonf->ap_addr_ip.addr));
wifi_dbg("[WiFi] SoftAP.mask = "IPSTR, GOOD_IP2STR(wificonf->ap_addr.netmask.addr)); wifi_dbg("[WiFi] SoftAP.mask = "IPSTR, GOOD_IP2STR(wificonf->ap_addr_mask.addr));
wifi_dbg("[WiFi] SoftAP.gw = "IPSTR, GOOD_IP2STR(wificonf->ap_addr.gw.addr));
wifi_softap_dhcps_stop(); wifi_softap_dhcps_stop();
// Configure DHCP // Configure DHCP
if (!wifi_set_ip_info(SOFTAP_IF, &wificonf->ap_addr)) { struct ip_info ipstruct;
ipstruct.ip.addr = wificonf->ap_addr_ip.addr;
ipstruct.netmask.addr = wificonf->ap_addr_mask.addr;
ipstruct.gw.addr = wificonf->ap_addr_ip.addr;
if (!wifi_set_ip_info(SOFTAP_IF, &ipstruct)) {
error("[WiFi] IP set fail!"); error("[WiFi] IP set fail!");
return; return;
} }
wifi_info("[WiFi] Configuring SoftAP DHCP server..."); wifi_info("[WiFi] Configuring SoftAP DHCP server...");
wifi_dbg("[WiFi] DHCP.start = "IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.start_ip.addr)); wifi_dbg("[WiFi] DHCP.start = "IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_start.addr));
wifi_dbg("[WiFi] DHCP.end = "IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.end_ip.addr)); wifi_dbg("[WiFi] DHCP.end = "IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_end.addr));
wifi_dbg("[WiFi] DHCP.lease = %d minutes", wificonf->ap_dhcp_time); wifi_dbg("[WiFi] DHCP.lease = %d minutes", wificonf->ap_dhcp_time);
if (!wifi_softap_set_dhcps_lease(&wificonf->ap_dhcp_range)) { struct dhcps_lease dhcpstruct;
dhcpstruct.start_ip = wificonf->ap_dhcp_start;
dhcpstruct.end_ip = wificonf->ap_dhcp_end;
dhcpstruct.enable = 1; // ???
if (!wifi_softap_set_dhcps_lease(&dhcpstruct)) {
error("[WiFi] DHCP address range set fail!"); error("[WiFi] DHCP address range set fail!");
return; return;
} }
@ -190,7 +318,7 @@ wifimgr_apply_settings(void)
} }
if (opmode != wificonf->opmode) { if (opmode != wificonf->opmode) {
wifi_set_opmode_current(wificonf->opmode); wifi_set_opmode_current((WIFI_MODE) wificonf->opmode);
} }
// Configure the client // Configure the client

@ -19,6 +19,43 @@
#define WIFICONF_VERSION 0 #define WIFICONF_VERSION 0
#define wifimgr_notify_ap() { wifi_change_flags.ap = true; }
#define wifimgr_notify_sta() { wifi_change_flags.ap = true; }
//....Type................Name..Suffix...............Deref..XGET.........Cast..XSET.........................NOTIFY
#define XTABLE_WIFI \
X(u8, opmode, , , xget_dec, , xset_wifi_opmode, NULL, xnoop) \
\
X(u8, tpw, , , xget_dec, , xset_wifi_tpw, NULL, wifimgr_notify_ap) \
X(u8, ap_channel, , , xget_dec, , xset_wifi_ap_channel, NULL, wifimgr_notify_ap) \
X(u8, ap_ssid, [SSID_LEN], , xget_ustring, (u8**), xset_wifi_ssid, 1, wifimgr_notify_ap) \
X(u8, ap_password, [PASSWORD_LEN], , xget_ustring, (u8**), xset_wifi_pwd, NULL, wifimgr_notify_ap) \
X(bool, ap_hidden, , , xget_bool, , xset_bool, NULL, wifimgr_notify_ap) \
\
X(u16, ap_dhcp_time, , , xget_dec, , xset_wifi_lease_time, NULL, wifimgr_notify_ap) \
X(u32, unused1, , , xget_dummy, , xset_dummy, NULL, xnoop) \
X(struct ip_addr, ap_dhcp_start, , &, xget_ip, , xset_ip, NULL, wifimgr_notify_ap) \
X(struct ip_addr, ap_dhcp_end, , &, xget_ip, , xset_ip, NULL, wifimgr_notify_ap) \
\
X(struct ip_addr, ap_addr_ip, , &, xget_ip, , xset_ip, NULL, wifimgr_notify_ap) \
X(struct ip_addr, ap_addr_mask, , &, xget_ip, , xset_ip, NULL, wifimgr_notify_ap) \
\
\
X(u32, unused2, , , xget_dummy, , xset_dummy, NULL, xnoop) \
X(u8, sta_ssid, [SSID_LEN], , xget_ustring, (u8**), xset_wifi_ssid, 0, wifimgr_notify_sta) \
X(u8, sta_password, [PASSWORD_LEN], , xget_ustring, (u8**), xset_wifi_pwd, NULL, wifimgr_notify_sta) \
X(bool, sta_dhcp_enable, , , xget_bool, , xset_bool, NULL, wifimgr_notify_sta) \
\
X(struct ip_addr, sta_addr_ip, , &, xget_ip, , xset_ip, NULL, wifimgr_notify_sta) \
X(struct ip_addr, sta_addr_mask, , &, xget_ip, , xset_ip, NULL, wifimgr_notify_sta) \
X(struct ip_addr, sta_addr_gw, , &, xget_ip, , xset_ip, NULL, wifimgr_notify_sta) \
\
\
X(u8, config_version, , , xget_dec, , xset_u8, NULL, xnoop)
// unused1 - replaces 'enabled' bit from old dhcps_lease struct
// unused2 - gap after 'ap_gw' which isn't used and doesn't make sense
/** /**
* A structure holding all configured WiFi parameters * A structure holding all configured WiFi parameters
* and the active state. * and the active state.
@ -26,25 +63,15 @@
* This block can be used eg. for WiFi config backup. * This block can be used eg. for WiFi config backup.
*/ */
typedef struct { typedef struct {
WIFI_MODE opmode : 8; #define X( \
u8 tpw; type, name, suffix, \
deref, xget, \
// AP config cast, xset, xsarg, \
u8 ap_channel; xnotify) type name suffix;
u8 ap_ssid[SSID_LEN];
u8 ap_password[PASSWORD_LEN]; XTABLE_WIFI
bool ap_hidden;
// #undef X
u16 ap_dhcp_time; // in minutes
struct dhcps_lease ap_dhcp_range;
struct ip_info ap_addr;
// Client config
u8 sta_ssid[SSID_LEN];
u8 sta_password[PASSWORD_LEN];
bool sta_dhcp_enable;
struct ip_info sta_addr;
u8 config_version;
} WiFiConfigBundle; } WiFiConfigBundle;
typedef struct { typedef struct {
@ -62,6 +89,13 @@ void wifimgr_apply_settings(void);
int getStaIpAsString(char *buffer); int getStaIpAsString(char *buffer);
enum xset_result xset_wifi_lease_time(const char *name, u16 *field, const char *buff, const void *arg);
enum xset_result xset_wifi_opmode(const char *name, u8 *field, const char *buff, const void *arg);
enum xset_result xset_wifi_tpw(const char *name, u8 *field, const char *buff, const void *arg);
enum xset_result xset_wifi_ap_channel(const char *name, u8 *field, const char *buff, const void *arg);
enum xset_result xset_wifi_ssid(const char *name, u8 **field, const char *buff, const void *arg);
enum xset_result xset_wifi_pwd(const char *name, u8 **field, const char *buff, const void *arg);
#if DEBUG_WIFI #if DEBUG_WIFI
#define wifi_warn warn #define wifi_warn warn
#define wifi_dbg dbg #define wifi_dbg dbg

Loading…
Cancel
Save