added auto-incrementing build number to the Makefile (available as "esp_link_build" in the C code)

converted the unconditional downloading of YUI compressor and HTML compressor to be conditional - only if they are not already present
moved all Javascript blocks from HTML files into separate JS files - otherwise HTML compressor does not compress the inlined Javascript code
changed the place of inclusion of JS files into HTML - it is now at the end of BODY instead of beginning (this speeds up the page loading a little)
added a page "Firmware" which allows for OTA upgrades - so the utility "wiflash" is no more needed
improved the Makefile to show firmware size as a percentage of the available ROM space
improved the Makefile to show the espFS size as a percentage of the raw uncompressed size of web assets
combined the 2 invokations of HTML compressor in Makefile (once for main folder and once for WIFI folder) into a single one
changed 4-5 CSS rules for better visual readability
fixed a bug in "cgiGetFirmwareNext" - it was not sending the No-Cache headers and so the browser shows wrong (older, cached) info
added "\n" in several DBG() statements
I had to rename "base64_decode" because there is same named function inside "ssl_crypto_misc" from the SSL library
pull/173/head
tmcdos 8 years ago
parent 65534229f2
commit 95d7e8e391
  1. 105
      Makefile
  2. 6
      esp-link/cgi.c
  3. 6
      esp-link/cgiflash.c
  4. 4
      esp-link/cgiwifi.c
  5. 22
      esp-link/main.c
  6. 81
      html/console.html
  7. 92
      html/home.html
  8. 50
      html/log.html
  9. 18
      html/mqtt.html
  10. 6
      html/mqtt.js
  11. 4
      html/pure.css
  12. 29
      html/services.html
  13. 7
      html/services.js
  14. 73
      html/style.css
  15. 18
      html/ui.js
  16. 97
      html/wifi/wifiAp.html
  17. 27
      html/wifi/wifiAp.js
  18. 71
      html/wifi/wifiSta.html
  19. 9
      html/wifi/wifiSta.js
  20. 4
      httpd/auth.c
  21. 2
      httpd/base64.c
  22. 2
      httpd/base64.h
  23. 2
      httpd/httpd.c
  24. 5
      include/user_config.h

