diff --git a/.gitignore b/.gitignore index 899b7c3..a541909 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ esp-link.opensdf esp-link.sdf espfs/mkespfsimage/mman-win32/libmman.a .localhistory/ +tools/ diff --git a/Makefile b/Makefile index f01d874..40dd6d5 100644 --- a/Makefile +++ b/Makefile @@ -136,15 +136,20 @@ CHANGE_TO_STA ?= yes #Static gzipping is disabled by default. GZIP_COMPRESSION ?= yes -# If COMPRESS_W_YUI is set to "yes" then the static css and js files will be compressed with -# yui-compressor. This option works only when GZIP_COMPRESSION is set to "yes". +# If COMPRESS_W_HTMLCOMPRESSOR is set to "yes" then the static css and js files will be compressed with +# htmlcompressor and yui-compressor. This option works only when GZIP_COMPRESSION is set to "yes". +# https://code.google.com/p/htmlcompressor/#For_Non-Java_Projects # http://yui.github.io/yuicompressor/ -#Disabled by default. -COMPRESS_W_YUI ?= yes +# enabled by default. +COMPRESS_W_HTMLCOMPRESSOR ?= yes +HTML-COMPRESSOR ?= htmlcompressor-1.5.3.jar YUI-COMPRESSOR ?= yuicompressor-2.4.8.jar +HTML_PATH = $(abspath ./html)/ +WIFI_PATH = $(HTML_PATH)wifi/ + # Optional Modules -MODULES ?= rest +MODULES ?= mqtt rest # -------------- End of config options ------------- @@ -170,19 +175,23 @@ ifneq (,$(findstring rest,$(MODULES))) CFLAGS += -DREST endif +ifneq (,$(findstring tcpclient,$(MODULES))) + CFLAGS += -DTCPCLIENT +endif + # which modules (subdirectories) of the project to include in compiling -LIBRARIES_DIR = libraries -MODULES += espfs httpd user serial cmd esp-link +LIBRARIES_DIR = libraries +MODULES += espfs httpd user serial cmd esp-link MODULES += $(foreach sdir,$(LIBRARIES_DIR),$(wildcard $(sdir)/*)) -EXTRA_INCDIR =include . -EXTRA_INCDIR = include . +EXTRA_INCDIR = include . # libraries used in this project, mainly provided by the SDK -LIBS = c gcc hal phy pp net80211 wpa main lwip # crypto ssl +LIBS = c gcc hal phy pp net80211 wpa main lwip # 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 -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \ -nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections \ + -Wno-unused-function -Wno-unused-variable \ -D__ets__ -DICACHE_FLASH -D_STDINT_H -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) \ @@ -217,17 +226,17 @@ BUILD_DIR := $(addprefix $(BUILD_BASE)/,$(MODULES)) SDK_LIBDIR := $(addprefix $(SDK_BASE)/,$(SDK_LIBDIR)) SDK_LDDIR := $(addprefix $(SDK_BASE)/,$(SDK_LDDIR)) SDK_INCDIR := $(addprefix -I$(SDK_BASE)/,$(SDK_INCDIR)) -SDK_TOOLS := $(addprefix $(SDK_BASE)/,$(SDK_TOOLSDIR)) +SDK_TOOLS := $(addprefix $(SDK_BASE)/,$(SDK_TOOLSDIR)) APPGEN_TOOL := $(addprefix $(SDK_TOOLS)/,$(APPGEN_TOOL)) -SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) -OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC)) $(BUILD_BASE)/espfs_img.o +SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) +OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC)) $(BUILD_BASE)/espfs_img.o LIBS := $(addprefix -l,$(LIBS)) APP_AR := $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a) USER1_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).user1.out) USER2_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).user2.out) -INCDIR := $(addprefix -I,$(SRC_DIR)) +INCDIR := $(addprefix -I,$(SRC_DIR)) EXTRA_INCDIR := $(addprefix -I,$(EXTRA_INCDIR)) MODULE_INCDIR := $(addsuffix /include,$(INCDIR)) @@ -320,35 +329,52 @@ flash: all $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash -fs $(ET_FS) -ff $(ET_FF) \ 0x00000 "$(SDK_BASE)/bin/boot_v1.4(b1).bin" 0x01000 $(FW_BASE)/user1.bin \ $(ET_BLANK) $(SDK_BASE)/bin/blank.bin - -yui/$(YUI-COMPRESSOR): - $(Q) mkdir -p yui + +tools/$(HTML-COMPRESSOR): + $(Q) mkdir -p tools ifeq ($(OS),Windows_NT) - cd yui; wget --no-check-certificate https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI-COMPRESSOR) -O $(YUI-COMPRESSOR) + cd tools; wget --no-check-certificate https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI-COMPRESSOR) -O $(YUI-COMPRESSOR) + cd tools; wget --no-check-certificate https://htmlcompressor.googlecode.com/files/$(HTML-COMPRESSOR) -O $(HTML-COMPRESSOR) else - cd yui; wget https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI-COMPRESSOR) + 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) endif -ifeq ("$(COMPRESS_W_YUI)","yes") -$(BUILD_BASE)/espfs_img.o: yui/$(YUI-COMPRESSOR) +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; - $(Q) cp -r html html_compressed; - $(Q) for file in `find html_compressed -type f -name "*.htm*"`; do \ - cat html_compressed/head- $$file >$${file}-; \ - mv $$file- $$file; \ - done -ifeq ("$(COMPRESS_W_YUI)","yes") + $(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; +ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes") + $(Q) echo "Compression assets with htmlcompressor. This may take a while..." + $(Q) java -jar tools/$(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..." $(Q) for file in `find html_compressed -type f -name "*.js"`; do \ - java -jar yui/$(YUI-COMPRESSOR) $$file --nomunge --line-break 40 -o $$file; \ + java -jar tools/$(YUI-COMPRESSOR) $$file -o $$file; \ done $(Q) for file in `find html_compressed -type f -name "*.css"`; do \ - java -jar yui/$(YUI-COMPRESSOR) $$file -o $$file; \ + java -jar tools/$(YUI-COMPRESSOR) $$file -o $$file; \ done 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) cd html_compressed; find . \! -name \*- | ../espfs/mkespfsimage/mkespfsimage > ../build/espfs.img; cd ..; $(Q) ls -sl build/espfs.img $(Q) cd build; $(OBJCP) -I binary -O elf32-xtensa-le -B xtensa --rename-section .data=.espfs \ @@ -398,7 +424,7 @@ clean: $(Q) make -C espfs/mkespfsimage/ clean $(Q) rm -rf $(FW_BASE) $(Q) rm -f webpages.espfs -ifeq ("$(COMPRESS_W_YUI)","yes") +ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes") $(Q) rm -rf html_compressed endif diff --git a/cmd/cmd.c b/cmd/cmd.c index 64aeef7..f3bcbba 100644 --- a/cmd/cmd.c +++ b/cmd/cmd.c @@ -2,10 +2,8 @@ // // Adapted from: github.com/tuanpmt/esp_bridge, Created on: Jan 9, 2015, Author: Minh -#include "esp8266.h" #include "cmd.h" #include "crc16.h" -#include "serbridge.h" #include "uart.h" extern const CmdList commands[]; @@ -83,22 +81,30 @@ CMD_Exec(const CmdList *scp, CmdPacket *packet) { // Iterate through the command table and call the appropriate function while (scp->sc_function != NULL) { if(scp->sc_name == packet->cmd) { - //os_printf("CMD: Dispatching cmd=%d\n", packet->cmd); +#ifdef CMD_DBG + os_printf("CMD: Dispatching cmd=%d\n", packet->cmd); +#endif // call command function uint32_t ret = scp->sc_function(packet); // if requestor asked for a response, send it if (packet->_return){ +#ifdef CMD_DBG os_printf("CMD: Response: 0x%lx, cmd: %d\r\n", ret, packet->cmd); +#endif crc = CMD_ResponseStart(packet->cmd, 0, ret, 0); CMD_ResponseEnd(crc); } else { - //os_printf("CMD: no response (%lu)\n", packet->_return); +#ifdef CMD_DBG + os_printf("CMD: no response (%lu)\n", packet->_return); +#endif } return ret; } scp++; } +#ifdef CMD_DBG os_printf("CMD: cmd=%d not found\n", packet->cmd); +#endif return 0; } @@ -112,27 +118,36 @@ CMD_parse_packet(uint8_t *buf, short len) { CmdPacket *packet = (CmdPacket*)buf; uint8_t *data_ptr = (uint8_t*)&packet->args; uint8_t *data_limit = data_ptr+len; - uint16_t argc = packet->argc; + uint16_t argc = packet->argc; +#ifdef CMD_DBG uint16_t argn = 0; - os_printf("CMD: cmd=%d argc=%d cb=%p ret=%lu\n", packet->cmd, packet->argc, (void *)packet->callback, packet->_return); +#endif // print out arguments while (data_ptr+2 < data_limit && argc--) { short l = *(uint16_t*)data_ptr; +#ifdef CMD_DBG os_printf("CMD: arg[%d] len=%d:", argn++, l); +#endif data_ptr += 2; while (data_ptr < data_limit && l--) { +#ifdef CMD_DBG os_printf(" %02X", *data_ptr++); +#endif } +#ifdef CMD_DBG os_printf("\n"); +#endif } if (data_ptr <= data_limit) { CMD_Exec(commands, packet); } else { +#ifdef CMD_DBG os_printf("CMD: packet length overrun, parsing arg %d\n", argn-1); +#endif } } diff --git a/cmd/handlers.c b/cmd/handlers.c index adf90b9..339c1dd 100644 --- a/cmd/handlers.c +++ b/cmd/handlers.c @@ -41,7 +41,7 @@ const CmdList commands[] = { {CMD_REST_REQUEST, REST_Request}, {CMD_REST_SETHEADER, REST_SetHeader}, #endif - { CMD_CB_ADD, CMD_AddCallback }, + {CMD_CB_ADD, CMD_AddCallback}, {CMD_NULL, NULL} }; @@ -52,14 +52,18 @@ cmdCallback callbacks[MAX_CALLBACKS]; // cleared in CMD_Reset // Command handler for IsReady (healthcheck) command static uint32_t ICACHE_FLASH_ATTR CMD_IsReady(CmdPacket *cmd) { +#ifdef CMD_DBG os_printf("CMD_IsReady: Check ready\n"); +#endif return 1; } // Command handler for Null command static uint32_t ICACHE_FLASH_ATTR CMD_Null(CmdPacket *cmd) { +#ifdef CMD_DBG os_printf("CMD_Null: NULL/unsupported command\n"); +#endif return 1; } @@ -68,7 +72,9 @@ CMD_Null(CmdPacket *cmd) { // uC. static uint32_t ICACHE_FLASH_ATTR CMD_Reset(CmdPacket *cmd) { +#ifdef CMD_DBG os_printf("CMD_Reset\n"); +#endif // clear callbacks table os_memset(callbacks, 0, sizeof(callbacks)); return 1; @@ -83,7 +89,9 @@ CMD_AddCb(char* name, uint32_t cb) { if (os_strcmp(callbacks[i].name, name) == 0 || callbacks[i].name[0] == '\0') { os_strncpy(callbacks[i].name, name, sizeof(callbacks[i].name)); callbacks[i].callback = cb; +#ifdef CMD_DBG os_printf("CMD_AddCb: cb %s added at index %d\n", callbacks[i].name, i); +#endif return 1; } } @@ -99,7 +107,9 @@ CMD_GetCbByName(char* name) { // (void *)callbacks[i].callback); // if callback doesn't exist or it's null if (os_strcmp(callbacks[i].name, checkname) == 0) { +#ifdef CMD_DBG os_printf("CMD_GetCbByName: cb %s found at index %d\n", callbacks[i].name, i); +#endif return &callbacks[i]; } } @@ -111,7 +121,9 @@ CMD_GetCbByName(char* name) { static void ICACHE_FLASH_ATTR CMD_WifiCb(uint8_t wifiStatus) { if (wifiStatus != lastWifiStatus){ +#ifdef CMD_DBG os_printf("CMD_WifiCb: wifiStatus=%d\n", wifiStatus); +#endif lastWifiStatus = wifiStatus; cmdCallback *wifiCb = CMD_GetCbByName("wifiCb"); if ((uint32_t)wifiCb->callback != -1) { @@ -128,7 +140,9 @@ static uint32_t ICACHE_FLASH_ATTR CMD_WifiConnect(CmdPacket *cmd) { CmdRequest req; CMD_Request(&req, cmd); +#ifdef CMD_DBG os_printf("CMD_WifiConnect: setup argc=%ld\n", CMD_GetArgc(&req)); +#endif if(cmd->argc != 2 || cmd->callback == 0) return 0; @@ -148,7 +162,9 @@ static uint32_t ICACHE_FLASH_ATTR CMD_AddCallback(CmdPacket *cmd) { CmdRequest req; CMD_Request(&req, cmd); +#ifdef CMD_DBG os_printf("CMD_AddCallback: setup argc=%ld\n", CMD_GetArgc(&req)); +#endif if (cmd->argc != 1 || cmd->callback == 0) return 0; @@ -157,11 +173,15 @@ CMD_AddCallback(CmdPacket *cmd) { // get the sensor name len = CMD_ArgLen(&req); +#ifdef CMD_DBG os_printf("CMD_AddCallback: name len=%d\n", len); +#endif if (len > 15) return 0; // max size of name is 15 characters if (CMD_PopArg(&req, (uint8_t *)name, len)) return 0; name[len] = 0; +#ifdef CMD_DBG os_printf("CMD_AddCallback: name=%s\n", name); +#endif return CMD_AddCb(name, (uint32_t)cmd->callback); // save the sensor callback } diff --git a/esp-link.vcxproj b/esp-link.vcxproj index 72b0ea6..5682d27 100644 --- a/esp-link.vcxproj +++ b/esp-link.vcxproj @@ -28,7 +28,7 @@ __ets__;_STDINT_H;ICACHE_FLASH;__MINGW32__;__WIN32__ - .\esp-link;.\mqtt;.\cmd;.\serial;.\user;.\espfs;.\httpd;.\include;..\esp_iot_sdk_v1.3.0\include;..\xtensa-lx106-elf\xtensa-lx106-elf\include;c:\tools\mingw64\x86_64-w64-mingw32\include;c:\tools\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.3\include + .\rest;.\esp-link;.\mqtt;.\cmd;.\serial;.\user;.\espfs;.\httpd;.\include;..\esp_iot_sdk_v1.3.0\include;..\xtensa-lx106-elf\xtensa-lx106-elf\include;c:\tools\mingw64\x86_64-w64-mingw32\include;c:\tools\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.3\include @@ -39,12 +39,12 @@ build - espmake flash + espmake all wiflash espmake clean all espmake clean - espmake all wiflash + espmake clean all wiflash espmake clean all espmake clean @@ -65,9 +65,11 @@ + + + - @@ -76,6 +78,7 @@ + @@ -108,9 +111,11 @@ + + - + @@ -122,6 +127,7 @@ + diff --git a/esp-link/cgi.c b/esp-link/cgi.c index bfb7028..c99bada 100644 --- a/esp-link/cgi.c +++ b/esp-link/cgi.c @@ -16,20 +16,19 @@ Some random cgi routines. #include #include "cgi.h" -#include "espfs.h" void 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"); + httpdStartResponse(connData, code); + httpdHeader(connData, "Cache-Control", "no-cache, no-store, must-revalidate"); + httpdHeader(connData, "Pragma", "no-cache"); + httpdHeader(connData, "Expires", "0"); } void ICACHE_FLASH_ATTR jsonHeader(HttpdConnData *connData, int code) { noCacheHeaders(connData, code); - httpdHeader(connData, "Content-Type", "application/json"); - httpdEndHeaders(connData); + httpdHeader(connData, "Content-Type", "application/json"); + httpdEndHeaders(connData); } void ICACHE_FLASH_ATTR @@ -37,7 +36,9 @@ errorResponse(HttpdConnData *connData, int code, char *message) { noCacheHeaders(connData, code); httpdEndHeaders(connData); httpdSend(connData, message, -1); +#ifdef CGI_DBG os_printf("HTTP %d error response: \"%s\"\n", code, message); +#endif } // look for the HTTP arg 'name' and store it at 'config' with max length 'max_len' (incl @@ -65,59 +66,96 @@ getBoolArg(HttpdConnData *connData, char *name, bool*config) { if (strcmp(buff, "1") == 0 || strcmp(buff, "true") == 0) { *config = true; return 1; - } + } if (strcmp(buff, "0") == 0 || strcmp(buff, "false") == 0) { *config = false; return 1; - } + } os_sprintf(buff, "Invalid value for %s", name); errorResponse(connData, 400, buff); return -1; } +uint8_t ICACHE_FLASH_ATTR +UTILS_StrToIP(const char* str, void *ip){ + /* The count of the number of bytes processed. */ + int i; + /* A pointer to the next digit to process. */ + const char * start; + + start = str; + for (i = 0; i < 4; i++) { + /* The digit being processed. */ + char c; + /* The value of this byte. */ + int n = 0; + while (1) { + c = *start; + start++; + if (c >= '0' && c <= '9') { + n *= 10; + n += c - '0'; + } + /* We insist on stopping at "." if we are still parsing + the first, second, or third numbers. If we have reached + the end of the numbers, we will allow any character. */ + else if ((i < 3 && c == '.') || i == 3) { + break; + } + else { + return 0; + } + } + if (n >= 256) { + return 0; + } + ((uint8_t*)ip)[i] = n; + } + return 1; +} #define TOKEN(x) (os_strcmp(token, x) == 0) #if 0 // Handle system information variables and print their value, returns the number of // characters appended to buff int ICACHE_FLASH_ATTR printGlobalInfo(char *buff, int buflen, char *token) { - if (TOKEN("si_chip_id")) { - return os_sprintf(buff, "0x%x", system_get_chip_id()); - } else if (TOKEN("si_freeheap")) { - return os_sprintf(buff, "%dKB", system_get_free_heap_size()/1024); - } else if (TOKEN("si_uptime")) { - uint32 t = system_get_time() / 1000000; // in seconds - return os_sprintf(buff, "%dd%dh%dm%ds", t/(24*3600), (t/(3600))%24, (t/60)%60, t%60); - } else if (TOKEN("si_boot_version")) { - return os_sprintf(buff, "%d", system_get_boot_version()); - } else if (TOKEN("si_boot_address")) { - return os_sprintf(buff, "0x%x", system_get_userbin_addr()); - } else if (TOKEN("si_cpu_freq")) { - return os_sprintf(buff, "%dMhz", system_get_cpu_freq()); - } else { - return 0; - } + if (TOKEN("si_chip_id")) { + return os_sprintf(buff, "0x%x", system_get_chip_id()); + } else if (TOKEN("si_freeheap")) { + return os_sprintf(buff, "%dKB", system_get_free_heap_size()/1024); + } else if (TOKEN("si_uptime")) { + uint32 t = system_get_time() / 1000000; // in seconds + return os_sprintf(buff, "%dd%dh%dm%ds", t/(24*3600), (t/(3600))%24, (t/60)%60, t%60); + } else if (TOKEN("si_boot_version")) { + return os_sprintf(buff, "%d", system_get_boot_version()); + } else if (TOKEN("si_boot_address")) { + return os_sprintf(buff, "0x%x", system_get_userbin_addr()); + } else if (TOKEN("si_cpu_freq")) { + return os_sprintf(buff, "%dMhz", system_get_cpu_freq()); + } else { + return 0; + } } #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]; - // don't use jsonHeader so the response does get cached - httpdStartResponse(connData, 200); - httpdHeader(connData, "Cache-Control", "max-age=3600, must-revalidate"); - httpdHeader(connData, "Content-Type", "application/json"); - httpdEndHeaders(connData); - // construct json response - os_sprintf(buff, + if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. + char buff[1024]; + // don't use jsonHeader so the response does get cached + httpdStartResponse(connData, 200); + httpdHeader(connData, "Cache-Control", "max-age=3600, must-revalidate"); + httpdHeader(connData, "Content-Type", "application/json"); + httpdEndHeaders(connData); + // construct json response + os_sprintf(buff, "{\"menu\": [\"Home\", \"/home.html\", " "\"Wifi\", \"/wifi/wifi.html\"," "\"\xC2\xB5" "C Console\", \"/console.html\", " "\"REST/MQTT\", \"/mqtt.html\"," "\"Debug log\", \"/log.html\" ],\n" - " \"version\": \"%s\" }", esp_link_version); - httpdSend(connData, buff, -1); - return HTTPD_CGI_DONE; + " \"version\": \"%s\" }", esp_link_version); + httpdSend(connData, buff, -1); + return HTTPD_CGI_DONE; } diff --git a/esp-link/cgiflash.c b/esp-link/cgiflash.c index e07443b..ccd6865 100644 --- a/esp-link/cgiflash.c +++ b/esp-link/cgiflash.c @@ -22,8 +22,10 @@ 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... static char* ICACHE_FLASH_ATTR check_header(void *buf) { uint8_t *cd = (uint8_t *)buf; +#ifdef CGIFLASH_DBG uint32_t *buf32 = buf; os_printf("%p: %08lX %08lX %08lX %08lX\n", buf, buf32[0], buf32[1], buf32[2], buf32[3]); +#endif if (cd[0] != 0xEA) return "IROM magic missing"; 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"; @@ -42,7 +44,9 @@ int ICACHE_FLASH_ATTR cgiGetFirmwareNext(HttpdConnData *connData) { httpdEndHeaders(connData); char *next = id == 1 ? "user1.bin" : "user2.bin"; httpdSend(connData, next, -1); +#ifdef CGIFLASH_DBG os_printf("Next firmware: %s (got %d)\n", next, id); +#endif return HTTPD_CGI_DONE; } @@ -80,7 +84,9 @@ int ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) { // return an error if there is one if (err != NULL) { +#ifdef CGIFLASH_DBG os_printf("Error %d: %s\n", code, err); +#endif httpdStartResponse(connData, code); httpdHeader(connData, "Content-Type", "text/plain"); //httpdHeader(connData, "Content-Length", strlen(err)+2); @@ -99,7 +105,9 @@ int ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) { // erase next flash block if necessary if (address % SPI_FLASH_SEC_SIZE == 0){ +#ifdef CGIFLASH_DBG os_printf("Flashing 0x%05x (id=%d)\n", address, 2-id); +#endif spi_flash_erase_sector(address/SPI_FLASH_SEC_SIZE); } @@ -129,11 +137,15 @@ int ICACHE_FLASH_ATTR cgiRebootFirmware(HttpdConnData *connData) { 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 uint32 buf[8]; +#ifdef CGIFLASH_DBG os_printf("Checking %p\n", (void *)address); +#endif spi_flash_read(address, buf, sizeof(buf)); char *err = check_header(buf); if (err != NULL) { +#ifdef CGIFLASH_DBG os_printf("Error %d: %s\n", 400, err); +#endif httpdStartResponse(connData, 400); httpdHeader(connData, "Content-Type", "text/plain"); //httpdHeader(connData, "Content-Length", strlen(err)+2); diff --git a/esp-link/cgimqtt.c b/esp-link/cgimqtt.c index cbf4c16..2c3c7b0 100644 --- a/esp-link/cgimqtt.c +++ b/esp-link/cgimqtt.c @@ -17,17 +17,29 @@ int ICACHE_FLASH_ATTR cgiMqttGet(HttpdConnData *connData) { "\"slip-enable\":%d, " "\"mqtt-enable\":%d, " "\"mqtt-status-enable\":%d, " + "\"mqtt-clean-session\":%d, " "\"mqtt-port\":%d, " + "\"mqtt-timeout\":%d, " + "\"mqtt-keepalive\":%d, " "\"mqtt-host\":\"%s\", " "\"mqtt-client-id\":\"%s\", " "\"mqtt-username\":\"%s\", " "\"mqtt-password\":\"%s\", " "\"mqtt-status-topic\":\"%s\", " "\"mqtt-state\":\"%s\" }", - flashConfig.slip_enable, flashConfig.mqtt_enable, flashConfig.mqtt_status_enable, - flashConfig.mqtt_port, flashConfig.mqtt_hostname, flashConfig.mqtt_client, - flashConfig.mqtt_username, flashConfig.mqtt_password, - flashConfig.mqtt_status_topic, "connected"); + flashConfig.slip_enable, + flashConfig.mqtt_enable, + flashConfig.mqtt_status_enable, + flashConfig.mqtt_clean_session, + flashConfig.mqtt_port, + flashConfig.mqtt_timeout, + flashConfig.mqtt_keepalive, + flashConfig.mqtt_host, + flashConfig.mqtt_clientid, + flashConfig.mqtt_username, + flashConfig.mqtt_password, + flashConfig.mqtt_status_topic, + "connected"); jsonHeader(connData, 200); httpdSend(connData, buff, len); @@ -41,22 +53,30 @@ int ICACHE_FLASH_ATTR cgiMqttSet(HttpdConnData *connData) { // handle MQTT server settings int mqtt_server = 0; // accumulator for changes/errors mqtt_server |= getStringArg(connData, "mqtt-host", - flashConfig.mqtt_hostname, sizeof(flashConfig.mqtt_hostname)); + flashConfig.mqtt_host, sizeof(flashConfig.mqtt_host)); if (mqtt_server < 0) return HTTPD_CGI_DONE; mqtt_server |= getStringArg(connData, "mqtt-client-id", - flashConfig.mqtt_client, sizeof(flashConfig.mqtt_client)); + flashConfig.mqtt_clientid, sizeof(flashConfig.mqtt_clientid)); + if (mqtt_server < 0) return HTTPD_CGI_DONE; mqtt_server |= getStringArg(connData, "mqtt-username", flashConfig.mqtt_username, sizeof(flashConfig.mqtt_username)); if (mqtt_server < 0) return HTTPD_CGI_DONE; mqtt_server |= getStringArg(connData, "mqtt-password", flashConfig.mqtt_password, sizeof(flashConfig.mqtt_password)); + + if (mqtt_server < 0) return HTTPD_CGI_DONE; + mqtt_server |= getBoolArg(connData, "mqtt-clean-session", + &flashConfig.mqtt_clean_session); + if (mqtt_server < 0) return HTTPD_CGI_DONE; mqtt_server |= getBoolArg(connData, "mqtt-enable", &flashConfig.mqtt_enable); - // handle mqtt port + char buff[16]; + + // handle mqtt port if (httpdFindArg(connData->getArgs, "mqtt-port", buff, sizeof(buff)) > 0) { int32_t port = atoi(buff); if (port > 0 && port < 65536) { @@ -68,9 +88,23 @@ int ICACHE_FLASH_ATTR cgiMqttSet(HttpdConnData *connData) { } } + // handle mqtt timeout + if (httpdFindArg(connData->getArgs, "mqtt-timeout", buff, sizeof(buff)) > 0) { + int32_t timeout = atoi(buff); + flashConfig.mqtt_timeout = timeout; + } + + // handle mqtt keepalive + if (httpdFindArg(connData->getArgs, "mqtt-keepalive", buff, sizeof(buff)) > 0) { + int32_t keepalive = atoi(buff); + flashConfig.mqtt_keepalive = keepalive; + } + // if server setting changed, we need to "make it so" if (mqtt_server) { +#ifdef CGIMQTT_DBG os_printf("MQTT server settings changed, enable=%d\n", flashConfig.mqtt_enable); +#endif // TODO } @@ -85,9 +119,11 @@ int ICACHE_FLASH_ATTR cgiMqttSet(HttpdConnData *connData) { // if SLIP-enable is toggled it gets picked-up immediately by the parser int slip_update = getBoolArg(connData, "slip-enable", &flashConfig.slip_enable); if (slip_update < 0) return HTTPD_CGI_DONE; +#ifdef CGIMQTT_DBG if (slip_update > 0) os_printf("SLIP-enable changed: %d\n", flashConfig.slip_enable); os_printf("Saving config\n"); +#endif if (configSave()) { httpdStartResponse(connData, 200); httpdEndHeaders(connData); diff --git a/esp-link/cgipins.c b/esp-link/cgipins.c index dabc1fd..80326df 100644 --- a/esp-link/cgipins.c +++ b/esp-link/cgipins.c @@ -85,8 +85,9 @@ int ICACHE_FLASH_ATTR cgiPinsSet(HttpdConnData *connData) { jsonHeader(connData, 400); return HTTPD_CGI_DONE; } - +#ifdef CGIPINS_DBG os_printf("Switching pin map to %s (%d)\n", map_names[m], m); +#endif int8_t *map = map_asn[m]; flashConfig.reset_pin = map[0]; flashConfig.isp_pin = map[1]; diff --git a/esp-link/cgiwifi.c b/esp-link/cgiwifi.c index 69d59b4..7292447 100644 --- a/esp-link/cgiwifi.c +++ b/esp-link/cgiwifi.c @@ -55,36 +55,48 @@ static void ICACHE_FLASH_ATTR wifiHandleEventCb(System_Event_t *evt) { case EVENT_STAMODE_CONNECTED: wifiState = wifiIsConnected; wifiReason = 0; +#ifdef CGIWIFI_DBG os_printf("Wifi connected to ssid %s, ch %d\n", evt->event_info.connected.ssid, evt->event_info.connected.channel); +#endif statusWifiUpdate(wifiState); break; case EVENT_STAMODE_DISCONNECTED: wifiState = wifiIsDisconnected; wifiReason = evt->event_info.disconnected.reason; +#ifdef CGIWIFI_DBG os_printf("Wifi disconnected from ssid %s, reason %s (%d)\n", evt->event_info.disconnected.ssid, wifiGetReason(), evt->event_info.disconnected.reason); +#endif statusWifiUpdate(wifiState); break; case EVENT_STAMODE_AUTHMODE_CHANGE: +#ifdef CGIWIFI_DBG os_printf("Wifi auth mode: %d -> %d\n", evt->event_info.auth_change.old_mode, evt->event_info.auth_change.new_mode); +#endif break; case EVENT_STAMODE_GOT_IP: wifiState = wifiGotIP; wifiReason = 0; +#ifdef CGIWIFI_DBG os_printf("Wifi got ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR "\n", IP2STR(&evt->event_info.got_ip.ip), IP2STR(&evt->event_info.got_ip.mask), IP2STR(&evt->event_info.got_ip.gw)); +#endif statusWifiUpdate(wifiState); break; case EVENT_SOFTAPMODE_STACONNECTED: +#ifdef CGIWIFI_DBG os_printf("Wifi AP: station " MACSTR " joined, AID = %d\n", MAC2STR(evt->event_info.sta_connected.mac), evt->event_info.sta_connected.aid); +#endif break; case EVENT_SOFTAPMODE_STADISCONNECTED: +#ifdef CGIWIFI_DBG os_printf("Wifi AP: station " MACSTR " left, AID = %d\n", MAC2STR(evt->event_info.sta_disconnected.mac), evt->event_info.sta_disconnected.aid); +#endif break; default: break; @@ -103,7 +115,9 @@ wifiAddStateChangeCb(WifiStateChangeCb cb) { return; } } +#ifdef CGIWIFI_DBG os_printf("WIFI: max state change cb count exceeded\n"); +#endif } // ===== wifi scanning @@ -132,7 +146,9 @@ void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) { struct bss_info *bss_link = (struct bss_info *)arg; if (status!=OK) { +#ifdef CGIWIFI_DBG os_printf("wifiScanDoneCb status=%d\n", status); +#endif cgiWifiAps.scanInProgress=0; return; } @@ -152,7 +168,9 @@ void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) { //Allocate memory for access point data cgiWifiAps.apData=(ApData **)os_malloc(sizeof(ApData *)*n); cgiWifiAps.noAps=n; +#ifdef CGIWIFI_DBG os_printf("Scan done: found %d APs\n", n); +#endif //Copy access point data to the static struct n=0; @@ -161,7 +179,9 @@ void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) { if (n>=cgiWifiAps.noAps) { //This means the bss_link changed under our nose. Shouldn't happen! //Break because otherwise we will write in unallocated memory. +#ifdef CGIWIFI_DBG os_printf("Huh? I have more than the allocated %d aps!\n", cgiWifiAps.noAps); +#endif break; } //Save the ap data. @@ -169,7 +189,9 @@ void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) { cgiWifiAps.apData[n]->rssi=bss_link->rssi; cgiWifiAps.apData[n]->enc=bss_link->authmode; strncpy(cgiWifiAps.apData[n]->ssid, (char*)bss_link->ssid, 32); +#ifdef CGIWIFI_DBG os_printf("bss%d: %s (%d)\n", n+1, (char*)bss_link->ssid, bss_link->rssi); +#endif bss_link = bss_link->next.stqe_next; n++; @@ -180,7 +202,9 @@ void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) { static ETSTimer scanTimer; static void ICACHE_FLASH_ATTR scanStartCb(void *arg) { +#ifdef CGIWIFI_DBG os_printf("Starting a scan\n"); +#endif wifi_station_scan(NULL, wifiScanDoneCb); } @@ -245,13 +269,17 @@ static ETSTimer resetTimer; static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) { int x = wifi_station_get_connect_status(); int m = wifi_get_opmode() & 0x3; +#ifdef CGIWIFI_DBG os_printf("Wifi check: mode=%s status=%d\n", wifiMode[m], x); +#endif if (x == STATION_GOT_IP) { if (m != 1) { #ifdef CHANGE_TO_STA // We're happily connected, go to STA mode +#ifdef CGIWIFI_DBG os_printf("Wifi got IP. Going into STA mode..\n"); +#endif wifi_set_opmode(1); wifi_set_sleep_type(SLEEP_MODE); os_timer_arm(&resetTimer, RESET_TIMEOUT, 0); @@ -261,11 +289,15 @@ static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) { // no more resetTimer at this point, gotta use physical reset to recover if in trouble } else { if (m != 3) { +#ifdef CGIWIFI_DBG os_printf("Wifi connect failed. Going into STA+AP mode..\n"); +#endif wifi_set_opmode(3); } log_uart(true); +#ifdef CGIWIFI_DBG os_printf("Enabling/continuing uart log\n"); +#endif os_timer_arm(&resetTimer, RESET_TIMEOUT, 0); } } @@ -277,7 +309,9 @@ static ETSTimer reassTimer; // Callback actually doing reassociation static void ICACHE_FLASH_ATTR reassTimerCb(void *arg) { +#ifdef CGIWIFI_DBG os_printf("Wifi changing association\n"); +#endif wifi_station_disconnect(); stconf.bssid_set = 0; wifi_station_set_config(&stconf); @@ -303,7 +337,9 @@ int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) { //Set to 0 if you want to disable the actual reconnecting bit os_strncpy((char*)stconf.ssid, essid, 32); os_strncpy((char*)stconf.password, passwd, 64); +#ifdef CGIWIFI_DBG os_printf("Wifi try to connect to AP %s pw %s\n", essid, passwd); +#endif //Schedule disconnect/connect os_timer_disarm(&reassTimer); @@ -342,7 +378,6 @@ static bool parse_ip(char *buff, ip_addr_t *ip_ptr) { return false; } -#define DEBUGIP #ifdef DEBUGIP static void ICACHE_FLASH_ATTR debugIP() { struct ip_info info; @@ -365,7 +400,9 @@ static void ICACHE_FLASH_ATTR configWifiIP() { if (wifi_station_dhcpc_status() == DHCP_STARTED) wifi_station_dhcpc_stop(); wifi_station_dhcpc_start(); +#ifdef CGIWIFI_DBG os_printf("Wifi uses DHCP, hostname=%s\n", flashConfig.hostname); +#endif } else { // no DHCP, we got static network config! wifi_station_dhcpc_stop(); @@ -374,7 +411,9 @@ static void ICACHE_FLASH_ATTR configWifiIP() { ipi.netmask.addr = flashConfig.netmask; ipi.gw.addr = flashConfig.gateway; wifi_set_ip_info(0, &ipi); +#ifdef CGIWIFI_DBG os_printf("Wifi uses static IP %d.%d.%d.%d\n", IP2STR(&ipi.ip.addr)); +#endif } #ifdef DEBUGIP debugIP(); @@ -454,7 +493,9 @@ int ICACHE_FLASH_ATTR cgiWiFiSetMode(HttpdConnData *connData) { len=httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff)); if (len!=0) { int m = atoi(buff); +#ifdef CGIWIFI_DBG os_printf("Wifi switching to mode %d\n", m); +#endif wifi_set_opmode(m&3); if (m == 1) { wifi_set_sleep_type(SLEEP_MODE); @@ -557,8 +598,9 @@ int ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData) { #endif len += os_sprintf(buff+len, "\"x\":0}\n"); - +#ifdef CGIWIFI_DBG os_printf(" -> %s\n", buff); +#endif httpdSend(connData, buff, len); return HTTPD_CGI_DONE; } @@ -582,8 +624,10 @@ int ICACHE_FLASH_ATTR cgiWifiInfo(HttpdConnData *connData) { // so we can revert to STA+AP mode if we can't connect. void ICACHE_FLASH_ATTR wifiInit() { wifi_set_phy_mode(2); +#ifdef CGIWIFI_DBG int x = wifi_get_opmode() & 0x3; os_printf("Wifi init, mode=%s\n", wifiMode[x]); +#endif configWifiIP(); wifi_set_event_handler_cb(wifiHandleEventCb); diff --git a/esp-link/config.c b/esp-link/config.c index 80ab55e..0a62191 100644 --- a/esp-link/config.c +++ b/esp-link/config.c @@ -19,8 +19,9 @@ FlashConfig flashDefault = { 1, 0, // tcp_enable, rssi_enable "\0", // api_key 0, 0, 0, // slip_enable, mqtt_enable, mqtt_status_enable - 1833, // mqtt port - "\0", "\0", "\0", "\0", "\0", // mqtt host, client, user, password, status-topic + 2, 1, // mqtt_timeout, mqtt_clean_session + 1833, 600, // mqtt port, mqtt_keepalive + "\0", "\0", "\0", "\0", "\0", // mqtt host, client_id, user, password, status-topic }; typedef union { @@ -51,8 +52,8 @@ static void memDump(void *addr, int len) { bool ICACHE_FLASH_ATTR configSave(void) { FlashFull ff; - memset(&ff, 0, sizeof(ff)); - memcpy(&ff, &flashConfig, sizeof(FlashConfig)); + os_memset(&ff, 0, sizeof(ff)); + os_memcpy(&ff, &flashConfig, sizeof(FlashConfig)); uint32_t seq = ff.fc.seq+1; // erase secondary uint32_t addr = FLASH_ADDR + (1-flash_pri)*FLASH_SECT; @@ -87,7 +88,9 @@ bool ICACHE_FLASH_ATTR configSave(void) { spi_flash_write(addr, (void *)&ff, sizeof(uint32_t)); return true; fail: +#ifdef CONFIG_DBG os_printf("*** Failed to save config ***\n"); +#endif return false; } @@ -102,19 +105,28 @@ bool ICACHE_FLASH_ATTR configRestore(void) { FlashFull ff0, ff1; // read both flash sectors if (spi_flash_read(FLASH_ADDR, (void *)&ff0, sizeof(ff0)) != SPI_FLASH_RESULT_OK) - memset(&ff0, 0, sizeof(ff0)); // clear in case of error + os_memset(&ff0, 0, sizeof(ff0)); // clear in case of error if (spi_flash_read(FLASH_ADDR+FLASH_SECT, (void *)&ff1, sizeof(ff1)) != SPI_FLASH_RESULT_OK) - memset(&ff1, 0, sizeof(ff1)); // clear in case of error + os_memset(&ff1, 0, sizeof(ff1)); // clear in case of error // figure out which one is good flash_pri = selectPrimary(&ff0, &ff1); // if neither is OK, we revert to defaults if (flash_pri < 0) { - memcpy(&flashConfig, &flashDefault, sizeof(FlashConfig)); + os_memcpy(&flashConfig, &flashDefault, sizeof(FlashConfig)); + char chipIdStr[6]; + os_sprintf(chipIdStr, "%06x", system_get_chip_id()); + os_memcpy(&flashConfig.mqtt_clientid, chipIdStr, os_strlen(chipIdStr)); +#ifdef CHIP_IN_HOSTNAME + char hostname[16]; + os_strcpy(hostname, "esp-link-"); + os_strcat(hostname, chipIdStr); + os_memcpy(&flashConfig.hostname, hostname, os_strlen(hostname)); +#endif flash_pri = 0; return false; } // copy good one into global var and return - memcpy(&flashConfig, flash_pri == 0 ? &ff0.fc : &ff1.fc, sizeof(FlashConfig)); + os_memcpy(&flashConfig, flash_pri == 0 ? &ff0.fc : &ff1.fc, sizeof(FlashConfig)); return true; } @@ -123,10 +135,14 @@ static int ICACHE_FLASH_ATTR selectPrimary(FlashFull *ff0, FlashFull *ff1) { uint16_t crc = ff0->fc.crc; ff0->fc.crc = 0; bool ff0_crc_ok = crc16_data((unsigned char*)ff0, sizeof(FlashFull), 0) == crc; - - os_printf("FLASH chk=0x%04x crc=0x%04x full_sz=%d sz=%d\n", +#ifdef CONFIG_DBG + os_printf("FLASH chk=0x%04x crc=0x%04x full_sz=%d sz=%d chip_sz=%d\n", crc16_data((unsigned char*)ff0, sizeof(FlashFull), 0), - crc, sizeof(FlashFull), sizeof(FlashConfig)); + crc, + sizeof(FlashFull), + sizeof(FlashConfig), + getFlashSize()); +#endif // check CRC of ff1 crc = ff1->fc.crc; @@ -142,3 +158,15 @@ static int ICACHE_FLASH_ATTR selectPrimary(FlashFull *ff0, FlashFull *ff1) { else return ff1_crc_ok ? 1 : -1; } + +// returns the flash chip's size, in BYTES +const size_t ICACHE_FLASH_ATTR +getFlashSize() { + uint32_t id = spi_flash_get_id(); + uint8_t mfgr_id = id & 0xff; + uint8_t type_id = (id >> 8) & 0xff; // not relevant for size calculation + uint8_t size_id = (id >> 16) & 0xff; // lucky for us, WinBond ID's their chips as a form that lets us calculate the size + if (mfgr_id != 0xEF) // 0xEF is WinBond; that's all we care about (for now) + return 0; + return 1 << size_id; +} diff --git a/esp-link/config.h b/esp-link/config.h index 89287e6..5a67058 100644 --- a/esp-link/config.h +++ b/esp-link/config.h @@ -17,9 +17,11 @@ typedef struct { uint8_t tcp_enable, rssi_enable; // TCP client settings char api_key[48]; // RSSI submission API key (Grovestreams for now) uint8_t slip_enable, mqtt_enable, // SLIP protocol, MQTT client - mqtt_status_enable; // MQTT status reporting - uint16_t mqtt_port; - char mqtt_hostname[32], mqtt_client[48], mqtt_username[32], mqtt_password[32]; + mqtt_status_enable, // MQTT status reporting + mqtt_timeout, // MQTT send timeout + mqtt_clean_session; // MQTT clean session + uint16_t mqtt_port, mqtt_keepalive; // MQTT Host port, MQTT Keepalive timer + char mqtt_host[32], mqtt_clientid[48], mqtt_username[32], mqtt_password[32]; char mqtt_status_topic[32]; } FlashConfig; extern FlashConfig flashConfig; @@ -27,5 +29,6 @@ extern FlashConfig flashConfig; bool configSave(void); bool configRestore(void); void configWipe(void); +const size_t getFlashSize(); #endif diff --git a/esp-link/log.c b/esp-link/log.c index 93da9aa..713b9c3 100644 --- a/esp-link/log.c +++ b/esp-link/log.c @@ -22,135 +22,139 @@ static bool log_newline; // at start of a new line // when we connect to wifi AP. Here this is gated by the flash setting void ICACHE_FLASH_ATTR log_uart(bool enable) { - if (!enable && !log_no_uart && flashConfig.log_mode != LOG_MODE_ON) { - // we're asked to turn uart off, and uart is on, and the flash setting isn't always-on + if (!enable && !log_no_uart && flashConfig.log_mode != LOG_MODE_ON) { + // we're asked to turn uart off, and uart is on, and the flash setting isn't always-on #if 1 - os_printf("Turning OFF uart log\n"); - os_delay_us(4*1000L); // time for uart to flush - log_no_uart = !enable; +#ifdef LOG_DBG + os_printf("Turning OFF uart log\n"); #endif - } else if (enable && log_no_uart && flashConfig.log_mode != LOG_MODE_OFF) { - // we're asked to turn uart on, and uart is off, and the flash setting isn't always-off - log_no_uart = !enable; - os_printf("Turning ON uart log\n"); - } + os_delay_us(4*1000L); // time for uart to flush + log_no_uart = !enable; +#endif + } else if (enable && log_no_uart && flashConfig.log_mode != LOG_MODE_OFF) { + // we're asked to turn uart on, and uart is off, and the flash setting isn't always-off + log_no_uart = !enable; +#ifdef LOG_DBG + os_printf("Turning ON uart log\n"); +#endif + } } static void ICACHE_FLASH_ATTR log_write(char c) { - log_buf[log_wr] = c; - log_wr = (log_wr+1) % BUF_MAX; - if (log_wr == log_rd) { - log_rd = (log_rd+1) % BUF_MAX; // full, eat first char - log_pos++; - } + log_buf[log_wr] = c; + log_wr = (log_wr+1) % BUF_MAX; + if (log_wr == log_rd) { + log_rd = (log_rd+1) % BUF_MAX; // full, eat first char + log_pos++; + } } #if 0 static char ICACHE_FLASH_ATTR log_read(void) { - char c = 0; - if (log_rd != log_wr) { - c = log_buf[log_rd]; - log_rd = (log_rd+1) % BUF_MAX; - } - return c; + char c = 0; + if (log_rd != log_wr) { + c = log_buf[log_rd]; + log_rd = (log_rd+1) % BUF_MAX; + } + return c; } #endif static void ICACHE_FLASH_ATTR log_write_char(char c) { - // Uart output unless disabled - if (!log_no_uart) { - if (log_newline) { - char buff[16]; - int l = os_sprintf(buff, "%6d> ", (system_get_time()/1000)%1000000); - for (int i=0; i ", (system_get_time()/1000)%1000000); + for (int i=0; iconn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. - jsonHeader(connData, 200); - - // figure out where to start in buffer based on URI param - len = httpdFindArg(connData->getArgs, "start", buff, sizeof(buff)); - if (len > 0) { - start = atoi(buff); - if (start < log_pos) { - start = 0; - } else if (start >= log_pos+log_len) { - start = log_len; - } else { - start = start - log_pos; - } - } - - // start outputting - len = os_sprintf(buff, "{\"len\":%d, \"start\":%d, \"text\": \"", - log_len-start, log_pos+start); - - int rd = (log_rd+start) % BUF_MAX; - while (len < 2040 && rd != log_wr) { - uint8_t c = log_buf[rd]; - if (c == '\\' || c == '"') { - buff[len++] = '\\'; - buff[len++] = c; - } else if (c < ' ') { - len += os_sprintf(buff+len, "\\u%04x", c); - } else { - buff[len++] = c; - } - rd = (rd + 1) % BUF_MAX; - } - os_strcpy(buff+len, "\"}"); len+=2; - httpdSend(connData, buff, len); - return HTTPD_CGI_DONE; + char buff[2048]; + int len; // length of text in buff + int log_len = (log_wr+BUF_MAX-log_rd) % BUF_MAX; // num chars in log_buf + int start = 0; // offset onto log_wr to start sending out chars + + if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. + jsonHeader(connData, 200); + + // figure out where to start in buffer based on URI param + len = httpdFindArg(connData->getArgs, "start", buff, sizeof(buff)); + if (len > 0) { + start = atoi(buff); + if (start < log_pos) { + start = 0; + } else if (start >= log_pos+log_len) { + start = log_len; + } else { + start = start - log_pos; + } + } + + // start outputting + len = os_sprintf(buff, "{\"len\":%d, \"start\":%d, \"text\": \"", + log_len-start, log_pos+start); + + int rd = (log_rd+start) % BUF_MAX; + while (len < 2040 && rd != log_wr) { + uint8_t c = log_buf[rd]; + if (c == '\\' || c == '"') { + buff[len++] = '\\'; + buff[len++] = c; + } else if (c < ' ') { + len += os_sprintf(buff+len, "\\u%04x", c); + } else { + buff[len++] = c; + } + rd = (rd + 1) % BUF_MAX; + } + os_strcpy(buff+len, "\"}"); len+=2; + httpdSend(connData, buff, len); + return HTTPD_CGI_DONE; } static char *dbg_mode[] = { "auto", "off", "on" }; int ICACHE_FLASH_ATTR ajaxLogDbg(HttpdConnData *connData) { - if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. - char buff[512]; - int len, status = 400; - len = httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff)); - if (len > 0) { - int8_t mode = -1; - if (os_strcmp(buff, "auto") == 0) mode = LOG_MODE_AUTO; - if (os_strcmp(buff, "off") == 0) mode = LOG_MODE_OFF; - if (os_strcmp(buff, "on") == 0) mode = LOG_MODE_ON; - if (mode >= 0) { - flashConfig.log_mode = mode; - if (mode != LOG_MODE_AUTO) log_uart(mode == LOG_MODE_ON); - status = configSave() ? 200 : 400; - } - } else if (connData->requestType == HTTPD_METHOD_GET) { - status = 200; - } - - jsonHeader(connData, status); - os_sprintf(buff, "{\"mode\": \"%s\"}", dbg_mode[flashConfig.log_mode]); - httpdSend(connData, buff, -1); - return HTTPD_CGI_DONE; + if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. + char buff[512]; + int len, status = 400; + len = httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff)); + if (len > 0) { + int8_t mode = -1; + if (os_strcmp(buff, "auto") == 0) mode = LOG_MODE_AUTO; + if (os_strcmp(buff, "off") == 0) mode = LOG_MODE_OFF; + if (os_strcmp(buff, "on") == 0) mode = LOG_MODE_ON; + if (mode >= 0) { + flashConfig.log_mode = mode; + if (mode != LOG_MODE_AUTO) log_uart(mode == LOG_MODE_ON); + status = configSave() ? 200 : 400; + } + } else if (connData->requestType == HTTPD_METHOD_GET) { + status = 200; + } + + jsonHeader(connData, status); + os_sprintf(buff, "{\"mode\": \"%s\"}", dbg_mode[flashConfig.log_mode]); + httpdSend(connData, buff, -1); + return HTTPD_CGI_DONE; } void ICACHE_FLASH_ATTR dumpMem(void *addr, int len) { @@ -168,9 +172,9 @@ void ICACHE_FLASH_ATTR dumpMem(void *addr, int len) { } void ICACHE_FLASH_ATTR logInit() { - log_no_uart = flashConfig.log_mode == LOG_MODE_OFF; // ON unless set to always-off - log_wr = 0; - log_rd = 0; + log_no_uart = flashConfig.log_mode == LOG_MODE_OFF; // ON unless set to always-off + log_wr = 0; + log_rd = 0; os_install_putc1((void *)log_write_char); } diff --git a/esp-link/main.c b/esp-link/main.c index 25a528a..78467cf 100644 --- a/esp-link/main.c +++ b/esp-link/main.c @@ -30,24 +30,24 @@ #include "log.h" #include -#define SHOW_HEAP_USE +//#define SHOW_HEAP_USE //Function that tells the authentication system what users/passwords live on the system. //This is disabled in the default build; if you want to try it, enable the authBasic line in //the builtInUrls below. -int myPassFn(HttpdConnData *connData, int no, char *user, int userLen, char *pass, int passLen) { - if (no == 0) { - os_strcpy(user, "admin"); - os_strcpy(pass, "s3cr3t"); - return 1; +//int myPassFn(HttpdConnData *connData, int no, char *user, int userLen, char *pass, int passLen) { +// if (no == 0) { +// os_strcpy(user, "admin"); +// os_strcpy(pass, "s3cr3t"); +// return 1; //Add more users this way. Check against incrementing no for each user added. // } else if (no==1) { // os_strcpy(user, "user1"); // os_strcpy(pass, "something"); // return 1; - } - return 0; -} +// } +// return 0; +//} /* @@ -97,9 +97,6 @@ HttpdBuiltInUrl builtInUrls[] = { { NULL, NULL, NULL } }; - -//#define SHOW_HEAP_USE - #ifdef SHOW_HEAP_USE static ETSTimer prHeapTimer; diff --git a/esp-link/mqtt_client.c b/esp-link/mqtt_client.c index 229d996..d59cd5f 100644 --- a/esp-link/mqtt_client.c +++ b/esp-link/mqtt_client.c @@ -10,8 +10,8 @@ static ETSTimer mqttTimer; static int once = 0; static void ICACHE_FLASH_ATTR mqttTimerCb(void *arg) { if (once++ > 0) return; - MQTT_Init(&mqttClient, flashConfig.mqtt_hostname, flashConfig.mqtt_port, 0, 2, - flashConfig.mqtt_client, flashConfig.mqtt_username, flashConfig.mqtt_password, 60); + MQTT_Init(&mqttClient, flashConfig.mqtt_host, flashConfig.mqtt_port, 0, 2, + flashConfig.mqtt_clientid, flashConfig.mqtt_username, flashConfig.mqtt_password, 60); MQTT_Connect(&mqttClient); MQTT_Subscribe(&mqttClient, "system/time", 0); } diff --git a/esp-link/status.c b/esp-link/status.c index 2b08b20..f71d921 100644 --- a/esp-link/status.c +++ b/esp-link/status.c @@ -107,7 +107,9 @@ void ICACHE_FLASH_ATTR statusInit(void) { makeGpio(flashConfig.conn_led_pin); setLed(1); } +#ifdef STATUS_DBG os_printf("CONN led=%d\n", flashConfig.conn_led_pin); +#endif os_timer_disarm(&ledTimer); os_timer_setfn(&ledTimer, ledTimerCb, NULL); diff --git a/espfs/espfs.c b/espfs/espfs.c index 128ca29..f9942f3 100644 --- a/espfs/espfs.c +++ b/espfs/espfs.c @@ -109,7 +109,9 @@ void ICACHE_FLASH_ATTR memcpyAligned(char *dst, char *src, int len) { // Returns flags of opened file. int ICACHE_FLASH_ATTR espFsFlags(EspFsFile *fh) { if (fh == NULL) { +#ifdef ESPFS_DBG os_printf("File handle not ready\n"); +#endif return -1; } @@ -121,7 +123,9 @@ int ICACHE_FLASH_ATTR espFsFlags(EspFsFile *fh) { //Open a file and return a pointer to the file desc struct. EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { if (espFsData == NULL) { +#ifdef ESPFS_DBG os_printf("Call espFsInit first!\n"); +#endif return NULL; } char *p=espFsData; @@ -137,7 +141,9 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { //Grab the next file header. os_memcpy(&h, p, sizeof(EspFsHeader)); if (h.magic!=ESPFS_MAGIC) { +#ifdef ESPFS_DBG os_printf("Magic mismatch. EspFS image broken.\n"); +#endif return NULL; } if (h.flags&FLAG_LASTFILE) { @@ -163,7 +169,9 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { if (h.compression==COMPRESS_NONE) { r->decompData=NULL; } else { +#ifdef ESPFS_DBG os_printf("Invalid compression: %d\n", h.compression); +#endif return NULL; } return r; diff --git a/html/favicon.ico b/html/favicon.ico index fe24a7b..bf372a1 100755 Binary files a/html/favicon.ico and b/html/favicon.ico differ diff --git a/html/mqtt.html b/html/mqtt.html index 257c137..edddb88 100644 --- a/html/mqtt.html +++ b/html/mqtt.html @@ -28,27 +28,30 @@