Normalized Wifi to WiFI.

Fixed button spacing on console clear and log reset buttons
Renamed cgiReboot method to cgiReset and called the proper reset method
Normalized whitespace in cgiflash.c
pull/72/head
Benjamin Runnels 9 years ago
parent ebda951769
commit 3eccd26e76
  1. 2
      esp-link/cgi.c
  2. 223
      esp-link/cgiflash.c
  3. 2
      esp-link/cgiflash.h
  4. 2
      esp-link/main.c
  5. 6
      html/console.html
  6. 10
      html/home.html
  7. 19
      html/log.html
  8. 2
      html/mqtt.html
  9. 2
      html/services.html
  10. 18
      html/wifi/wifi.html

@ -206,7 +206,7 @@ int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) {
"{ " "{ "
"\"menu\": [ " "\"menu\": [ "
"\"Home\", \"/home.html\", " "\"Home\", \"/home.html\", "
"\"Wifi\", \"/wifi/wifi.html\", " "\"WiFI\", \"/wifi/wifi.html\", "
"\"µC Console\", \"/console.html\", " "\"µC Console\", \"/console.html\", "
"\"Services\", \"/services.html\", " "\"Services\", \"/services.html\", "
#ifdef MQTT #ifdef MQTT

@ -27,16 +27,16 @@ Some flash handling cgi routines. Used for reading the existing flash and updati
// Check that the header of the firmware blob looks like actual firmware... // Check that the header of the firmware blob looks like actual firmware...
static char* ICACHE_FLASH_ATTR check_header(void *buf) { static char* ICACHE_FLASH_ATTR check_header(void *buf) {
uint8_t *cd = (uint8_t *)buf; uint8_t *cd = (uint8_t *)buf;
#ifdef CGIFLASH_DBG #ifdef CGIFLASH_DBG
uint32_t *buf32 = buf; uint32_t *buf32 = buf;
os_printf("%p: %08lX %08lX %08lX %08lX\n", buf, buf32[0], buf32[1], buf32[2], buf32[3]); os_printf("%p: %08lX %08lX %08lX %08lX\n", buf, buf32[0], buf32[1], buf32[2], buf32[3]);
#endif #endif
if (cd[0] != 0xEA) return "IROM magic missing"; if (cd[0] != 0xEA) return "IROM magic missing";
if (cd[1] != 4 || cd[2] > 3 || (cd[3]>>4) > 6) return "bad flash header"; if (cd[1] != 4 || cd[2] > 3 || (cd[3]>>4) > 6) return "bad flash header";
if (((uint16_t *)buf)[3] != 0x4010) return "Invalid entry addr"; if (((uint16_t *)buf)[3] != 0x4010) return "Invalid entry addr";
if (((uint32_t *)buf)[2] != 0) return "Invalid start offset"; if (((uint32_t *)buf)[2] != 0) return "Invalid start offset";
return NULL; return NULL;
} }
// check whether the flash map/size we have allows for OTA upgrade // check whether the flash map/size we have allows for OTA upgrade
@ -49,143 +49,143 @@ static char *flash_too_small = "Flash too small for OTA update";
//===== Cgi to query which firmware needs to be uploaded next //===== Cgi to query which firmware needs to be uploaded next
int ICACHE_FLASH_ATTR cgiGetFirmwareNext(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiGetFirmwareNext(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
if (!canOTA()) { if (!canOTA()) {
errorResponse(connData, 400, flash_too_small); errorResponse(connData, 400, flash_too_small);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
uint8 id = system_upgrade_userbin_check(); uint8 id = system_upgrade_userbin_check();
httpdStartResponse(connData, 200); httpdStartResponse(connData, 200);
httpdHeader(connData, "Content-Type", "text/plain"); httpdHeader(connData, "Content-Type", "text/plain");
httpdHeader(connData, "Content-Length", "9"); httpdHeader(connData, "Content-Length", "9");
httpdEndHeaders(connData); httpdEndHeaders(connData);
char *next = id == 1 ? "user1.bin" : "user2.bin"; char *next = id == 1 ? "user1.bin" : "user2.bin";
httpdSend(connData, next, -1); httpdSend(connData, next, -1);
DBG("Next firmware: %s (got %d)\n", next, id); DBG("Next firmware: %s (got %d)\n", next, id);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
//===== Cgi that allows the firmware to be replaced via http POST //===== Cgi that allows the firmware to be replaced via http POST
int ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
if (!canOTA()) { if (!canOTA()) {
errorResponse(connData, 400, flash_too_small); errorResponse(connData, 400, flash_too_small);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
int offset = connData->post->received - connData->post->buffLen; int offset = connData->post->received - connData->post->buffLen;
if (offset == 0) { if (offset == 0) {
connData->cgiPrivData = NULL; connData->cgiPrivData = NULL;
} else if (connData->cgiPrivData != NULL) { } else if (connData->cgiPrivData != NULL) {
// we have an error condition, do nothing // we have an error condition, do nothing
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
// assume no error yet... // assume no error yet...
char *err = NULL; char *err = NULL;
int code = 400; int code = 400;
// check overall size // check overall size
//os_printf("FW: %d (max %d)\n", connData->post->len, FIRMWARE_SIZE); //os_printf("FW: %d (max %d)\n", connData->post->len, FIRMWARE_SIZE);
if (connData->post->len > FIRMWARE_SIZE) err = "Firmware image too large"; if (connData->post->len > FIRMWARE_SIZE) err = "Firmware image too large";
if (connData->post->buff == NULL || connData->requestType != HTTPD_METHOD_POST || if (connData->post->buff == NULL || connData->requestType != HTTPD_METHOD_POST ||
connData->post->len < 1024) err = "Invalid request"; connData->post->len < 1024) err = "Invalid request";
// check that data starts with an appropriate header // check that data starts with an appropriate header
if (err == NULL && offset == 0) err = check_header(connData->post->buff); if (err == NULL && offset == 0) err = check_header(connData->post->buff);
// make sure we're buffering in 1024 byte chunks // make sure we're buffering in 1024 byte chunks
if (err == NULL && offset % 1024 != 0) { if (err == NULL && offset % 1024 != 0) {
err = "Buffering problem"; err = "Buffering problem";
code = 500; code = 500;
} }
// return an error if there is one // return an error if there is one
if (err != NULL) { if (err != NULL) {
DBG("Error %d: %s\n", code, err); DBG("Error %d: %s\n", code, err);
httpdStartResponse(connData, code); httpdStartResponse(connData, code);
httpdHeader(connData, "Content-Type", "text/plain"); httpdHeader(connData, "Content-Type", "text/plain");
//httpdHeader(connData, "Content-Length", strlen(err)+2); //httpdHeader(connData, "Content-Length", strlen(err)+2);
httpdEndHeaders(connData); httpdEndHeaders(connData);
httpdSend(connData, err, -1); httpdSend(connData, err, -1);
httpdSend(connData, "\r\n", -1); httpdSend(connData, "\r\n", -1);
connData->cgiPrivData = (void *)1; connData->cgiPrivData = (void *)1;
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
// let's see which partition we need to flash and what flash address that puts us at // let's see which partition we need to flash and what flash address that puts us at
uint8 id = system_upgrade_userbin_check(); uint8 id = system_upgrade_userbin_check();
int address = id == 1 ? 4*1024 // either start after 4KB boot partition int address = id == 1 ? 4*1024 // either start after 4KB boot partition
: 4*1024 + FIRMWARE_SIZE + 16*1024 + 4*1024; // 4KB boot, fw1, 16KB user param, 4KB reserved : 4*1024 + FIRMWARE_SIZE + 16*1024 + 4*1024; // 4KB boot, fw1, 16KB user param, 4KB reserved
address += offset; address += offset;
// erase next flash block if necessary // erase next flash block if necessary
if (address % SPI_FLASH_SEC_SIZE == 0){ if (address % SPI_FLASH_SEC_SIZE == 0){
DBG("Flashing 0x%05x (id=%d)\n", address, 2 - id); DBG("Flashing 0x%05x (id=%d)\n", address, 2 - id);
spi_flash_erase_sector(address/SPI_FLASH_SEC_SIZE); spi_flash_erase_sector(address/SPI_FLASH_SEC_SIZE);
} }
// Write the data // Write the data
//DBG("Writing %d bytes at 0x%05x (%d of %d)\n", connData->post->buffSize, address, //DBG("Writing %d bytes at 0x%05x (%d of %d)\n", connData->post->buffSize, address,
// connData->post->received, connData->post->len); // connData->post->received, connData->post->len);
spi_flash_write(address, (uint32 *)connData->post->buff, connData->post->buffLen); spi_flash_write(address, (uint32 *)connData->post->buff, connData->post->buffLen);
if (connData->post->received == connData->post->len){ if (connData->post->received == connData->post->len){
httpdStartResponse(connData, 200); httpdStartResponse(connData, 200);
httpdEndHeaders(connData); httpdEndHeaders(connData);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} else { } else {
return HTTPD_CGI_MORE; return HTTPD_CGI_MORE;
} }
} }
static ETSTimer flash_reboot_timer; static ETSTimer flash_reboot_timer;
// Handle request to reboot into the new firmware // Handle request to reboot into the new firmware
int ICACHE_FLASH_ATTR cgiRebootFirmware(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiRebootFirmware(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
if (!canOTA()) { if (!canOTA()) {
errorResponse(connData, 400, flash_too_small); errorResponse(connData, 400, flash_too_small);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
// sanity-check that the 'next' partition actually contains something that looks like // sanity-check that the 'next' partition actually contains something that looks like
// valid firmware // valid firmware
uint8 id = system_upgrade_userbin_check(); uint8 id = system_upgrade_userbin_check();
int address = id == 1 ? 4*1024 // either start after 4KB boot partition int address = id == 1 ? 4*1024 // either start after 4KB boot partition
: 4*1024 + FIRMWARE_SIZE + 16*1024 + 4*1024; // 4KB boot, fw1, 16KB user param, 4KB reserved : 4*1024 + FIRMWARE_SIZE + 16*1024 + 4*1024; // 4KB boot, fw1, 16KB user param, 4KB reserved
uint32 buf[8]; uint32 buf[8];
DBG("Checking %p\n", (void *)address); DBG("Checking %p\n", (void *)address);
spi_flash_read(address, buf, sizeof(buf)); spi_flash_read(address, buf, sizeof(buf));
char *err = check_header(buf); char *err = check_header(buf);
if (err != NULL) { if (err != NULL) {
DBG("Error %d: %s\n", 400, err); DBG("Error %d: %s\n", 400, err);
httpdStartResponse(connData, 400); httpdStartResponse(connData, 400);
httpdHeader(connData, "Content-Type", "text/plain"); httpdHeader(connData, "Content-Type", "text/plain");
//httpdHeader(connData, "Content-Length", strlen(err)+2); //httpdHeader(connData, "Content-Length", strlen(err)+2);
httpdEndHeaders(connData); httpdEndHeaders(connData);
httpdSend(connData, err, -1); httpdSend(connData, err, -1);
httpdSend(connData, "\r\n", -1); httpdSend(connData, "\r\n", -1);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
httpdStartResponse(connData, 200); httpdStartResponse(connData, 200);
httpdHeader(connData, "Content-Length", "0"); httpdHeader(connData, "Content-Length", "0");
httpdEndHeaders(connData); httpdEndHeaders(connData);
// Schedule a reboot // Schedule a reboot
system_upgrade_flag_set(UPGRADE_FLAG_FINISH); system_upgrade_flag_set(UPGRADE_FLAG_FINISH);
os_timer_disarm(&flash_reboot_timer); os_timer_disarm(&flash_reboot_timer);
os_timer_setfn(&flash_reboot_timer, (os_timer_func_t *)system_upgrade_reboot, NULL); os_timer_setfn(&flash_reboot_timer, (os_timer_func_t *)system_upgrade_reboot, NULL);
os_timer_arm(&flash_reboot_timer, 2000, 1); os_timer_arm(&flash_reboot_timer, 2000, 1);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
int ICACHE_FLASH_ATTR cgiReboot(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiReset(HttpdConnData *connData) {
if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
httpdStartResponse(connData, 200); httpdStartResponse(connData, 200);
@ -193,9 +193,8 @@ int ICACHE_FLASH_ATTR cgiReboot(HttpdConnData *connData) {
httpdEndHeaders(connData); httpdEndHeaders(connData);
// Schedule a reboot // Schedule a reboot
system_upgrade_flag_set(UPGRADE_FLAG_FINISH);
os_timer_disarm(&flash_reboot_timer); os_timer_disarm(&flash_reboot_timer);
os_timer_setfn(&flash_reboot_timer, (os_timer_func_t *)system_upgrade_reboot, NULL); os_timer_setfn(&flash_reboot_timer, (os_timer_func_t *)system_restart, NULL);
os_timer_arm(&flash_reboot_timer, 2000, 1); os_timer_arm(&flash_reboot_timer, 2000, 1);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }

@ -7,6 +7,6 @@ int cgiReadFlash(HttpdConnData *connData);
int cgiGetFirmwareNext(HttpdConnData *connData); int cgiGetFirmwareNext(HttpdConnData *connData);
int cgiUploadFirmware(HttpdConnData *connData); int cgiUploadFirmware(HttpdConnData *connData);
int cgiRebootFirmware(HttpdConnData *connData); int cgiRebootFirmware(HttpdConnData *connData);
int cgiReboot(HttpdConnData *connData); int cgiReset(HttpdConnData *connData);
#endif #endif

@ -57,7 +57,7 @@ HttpdBuiltInUrl builtInUrls[] = {
{ "/pgm/upload", cgiOptibootData, NULL }, { "/pgm/upload", cgiOptibootData, NULL },
{ "/log/text", ajaxLog, NULL }, { "/log/text", ajaxLog, NULL },
{ "/log/dbg", ajaxLogDbg, NULL }, { "/log/dbg", ajaxLogDbg, NULL },
{ "/log/reboot", cgiReboot, NULL }, { "/log/reset", cgiReset, NULL },
{ "/console/reset", ajaxConsoleReset, NULL }, { "/console/reset", ajaxConsoleReset, NULL },
{ "/console/baud", ajaxConsoleBaud, NULL }, { "/console/baud", ajaxConsoleBaud, NULL },
{ "/console/text", ajaxConsole, NULL }, { "/console/text", ajaxConsole, NULL },

@ -6,8 +6,8 @@
<div class="content flex-fill flex-vbox"> <div class="content flex-fill flex-vbox">
<p> <p>
<a id="reset-button" class="pure-button button-primary" href="#">Reset &#xb5;C</a> <a id="reset-button" class="pure-button button-primary" href="#">Reset &#xb5;C</a>
<a id="clear-button" class="pure-button button-primary" href="#">Clear Log</a> &nbsp; <a id="clear-button" class="pure-button button-primary" href="#">Clear Log</a>
&nbsp;&nbsp;Baud: &nbsp; Baud:
<select id="baud-sel" class="pure-button" href="#"> <select id="baud-sel" class="pure-button" href="#">
<option value="460800">460800</option> <option value="460800">460800</option>
<option value="250000">250000</option> <option value="250000">250000</option>
@ -18,7 +18,7 @@
<option value="19200">19200</option> <option value="19200">19200</option>
<option value="9600">9600</option> <option value="9600">9600</option>
</select> </select>
&nbsp;&nbsp;Fmt: 8N1 &nbsp; Fmt: 8N1
</p> </p>
<div class="pure-g"> <div class="pure-g">
<div class="pure-u-1-4"><legend><b>Console</b></legend></div> <div class="pure-u-1-4"><legend><b>Console</b></legend></div>

@ -22,8 +22,8 @@
</div> </div>
</td></tr> </td></tr>
<tr><td>Network SSID</td><td id="wifi-ssid"></td></tr> <tr><td>Network SSID</td><td id="wifi-ssid"></td></tr>
<tr><td>Wifi status</td><td id="wifi-status"></td></tr> <tr><td>WiFI status</td><td id="wifi-status"></td></tr>
<tr><td>Wifi address</td><td id="wifi-ip"></td></tr> <tr><td>WiFI address</td><td id="wifi-ip"></td></tr>
<tr><td>SLIP status</td><td class="system-slip"></td></tr> <tr><td>SLIP status</td><td class="system-slip"></td></tr>
<tr><td>MQTT status</td><td class="system-mqtt"></td></tr> <tr><td>MQTT status</td><td class="system-mqtt"></td></tr>
<tr><td>Serial baud</td><td class="system-baud"></td></tr> <tr><td>Serial baud</td><td class="system-baud"></td></tr>
@ -32,7 +32,7 @@
<div class="card"> <div class="card">
<h1>Info</h1> <h1>Info</h1>
<p style="margin-bottom:0;">The JeeLabs esp-link firmware bridges the ESP8266 <p style="margin-bottom:0;">The JeeLabs esp-link firmware bridges the ESP8266
serial port to Wifi and can serial port to WiFI and can
program microcontrollers over the serial port, in particular Arduinos, AVRs, and program microcontrollers over the serial port, in particular Arduinos, AVRs, and
NXP's LPC800 and other ARM processors. Typical avrdude command line to NXP's LPC800 and other ARM processors. Typical avrdude command line to
program an Arduino:</p> program an Arduino:</p>
@ -109,8 +109,8 @@
<h1>System details</h1> <h1>System details</h1>
<div id="system-spinner" class="spinner spinner-small"></div> <div id="system-spinner" class="spinner spinner-small"></div>
<table id="system-table" class="pure-table pure-table-horizontal" hidden><tbody> <table id="system-table" class="pure-table pure-table-horizontal" hidden><tbody>
<tr><td>WiFi mode</td><td id="wifi-mode"></td></tr> <tr><td>WiFI mode</td><td id="wifi-mode"></td></tr>
<tr><td>Wifi channel</td><td id="wifi-chan"></td></tr> <tr><td>WiFI channel</td><td id="wifi-chan"></td></tr>
<tr><td>Flash chip ID</td><td> <tr><td>Flash chip ID</td><td>
<div> <div>
<span class="system-id"></span> <span class="system-id"></span>

@ -7,12 +7,11 @@
<p>The debug log shows the most recent characters printed by the esp-link software itself to <p>The debug log shows the most recent characters printed by the esp-link software itself to
its own debug log.</p> its own debug log.</p>
<div class="pure-g"> <div class="pure-g">
<p class="pure-u-1-4"> <p class="pure-u-1-4" style="vertical-align: baseline;width:40%">
<a id="refresh-button" class="pure-button button-primary" href="#">Refresh</a> <a id="refresh-button" class="pure-button button-primary" href="#">Refresh</a>
<a id="reboot-button" class="pure-button button-primary" href="#">Reboot esp-link</a> &nbsp;<a id="reset-button" class="dbg-btn pure-button button-primary" href="#">Reset esp-link</a>
<a id="clear-button" class="pure-button button-primary" href="#">Clear Log</a>
</p> </p>
<p class="pure-u-3-4" style="vertical-align: baseline"> <p class="pure-u-3-4" style="vertical-align: baseline;width:60%">
UART debug log: UART debug log:
<a id="dbg-auto" class="dbg-btn pure-button" href="#">auto</a> <a id="dbg-auto" class="dbg-btn pure-button" href="#">auto</a>
<a id="dbg-off" class="dbg-btn pure-button" href="#">off</a> <a id="dbg-off" class="dbg-btn pure-button" href="#">off</a>
@ -36,22 +35,16 @@
fetchText(100, false); fetchText(100, false);
}); });
$("#reboot-button").addEventListener("click", function (e) { $("#reset-button").addEventListener("click", function (e) {
e.preventDefault(); e.preventDefault();
var co = $("#console"); var co = $("#console");
co.innerHTML = ""; co.innerHTML = "";
ajaxSpin('POST', "/log/reboot", ajaxSpin('POST', "/log/reset",
function (resp) { showNotification("esp-link reset"); co.textEnd = 0; }, function (resp) { showNotification("Resetting esp-link"); co.textEnd = 0; fetchText(2000, false); },
function (s, st) { showWarning("Error resetting esp-link"); } function (s, st) { showWarning("Error resetting esp-link"); }
); );
}); });
$("#clear-button").addEventListener("click", function (e) {
e.preventDefault();
var co = $("#console");
co.innerHTML = "";
});
["auto", "off", "on0", "on1"].forEach(function(mode) { ["auto", "off", "on0", "on1"].forEach(function(mode) {
bnd($('#dbg-'+mode), "click", function(el) { bnd($('#dbg-'+mode), "click", function(el) {
ajaxJsonSpin('POST', "/log/dbg?mode="+mode, ajaxJsonSpin('POST', "/log/dbg?mode="+mode,

@ -14,7 +14,7 @@
using parameters set below and stored in esp-link's flash settings. This allows using parameters set below and stored in esp-link's flash settings. This allows
esp-link to take care of connection parameters and disconnect/reconnect operations.</p> esp-link to take care of connection parameters and disconnect/reconnect operations.</p>
<p>The MQTT client also supports sending periodic status messages about esp-link itself, <p>The MQTT client also supports sending periodic status messages about esp-link itself,
including Wifi RSSI, and free heap memory.</p> including WiFI RSSI, and free heap memory.</p>
<div class="form-horizontal"> <div class="form-horizontal">
<input type="checkbox" name="slip-enable"/> <input type="checkbox" name="slip-enable"/>
<label>Enable SLIP on serial port</label> <label>Enable SLIP on serial port</label>

@ -48,7 +48,7 @@
<div class="popup">Synology does a log rotate if timestamp is in the past so disable to prevent this</div> <div class="popup">Synology does a log rotate if timestamp is in the past so disable to prevent this</div>
</div> </div>
<button id="Syslog-button" type="submit" class="pure-button button-primary"> <button id="Syslog-button" type="submit" class="pure-button button-primary">
Update syslog settings! Update Syslog settings!
</button> </button>
</form> </form>
</div> </div>

@ -1,27 +1,27 @@
<div id="main"> <div id="main">
<div class="header"> <div class="header">
<h1>Wifi Configuration</h1> <h1>WiFi Configuration</h1>
</div> </div>
<div class="content"> <div class="content">
<div class="pure-g"> <div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2"><div class="card"> <div class="pure-u-1 pure-u-md-1-2"><div class="card">
<h1>Wifi State</h1> <h1>WiFi State</h1>
<div id="wifi-spinner" class="spinner spinner-small"></div> <div id="wifi-spinner" class="spinner spinner-small"></div>
<table id="wifi-table" class="pure-table pure-table-horizontal" hidden><tbody> <table id="wifi-table" class="pure-table pure-table-horizontal" hidden><tbody>
<tr><td>WiFi mode</td><td id="wifi-mode"></td></tr> <tr><td>WiFi mode</td><td id="wifi-mode"></td></tr>
<tr><td>Wifi channel</td><td id="wifi-chan"></td></tr> <tr><td>WiFi channel</td><td id="wifi-chan"></td></tr>
<tr><td>Configured network</td><td id="wifi-ssid"></td></tr> <tr><td>Configured network</td><td id="wifi-ssid"></td></tr>
<tr><td>Wifi status</td><td id="wifi-status"></td></tr> <tr><td>WiFi status</td><td id="wifi-status"></td></tr>
<tr><td>Wifi address</td><td id="wifi-ip"></td></tr> <tr><td>WiFi address</td><td id="wifi-ip"></td></tr>
<tr><td>Wifi rssi</td><td id="wifi-rssi"></td></tr> <tr><td>WiFi rssi</td><td id="wifi-rssi"></td></tr>
<tr><td>Wifi phy</td><td id="wifi-phy"></td></tr> <tr><td>WiFi phy</td><td id="wifi-phy"></td></tr>
<tr><td>Wifi MAC</td><td id="wifi-mac"></td></tr> <tr><td>WiFi MAC</td><td id="wifi-mac"></td></tr>
<tr><td colspan="2" id="wifi-warn"></td></tr> <tr><td colspan="2" id="wifi-warn"></td></tr>
</tbody> </table> </tbody> </table>
</div></div> </div></div>
<div class="pure-u-1 pure-u-md-1-2"><div class="card"> <div class="pure-u-1 pure-u-md-1-2"><div class="card">
<h1>Wifi Association</h1> <h1>WiFi Association</h1>
<p id="reconnect" style="color: #600" hidden></p> <p id="reconnect" style="color: #600" hidden></p>
<form action="#" id="wifiform" class="pure-form pure-form-stacked"> <form action="#" id="wifiform" class="pure-form pure-form-stacked">
<legend>To connect to a WiFi network, please select one of the detected networks, <legend>To connect to a WiFi network, please select one of the detected networks,

Loading…
Cancel
Save