@ -84,7 +84,7 @@ ESPBAUD ?= 460800
# --------------- chipset configuration ---------------
# Pick your flash size: "512KB", "1MB", or "4MB"
# Pick your flash size: "512KB", "1MB", "2MB" or "4MB"
FLASH_SIZE ?= 4MB
# The pin assignments below are used when the settings in flash are invalid, they
@ -135,13 +135,12 @@ YUI_COMPRESSOR ?= yuicompressor-2.4.8.jar
HTML_PATH = $(abspath ./html)/
WIFI_PATH = $(HTML_PATH)wifi/
ESP_FLASH_MAX ?= 503808 # max bin file
ifeq ("$(FLASH_SIZE)","512KB")
# Winbond 25Q40 512KB flash, typ for esp-01 thru esp-11
ESP_SPI_SIZE ?= 0 # 0->512KB (256KB+256KB)
ESP_FLASH_MODE ?= 0 # 0->QIO
ESP_FLASH_FREQ_DIV ?= 0 # 0->40Mhz
ESP_FLASH_MAX ?= 241664 # max bin file for 512KB flash: 236KB
ET_FS ?= 4m # 4Mbit flash size in esptool flash command
ET_FF ?= 40m # 40Mhz flash speed in esptool flash command
ET_BLANK ?= 0x7E000 # where to flash blank.bin to erase wireless settings
@ -151,6 +150,7 @@ else ifeq ("$(FLASH_SIZE)","1MB")
ESP_SPI_SIZE ?= 2 # 2->1MB (512KB+512KB)
ESP_FLASH_MODE ?= 0 # 0->QIO
ESP_FLASH_FREQ_DIV ?= 15 # 15->80MHz
ESP_FLASH_MAX ?= 503808 # max bin file for 1MB flash: 492KB
ET_FS ?= 8m # 8Mbit flash size in esptool flash command
ET_FF ?= 80m # 80Mhz flash speed in esptool flash command
ET_BLANK ?= 0xFE000 # where to flash blank.bin to erase wireless settings
@ -163,6 +163,7 @@ else ifeq ("$(FLASH_SIZE)","2MB")
ESP_SPI_SIZE ?= 4 # 6->4MB (1MB+1MB) or 4->4MB (512KB+512KB)
ESP_FLASH_MODE ?= 0 # 0->QIO, 2->DIO
ESP_FLASH_FREQ_DIV ?= 15 # 15->80Mhz
ESP_FLASH_MAX ?= 503808 # max bin file for 2MB flash: 492KB
ET_FS ?= 16m # 16Mbit flash size in esptool flash command
ET_FF ?= 80m # 80Mhz flash speed in esptool flash command
ET_BLANK ?= 0x1FE000 # where to flash blank.bin to erase wireless settings
@ -175,6 +176,8 @@ else
ESP_SPI_SIZE ?= 4 # 6->4MB (1MB+1MB) or 4->4MB (512KB+512KB)
ESP_FLASH_MODE ?= 0 # 0->QIO, 2->DIO
ESP_FLASH_FREQ_DIV ?= 15 # 15->80Mhz
ESP_FLASH_MAX ?= 503808 # max bin file for 512KB flash partition: 492KB
#ESP_FLASH_MAX ?= 1028096 # max bin file for 1MB flash partition: 1004KB
ET_FS ?= 32m # 32Mbit flash size in esptool flash command
ET_FF ?= 80m # 80Mhz flash speed in esptool flash command
ET_BLANK ?= 0x3FE000 # where to flash blank.bin to erase wireless settings
@ -187,12 +190,17 @@ endif
# Steps to release: create release on github, git pull, git describe --tags to verify you're
# on the release tag, make release, upload esp-link.tgz into the release files
#VERSION ?= "esp-link custom version"
DATE := $(shell date '+%F %T')
DATE := $(shell date '+%F')
TIME := $(shell date '+%T')
BRANCH ?= $(shell if git diff --quiet HEAD; then git describe --tags; \
else git symbolic-ref --short HEAD; fi)
SHA := $(shell if git diff --quiet HEAD; then git rev-parse --short HEAD | cut -d"/" -f 3; \
else echo "development"; fi)
VERSION ?=esp-link $(BRANCH) - $(DATE) - $(SHA)
VERSION ?=esp-link $(BRANCH) - $(DATE) - $(TIME) - $(SHA)
BUILD_NUMBER_FILE = $(abspath ./build-number.txt)
BUILD_NUMBER_SRC = $(abspath ./user/buildnum.c)
BUILD_NUMBER := $(shell if ! test -f $(BUILD_NUMBER_FILE); then echo 1 > $(BUILD_NUMBER_FILE); fi; cat $(BUILD_NUMBER_FILE))
# Output directors to store intermediate compiled files
# relative to the project directory
@ -227,15 +235,15 @@ MODULES += $(foreach sdir,$(LIBRARIES_DIR),$(wildcard $(sdir)/*))
EXTRA_INCDIR = include .
# libraries used in this project, mainly provided by the SDK
LIBS = c gcc hal phy pp net80211 wpa main lwip crypto
LIBS = c gcc hal phy pp net80211 wpa main lwip crypto ssl
# compiler flags using during compilation of source files
CFLAGS += -Os -ggdb -std=c99 -Werror -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \
CFLAGS += -Os -ggdb -std=c99 -Werror -Wno-unused-value -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \
-nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections \
-D__ets__ -DICACHE_FLASH -Wno-address -DFIRMWARE_SIZE=$(ESP_FLASH_MAX) \
-DMCU_RESET_PIN=$(MCU_RESET_PIN) -DMCU_ISP_PIN=$(MCU_ISP_PIN) \
-DLED_CONN_PIN=$(LED_CONN_PIN) -DLED_SERIAL_PIN=$(LED_SERIAL_PIN) \
-DVERSION="$(VERSION)"
-DVERSION="$(VERSION)" -DBUILD_DATE="$(DATE)" -DBUILD_TIME="$(TIME)" -DBUILD_NUM="$(BUILD_NUMBER)"
# linker flags used to generate the main object file
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -Wl,--gc-sections
@ -343,13 +351,23 @@ all: echo_version checkdirs $(FW_BASE)/user1.bin $(FW_BASE)/user2.bin
echo_version:
@echo VERSION: $(VERSION)
# Create an auto-incrementing build number.
@echo "#define VER_STR2(V) #V" > $(BUILD_NUMBER_SRC)
@echo "#define VER_STR(V) VER_STR2(V)" >> $(BUILD_NUMBER_SRC)
@echo "char esp_link_version[] = VER_STR(VERSION);" >> $(BUILD_NUMBER_SRC)
@echo "char esp_link_date[] = VER_STR(BUILD_DATE);" >> $(BUILD_NUMBER_SRC)
@echo "char esp_link_time[] = VER_STR(BUILD_TIME);" >> $(BUILD_NUMBER_SRC)
@echo "char esp_link_build[] = VER_STR(BUILD_NUM);" >> $(BUILD_NUMBER_SRC)
# Build number file. Increment if firmware file changes
$(BUILD_NUMBER_FILE): $(USER1_OUT)
@if ! test -f $(BUILD_NUMBER_FILE); then echo 0 > $(BUILD_NUMBER_FILE); fi
@echo $$(($$(cat $(BUILD_NUMBER_FILE)) + 1)) > $(BUILD_NUMBER_FILE)
$(USER1_OUT): $(APP_AR) $(LD_SCRIPT1)
$(vecho) "LD $@"
$(Q) $(LD) -L$(SDK_LIBDIR) -T$(LD_SCRIPT1) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@
@echo Dump : $(OBJDP) -x $(USER1_OUT)
@echo Disass: $(OBJDP) -d -l -x $(USER1_OUT)
# $(Q) $(OBJDP) -x $(TARGET_OUT) | egrep espfs_img
$(Q) $(OBJDP) -S $(USER1_OUT) > $(addprefix $(BUILD_BASE)/,$(TARGET).dump)
$(USER2_OUT): $(APP_AR) $(LD_SCRIPT2)
$(vecho) "LD $@"
@ -360,16 +378,15 @@ $(FW_BASE):
$(vecho) "FW $@"
$(Q) mkdir -p $@
$(FW_BASE)/user1.bin: $(USER1_OUT) $(FW_BASE)
$(FW_BASE)/user1.bin: $(USER1_OUT) $(FW_BASE) $(BUILD_NUMBER_FILE)
$(Q) $(OBJCP) --only-section .text -O binary $(USER1_OUT) eagle.app.v6.text.bin
$(Q) $(OBJCP) --only-section .data -O binary $(USER1_OUT) eagle.app.v6.data.bin
$(Q) $(OBJCP) --only-section .rodata -O binary $(USER1_OUT) eagle.app.v6.rodata.bin
$(Q) $(OBJCP) --only-section .irom0.text -O binary $(USER1_OUT) eagle.app.v6.irom0text.bin
ls -ls eagle*bin
$(Q) COMPILE=gcc PATH=$(XTENSA_TOOLS_ROOT):$(PATH) python $(APPGEN_TOOL) $(USER1_OUT) 2 $(ESP_FLASH_MODE) $(ESP_FLASH_FREQ_DIV) $(ESP_SPI_SIZE) 0
$(Q) rm -f eagle.app.v6.*.bin
$(Q) mv eagle.app.flash.bin $@
@echo "** user1.bin uses $$(stat -c '%s' $@) bytes of" $(ESP_FLASH_MAX) "available"
@echo "** user1.bin uses $$(stat -c '%s' $@) bytes of" $(ESP_FLASH_MAX) "available =" $(shell expr $$(stat -c '%s' $@) \* 100 / $(ESP_FLASH_MAX) ) "%"
$(Q) if [ $$(stat -c '%s' $@) -gt $$(( $(ESP_FLASH_MAX) )) ]; then echo "$@ too big!"; false; fi
$(FW_BASE)/user2.bin: $(USER2_OUT) $(FW_BASE)
@ -410,60 +427,55 @@ tools/$(HTML_COMPRESSOR):
else
tools/$(HTML_COMPRESSOR):
$(Q) mkdir -p tools
cd tools; wget https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI_COMPRESSOR)
cd tools; wget https://htmlcompressor.googlecode.com/files/$(HTML_COMPRESSOR)
$(Q) if ! test -f tools/$(YUI_COMPRESSOR); then wget https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI_COMPRESSOR) -O tools/$(YUI_COMPRESSOR); fi
$(Q) if ! test -f tools/$(HTML_COMPRESSOR); then wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/htmlcompressor/$(HTML_COMPRESSOR) -O tools/$(HTML_COMPRESSOR); fi
endif
ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes")
$(BUILD_BASE)/espfs_img.o: tools/$(HTML_COMPRESSOR)
endif
$(BUILD_BASE)/espfs_img.o: html/ html/wifi/ espfs/mkespfsimage/mkespfsimage
$(Q) rm -rf html_compressed; mkdir html_compressed; mkdir html_compressed/wifi;
$(Q) cp -r html/*.ico html_compressed;
$(Q) cp -r html/*.css html_compressed;
$(Q) cp -r html/*.js html_compressed;
$(Q) cp -r html/wifi/*.png html_compressed/wifi;
$(Q) cp -r html/wifi/*.js html_compressed/wifi;
$(BUILD_BASE)/espfs_img.o: $(shell find html) espfs/mkespfsimage/mkespfsimage
$(Q) rm -rf html_compressed; mkdir -p html_compressed; cp -r html/* html_compressed;
ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes")
$(Q) echo "Compression assets with htmlcompressor. This may take a while..."
$(Q) java -jar tools/$(HTML_COMPRESSOR) \
$(Q) echo "Compression assets with htmlcompressor. This is fast..."
$(Q) for file in `find html_compressed -type f -name "*.html"`; do \
java -jar yui/$(HTML_COMPRESSOR) \
-t html --remove-surrounding-spaces max --remove-quotes --remove-intertag-spaces \
-o $(abspath ./html_compressed)/ \
$(HTML_PATH)head- \
$(HTML_PATH)*.html
$(Q) java -jar tools/$(HTML_COMPRESSOR) \
-t html --remove-surrounding-spaces max --remove-quotes --remove-intertag-spaces \
-o $(abspath ./html_compressed)/wifi/ \
$(WIFI_PATH)*.html
$(Q) echo "Compression assets with yui-compressor. This may take a while..."
-o $$file $$file; \
done
$(Q) echo "Compressing JS/CSS with yui-compressor. This may take a while..."
$(Q) for file in `find html_compressed -type f -name "*.js"`; do \
java -jar tools/$(YUI_COMPRESSOR) $$file --line-break 0 -o $$file; \
java -jar yui/$(YUI_COMPRESSOR) $$file --line-break 0 -o $$file; \
done
$(Q) for file in `find html_compressed -type f -name "*.css"`; do \
java -jar tools/$(YUI_COMPRESSOR) $$file -o $$file; \
java -jar yui/$(YUI_COMPRESSOR) $$file -o $$file; \
done
else
$(Q) cp -r html/head- html_compressed;
$(Q) cp -r html/*.html html_compressed;
$(Q) cp -r html/wifi/*.html html_compressed/wifi;
endif
ifeq (,$(findstring mqtt,$(MODULES)))
$(Q) rm -rf html_compressed/mqtt.html
$(Q) rm -rf html_compressed/mqtt.js
endif
$(Q) for file in `find html_compressed -type f -name "*.htm*"`; do \
cat html_compressed/head- $$file >$${file}-; \
mv $$file- $$file; \
done
$(Q) rm html_compressed/head-
$(Q) echo "Now building espFS ..."
$(Q) cd html_compressed; find . \! -name \*- | ../espfs/mkespfsimage/mkespfsimage > ../build/espfs.img; cd ..;
$(Q) ls -sl build/espfs.img
@echo "espFS image is $$(stat -c '%s' build/espfs.img) bytes =" $(shell expr $$(stat -c '%s' build/espfs.img) \* 100 / $$(du -sb html_compressed | { read first _ ; echo $$first; })) "% of uncompressed originals"
$(Q) cd build; $(OBJCP) -I binary -O elf32-xtensa-le -B xtensa --rename-section .data=.espfs \
espfs.img espfs_img.o; cd ..
# edit the loader script to add the espfs section to the end of irom with a 4 byte alignment.
# we also adjust the sizes of the segments 'cause we need more irom0
# in the end the only thing that matters wrt size is that the whole shebang fits into the
# 236KB available (in a 512KB flash)
ifeq ("$(FLASH_SIZE)","512KB")
build/eagle.esphttpd1.v6.ld: $(SDK_LDDIR)/eagle.app.v6.new.512.app1.ld
$(Q) sed -e '/\.irom\.text/{' -e 'a . = ALIGN (4);' -e 'a *(.espfs)' -e '}' \
-e '/^ irom0_0_seg/ s/2B000/38000/' \
$(SDK_LDDIR)/eagle.app.v6.new.512.app1.ld >$@
build/eagle.esphttpd2.v6.ld: $(SDK_LDDIR)/eagle.app.v6.new.512.app2.ld
$(Q) sed -e '/\.irom\.text/{' -e 'a . = ALIGN (4);' -e 'a *(.espfs)' -e '}' \
-e '/^ irom0_0_seg/ s/2B000/38000/' \
$(SDK_LDDIR)/eagle.app.v6.new.512.app2.ld >$@
else
build/eagle.esphttpd1.v6.ld: $(SDK_LDDIR)/eagle.app.v6.new.1024.app1.ld
$(Q) sed -e '/\.irom\.text/{' -e 'a . = ALIGN (4);' -e 'a *(.espfs)' -e '}' \
-e '/^ irom0_0_seg/ s/6B000/7C000/' \
@ -472,8 +484,9 @@ build/eagle.esphttpd2.v6.ld: $(SDK_LDDIR)/eagle.app.v6.new.1024.app2.ld
$(Q) sed -e '/\.irom\.text/{' -e 'a . = ALIGN (4);' -e 'a *(.espfs)' -e '}' \
-e '/^ irom0_0_seg/ s/6B000/7C000/' \
$(SDK_LDDIR)/eagle.app.v6.new.1024.app2.ld >$@
endif
espfs/mkespfsimage/mkespfsimage: espfs/mkespfsimage/
espfs/mkespfsimage/mkespfsimage: espfs/mkespfsimage/*.c
$(Q) $(MAKE) -C espfs/mkespfsimage GZIP_COMPRESSION="$(GZIP_COMPRESSION)"
release: all

@ -27,10 +27,11 @@ void ICACHE_FLASH_ATTR noCacheHeaders(HttpdConnData *connData, int code) {
httpdStartResponse(connData, code);
httpdHeader(connData, "Cache-Control", "no-cache, no-store, must-revalidate");
httpdHeader(connData, "Pragma", "no-cache");
httpdHeader(connData, "Expires", "0");
httpdHeader(connData, "Expires", "Mon, 26 Jul 1997 05:00:00 GMT");
}
void ICACHE_FLASH_ATTR jsonHeader(HttpdConnData *connData, int code) {
httpdStartResponse(connData, code);
noCacheHeaders(connData, code);
httpdHeader(connData, "Content-Type", "application/json");
httpdEndHeaders(connData);
@ -187,8 +188,6 @@ int ICACHE_FLASH_ATTR printGlobalInfo(char *buff, int buflen, char *token) {
}
#endif
extern char *esp_link_version; // in user_main.c
int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
char buff[1024];
@ -214,6 +213,7 @@ int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) {
"\"REST/MQTT\", \"/mqtt.html\", "
#endif
"\"Debug log\", \"/log.html\""
"\"Firmware\", \"/flash/flash.html\""
" ], "
"\"version\": \"%s\", "
"\"name\": \"%s\""

@ -57,11 +57,11 @@ int ICACHE_FLASH_ATTR cgiGetFirmwareNext(HttpdConnData *connData) {
}
uint8 id = system_upgrade_userbin_check();
httpdStartResponse(connData, 200);
noCacheHeaders(connData, 200);
httpdHeader(connData, "Content-Type", "text/plain");
httpdHeader(connData, "Content-Length", "9");
httpdEndHeaders(connData);
char *next = id == 1 ? "user1.bin" : "user2.bin";
char *next = (id == 1 ? "user1.bin" : "user2.bin");
httpdSend(connData, next, -1);
DBG("Next firmware: %s (got %d)\n", next, id);
return HTTPD_CGI_DONE;
@ -124,7 +124,7 @@ int ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) {
// erase next flash block if necessary
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);
}

@ -732,8 +732,8 @@ int ICACHE_FLASH_ATTR printWifiInfo(char *buff) {
if (rssi > 0) rssi = 0;
uint8 mac_addr[6];
uint8 apmac_addr[6];
wifi_get_macaddr(0, mac_addr);
wifi_get_macaddr(1, apmac_addr);
wifi_get_macaddr(STATION_IF, mac_addr);
wifi_get_macaddr(SOFTAP_IF, apmac_addr);
uint8_t chan = wifi_get_channel();
len = os_sprintf(buff,

@ -64,6 +64,8 @@ should be placed above the URLs they protect.
HttpdBuiltInUrl builtInUrls[] = {
{ "/", cgiRedirect, "/home.html" },
{ "/menu", cgiMenu, NULL },
{"/flash", cgiRedirect, "/flash/flash.html"},
{"/flash/", cgiRedirect, "/flash/flash.html"},
{ "/flash/next", cgiGetFirmwareNext, NULL },
{ "/flash/upload", cgiUploadFirmware, NULL },
{ "/flash/reboot", cgiRebootFirmware, NULL },
@ -107,10 +109,6 @@ static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) {
}
#endif
# define VERS_STR_STR(V) #V
# define VERS_STR(V) VERS_STR_STR(V)
char* esp_link_version = VERS_STR(VERSION);
// address of espfs binary blob
extern uint32_t _binary_espfs_img_start;
@ -139,7 +137,7 @@ void user_init(void) {
logInit(); // must come after init of uart
// Say hello (leave some time to cause break in TX after boot loader's msg
os_delay_us(10000L);
os_printf("\n\n** %s\n", esp_link_version);
os_printf("\n\n** %s, build %s\n", esp_link_version, esp_link_build);
os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*");
// Status LEDs
statusInit();
@ -162,26 +160,26 @@ void user_init(void) {
#endif
struct rst_info *rst_info = system_get_rst_info();
NOTICE("Reset cause: %d=%s", rst_info->reason, rst_codes[rst_info->reason]);
NOTICE("exccause=%d epc1=0x%x epc2=0x%x epc3=0x%x excvaddr=0x%x depc=0x%x",
NOTICE("Reset cause: %d=%s\n", rst_info->reason, rst_codes[rst_info->reason]);
NOTICE("exccause=%d epc1=0x%x epc2=0x%x epc3=0x%x excvaddr=0x%x depc=0x%x\n",
rst_info->exccause, rst_info->epc1, rst_info->epc2, rst_info->epc3,
rst_info->excvaddr, rst_info->depc);
uint32_t fid = spi_flash_get_id();
NOTICE("Flash map %s, manuf 0x%02X chip 0x%04X", flash_maps[system_get_flash_size_map()],
NOTICE("Flash map %s, manuf 0x%02X chip 0x%04X\n", flash_maps[system_get_flash_size_map()],
fid & 0xff, (fid&0xff00)|((fid>>16)&0xff));
NOTICE("** %s: ready, heap=%ld", esp_link_version, (unsigned long)system_get_free_heap_size());
NOTICE("** %s: ready, heap=%ld\n", esp_link_version, (unsigned long)system_get_free_heap_size());
// Init SNTP service
cgiServicesSNTPInit();
#ifdef MQTT
if (flashConfig.mqtt_enable) {
NOTICE("initializing MQTT");
NOTICE("initializing MQTT\n");
mqtt_client_init();
}
#endif
NOTICE("initializing user application");
NOTICE("initializing user application\n");
app_init();
NOTICE("Waiting for work to do...");
NOTICE("Waiting for work to do...\n");
#ifdef MEMLEAK_DEBUG
system_show_malloc();
#endif

@ -1,25 +1,38 @@
<!doctype html>
<html><head>
<title>esp-link</title>
<link rel="stylesheet" href="pure.css">
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="layout">
<div id="main" class="flex-fill flex-vbox" style="max-height:100%">
<div class="header">
<h1>Microcontroller Console</h1>
</div>
<div class="content flex-fill flex-vbox">
<p>
<p>The Microcontroller console shows the last 1024 characters
received from UART0, to which a microcontroller is typically attached.
The UART is configured for 8 bits, no parity, 1 stop bit (8N1).
</p>
<div>
<a id="reset-button" class="pure-button button-primary" href="#">Reset &#xb5;C</a>
&nbsp; <a id="clear-button" class="pure-button button-primary" href="#">Clear Log</a>
&nbsp; Baud:
&nbsp; Baud (8N1):
<select id="baud-sel" class="pure-button" href="#">
<option value="460800">460800</option>
<option value="250000">250000</option>
<option value="230400">230400</option>
<option value="115200">115200</option>
<option value="57600">57600</option>
<option value="38400">38400</option>
<option value="19200">19200</option>
<option value="0"> </option>
<option value="9600">9600</option>
<option value="19200">19200</option>
<option value="38400">38400</option>
<option value="57600">57600</option>
<option value="115200">115200</option>
<option value="230400">230400</option>
<option value="250000">250000</option>
<option value="460800">460800</option>
</select>
&nbsp; Fmt: 8N1
</p>
</div>
<div class="pure-g">
<div class="pure-u-1-4"><legend><b>Console</b></legend></div>
<div class="pure-u-3-4"></div>
@ -56,49 +69,7 @@
</div>
</div>
</div>
<script type="text/javascript">console_url = "/console/text"</script>
<script src="ui.js"></script>
<script src="console.js"></script>
<script type="text/javascript">
onLoad(function() {
fetchText(100, true);
$("#reset-button").addEventListener("click", function(e) {
e.preventDefault();
var co = $("#console");
co.innerHTML = "";
ajaxSpin('POST', "/console/reset",
function(resp) { showNotification("uC reset"); co.textEnd = 0; },
function(s, st) { showWarning("Error resetting uC"); }
);
});
$("#clear-button").addEventListener("click", function(e) {
e.preventDefault();
var co = $("#console");
co.innerHTML = "";
});
ajaxJson('GET', "/console/baud",
function(data) { $("#baud-sel").value = data.rate; },
function(s, st) { showNotification(st); }
);
bnd($("#baud-sel"), "change", function(ev) {
ev.preventDefault();
var baud = $("#baud-sel").value;
ajaxSpin('POST', "/console/baud?rate="+baud,
function(resp) { showNotification("" + baud + " baud set"); },
function(s, st) { showWarning("Error setting baud rate: " + st); }
);
});
consoleSendInit();
addClass($('html')[0], "height100");
addClass($('body')[0], "height100");
addClass($('#layout'), "height100");
addClass($('#layout'), "flex-vbox");
});
</script>
<script src="console_main.js"></script>
</body></html>

@ -1,3 +1,12 @@
<!doctype html>
<html><head>
<title>esp-link</title>
<link rel="stylesheet" href="pure.css">
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="layout">
<div id="main">
<div class="header">
<div><img src="favicon.ico" height="64"><span class="jl">JEELABS</span></div>
@ -6,9 +15,7 @@
</div>
<div class="content">
<div class="pure-g">
<!-- LEFT COLUMN -->
<div class="pure-u-1 pure-u-md-1-2">
<div style="float:left; padding:2px">
<div class="card">
<h1>System overview</h1>
<div id="wifi-spinner" class="spinner spinner-small"></div>
@ -51,8 +58,38 @@
for up-to-date help.</p>
</div>
</div>
<!-- RIGHT COLUMN -->
<div class="pure-u-1 pure-u-md-1-2">
<div style="float:left; padding:2px">
<div class="card">
<h1>System details</h1>
<div id="system-spinner" class="spinner spinner-small"></div>
<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 channel</td><td id="wifi-chan"></td></tr>
<tr><td>Flash chip ID</td><td>
<div>
<span class="system-id"></span>
<div class="popup pop-left">Common IDs: 4016=4MB, 4014=1MB, 4013=512KB</div>
</div>
</td></tr>
<tr><td>Flash size</td><td>
<div>
<span class="system-size"></span>
<div class="popup pop-left">Size configured into bootloader, must match chip size</div>
</div>
</td></tr>
<tr><td>Current partition</td><td class="system-partition"></td></tr>
<tr><td colspan=2 class="popup-target">Description:<br>
<div class="click-to-edit system-description">
<span class="edit-off" style="display:block; width:auto;"></span>
<textarea class="edit-on" rows=3 maxlength=127 hidden> </textarea>
<div class="popup">Click to edit!<br>A short description or memo for this esp-link
module, 128 chars max</div>
</div>
</td></tr>
</tbody></table>
</div>
</div>
<div style="float:left; padding:2px">
<div class="card">
<h1>Pin assignment</h1>
<div id="pin-spinner" class="spinner spinner-small"></div>
@ -105,51 +142,10 @@
</form>
</div>
</div>
<div class="card">
<h1>System details</h1>
<div id="system-spinner" class="spinner spinner-small"></div>
<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 channel</td><td id="wifi-chan"></td></tr>
<tr><td>Flash chip ID</td><td>
<div>
<span class="system-id"></span>
<div class="popup pop-left">Common IDs: 4016=4MB, 4014=1MB, 4013=512KB</div>
</div>
</td></tr>
<tr><td>Flash size</td><td>
<div>
<span class="system-size"></span>
<div class="popup pop-left">Size configured into bootloader, must match chip size</div>
</div>
</td></tr>
<tr><td>Current partition</td><td class="system-partition"></td></tr>
<tr><td colspan=2 class="popup-target">Description:<br>
<div class="click-to-edit system-description">
<span class="edit-off" style="display:block; width:auto;"></span>
<textarea class="edit-on" rows=3 maxlength=127 hidden> </textarea>
<div class="popup">Click to edit!<br>A short description or memo for this esp-link
module, 128 chars max</div>
</div>
</td></tr>
</tbody></table>
</div>
</div>
</div>
<div class="pure-g">
</div>
</div>
</div>
</div>
<script type="text/javascript">
onLoad(function() {
makeAjaxInput("system", "description");
makeAjaxInput("system", "name");
fetchPins();
getWifiInfo();
getSystemInfo();
bnd($("#pinform"), "submit", setPins);
});
</script>
<script src="ui.js"></script>
<script src="home.js"></script>
</body></html>

@ -1,11 +1,19 @@
<!doctype html>
<html><head>
<title>esp-link</title>
<link rel="stylesheet" href="pure.css">
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="layout">
<div id="main">
<div class="header">
<h1>Debug Log</h1>
</div>
<div class="content">
<p>The debug log shows the most recent characters printed by the esp-link software itself to
its own debug log.</p>
<p>The debug log shows the most recent characters printed by the ESP-LINK software itself to its own debug log.</p>
<div class="pure-g">
<p class="pure-u-1-4" style="vertical-align: baseline;width:40%">
<a id="refresh-button" class="pure-button button-primary" href="#">Refresh</a>
@ -14,8 +22,11 @@
<p class="pure-u-3-4" style="vertical-align: baseline;width:60%">
UART debug log:
<a id="dbg-auto" class="dbg-btn pure-button" href="#">auto</a>
&nbsp;
<a id="dbg-off" class="dbg-btn pure-button" href="#">off</a>
&nbsp;
<a id="dbg-on0" class="dbg-btn pure-button" href="#">on uart0</a>
&nbsp;
<a id="dbg-on1" class="dbg-btn pure-button" href="#">on uart1</a>
</p>
</div>
@ -23,38 +34,7 @@
</div>
</div>
</div>
<script type="text/javascript">console_url = "/log/text"</script>
<script src="ui.js"></script>
<script src="console.js"></script>
<script type="text/javascript">
onLoad(function() {
fetchText(100, false);
$("#refresh-button").addEventListener("click", function(e) {
e.preventDefault();
fetchText(100, false);
});
$("#reset-button").addEventListener("click", function (e) {
e.preventDefault();
var co = $("#console");
co.innerHTML = "";
ajaxSpin('POST', "/log/reset",
function (resp) { showNotification("Resetting esp-link"); co.textEnd = 0; fetchText(2000, false); },
function (s, st) { showWarning("Error resetting esp-link"); }
);
});
["auto", "off", "on0", "on1"].forEach(function(mode) {
bnd($('#dbg-'+mode), "click", function(el) {
ajaxJsonSpin('POST', "/log/dbg?mode="+mode,
function(data) { showNotification("UART mode " + data.mode); showDbgMode(data.mode); },
function(s, st) { showWarning("Error setting UART mode: " + st); }
);
});
});
ajaxJson('GET', "/log/dbg", function(data) { showDbgMode(data.mode); }, function() {});
});
</script>
<script src="log_main.js"></script>
</body></html>

@ -1,3 +1,12 @@
<!doctype html>
<html><head>
<title>esp-link</title>
<link rel="stylesheet" href="pure.css">
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="layout">
<div id="main">
<div class="header">
<h1>REST &amp; MQTT</h1>
@ -92,13 +101,6 @@
</div>
</div>
</div>
<script src="ui.js"></script>
<script src="mqtt.js"></script>
<script type="text/javascript">
onLoad(function() {
fetchMqtt();
bnd($("#mqtt-form"), "submit", changeMqtt);
bnd($("#mqtt-status-form"), "submit", changeMqttStatus);
});
</script>
</body></html>

@ -1,3 +1,9 @@
onLoad(function() {
fetchMqtt();
bnd($("#mqtt-form"), "submit", changeMqtt);
bnd($("#mqtt-status-form"), "submit", changeMqttStatus);
});
//===== MQTT cards
function changeMqtt(e) {

@ -693,8 +693,8 @@ this the same font stack that Normalize.css sets for the `body`.
font-family: inherit;
font-size: 100%;
padding: 0.5em 1em;
color: #444; /* rgba not supported (IE 8) */
color: rgba(0, 0, 0, 0.80); /* rgba supported */
color: #fff; /* rgba not supported (IE 8) */
color: rgba(f, f, f, 0.80); /* rgba supported */
border: 1px solid #999; /*IE 6/7/8*/
border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/
background-color: #E6E6E6;

@ -1,11 +1,19 @@
<!doctype html>
<html><head>
<title>esp-link</title>
<link rel="stylesheet" href="pure.css">
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="layout">
<div id="main">
<div class="header">
<h1>Services</h1>
</div>
<div class="content">
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2">
<div style="float:left; padding:2px">
<div class="card">
<h1>
Syslog
@ -53,6 +61,8 @@
</button>
</form>
</div>
</div>
<div style="float:left; padding:2px">
<div class="card">
<h1>
mDNS
@ -77,7 +87,7 @@
</form>
</div>
</div>
<div class="pure-u-1 pure-u-md-1-2">
<div style="float:left; padding:2px">
<div class="card">
<h1>
SNTP
@ -92,7 +102,7 @@
Leave empty to disable SNTP</div>
</div>
<div>
<label>Timezone Offset</label>
<label>Timezone Offset (+/- hours)</label>
<input type="text" name="timezone_offset" />
<div class="popup">Offset hours to apply (no daylight savings support)</div>
</div>
@ -105,16 +115,7 @@
</div>
</div>
</div>
</div>
</div>
<script src="ui.js"></script>
<script src="services.js"></script>
<script type="text/javascript">
onLoad(function() {
fetchServices();
bnd($("#Syslog-form"), "submit", changeServices);
bnd($("#SNTP-form"), "submit", changeServices);
bnd($("#mDNS-form"), "submit", changeServices);
});
</script>
</body></html>

@ -1,3 +1,10 @@
onLoad(function() {
fetchServices();
bnd($("#Syslog-form"), "submit", changeServices);
bnd($("#SNTP-form"), "submit", changeServices);
bnd($("#mDNS-form"), "submit", changeServices);
});
function changeServices(e) {
e.preventDefault();
var url = "services/update?1=1";

@ -26,6 +26,8 @@ a:hover {
background-color: #eee;
padding: 1em;
margin: 0.5em;
-moz-border-radius: 0.5em;
-webkit-border-radius: 0.5em;
border-radius: 0.5em;
border: 0px solid #000000;
}
@ -39,7 +41,7 @@ a:hover {
}
.click-to-edit input, .click-to-edit textarea {
color: black;
background-color: #eee;
background-color: #F0CAA6;
width: 100%;
}
.click-to-edit span, .click-to-edit div {
@ -49,9 +51,9 @@ a:hover {
width: 100%;
color: #444; /* rgba not supported (IE 8) */
color: rgba(0, 0, 0, 0.80); /* rgba supported */
border: 1px solid #999; /*IE 6/7/8*/
border: 1px solid #111; /*IE 6/7/8*/
border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/
background-color: #E6E6E6;
background-color: #CCCCCC;
text-decoration: none;
border-radius: 2px;
}
@ -155,6 +157,9 @@ fieldset fields {
/* Add transition to containers so they can push in and out */
#layout, #menu, .menu-link {
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
@ -186,10 +191,10 @@ div.tt {
.content {
margin: 0 auto;
padding: 0 2em;
max-width: 800px;
/*max-width: 800px;*/
margin-bottom: 20px;
line-height: 1.6em;
width: 100%;
/*width: 100%;*/
box-sizing: border-box;
overflow: auto;
}
@ -198,12 +203,12 @@ div.tt {
margin: 0;
color: #333;
text-align: center;
padding: 2.5em 2em 0;
padding: 0.5em;
border-bottom: 1px solid #eee;
background-color: #fc0;
}
.header h1 {
margin: 0.2em 0;
margin: 0;
font-size: 3em;
font-weight: 300;
}
@ -251,6 +256,8 @@ input.inline {
/* Text console */
pre.console {
background-color: #663300;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
border: 0px solid #000000;
color: #66ff66;
@ -495,6 +502,8 @@ pre.console a {
height: 50px;
width: 50px;
-webkit-animation: rotation 1s infinite linear;
-moz-animation: rotation 1s infinite linear;
-o-animation: rotation 1s infinite linear;
animation: rotation 1s infinite linear;
border-left: 10px solid rgba(204, 51, 0, 0.15);
border-right: 10px solid rgba(204, 51, 0, 0.15);
@ -518,6 +527,23 @@ pre.console a {
}
}
@-moz-keyframes rotation {
from {
-moz-transform: rotate(0deg);
}
to {
-moz-transform: rotate(359deg);
}
}
@-o-keyframes rotation {
from {
-o-transform: rotate(0deg);
}
to {
-o-transform: rotate(359deg);
}
}
@keyframes rotation {
from {
-webkit-transform: rotate(0deg);
@ -528,3 +554,36 @@ pre.console a {
transform: rotate(359deg);
}
}
a
{
color: #5873DD;
font-family: Arial;
font-size: 10pt;
font-weight: bold;
text-decoration: none;
}
a.btn
{
white-space: nowrap;
text-align: center;
vertical-align: middle;
display: inline-block;
border-radius: 6px;
font-size: 16pt;
line-height: 1.33;
padding: 10px 10px;
}
a.btn-yes
{
background-color: #5CB85C;
color: white;
}
a.btn-no
{
background-color: #D9534F;
color: white;
}

@ -330,6 +330,15 @@ function makeAjaxInput(klass, field) {
eoff.setAttribute('hidden','');
domForEach(eon, function(el){ el.removeAttribute('hidden'); });
eon[0].select();
old_hostname = eon[0].value;
return false;
}
var just_close = function()
{
domForEach(eon, function(el){ el.setAttribute('hidden',''); });
eoff.removeAttribute('hidden');
setEditToClick(klass+"-"+field, old_hostname);
return false;
}
@ -347,9 +356,10 @@ function makeAjaxInput(klass, field) {
}
bnd(eoff, "click", function(){return enableEditToClick();});
bnd(eon[0], "blur", function(){return submitEditToClick(eon[0].value);});
bnd(eon[0], "blur", function(){return just_close();});
bnd(eon[0], "keyup", function(ev){
if ((ev||window.event).keyCode==13) return submitEditToClick(eon[0].value);
else if ((ev||window.event).keyCode==27) return just_close();
});
});
}
@ -369,11 +379,17 @@ function setEditToClick(klass, value) {
//===== Notifications
var notifTimeout = null;
function showWarning(text) {
var el = $("#warning");
el.innerHTML = text;
el.removeAttribute('hidden');
window.scrollTo(0, 0);
if (notifTimeout != null) clearTimeout(notifTimeout);
notifTimout = setTimeout(function() {
el.setAttribute('hidden', '');
notifTimout = null;
}, 6000);
}
function hideWarning() {
el = $("#warning").setAttribute('hidden', '');

@ -1,15 +1,21 @@
<!doctype html>
<html><head>
<title>esp-link</title>
<link rel="stylesheet" href="../pure.css">
<link rel="stylesheet" href="../style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="layout">
<div id="main">
<div class="header">
<h1>WiFi Soft-AP Configuration</h1>
</div>
<div class="content">
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2">
<div style="float:left; padding:2px">
<div class="card">
<h1>Soft-AP 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>
<tr><td>WiFi mode</td><td id="wifi-mode"></td></tr>
<tr><td>Soft-AP SSID</td><td id="wifi-apssid"></td></tr>
@ -17,86 +23,77 @@
<tr><td>Soft-AP Channel</td><td id="wifi-apchan"></td></tr>
<tr><td>Soft-AP Max Conn</td><td id="wifi-apmaxc"></td></tr>
<tr><td>Soft-AP Hidden</td><td id="wifi-aphidd"></td></tr>
<tr><td>Soft-AP Beacon Int</td><td id="wifi-apbeac"></td></tr>
<tr><td>Soft-AP Beacon Interval</td><td id="wifi-apbeac"></td></tr>
<tr><td>Soft-AP Auth Mode</td><td id="wifi-apauth"></td></tr>
<tr><td>Soft-AP MAC</td><td id="wifi-apmac"></td></tr>
<tr><td colspan="2" id="wifi-apwarn"></td></tr>
</tbody> </table>
</div><!-- card-->
</div><!-- pure-u-1 -->
<div class="pure-u-1 pure-u-md-1-2">
</div>
</div>
<div style="float:left; padding:2px">
<div class="card">
<h1>Soft-AP Settings</h1>
<div id="AP_Settings-spinner" class="spinner spinner-small"></div>
<form action="#" id="AP_Settings-form" class="pure-form" hidden>
<form action="#" name="ap_form" id="AP_Settings-form" class="pure-form" hidden>
<legend>Soft-AP main settings, use with care!</legend>
<div class="pure-form-stacked">
<label>Soft-AP SSID</label>
<input type="text" name="ap_ssid" />
<div class="popup">Change the name of your AP!</div>
</div>
<div class="pure-form-stacked">
<label>Soft-AP Password</label>
<input type="text" name="ap_password" />
<div class="popup">Password must be at least 8 chars long!</div>
</div>
<div class="pure-form-stacked">
<label>Soft-AP Auth Mode</label>
<select name="ap_authmode" href="#">
<option value="0">OPEN</option>
<option value="1">WEP</option>
<option value="2">WPA_PSK</option>
<option value="3">WPA2_PSK</option>
<option value="4">WPA_WPA2_PSK</option>
</select>
<div class="popup">Default WPA_WPA2_PSK</div>
<legend>Soft-AP Advanced Settings</legend>
</div>
<div class="form-horizontal">
<label for="AP_Settings-ron" style="margin-right:1em">
<input type="radio" name="ap" value="on" id="AP_Settings-ron"/> Show
</label>
<label for="AP_Settings-roff" style="margin-right:1em">
<input type="radio" name="ap" value="off" id="AP_Settings-roff"/> Hide
</label>
</div>
<div id="AP_Settings-off" class="pure-form-stacked"></div>
<div id="AP_Settings-on" class="pure-form-stacked">
<div class="pure-form-stacked">
<label>Soft-AP Max Connections</label>
<input type="text" name="ap_maxconn" />
<div class="popup">Max 4 ( default 4 )</div>
</div>
<div class="pure-form-stacked">
<label>Soft-AP Beacon Interval</label>
<label>Soft-AP Beacon Interval (ms)</label>
<input type="text" name="ap_beacon" />
<div class="popup">Between 100 - 60000 ms ( default 100ms )</div>
</div>
<div class="pure-form-stacked">
<label>Soft-AP Auth Mode</label>
<select name="ap_authmode" href="#">
<option value="0">OPEN</option>
<option value="1">WEP</option>
<option value="2">WPA_PSK</option>
<option value="3">WPA2_PSK</option>
<option value="4">WPA_WPA2_PSK</option>
</select>
<div class="popup">Default WPA_WPA2_PSK</div>
</div>
<div class="form-horizontal">
<label><input type="checkbox" name="ap_hidden" />Soft-AP SSID hidden</label>
<div class="popup">Check this box to hide you Soft-AP SSID ( default Not Hidden )</div>
<div class="popup">Check this box to hide your Soft-AP SSID ( default Not Hidden )</div>
</div>
</div>
<button id="AP_Settings-button" type="submit" class="pure-button button-primary">
Change Soft-AP settings!
Change Soft-AP settings
</button>
</form>
</div>
</div><!-- pure-u-1 -->
</div><!-- pure-g -->
</div><!-- content -->
</div><!-- main -->
</div><!-- layout -->
<script type="text/javascript">
</script>
</div>
</div>
</div>
</div>
<script src="../ui.js"></script>
<script src="wifiAp.js"></script>
<script type="text/javascript">
onLoad(function() {
// Show info about AP
getWifiInfo();
// Fetch actual settings
fetchApSettings();
// Wire-up form
bnd($("#AP_Settings-form"), "submit", changeApSettings);
});
</script>
</body></html>

@ -7,7 +7,7 @@ specials["ap_beacon"] = "Beacon Interval";
function changeWifiMode(m) {
blockScan = 1;
hideWarning();
ajaxSpin("POST", "setmode?mode=" + m, function(resp) {
ajaxSpin("POST", "/wifi/setmode?mode=" + m, function(resp) {
showNotification("Mode changed");
window.setTimeout(getWifiInfo, 100);
blockScan = 0;
@ -83,3 +83,28 @@ function fetchApSettings() {
window.setTimeout(fetchApSettings, 1000);
});
}
function doApAdvanced() {
$('#AP_Settings-on').removeAttribute('hidden');
$("#AP_Settings-off").setAttribute("hidden", "");
$("#AP_Settings-roff").removeAttribute("checked");
}
function undoApAdvanced(){
$("#AP_Settings-on").setAttribute("hidden", "");
$("#AP_Settings-off").removeAttribute("hidden");
$("#AP_Settings-roff").setAttribute("checked", "");
}
onLoad(function() {
// Show info about AP
getWifiInfo();
// Fetch actual settings
fetchApSettings();
// Hide advanced settings
undoApAdvanced();
document.ap_form.ap.value='off';
bnd($("#AP_Settings-ron"), "click", doApAdvanced);
bnd($("#AP_Settings-roff"), "click", undoApAdvanced);
bnd($("#AP_Settings-form"), "submit", changeApSettings);
});

@ -1,11 +1,20 @@
<!doctype html>
<html><head>
<title>esp-link</title>
<link rel="stylesheet" href="../pure.css">
<link rel="stylesheet" href="../style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="layout">
<div id="main">
<div class="header">
<h1>WiFi Station Configuration</h1>
</div>
<div class="content">
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2"><div class="card">
<div style="float:left; padding:2px">
<div class="card">
<h1>WiFi State</h1>
<div id="wifi-spinner" class="spinner spinner-small"></div>
<table id="wifi-table" class="pure-table pure-table-horizontal" hidden><tbody>
@ -20,28 +29,9 @@
<tr><td colspan="2" id="wifi-warn"></td></tr>
</tbody> </table>
</div>
</div>
<div class="pure-u-1 pure-u-md-1-2"><div class="card">
<h1>WiFi Association</h1>
<p id="reconnect" style="color: #600" hidden></p>
<form action="#" id="wifiform" class="pure-form pure-form-stacked">
<legend>To connect to a WiFi network, please select one of the detected networks,
enter the password, and hit the connect button...</legend>
<label>Network SSID</label>
<div id="aps">Scanning... <div class="spinner spinner-small"></div></div>
<label for="opt-hiddenssid">
<input type="radio" name="essid" value="_hidden_ssid_" id="opt-hiddenssid">
<input type="text" id="hidden-ssid" value="" style="width:auto; display:inline-block; margin-left: 0.7em">
</label>
<label>WiFi password, if applicable:</label>
<input id="wifi-passwd" type="password" name="passwd" placeholder="password">
<button id="connect-button" type="submit" class="pure-button button-primary">Connect!</button>
</form>
</div></div>
</div>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2"><div class="card">
<div style="float:left; padding:2px">
<div class="card">
<h1>Special Settings</h1>
<form action="#" id="specform" class="pure-form">
<legend>Special settings, use with care!</legend>
@ -64,23 +54,30 @@
</div>
<button id="special-button" type="submit" class="pure-button button-primary">Change!</button>
</form>
</div></div>
</div>
</div>
<div style="float:left; padding:2px">
<div class="card">
<h1>WiFi Association</h1>
<p id="reconnect" style="color: #600" hidden></p>
<form action="#" id="wifiform" class="pure-form pure-form-stacked">
<legend>To connect to a WiFi network - choose one of detected networks (or enter a SSID),<br>
enter the password, and hit the CONNECT button...</legend>
<label>Network SSID</label>
<div id="aps">Scanning... <div class="spinner spinner-small"></div></div>
<label for="opt-hiddenssid">
<input type="radio" name="essid" value="_hidden_ssid_" id="opt-hiddenssid" />
<input type="text" id="hidden-ssid" value="" style="width:auto; display:inline-block; margin-left: 0.7em" />
</label>
<label>WiFi password, if applicable:</label>
<input id="wifi-passwd" type="password" name="passwd" placeholder="password" />
<button id="connect-button" type="submit" class="pure-button button-primary">Connect</button>
</form>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
</script>
<script src="../ui.js"></script>
<script src="wifiSta.js"></script>
<script type="text/javascript">
onLoad(function() {
getWifiInfo();
bnd($("#wifiform"), "submit", changeWifiAp);
bnd($("#specform"), "submit", changeSpecial);
bnd($("#dhcp-ron"), "click", doDhcp);
bnd($("#dhcp-roff"), "click", doStatic);
scanTimeout = window.setTimeout(scanAPs, 500);
});
</script>
</body></html>

@ -201,3 +201,12 @@ function doStatic() {
$('#dhcp-off').removeAttribute('hidden');
$('#dhcp-on').setAttribute('hidden', '');
}
onLoad(function() {
getWifiInfo();
bnd($("#wifiform"), "submit", changeWifiAp);
bnd($("#specform"), "submit", changeSpecial);
bnd($("#dhcp-ron"), "click", doDhcp);
bnd($("#dhcp-roff"), "click", doStatic);
scanTimeout = window.setTimeout(scanAPs, 500);
});

@ -31,10 +31,10 @@ int ICACHE_FLASH_ATTR authBasic(HttpdConnData *connData) {
r=httpdGetHeader(connData, "Authorization", hdr, sizeof(hdr));
if (r && strncmp(hdr, "Basic", 5)==0) {
r=base64_decode(strlen(hdr)-6, hdr+6, sizeof(userpass), (unsigned char *)userpass);
r=ubase64_decode(strlen(hdr)-6, hdr+6, sizeof(userpass), (unsigned char *)userpass);
if (r<0) r=0; //just clean out string on decode error
userpass[r]=0; //zero-terminate user:pass string
// os_printf("Auth: %s\n", userpass);
// DBG("Auth: %s\n", userpass);
while (((AuthGetUserPw)(connData->cgiArg))(connData, no,
user, AUTH_MAX_USER_LEN, pass, AUTH_MAX_PASS_LEN)) {
//Check user/pass against auth header

@ -39,7 +39,7 @@ static int ICACHE_FLASH_ATTR base64decode(const char in[4], char out[3]) {
#endif
/* decode a base64 string in one shot */
int ICACHE_FLASH_ATTR base64_decode(size_t in_len, const char *in, size_t out_len, unsigned char *out) {
int ICACHE_FLASH_ATTR ubase64_decode(size_t in_len, const char *in, size_t out_len, unsigned char *out) {
unsigned int ii, io;
uint32_t v;
unsigned int rem;

@ -1,6 +1,6 @@
#ifndef BASE64_H
#define BASE64_H
int base64_decode(size_t in_len, const char *in, size_t out_len, unsigned char *out);
int ubase64_decode(size_t in_len, const char *in, size_t out_len, unsigned char *out);
#endif

@ -396,7 +396,7 @@ static void ICACHE_FLASH_ATTR httpdProcessRequest(HttpdConnData *conn) {
return;
}
else {
if (!(r == HTTPD_CGI_NOTFOUND || r == HTTPD_CGI_AUTHENTICATED)) {
if (r == HTTPD_CGI_NOTFOUND) {
os_printf("%shandler for %s returned invalid result %d\n", connStr, conn->url, r);
}
//URL doesn't want to handle the request: either the data isn't found or there's no

@ -37,7 +37,10 @@
// If defined, the default hostname for DHCP will include the chip ID to make it unique
#undef CHIP_IN_HOSTNAME
extern char* esp_link_version;
extern char esp_link_version[];
extern char esp_link_date[];
extern char esp_link_time[];
extern char esp_link_build[];
extern uint8_t UTILS_StrToIP(const char* str, void *ip);
#endif

Loading…
Cancel
Save