diff --git a/CMakeLists.txt b/CMakeLists.txt index 2701a1e..8e4efcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,8 @@ set(SOURCE_FILES user/io.h user/cgi_wifi.c user/cgi_wifi.h + user/cgi_network.c + user/cgi_network.h user/cgi_appcfg.c user/cgi_appcfg.h user/cgi_ping.c @@ -119,7 +121,7 @@ set(SOURCE_FILES user/wifimgr.c user/wifimgr.h user/persist.c - user/persist.h) + user/persist.h include/helpers.h) include_directories(include) include_directories(user) diff --git a/html_orig/_debug_replacements.php b/html_orig/_debug_replacements.php index 3cde458..e693ea1 100644 --- a/html_orig/_debug_replacements.php +++ b/html_orig/_debug_replacements.php @@ -8,11 +8,12 @@ return [ '%term_title%' => 'ESP8266 Wireless Terminal', - '%b1%' => '1', - '%b2%' => '2', - '%b3%' => '3', - '%b4%' => '4', - '%b5%' => '5', + '%btn1%' => '1', + '%btn2%' => '2', + '%btn3%' => '3', + '%btn4%' => '4', + '%btn5%' => '5', + '%screenData%' => '{ "w": 26, "h": 10, "x": 0, "y": 0, @@ -50,4 +51,12 @@ return [ '%sta_addr_ip%' => '192.168.0.33', '%sta_addr_mask%' => '255.255.255.0', '%sta_addr_gw%' => '192.168.0.1', + + '%sta_mac%' => 'ab:cd:ef:01:23:45', + '%ap_mac%' => '01:23:45:ab:cd:ef', + + '%term_width%' => '26', + '%term_height%' => '10', + '%default_bg%' => '0', + '%default_fg%' => '7', ]; diff --git a/html_orig/_pages.php b/html_orig/_pages.php index 30e66f5..2db1299 100644 --- a/html_orig/_pages.php +++ b/html_orig/_pages.php @@ -17,17 +17,22 @@ if (! function_exists('pg')) { } } -pg('cfg_wifi', 'cfg', '/cfg/wifi'); -pg('cfg_wifi_conn', '', '/wifi/connecting'); // page without menu that tries to show the connection progress -pg('cfg_network', 'cfg', '/cfg/network'); -//pg('cfg_term', 'cfg', '/cfg/term'); -pg('help', 'cfg page-help', '/help'); +pg('cfg_wifi', 'cfg', '/cfg/wifi'); +pg('cfg_wifi_conn', '', '/cfg/wifi/connecting'); +pg('wifi_connstatus', 'api', '/cfg/wifi/connstatus'); +pg('wifi_set', 'api', '/cfg/wifi/set'); +pg('wifi_scan', 'api', '/cfg/wifi/scan'); + +pg('cfg_network', 'cfg', '/cfg/network'); +pg('network_set', 'api', '/cfg/network/set'); + +pg('cfg_app', 'cfg', '/cfg/app'); +pg('app_set', 'api', '/cfg/app/set'); + +pg('help', 'cfg page-help', '/help'); pg('about', 'cfg page-about', '/about'); -pg('term', 'term', '/', 'title.term'); +pg('term', 'term', '/', 'title.term'); // ajax API -pg('wifi_set', 'api', '/wifi/set');//'/cfg/wifi/set'); -pg('wifi_scan', 'api', '/wifi/scan');//'/cfg/wifi/scan'); -pg('wifi_connstatus', 'api', '/wifi/connstatus'); return $pages; diff --git a/html_orig/css/app.css b/html_orig/css/app.css index f425e9a..bf34372 100644 --- a/html_orig/css/app.css +++ b/html_orig/css/app.css @@ -489,14 +489,17 @@ ul > * { margin-top: 1rem; padding: 0.61805rem 1rem; border-radius: 3px; - background-color: rgba(255, 255, 255, 0.07); } + background-color: rgba(255, 255, 255, 0.07); + box-shadow: 0 0 4px black; + border: 1px solid #4f4f4f; } @media screen and (max-width: 544px) { .Box { margin-top: 0.61805rem; } } h1 + .Box { margin-top: 0; } .Box h2 { - margin-top: 0; } + margin-top: 0; + margin-bottom: 0 !important; } .Box.wide { width: initial; max-width: initial; } @@ -515,13 +518,26 @@ ul > * { right: 0; top: 0; margin-top: 0.61805rem; } } + .Box.str.mobopen .Row.buttons { + top: 0; + margin-top: 0.61805rem; } + .Box .Row.explain { + max-width: 600px; + margin-left: 0; } + @media screen and (max-width: 544px) { + .Box .Row.explain { + margin-top: 60px; } } + .Box.mobopen .Row.explain { + margin-top: 12px; } + @media screen and (max-width: 544px) { + .Box.mobopen .Row.explain { + margin-top: 18px; } } @media screen and (max-width: 544px) { .Box.mobcol h2 { position: relative; cursor: pointer; - padding-right: 1.3rem; - margin-bottom: 0 !important; } + padding-right: 1.3rem; } .Box.mobcol h2::after { position: absolute; right: 0; @@ -732,7 +748,7 @@ form { input[type="number"], input[type="password"], input[type="text"], textarea, select, label.select-wrap { width: 250px; } -input[type="number"] { +input[type="number"], input.short { width: 125px; } .Box.errors .list { @@ -741,46 +757,46 @@ input[type="number"] { .Box.errors .lead { color: white; } -form .Row { +.Row { vertical-align: middle; margin: 12px auto; text-align: left; display: flex; flex-direction: row; align-items: center; } - form .Row:first-child { + .Row:first-child { margin-top: 0; } - form .Row:last-child { + .Row:last-child { margin-bottom: 0; } - form .Row .spacer { + .Row .spacer { width: 160px; } @media screen and (max-width: 544px) { - form .Row .spacer { + .Row .spacer { display: none; } } - form .Row.buttons { + .Row.buttons { margin: 16px auto; } - form .Row.buttons input, form .Row.buttons .button { + .Row.buttons input, .Row.buttons .button { margin-right: 0.61805rem; } - form .Row.centered { + .Row.centered { justify-content: center; } - form .Row.message { + .Row.message { font-size: 1em; text-shadow: 1px 1px 3px black; text-align: center; } - form .Row.message.error { + .Row.message.error { color: crimson; } - form .Row.message.ok { + .Row.message.ok { color: #0fe851; } - form .Row.separator { + .Row.separator { padding-top: 14px; border-top: 2px solid rgba(255, 255, 255, 0.1); } - form .Row textarea { + .Row textarea { display: inline-block; vertical-align: top; min-height: 10rem; flex-grow: 1; resize: vertical; } - form .Row label { + .Row label { font-weight: bold; color: white; display: inline-block; @@ -795,32 +811,33 @@ form .Row { user-select: none; white-space: nowrap; word-wrap: normal; } - form .Row label.error { + .Row label.error { color: crimson; } - form .Row input[type="range"] { + .Row input[type="range"] { width: 200px; } @media screen and (max-width: 544px) { - form .Row { - flex-direction: column; } - form .Row.buttons, form .Row.centered, form .Row.checkbox { + .Row { + flex-direction: column; + margin: 6px auto; } + .Row.buttons, .Row.centered, .Row.checkbox { flex-direction: row; } - form .Row.buttons { + .Row.buttons { justify-content: center; } - form .Row.buttons :last-child { + .Row.buttons :last-child { margin-right: 0; } - form .Row label { + .Row label { padding-left: 0; text-align: left; width: auto; } - form .Row .checkbox-wrap { + .Row .checkbox-wrap { order: 1; text-align: left; padding-bottom: 0; border-radius: .4px; width: auto; } - form .Row .checkbox-wrap + label { + .Row .checkbox-wrap + label { width: auto; } - form .Row input[type="number"], form .Row input[type="password"], form .Row input[type="text"], form .Row textarea, form .Row input[type="range"], form .Row textarea { + .Row input[type="number"], .Row input[type="password"], .Row input[type="text"], .Row textarea, .Row input[type="range"], .Row textarea, .Row select { width: 100%; } } form span.required { diff --git a/html_orig/lang/en.php b/html_orig/lang/en.php index f866c36..3c5c115 100644 --- a/html_orig/lang/en.php +++ b/html_orig/lang/en.php @@ -5,7 +5,7 @@ return [ 'menu.cfg_wifi' => 'WiFi Settings', 'menu.cfg_network' => 'Network Configuration', - 'menu.cfg_term' => 'Terminal Settings', + 'menu.cfg_app' => 'Terminal Settings', 'menu.about' => 'About ESPTerm', 'menu.help' => 'Quick Reference', 'menu.term' => 'Back to Terminal', @@ -13,8 +13,46 @@ return [ 'title.term' => 'Terminal', - 'net.ap' => 'DHCP Server', - 'net.sta' => 'DHCP Client', + 'net.ap' => 'DHCP Server (AP)', + 'net.sta' => 'DHCP Client (Station)', + 'net.sta_mac' => 'Station MAC', + 'net.ap_mac' => 'AP MAC', + 'net.details' => 'MAC addresses', + + 'app.defaults' => 'Initial settings', + 'app.explain_initials' => ' + Those are the initial settings used after ESPTerm restarts, and they + will also be applied immediately after you submit this form. + They can be subsequently changed by ESC commands, but those changes + aren\'t persistent and will be lost when the device powers off.', + + 'app.term_title' => 'Header text', + 'app.term_width' => 'Screen width', + 'app.term_height' => 'Screen height', + 'app.default_fg' => 'Base text color', + 'app.default_bg' => 'Base background', + 'app.btn1' => 'Button 1 text', + 'app.btn2' => 'Button 2 text', + 'app.btn3' => 'Button 3 text', + 'app.btn4' => 'Button 4 text', + 'app.btn5' => 'Button 5 text', + + 'color.0' => 'Black', + 'color.1' => 'Dark Red', + 'color.2' => 'Dark Green', + 'color.3' => 'Dim Yellow', + 'color.4' => 'Deep Blue', + 'color.5' => 'Dark Violet', + 'color.6' => 'Dark Cyan', + 'color.7' => 'Silver', + 'color.8' => 'Gray', + 'color.9' => 'Light Red', + 'color.10' => 'Light Green', + 'color.11' => 'Light Yellow', + 'color.12' => 'Light Blue', + 'color.13' => 'Light Violet', + 'color.14' => 'Light Cyan', + 'color.15' => 'White', 'net.explain_sta' => ' Those settings affect the built-in DHCP client used for @@ -42,16 +80,14 @@ return [ 'wifi.ap' => 'Built-in Access Point', 'wifi.sta' => 'Connect to External Network', - 'wifi.enable' => 'Enabled:', - 'wifi.tpw' => 'Transmit Power:', - 'wifi.ap_channel' => 'Channel:', - 'wifi.ap_ssid' => 'AP SSID:', - 'wifi.ap_password' => 'Password:', - 'wifi.ap_hidden' => 'Hide SSID:', - 'wifi.sta_info' => 'Selected:', + 'wifi.enable' => 'Enabled', + 'wifi.tpw' => 'Transmit power', + 'wifi.ap_channel' => 'Channel', + 'wifi.ap_ssid' => 'AP SSID', + 'wifi.ap_password' => 'Password', + 'wifi.ap_hidden' => 'Hide SSID', + 'wifi.sta_info' => 'Selected', - 'wifi.sta_ssid' => 'Network SSID:', - 'wifi.sta_password' => 'Password:', 'wifi.not_conn' => 'Not connected.', 'wifi.sta_none' => 'None', 'wifi.sta_active_pw' => '🔒', @@ -67,10 +103,11 @@ return [ 'wifi.conn.back_to_config' => 'Back to WiFi config', 'wifi.conn.telemetry_lost' => 'Telemetry lost, something went wrong. Try again...', - 'wifi.conn.idle' =>"Preparing to connect", + 'wifi.conn.disabled' =>"Station mode is disabled.", + 'wifi.conn.idle' =>"Idle, not connected and with no IP.", 'wifi.conn.success' => "Connected! Received IP ", 'wifi.conn.working' => "Connecting to selected AP", - 'wifi.conn.fail' => "Connection failed, check your password and try again.", + 'wifi.conn.fail' => "Connection failed, check settings & try again. Cause: ", 'apply' => 'Apply!', 'enabled' => 'Enabled', diff --git a/html_orig/pages/cfg_app.php b/html_orig/pages/cfg_app.php new file mode 100644 index 0000000..f030da4 --- /dev/null +++ b/html_orig/pages/cfg_app.php @@ -0,0 +1,71 @@ +
+

+ +
+ +
+ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
diff --git a/html_orig/pages/cfg_network.php b/html_orig/pages/cfg_network.php index cf7672b..9e687a1 100644 --- a/html_orig/pages/cfg_network.php +++ b/html_orig/pages/cfg_network.php @@ -2,15 +2,14 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"'; ?> -
+

-
-
+
@@ -41,15 +40,14 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
-
+

-
-
+
@@ -74,3 +72,14 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"'; required>
+ +
+

+ +
+ +
+
+ +
+
diff --git a/html_orig/pages/cfg_wifi_conn.php b/html_orig/pages/cfg_wifi_conn.php index e12cfa2..a5cab5a 100755 --- a/html_orig/pages/cfg_wifi_conn.php +++ b/html_orig/pages/cfg_wifi_conn.php @@ -10,6 +10,7 @@ var abortTmeo; var messages = tr('wifi.conn.disabled'), 'idle' => tr('wifi.conn.idle'), 'success' => tr('wifi.conn.success'), 'working' => tr('wifi.conn.working'), @@ -25,6 +26,7 @@ var done = false; var msg = messages[data.status] || '...'; if (data.status == 'success') msg += data.ip; + if (data.status == 'fail') msg += data.cause; $("#status").html(msg); diff --git a/html_orig/pages/term.php b/html_orig/pages/term.php index 427efb5..1dbf074 100644 --- a/html_orig/pages/term.php +++ b/html_orig/pages/term.php @@ -13,11 +13,11 @@
- +
diff --git a/html_orig/sass/form/_form_layout.scss b/html_orig/sass/form/_form_layout.scss index 2f0d570..ec373a7 100755 --- a/html_orig/sass/form/_form_layout.scss +++ b/html_orig/sass/form/_form_layout.scss @@ -5,7 +5,7 @@ form { @include naked(); } width: $form-field-w; } -input[type="number"] { +input[type="number"], input.short { width: $form-field-w/2; } @@ -20,7 +20,7 @@ input[type="number"] { } } -form .Row { +.Row { vertical-align: middle; margin: 12px auto; text-align: left; @@ -132,6 +132,7 @@ form .Row { // special phone style @include media($phone) { flex-direction: column; + margin: 6px auto; &.buttons, &.centered, &.checkbox { flex-direction: row; @@ -165,7 +166,7 @@ form .Row { } } - #{$all-text-inputs}, input[type="range"], textarea { + #{$all-text-inputs}, input[type="range"], textarea, select { width: 100%; } } diff --git a/html_orig/sass/layout/_box.scss b/html_orig/sass/layout/_box.scss index def421f..cdd80b3 100755 --- a/html_orig/sass/layout/_box.scss +++ b/html_orig/sass/layout/_box.scss @@ -15,10 +15,13 @@ h2 { margin-top: 0; + margin-bottom: 0 !important; } border-radius: 3px; background-color: rgba(white, .07); + box-shadow: 0 0 4px black; + border: 1px solid #4f4f4f; &.wide { width: initial; @@ -52,6 +55,25 @@ } } } + + &.str.mobopen .Row.buttons { + top: 0; + margin-top: dist(-1); + } + + .Row.explain { + max-width: 600px; margin-left: 0; + @include media($phone) { + margin-top: 60px; + } + } + &.mobopen .Row.explain { + margin-top: 12px; // default from .Row + + @include media($phone) { + margin-top: 18px; + } + } } @include media($phone) { @@ -71,8 +93,6 @@ font-weight: bold; transform: translate(0,-50%) rotate(90deg); } - - margin-bottom: 0 !important; } &.expanded h2::after { diff --git a/include/helpers.h b/include/helpers.h new file mode 100644 index 0000000..37eeba8 --- /dev/null +++ b/include/helpers.h @@ -0,0 +1,22 @@ +// +// Created by MightyPork on 2017/07/23. +// + +#ifndef ESP_VT100_FIRMWARE_HELPERS_H +#define ESP_VT100_FIRMWARE_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) + +/** + * 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 + +/** + * Helper that retrieves an arg from `connData->getArgs` and stores it in `buff`. Returns 1 on success + */ +#define GET_ARG(key) (httpdFindArg(connData->getArgs, key, buff, sizeof(buff)) > 0) + +#endif //ESP_VT100_FIRMWARE_HELPERS_H diff --git a/user/cgi_appcfg.c b/user/cgi_appcfg.c index 87c1b73..0c3fe50 100644 --- a/user/cgi_appcfg.c +++ b/user/cgi_appcfg.c @@ -3,28 +3,24 @@ Cgi/template routines for configuring non-wifi settings */ #include -#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) + // 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 width: \"%s\"", buff); + redir_url += sprintf(redir_url, "term_width,"); + } + } + + 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,"); + } + } - // 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; + 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 opmode value \"%s\"", buff); - redir_url += sprintf(redir_url, "opmode,"); + warn("Bad color %s", buff); + redir_url += sprintf(redir_url, "default_fg,"); } } - if (redir_url_buf[strlen(REDIR_BASE_URL)] == 0) { + 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); diff --git a/user/cgi_network.c b/user/cgi_network.c new file mode 100644 index 0000000..5067c49 --- /dev/null +++ b/user/cgi_network.c @@ -0,0 +1,251 @@ +/* +configuring the network settings +*/ + +#include +#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; +} diff --git a/user/cgi_network.h b/user/cgi_network.h new file mode 100644 index 0000000..818c953 --- /dev/null +++ b/user/cgi_network.h @@ -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 diff --git a/user/cgi_wifi.c b/user/cgi_wifi.c index 31b1ed7..2a45e2a 100644 --- a/user/cgi_wifi.c +++ b/user/cgi_wifi.c @@ -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\"}"); + // 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; } - else if (connTryStatus == CONNTRY_WORKING || connTryStatus == CONNTRY_SUCCESS) { - if (st == STATION_GOT_IP) { + + 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); - 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\"}"); + sprintf(buff, "{\"status\": \"success\", \"ip\": \""IPSTR"\"}", GOOD_IP2STR(info.ip.addr)); + break; } - httpdSend(connData, buff, len); + 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()); } diff --git a/user/cgi_wifi.h b/user/cgi_wifi.h index a300d2a..53999dc 100644 --- a/user/cgi_wifi.h +++ b/user/cgi_wifi.h @@ -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