terminal settings page and backend

This commit is contained in:
2017-07-23 14:59:59 +02:00
parent 3c202a1f50
commit 5f3cb6685d
17 changed files with 694 additions and 442 deletions
+121 -43
View File
@@ -3,28 +3,24 @@ Cgi/template routines for configuring non-wifi settings
*/
#include <esp8266.h>
#include "cgi_wifi.h"
#include "wifimgr.h"
#include "cgi_appcfg.h"
#include "persist.h"
#include "screen.h"
#include "helpers.h"
// strcpy that adds 0 at the end of the buffer. Returns void.
#define strncpy_safe(dst, src, n) do { strncpy((char *)(dst), (char *)(src), (n)); (dst)[(n)-1]=0; } while (0)
#define SET_REDIR_SUC "/cfg/term"
#define SET_REDIR_ERR SET_REDIR_SUC"?err="
/**
* Universal CGI endpoint to set WiFi params.
* Note that some may cause a (delayed) restart.
* Universal CGI endpoint to set Terminal params.
*/
httpd_cgi_state ICACHE_FLASH_ATTR cgiAppCfgSet(HttpdConnData *connData)
{
static ETSTimer timer;
char buff[50];
#define REDIR_BASE_URL "/wifi?err="
char redir_url_buf[300];
char *redir_url = redir_url_buf;
redir_url += sprintf(redir_url, REDIR_BASE_URL);
redir_url += sprintf(redir_url, SET_REDIR_ERR);
// we'll test if anything was printed by looking for \0 in failed_keys_buf
if (connData->conn == NULL) {
@@ -32,40 +28,98 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiAppCfgSet(HttpdConnData *connData)
return HTTPD_CGI_DONE;
}
#define GET_ARG(key) (httpdFindArg(connData->getArgs, key, buff, sizeof(buff)) > 0)
// TODO
if (GET_ARG("opmode")) {
dbg("Setting WiFi opmode to: %s", buff);
int mode = atoi(buff);
if (mode > NULL_MODE && mode < MAX_MODE) {
wificonf->opmode = (WIFI_MODE) mode;
// width and height must always go together so we can do max size validation
if (GET_ARG("term_width")) {
dbg("Default screen width: %s", buff);
int w = atoi(buff);
if (w > 1) {
if (GET_ARG("term_height")) {
dbg("Default screen height: %s", buff);
int h = atoi(buff);
if (h > 1) {
if (w * h <= MAX_SCREEN_SIZE) {
termconf->width = w;
termconf->height = h;
} else {
warn("Bad dimensions: %d x %d (total %d)", w, h, w*h);
redir_url += sprintf(redir_url, "term_width,term_height,");
}
} else {
warn("Bad height: \"%s\"", buff);
redir_url += sprintf(redir_url, "term_width,");
}
} else {
warn("Missing height arg", buff);
// this wont happen normally when the form is used
redir_url += sprintf(redir_url, "term_width,term_height,");
}
} else {
warn("Bad opmode value \"%s\"", buff);
redir_url += sprintf(redir_url, "opmode,");
warn("Bad width: \"%s\"", buff);
redir_url += sprintf(redir_url, "term_width,");
}
}
if (redir_url_buf[strlen(REDIR_BASE_URL)] == 0) {
if (GET_ARG("default_bg")) {
dbg("Screen default BG: %s", buff);
int color = atoi(buff);
if (color >= 0 && color < 16) {
termconf->default_bg = (u8) color;
} else {
warn("Bad color %s", buff);
redir_url += sprintf(redir_url, "default_bg,");
}
}
if (GET_ARG("default_fg")) {
dbg("Screen default FG: %s", buff);
int color = atoi(buff);
if (color >= 0 && color < 16) {
termconf->default_fg = (u8) color;
} else {
warn("Bad color %s", buff);
redir_url += sprintf(redir_url, "default_fg,");
}
}
if (GET_ARG("term_title")) {
dbg("Terminal title default text: \"%s\"", buff);
strncpy_safe(termconf->title, buff, 64); // ATTN those must match the values in
}
if (GET_ARG("btn1")) {
dbg("Button1 default text: \"%s\"", buff);
strncpy_safe(termconf->btn1, buff, 10);
}
if (GET_ARG("btn2")) {
dbg("Button1 default text: \"%s\"", buff);
strncpy_safe(termconf->btn2, buff, 10);
}
if (GET_ARG("btn3")) {
dbg("Button1 default text: \"%s\"", buff);
strncpy_safe(termconf->btn3, buff, 10);
}
if (GET_ARG("btn4")) {
dbg("Button1 default text: \"%s\"", buff);
strncpy_safe(termconf->btn4, buff, 10);
}
if (GET_ARG("btn5")) {
dbg("Button1 default text: \"%s\"", buff);
strncpy_safe(termconf->btn5, buff, 10);
}
if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) {
// All was OK
info("Set WiFi params - success, applying in 1000 ms");
info("Set app params - success, saving...");
// Settings are applied only if all was OK
//
// This is so that options that consist of multiple keys sent together are not applied
// only partially if set wrong, which could lead to eg. user losing access and having
// to reset to defaults.
persist_store();
// Delayed settings apply, so the response page has a chance to load.
// If user connects via the Station IF, they may not even notice the connection reset.
os_timer_disarm(&timer);
os_timer_setfn(&timer, applyWifiSettingsLaterCb, NULL);
os_timer_arm(&timer, 1000, false);
httpdRedirect(connData, "/wifi");
httpdRedirect(connData, SET_REDIR_SUC);
} else {
warn("Some WiFi settings did not validate, asking for correction");
warn("Some settings did not validate, asking for correction");
// Some errors, appended to the URL as ?err=
httpdRedirect(connData, redir_url_buf);
}
@@ -73,12 +127,10 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiAppCfgSet(HttpdConnData *connData)
}
//Template code for the WLAN page.
httpd_cgi_state ICACHE_FLASH_ATTR tplAppCfg(HttpdConnData *connData, char *token, void **arg)
{
char buff[100];
int x;
int connectStatus;
#define BUFLEN 100
char buff[BUFLEN];
if (token == NULL) {
// We're done
@@ -87,9 +139,35 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplAppCfg(HttpdConnData *connData, char *token
strcpy(buff, ""); // fallback
// TODO
if (streq(token, "opmode_name")) {
strcpy(buff, opmode2str(wificonf->opmode));
if (streq(token, "term_width")) {
sprintf(buff, "%d", termconf->width);
}
else if (streq(token, "term_height")) {
sprintf(buff, "%d", termconf->height);
}
else if (streq(token, "default_bg")) {
sprintf(buff, "%d", termconf->default_bg);
}
else if (streq(token, "default_fg")) {
sprintf(buff, "%d", termconf->default_bg);
}
else if (streq(token, "term_title")) {
strncpy_safe(buff, termconf->title, BUFLEN);
}
else if (streq(token, "btn1")) {
strncpy_safe(buff, termconf->btn1, BUFLEN);
}
else if (streq(token, "btn2")) {
strncpy_safe(buff, termconf->btn2, BUFLEN);
}
else if (streq(token, "btn3")) {
strncpy_safe(buff, termconf->btn3, BUFLEN);
}
else if (streq(token, "btn4")) {
strncpy_safe(buff, termconf->btn4, BUFLEN);
}
else if (streq(token, "btn5")) {
strncpy_safe(buff, termconf->btn5, BUFLEN);
}
httpdSend(connData, buff, -1);
+251
View File
@@ -0,0 +1,251 @@
/*
configuring the network settings
*/
#include <esp8266.h>
#include "cgi_network.h"
#include "wifimgr.h"
#include "persist.h"
#include "helpers.h"
#define SET_REDIR_SUC "/cfg/network"
#define SET_REDIR_ERR SET_REDIR_SUC"?err="
/**
* Callback for async timer
*/
static void ICACHE_FLASH_ATTR applyNetSettingsLaterCb(void *arg)
{
wifimgr_apply_settings();
}
/**
* Universal CGI endpoint to set network params.
* Those affect DHCP etc, may cause a disconnection.
*/
httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
{
static ETSTimer timer;
char buff[50];
char redir_url_buf[300];
char *redir_url = redir_url_buf;
redir_url += sprintf(redir_url, SET_REDIR_ERR);
// we'll test if anything was printed by looking for \0 in failed_keys_buf
if (connData->conn == NULL) {
//Connection aborted. Clean up.
return HTTPD_CGI_DONE;
}
// ---- AP DHCP server lease time ----
if (GET_ARG("ap_dhcp_time")) {
dbg("Setting DHCP lease time to: %s min.", buff);
int min = atoi(buff);
if (min >= 1 && min <= 2880) {
if (wificonf->ap_dhcp_time != min) {
wificonf->ap_dhcp_time = (u16) min;
wifi_change_flags.ap = true;
}
} else {
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")) {
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 {
warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_dhcp_start,");
}
}
if (GET_ARG("ap_dhcp_end")) {
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 {
warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_dhcp_end,");
}
}
// ---- AP local address & config ----
if (GET_ARG("ap_addr_ip")) {
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 {
warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_addr_ip,");
}
}
if (GET_ARG("ap_addr_mask")) {
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 {
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")) {
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")) {
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 {
warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_ip,");
}
}
if (GET_ARG("sta_addr_mask")) {
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 {
warn("Bad IP mask: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_mask,");
}
}
if (GET_ARG("sta_addr_gw")) {
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 {
warn("Bad gw IP: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_gw,");
}
}
if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) {
// All was OK
info("Set network params - success, applying in 1000 ms");
// Settings are applied only if all was OK
persist_store();
// Delayed settings apply, so the response page has a chance to load.
// If user connects via the Station IF, they may not even notice the connection reset.
os_timer_disarm(&timer);
os_timer_setfn(&timer, applyNetSettingsLaterCb, NULL);
os_timer_arm(&timer, 1000, false);
httpdRedirect(connData, SET_REDIR_SUC);
} else {
warn("Some WiFi settings did not validate, asking for correction");
// Some errors, appended to the URL as ?err=
httpdRedirect(connData, redir_url_buf);
}
return HTTPD_CGI_DONE;
}
//Template code for the WLAN page.
httpd_cgi_state ICACHE_FLASH_ATTR tplNetwork(HttpdConnData *connData, char *token, void **arg)
{
char buff[100];
u8 mac[6];
if (token == NULL) {
// We're done
return HTTPD_CGI_DONE;
}
strcpy(buff, ""); // fallback
if (streq(token, "ap_dhcp_time")) {
sprintf(buff, "%d", wificonf->ap_dhcp_time);
}
else if (streq(token, "ap_dhcp_start")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.start_ip.addr));
}
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, "ap_addr_mask")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.netmask.addr));
}
else if (streq(token, "ap_addr_gw")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.gw.addr));
}
else if (streq(token, "sta_mac")) {
wifi_get_macaddr(STATION_IF, mac);
sprintf(buff, MACSTR, MAC2STR(mac));
}
else if (streq(token, "ap_mac")) {
wifi_get_macaddr(SOFTAP_IF, mac);
sprintf(buff, MACSTR, MAC2STR(mac));
}
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
}
+9
View File
@@ -0,0 +1,9 @@
#ifndef CGINET_H
#define CGINET_H
#include "httpd.h"
httpd_cgi_state cgiNetworkSetParams(HttpdConnData *connData);
httpd_cgi_state tplNetwork(HttpdConnData *connData, char *token, void **arg);
#endif
+40 -301
View File
@@ -17,9 +17,10 @@ Cgi/template routines for the /wifi url.
#include "cgi_wifi.h"
#include "wifimgr.h"
#include "persist.h"
#include "helpers.h"
// strcpy that adds 0 at the end of the buffer. Returns void.
#define strncpy_safe(dst, src, n) do { strncpy((char *)(dst), (char *)(src), (n)); (dst)[(n)-1]=0; } while (0)
#define SET_REDIR_SUC "/cfg/wifi"
#define SET_REDIR_ERR SET_REDIR_SUC"?err="
/** WiFi access point data */
typedef struct {
@@ -40,17 +41,6 @@ typedef struct {
/** Static scan status storage. */
static ScanResultData cgiWifiAps;
/** Progress of connection to AP enum */
typedef enum {
CONNTRY_IDLE = 0,
CONNTRY_WORKING = 1,
CONNTRY_SUCCESS = 2,
CONNTRY_FAIL = 3,
} ConnTry;
/** Connection result var */
static ConnTry connTryStatus = CONNTRY_IDLE;
/** Connection to AP periodic check timer */
static os_timer_t staCheckTimer;
@@ -257,102 +247,6 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData)
}
}
/**
* This routine is ran some time after a connection attempt to an access point. If
* the connect succeeds, this gets the module in STA-only mode.
*/
static void ICACHE_FLASH_ATTR staCheckConnStatus(void *arg)
{
int x = wifi_station_get_connect_status();
if (x == STATION_GOT_IP) {
info("Connected to AP.");
connTryStatus = CONNTRY_SUCCESS;
// This would enter STA only mode, but that kills the browser page if using STA+AP.
// Instead we stay in the current mode and let the user switch manually.
//wifi_set_opmode(STATION_MODE);
//system_restart();
}
else {
connTryStatus = CONNTRY_FAIL;
error("Connection failed.");
}
}
/**
* Delayed connect callback
*/
static void ICACHE_FLASH_ATTR cgiWiFiConnect_do(void *arg)
{
int x;
struct station_config cfg;
dbg("Try to connect to AP...");
strncpy_safe(cfg.password, wificonf->sta_password, PASSWORD_LEN);
strncpy_safe(cfg.ssid, wificonf->sta_ssid, SSID_LEN);
cfg.bssid_set = 0;
wifi_station_disconnect();
wifi_station_set_config(&cfg);
wifi_station_connect();
x = wifi_get_opmode();
connTryStatus = CONNTRY_WORKING;
// Assumption:
// if we're in station mode, no need to check: the browser will be disconnected
// and the user finds out whether it succeeded or not by checking if they can connect
if (x != STATION_MODE) {
os_timer_disarm(&staCheckTimer);
os_timer_setfn(&staCheckTimer, staCheckConnStatus, NULL);
os_timer_arm(&staCheckTimer, 15000, 0); //time out after 15 secs of trying to connect
}
}
/**
* This cgi uses the routines above to connect to a specific access point with the
* given ESSID using the given password.
*
* Args:
* - essid = SSID to connect to
* - passwd = password to connect with
*/
httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData)
{
char ssid[100];
char password[100];
static os_timer_t reassTimer;
if (connData->conn == NULL) {
//Connection aborted. Clean up.
return HTTPD_CGI_DONE;
}
int ssilen = httpdFindArg(connData->post->buff, "sta_ssid", ssid, sizeof(ssid));
int passlen = httpdFindArg(connData->post->buff, "sta_password", password, sizeof(password));
if (ssilen == -1 || passlen == -1) {
error("Did not receive the required arguments!");
httpdRedirect(connData, "/wifi");
}
else {
strncpy_safe(wificonf->sta_ssid, ssid, SSID_LEN);
strncpy_safe(wificonf->sta_password, password, PASSWORD_LEN);
info("Try to connect to AP \"%s\" pw \"%s\".", ssid, password);
//Schedule disconnect/connect
os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, cgiWiFiConnect_do, NULL);
// redirect & start connecting a little bit later
os_timer_arm(&reassTimer, 1000, 0); // was 500, increased so the connecting page has time to load
connTryStatus = CONNTRY_IDLE;
httpdRedirect(connData, "/wifi/connecting"); // this page is meant to show progress
}
return HTTPD_CGI_DONE;
}
/**
* Cgi to get connection status.
*
@@ -363,45 +257,56 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData)
httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData)
{
char buff[100];
int len;
struct ip_info info;
int st = wifi_station_get_connect_status();
httpdStartResponse(connData, 200);
httpdHeader(connData, "Content-Type", "application/json");
httpdEndHeaders(connData);
if (connTryStatus == CONNTRY_IDLE) {
len = sprintf(buff, "{\"status\": \"idle\"}");
}
else if (connTryStatus == CONNTRY_WORKING || connTryStatus == CONNTRY_SUCCESS) {
if (st == STATION_GOT_IP) {
wifi_get_ip_info(STATION_IF, &info);
len = sprintf(buff, "{\"status\": \"success\", \"ip\": \""
IPSTR
"\"}", GOOD_IP2STR(info.ip.addr));
os_timer_disarm(&staCheckTimer);
os_timer_setfn(&staCheckTimer, staCheckConnStatus, NULL);
os_timer_arm(&staCheckTimer, 1000, 0);
} else {
len = sprintf(buff, "{\"status\": \"working\"}");
}
}
else {
len = sprintf(buff, "{\"status\": \"fail\"}");
// if bad opmode or no SSID configured, skip any checks
if (!(wificonf->opmode & STATION_MODE) || wificonf->sta_ssid[0] == 0) {
httpdSend(connData, "{\"status\": \"disabled\"}", -1);
return HTTPD_CGI_DONE;
}
httpdSend(connData, buff, len);
STATION_STATUS st = wifi_station_get_connect_status();
switch(st) {
case STATION_IDLE:
sprintf(buff, "{\"status\": \"idle\"}"); // unclear when this is used
break;
case STATION_CONNECTING:
sprintf(buff, "{\"status\": \"working\"}");
break;
case STATION_WRONG_PASSWORD:
sprintf(buff, "{\"status\": \"fail\", \"cause\": \"WRONG_PASSWORD\"}");
break;
case STATION_NO_AP_FOUND:
sprintf(buff, "{\"status\": \"fail\", \"cause\": \"AP_NOT_FOUND\"}");
break;
case STATION_CONNECT_FAIL:
sprintf(buff, "{\"status\": \"fail\", \"cause\": \"CONNECTION_FAILED\"}");
break;
case STATION_GOT_IP:
wifi_get_ip_info(STATION_IF, &info);
sprintf(buff, "{\"status\": \"success\", \"ip\": \""IPSTR"\"}", GOOD_IP2STR(info.ip.addr));
break;
}
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
}
/** reset_later() timer */
/**
* Callback for async timer
*/
static void ICACHE_FLASH_ATTR applyWifiSettingsLaterCb(void *arg)
{
(void*)arg;
wifimgr_apply_settings();
}
@@ -415,11 +320,9 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
char buff[50];
#define REDIR_BASE_URL "/wifi?err="
char redir_url_buf[300];
char *redir_url = redir_url_buf;
redir_url += sprintf(redir_url, REDIR_BASE_URL);
redir_url += sprintf(redir_url, SET_REDIR_ERR);
// we'll test if anything was printed by looking for \0 in failed_keys_buf
if (connData->conn == NULL) {
@@ -427,8 +330,6 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
return HTTPD_CGI_DONE;
}
#define GET_ARG(key) (httpdFindArg(connData->getArgs, key, buff, sizeof(buff)) > 0)
// ---- WiFi opmode ----
if (GET_ARG("opmode")) {
@@ -548,85 +449,6 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
}
}
// ---- AP DHCP server lease time ----
if (GET_ARG("ap_dhcp_time")) {
dbg("Setting DHCP lease time to: %s min.", buff);
int min = atoi(buff);
if (min >= 1 && min <= 2880) {
if (wificonf->ap_dhcp_time != min) {
wificonf->ap_dhcp_time = (u16) min;
wifi_change_flags.ap = true;
}
} else {
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")) {
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 {
warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_dhcp_start,");
}
}
if (GET_ARG("ap_dhcp_end")) {
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 {
warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_dhcp_end,");
}
}
// ---- AP local address & config ----
if (GET_ARG("ap_addr_ip")) {
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 {
warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_addr_ip,");
}
}
if (GET_ARG("ap_addr_mask")) {
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 {
warn("Bad IP mask: %s", buff);
redir_url += sprintf(redir_url, "ap_addr_mask,");
}
}
// ---- Station SSID (to connect to) ----
if (GET_ARG("sta_ssid")) {
@@ -649,63 +471,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
}
}
// ---- Station enable/disable DHCP ----
// DHCP enable / disable (disable means static IP is enabled)
if (GET_ARG("sta_dhcp_enable")) {
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")) {
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 {
warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_ip,");
}
}
if (GET_ARG("sta_addr_mask")) {
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 {
warn("Bad IP mask: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_mask,");
}
}
if (GET_ARG("sta_addr_gw")) {
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 {
warn("Bad gw IP: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_gw,");
}
}
if (redir_url_buf[strlen(REDIR_BASE_URL)] == 0) {
if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) {
// All was OK
info("Set WiFi params - success, applying in 1000 ms");
@@ -722,7 +488,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
os_timer_setfn(&timer, applyWifiSettingsLaterCb, NULL);
os_timer_arm(&timer, 1000, false);
httpdRedirect(connData, "/wifi");
httpdRedirect(connData, SET_REDIR_SUC);
} else {
warn("Some WiFi settings did not validate, asking for correction");
// Some errors, appended to the URL as ?err=
@@ -773,39 +539,12 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token,
else if (streq(token, "ap_hidden")) {
sprintf(buff, "%d", wificonf->ap_hidden);
}
else if (streq(token, "ap_dhcp_time")) {
sprintf(buff, "%d", wificonf->ap_dhcp_time);
}
else if (streq(token, "ap_dhcp_start")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.start_ip.addr));
}
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_ssid")) {
sprintf(buff, "%s", wificonf->sta_ssid);
}
else if (streq(token, "sta_password")) {
sprintf(buff, "%s", wificonf->sta_password);
}
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, "ap_addr_mask")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.netmask.addr));
}
else if (streq(token, "ap_addr_gw")) {
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.gw.addr));
}
else if (streq(token, "sta_rssi")) {
sprintf(buff, "%d", wifi_station_get_rssi());
}
+3 -23
View File
@@ -2,32 +2,12 @@
#define CGIWIFI_H
#include "httpd.h"
/**
* Convert IP hex to arguments for printf.
* Library IP2STR(ip) does not work correctly due to unaligned memory access.
*/
#define GOOD_IP2STR(ip) ((ip)>>0)&0xff, ((ip)>>8)&0xff, ((ip)>>16)&0xff, ((ip)>>24)&0xff
#include "helpers.h"
httpd_cgi_state cgiWiFiScan(HttpdConnData *connData);
httpd_cgi_state cgiWiFiConnect(HttpdConnData *connData);
httpd_cgi_state cgiWiFiConnStatus(HttpdConnData *connData);
httpd_cgi_state cgiWiFiSetParams(HttpdConnData *connData);
httpd_cgi_state tplWlan(HttpdConnData *connData, char *token, void **arg);
// WiFi config options:
// - Persistent
// - channel
// - AP ssid
// - opmode
// - AP to connect to
// - Temporary
// - sta_hostname (sta)
// - tpw (ap, sta+ap?)
// - dhcp_lt (ap, sta+ap)
// - static IP
// - static mask
// - static gw
// - dhcp enable or disable
httpd_cgi_state cgiWiFiConnStatus(HttpdConnData *connData);
#endif