Merge pull request #72 from brunnels/master

Thank you!
pull/91/head
Thorsten von Eicken 9 years ago
commit 60d3dbfa33
  1. 59
      Makefile
  2. 14
      WINDOWS.md
  3. 55
      cmd/cmd.c
  4. 22
      cmd/handlers.c
  5. 18
      esp-link.vcxproj
  6. 95
      esp-link/cgi.c
  7. 10
      esp-link/cgi.h
  8. 44
      esp-link/cgiflash.c
  9. 1
      esp-link/cgiflash.h
  10. 41
      esp-link/cgimqtt.c
  11. 2
      esp-link/cgimqtt.h
  12. 4
      esp-link/cgioptiboot.c
  13. 216
      esp-link/cgiservices.c
  14. 16
      esp-link/cgiservices.h
  15. 39
      esp-link/cgiwifi.c
  16. 2
      esp-link/cgiwifi.h
  17. 11
      esp-link/config.c
  18. 16
      esp-link/config.h
  19. 2
      esp-link/log.c
  20. 114
      esp-link/main.c
  21. 41
      esp-link/mqtt_client.c
  22. 26
      html/console.html
  23. 2
      html/console.js
  24. 35
      html/home.html
  25. 15
      html/log.html
  26. 2
      html/mqtt.html
  27. 2
      html/mqtt.js
  28. 106
      html/services.html
  29. 77
      html/services.js
  30. 12
      html/ui.js
  31. 24
      html/wifi/wifi.html
  32. 2
      html/wifi/wifi.js
  33. 61
      httpd/httpd.c
  34. 6
      include/user_config.h
  35. 38
      mqtt/mqtt_cmd.c
  36. 24
      mqtt/pktbuf.c
  37. 24
      serial/slip.c
  38. 80
      syslog/syslog.c
  39. 2
      syslog/syslog.h

@ -29,7 +29,7 @@ XTENSA_TOOLS_ROOT ?= $(abspath ../esp-open-sdk/xtensa-lx106-elf/bin)/
# Base directory of the ESP8266 SDK package, absolute
# Typically you'll download from Espressif's BBS, http://bbs.espressif.com/viewforum.php?f=5
SDK_BASE ?= $(abspath ../esp_iot_sdk_v1.4.1_pre7)
SDK_BASE ?= $(abspath ../esp_iot_sdk_v1.5.0)
# Esptool.py path and port, only used for 1-time serial flashing
# Typically you'll use https://github.com/themadinventor/esptool
@ -38,29 +38,11 @@ ESPTOOL ?= $(abspath ../esp-open-sdk/esptool/esptool.py)
ESPPORT ?= /dev/ttyUSB0
ESPBAUD ?= 460800
# --------------- chipset configuration ---------------
# Pick your flash size: "512KB" or "4MB"
FLASH_SIZE ?= 4MB
ifeq ("$(FLASH_SIZE)","512KB")
# Winbond 25Q40 512KB flash, typ for esp-01 thru esp-11
ESP_SPI_SIZE ?= 0 # 0->512KB
ESP_FLASH_MODE ?= 0 # 0->QIO
ESP_FLASH_FREQ_DIV ?= 0 # 0->40Mhz
ESP_FLASH_MAX ?= 241664 # max bin file for 512KB flash: 236KB
else
# Winbond 25Q32 4MB flash, typ for esp-12
# Here we're using two partitions of approx 0.5MB because that's what's easily available in terms
# of linker scripts in the SDK. Ideally we'd use two partitions of approx 1MB, the remaining 2MB
# cannot be used for code.
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
endif
# The Wifi station configuration can be hard-coded here, which makes esp-link come up in STA+AP
# mode trying to connect to the specified AP *only* if the flash wireless settings are empty!
# This happens on a full serial flash and avoids having to hunt for the AP...
# STA_SSID ?=
# STA_PASS ?=
# hostname or IP address for wifi flashing
ESP_HOSTNAME ?= esp-link
@ -120,6 +102,25 @@ YUI_COMPRESSOR ?= yuicompressor-2.4.8.jar
# -------------- End of config options -------------
ifeq ("$(FLASH_SIZE)","512KB")
# Winbond 25Q40 512KB flash, typ for esp-01 thru esp-11
ESP_SPI_SIZE ?= 0 # 0->512KB
ESP_FLASH_MODE ?= 0 # 0->QIO
ESP_FLASH_FREQ_DIV ?= 0 # 0->40Mhz
ESP_FLASH_MAX ?= 241664 # max bin file for 512KB flash: 236KB
else
# Winbond 25Q32 4MB flash, typ for esp-12
# Here we're using two partitions of approx 0.5MB because that's what's easily available in terms
# of linker scripts in the SDK. Ideally we'd use two partitions of approx 1MB, the remaining 2MB
# cannot be used for code.
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
endif
HTML_PATH = $(abspath ./html)/
WIFI_PATH = $(HTML_PATH)wifi/
@ -215,7 +216,7 @@ 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
LIBS = c gcc hal phy pp net80211 wpa main lwip crypto
# compiler flags using during compilation of source files
CFLAGS += -Os -ggdb -std=c99 -Werror -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \
@ -330,7 +331,7 @@ $(FW_BASE)/user1.bin: $(USER1_OUT) $(FW_BASE)
$(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)
$(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"
@ -341,7 +342,7 @@ $(FW_BASE)/user2.bin: $(USER2_OUT) $(FW_BASE)
$(Q) $(OBJCP) --only-section .data -O binary $(USER2_OUT) eagle.app.v6.data.bin
$(Q) $(OBJCP) --only-section .rodata -O binary $(USER2_OUT) eagle.app.v6.rodata.bin
$(Q) $(OBJCP) --only-section .irom0.text -O binary $(USER2_OUT) eagle.app.v6.irom0text.bin
$(Q) COMPILE=gcc PATH=$(XTENSA_TOOLS_ROOT):$(PATH) python $(APPGEN_TOOL) $(USER2_OUT) 2 $(ESP_FLASH_MODE) $(ESP_FLASH_FREQ_DIV) $(ESP_SPI_SIZE)
$(Q) COMPILE=gcc PATH=$(XTENSA_TOOLS_ROOT):$(PATH) python $(APPGEN_TOOL) $(USER2_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 $@
$(Q) if [ $$(stat -c '%s' $@) -gt $$(( $(ESP_FLASH_MAX) )) ]; then echo "$@ too big!"; false; fi
@ -405,6 +406,10 @@ ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes")
$(Q) for file in `find html_compressed -type f -name "*.css"`; do \
java -jar tools/$(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

@ -0,0 +1,14 @@
* Install [SourceTree](https://www.sourcetreeapp.com) and check CLI git or other git distribution to obtain git from CLI
* Install the latest Java JRE
* Install Python 2.7 to C:\Python27
* Install link shell extension from [here](http://schinagl.priv.at/nt/hardlinkshellext/linkshellextension.html)
* Download and install the [Windows Unofficial Development Kit for Espressif ESP8266](http://programs74.ru/get.php?file=EspressifESP8266DevKit) to c:\espressif
* Create a symbolic link for java/bin and git/bin directories under C:\espressif\git-bin and C:\espressif\java-bin. You must do this because "make" doesn't work properly with paths like "program files(x86)". You can see all the expected paths in the [espmake.cmd](https://github.com/jeelabs/esp-link/blob/master/espmake.cmd)
* [Download](http://sourceforge.net/projects/mingw/files/Installer/) and install MinGW. Run mingw-get-setup.exe. During the installation process select without GUI. (uncheck "... also install support for the graphical user interface")
* [Download](http://programs74.ru/get.php?file=EspressifESP8266DevKitAddon) the scripts to automate the installation of additional modules for MinGW.
* Run install-mingw-package.bat. This will install the basic modules required for MinGW to build esp8266.
* Checkout esp-link from git to C:\espressif\esp-link
* When you're done open a command prompt and run: espmake.cmd "make all wiflash"
* For a new flash over serial use: espmake.cmd "make all flash"
* If you want to program with serial but not loose your config each time use: espmake.cmd "make all baseflash"
* You can open the esp-link.sln file in Visual Studio 2013. "Build Solution" will issue "make all wiflash". "Clean Solution" will issue "make clean". "Rebuild Solution" will issue "make clean all". This can be changed under solution properties -> Configuration Properties -> NMake

@ -7,6 +7,19 @@
#include "crc16.h"
#include "uart.h"
#ifdef CMD_DBG
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
static const char *cmd_names[] = {
"NULL", "RESET", "IS_READY", "WIFI_CONNECT",
"MQTT_SETUP", "MQTT_CONNECT", "MQTT_DISCONNECT",
"MQTT_PUBLISH", "MQTT_SUBSCRIBE", "MQTT_LWT", "MQTT_EVENTS",
"REST_SETUP", "REST_REQUEST", "REST_SETHEADER", "REST_EVENTS",
"CB_ADD", "CB_EVENTS",
};
#else
#define DBG(format, ...) do { } while(0)
#endif
extern const CmdList commands[];
//===== ESP -> Serial responses
@ -82,39 +95,25 @@ 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);
DBG("CMD_Exec: Dispatching cmd=%s\n", cmd_names[packet->cmd]);
// 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
DBG("CMD_Exec: Response: 0x%lx, cmd: %d\r\n", ret, packet->cmd);
crc = CMD_ResponseStart(packet->cmd, 0, ret, 0);
CMD_ResponseEnd(crc);
} else {
#ifdef CMD_DBG
os_printf("CMD: no response (%lu)\n", packet->_return);
#endif
DBG("CMD_Exec: no response (%lu)\n", packet->_return);
}
return ret;
}
scp++;
}
#ifdef CMD_DBG
os_printf("CMD: cmd=%d not found\n", packet->cmd);
#endif
DBG("CMD_Exec: cmd=%d not found\n", packet->cmd);
return 0;
}
char *cmd_names[] = {
"NULL", "RESET", "IS_READY", "WIFI_CONNECT",
"MQTT_SETUP", "MQTT_CONNECT", "MQTT_DISCONNECT",
"MQTT_PUBLISH", "MQTT_SUBSCRIBE", "MQTT_LWT", "MQTT_EVENTS",
"REST_SETUP", "REST_REQUEST", "REST_SETHEADER", "REST_EVENTS",
"CB_ADD", "CB_EVENTS",
};
// Parse a packet and print info about it
void ICACHE_FLASH_ATTR
CMD_parse_packet(uint8_t *buf, short len) {
@ -125,18 +124,22 @@ 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;
#ifdef CMD_DBG
uint16_t argn = 0;
os_printf("CMD: cmd=%d(%s) argc=%d cb=%p ret=%lu\n",
packet->cmd, cmd_names[packet->cmd], packet->argc, (void *)packet->callback, packet->_return);
#endif
DBG("CMD_parse_packet: cmd=%d(%s) argc=%d cb=%p ret=%lu\n",
packet->cmd,
cmd_names[packet->cmd],
packet->argc,
(void *)packet->callback,
packet->_return
);
#if 0
// print out arguments
uint16_t argn = 0;
uint16_t argc = packet->argc;
while (data_ptr+2 < data_limit && argc--) {
short l = *(uint16_t*)data_ptr;
os_printf("CMD: arg[%d] len=%d:", argn++, l);
os_printf("CMD_parse_packet: arg[%d] len=%d:", argn++, l);
data_ptr += 2;
while (data_ptr < data_limit && l--) {
os_printf(" %02X", *data_ptr++);
@ -148,9 +151,7 @@ CMD_parse_packet(uint8_t *buf, short len) {
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
DBG("CMD_parse_packet: packet length overrun, parsing arg %d\n", packet->argc);
}
}

@ -12,6 +12,12 @@
#include <rest.h>
#endif
#ifdef CMD_DBG
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG(format, ...) do { } while(0)
#endif
static uint32_t CMD_Null(CmdPacket *cmd);
static uint32_t CMD_IsReady(CmdPacket *cmd);
static uint32_t CMD_Reset(CmdPacket *cmd);
@ -81,9 +87,7 @@ CMD_AddCb(char* name, uint32_t cb) {
os_strncpy(callbacks[i].name, name, sizeof(callbacks[i].name));
callbacks[i].name[CMD_CBNLEN-1] = 0; // strncpy doesn't null terminate
callbacks[i].callback = cb;
#ifdef CMD_DBG
os_printf("CMD_AddCb: cb %s added at index %d\n", callbacks[i].name, i);
#endif
DBG("CMD_AddCb: cb %s added at index %d\n", callbacks[i].name, i);
return 1;
}
}
@ -97,9 +101,7 @@ CMD_GetCbByName(char* name) {
// (void *)callbacks[i].callback);
// if callback doesn't exist or it's null
if (os_strncmp(callbacks[i].name, name, CMD_CBNLEN) == 0) {
#ifdef CMD_DBG
os_printf("CMD_GetCbByName: cb %s found at index %d\n", name, i);
#endif
DBG("CMD_GetCbByName: cb %s found at index %d\n", name, i);
return &callbacks[i];
}
}
@ -111,9 +113,7 @@ 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
DBG("CMD_WifiCb: wifiStatus=%d\n", wifiStatus);
lastWifiStatus = wifiStatus;
cmdCallback *wifiCb = CMD_GetCbByName("wifiCb");
if ((uint32_t)wifiCb->callback != -1) {
@ -160,9 +160,7 @@ CMD_AddCallback(CmdPacket *cmd) {
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
DBG("CMD_AddCallback: name=%s\n", name);
return CMD_AddCb(name, (uint32_t)cmd->callback); // save the sensor callback
}

@ -16,7 +16,9 @@
<ClCompile Include="esp-link\cgi.c" />
<ClCompile Include="esp-link\cgiflash.c" />
<ClCompile Include="esp-link\cgimqtt.c" />
<ClCompile Include="esp-link\cgioptiboot.c" />
<ClCompile Include="esp-link\cgipins.c" />
<ClCompile Include="esp-link\cgiservices.c" />
<ClCompile Include="esp-link\cgitcp.c" />
<ClCompile Include="esp-link\cgiwifi.c" />
<ClCompile Include="esp-link\config.c" />
@ -24,6 +26,7 @@
<ClCompile Include="esp-link\main.c" />
<ClCompile Include="esp-link\mqtt_client.c" />
<ClCompile Include="esp-link\status.c" />
<ClCompile Include="esp-link\task.c" />
<ClCompile Include="espfs\espfs.c" />
<ClCompile Include="espfs\mkespfsimage\main.c" />
<ClCompile Include="espfs\mkespfsimage\mman-win32\mman.c" />
@ -43,6 +46,7 @@
<ClCompile Include="serial\serled.c" />
<ClCompile Include="serial\slip.c" />
<ClCompile Include="serial\uart.c" />
<ClCompile Include="syslog\syslog.c" />
<ClCompile Include="user\user_main.c" />
</ItemGroup>
<ItemGroup>
@ -50,13 +54,17 @@
<ClInclude Include="esp-link\cgi.h" />
<ClInclude Include="esp-link\cgiflash.h" />
<ClInclude Include="esp-link\cgimqtt.h" />
<ClInclude Include="esp-link\cgioptiboot.h" />
<ClInclude Include="esp-link\cgipins.h" />
<ClInclude Include="esp-link\cgiservices.h" />
<ClInclude Include="esp-link\cgitcp.h" />
<ClInclude Include="esp-link\cgiwifi.h" />
<ClInclude Include="esp-link\config.h" />
<ClInclude Include="esp-link\log.h" />
<ClInclude Include="esp-link\mqtt_client.h" />
<ClInclude Include="esp-link\status.h" />
<ClInclude Include="esp-link\stk500.h" />
<ClInclude Include="esp-link\task.h" />
<ClInclude Include="espfs\espfs.h" />
<ClInclude Include="espfs\espfsformat.h" />
<ClInclude Include="espfs\mkespfsimage\mman-win32\mman.h" />
@ -79,8 +87,11 @@
<ClInclude Include="serial\serled.h" />
<ClInclude Include="serial\slip.h" />
<ClInclude Include="serial\uart.h" />
<ClInclude Include="syslog\syslog.h" />
</ItemGroup>
<ItemGroup>
<None Include=".gitignore" />
<None Include="avrflash" />
<None Include="BOARDS.md" />
<None Include="espmake.cmd" />
<None Include="FLASH.md" />
@ -93,6 +104,8 @@
<None Include="html\mqtt.html" />
<None Include="html\mqtt.js" />
<None Include="html\pure.css" />
<None Include="html\services.html" />
<None Include="html\services.js" />
<None Include="html\style.css" />
<None Include="html\ui.js" />
<None Include="html\wifi\wifi.html" />
@ -100,6 +113,7 @@
<None Include="Makefile" />
<None Include="README.md" />
<None Include="wiflash" />
<None Include="WINDOWS.md" />
</ItemGroup>
<ItemGroup>
<Text Include="esp-link.log" />
@ -125,8 +139,8 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<NMakeOutput />
<NMakePreprocessorDefinitions>__ets__;_STDINT_H;ICACHE_FLASH;__MINGW32__;__WIN32__</NMakePreprocessorDefinitions>
<NMakeIncludeSearchPath>.\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</NMakeIncludeSearchPath>
<NMakePreprocessorDefinitions>__ets__;_STDINT_H;ICACHE_FLASH;__MINGW32__;__WIN32__;MQTT;REST;SYSLOG;FIRMWARE_SIZE</NMakePreprocessorDefinitions>
<NMakeIncludeSearchPath>.\syslog;.\rest;.\esp-link;.\mqtt;.\cmd;.\serial;.\user;.\espfs;.\httpd;.\include;..\esp_iot_sdk_v1.5.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</NMakeIncludeSearchPath>
<ExecutablePath />
<ReferencePath />
<LibraryPath />

@ -13,40 +13,39 @@ Some random cgi routines.
* ----------------------------------------------------------------------------
*/
#include <esp8266.h>
#include "cgi.h"
#include "config.h"
void ICACHE_FLASH_ATTR
noCacheHeaders(HttpdConnData *connData, int code) {
#ifdef CGI_DBG
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG(format, ...) do { } while(0)
#endif
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");
}
void ICACHE_FLASH_ATTR
jsonHeader(HttpdConnData *connData, int code) {
void ICACHE_FLASH_ATTR jsonHeader(HttpdConnData *connData, int code) {
noCacheHeaders(connData, code);
httpdHeader(connData, "Content-Type", "application/json");
httpdEndHeaders(connData);
}
void ICACHE_FLASH_ATTR
errorResponse(HttpdConnData *connData, int code, char *message) {
void ICACHE_FLASH_ATTR 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
DBG("HTTP %d error response: \"%s\"\n", code, message);
}
// look for the HTTP arg 'name' and store it at 'config' with max length 'max_len' (incl
// terminating zero), returns -1 on error, 0 if not found, 1 if found and OK
int8_t ICACHE_FLASH_ATTR
getStringArg(HttpdConnData *connData, char *name, char *config, int max_len) {
int8_t ICACHE_FLASH_ATTR getStringArg(HttpdConnData *connData, char *name, char *config, int max_len) {
char buff[128];
int len = httpdFindArg(connData->getArgs, name, buff, sizeof(buff));
if (len < 0) return 0; // not found, skip
@ -55,19 +54,34 @@ getStringArg(HttpdConnData *connData, char *name, char *config, int max_len) {
errorResponse(connData, 400, buff);
return -1;
}
strcpy(config, buff);
os_strcpy(config, buff);
return 1;
}
// look for the HTTP arg 'name' and store it at 'config' as an 8-bit integer
// returns -1 on error, 0 if not found, 1 if found and OK
int8_t ICACHE_FLASH_ATTR
getInt8Arg(HttpdConnData *connData, char *name, int8_t *config) {
int8_t ICACHE_FLASH_ATTR getInt8Arg(HttpdConnData *connData, char *name, int8_t *config) {
char buff[16];
int len = httpdFindArg(connData->getArgs, name, buff, sizeof(buff));
if (len < 0) return 0; // not found, skip
int m = atoi(buff);
if (len > 5 || m < -127 || m > 127) {
os_sprintf(buff, "Value for %s out of range", name);
errorResponse(connData, 400, buff);
return -1;
}
*config = m;
return 1;
}
// look for the HTTP arg 'name' and store it at 'config' as an unsigned 8-bit integer
// returns -1 on error, 0 if not found, 1 if found and OK
int8_t ICACHE_FLASH_ATTR getUInt8Arg(HttpdConnData *connData, char *name, uint8_t *config) {
char buff[16];
int len = httpdFindArg(connData->getArgs, name, buff, sizeof(buff));
if (len < 0) return 0; // not found, skip
int m = atoi(buff);
if (len >= 6 || m < -128 || m > 255) {
if (len > 4 || m < 0 || m > 255) {
os_sprintf(buff, "Value for %s out of range", name);
errorResponse(connData, 400, buff);
return -1;
@ -76,27 +90,43 @@ getInt8Arg(HttpdConnData *connData, char *name, int8_t *config) {
return 1;
}
int8_t ICACHE_FLASH_ATTR
getBoolArg(HttpdConnData *connData, char *name, bool*config) {
char buff[64];
// look for the HTTP arg 'name' and store it at 'config' as an unsigned 16-bit integer
// returns -1 on error, 0 if not found, 1 if found and OK
int8_t ICACHE_FLASH_ATTR getUInt16Arg(HttpdConnData *connData, char *name, uint16_t *config) {
char buff[16];
int len = httpdFindArg(connData->getArgs, name, buff, sizeof(buff));
if (len < 0) return 0; // not found, skip
int m = atoi(buff);
if (len > 6 || m < 0 || m > 65535) {
os_sprintf(buff, "Value for %s out of range", name);
errorResponse(connData, 400, buff);
return -1;
}
*config = m;
return 1;
}
if (strcmp(buff, "1") == 0 || strcmp(buff, "true") == 0) {
int8_t ICACHE_FLASH_ATTR getBoolArg(HttpdConnData *connData, char *name, bool *config) {
char buff[16];
int len = httpdFindArg(connData->getArgs, name, buff, sizeof(buff));
if (len < 0) return 0; // not found, skip
if (os_strcmp(buff, "1") == 0 || os_strcmp(buff, "true") == 0) {
*config = true;
return 1;
}
if (strcmp(buff, "0") == 0 || strcmp(buff, "false") == 0) {
if (os_strcmp(buff, "0") == 0 || os_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){
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. */
@ -133,8 +163,8 @@ UTILS_StrToIP(const char* str, void *ip){
return 1;
}
#define TOKEN(x) (os_strcmp(token, x) == 0)
#if 0
#define TOKEN(x) (os_strcmp(token, x) == 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) {
@ -173,15 +203,22 @@ int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) {
name[12] = 0;
// construct json response
os_sprintf(buff,
"{\"menu\": [\"Home\", \"/home.html\", "
"\"Wifi\", \"/wifi/wifi.html\","
"\"\xC2\xB5" "C Console\", \"/console.html\", "
"{ "
"\"menu\": [ "
"\"Home\", \"/home.html\", "
"\"WiFI\", \"/wifi/wifi.html\", "
"\"&#xb5;C Console\", \"/console.html\", "
"\"Services\", \"/services.html\", "
#ifdef MQTT
"\"REST/MQTT\", \"/mqtt.html\", "
#endif
"\"Debug log\", \"/log.html\" ],\n"
"\"Debug log\", \"/log.html\""
" ], "
"\"version\": \"%s\", "
"\"name\":\"%s\"}", esp_link_version, name);
"\"name\": \"%s\""
" }",
esp_link_version, name);
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
}

@ -12,10 +12,18 @@ void errorResponse(HttpdConnData *connData, int code, char *message);
// 'max_len' (incl terminating zero), returns -1 on error, 0 if not found, 1 if found
int8_t getStringArg(HttpdConnData *connData, char *name, char *config, int max_len);
// Get the HTTP query-string param 'name' and store it as a int8 value at 'config',
// Get the HTTP query-string param 'name' and store it as a int8_t value at 'config',
// supports signed and unsigned, returns -1 on error, 0 if not found, 1 if found
int8_t getInt8Arg(HttpdConnData *connData, char *name, int8_t *config);
// Get the HTTP query-string param 'name' and store it as a uint8_t value at 'config',
// supports signed and unsigned, returns -1 on error, 0 if not found, 1 if found
int8_t getUInt8Arg(HttpdConnData *connData, char *name, uint8_t *config);
// Get the HTTP query-string param 'name' and store it as a uint16_t value at 'config',
// supports signed and unsigned, returns -1 on error, 0 if not found, 1 if found
int8_t getUInt16Arg(HttpdConnData *connData, char *name, uint16_t *config);
// Get the HTTP query-string param 'name' and store it boolean value at 'config',
// supports 1/true and 0/false, returns -1 on error, 0 if not found, 1 if found
int8_t getBoolArg(HttpdConnData *connData, char *name, bool *config);

@ -18,7 +18,12 @@ Some flash handling cgi routines. Used for reading the existing flash and updati
#include <osapi.h>
#include "cgi.h"
#include "cgiflash.h"
#include "espfs.h"
#ifdef CGIFLASH_DBG
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG(format, ...) do { } while(0)
#endif
// Check that the header of the firmware blob looks like actual firmware...
static char* ICACHE_FLASH_ATTR check_header(void *buf) {
@ -58,10 +63,7 @@ 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
DBG("Next firmware: %s (got %d)\n", next, id);
return HTTPD_CGI_DONE;
}
@ -103,9 +105,7 @@ 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
DBG("Error %d: %s\n", code, err);
httpdStartResponse(connData, code);
httpdHeader(connData, "Content-Type", "text/plain");
//httpdHeader(connData, "Content-Length", strlen(err)+2);
@ -124,14 +124,12 @@ 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
DBG("Flashing 0x%05x (id=%d)\n", address, 2 - id);
spi_flash_erase_sector(address/SPI_FLASH_SEC_SIZE);
}
// Write the data
//os_printf("Writing %d bytes at 0x%05x (%d of %d)\n", connData->post->buffSize, address,
//DBG("Writing %d bytes at 0x%05x (%d of %d)\n", connData->post->buffSize, address,
// connData->post->received, connData->post->len);
spi_flash_write(address, (uint32 *)connData->post->buff, connData->post->buffLen);
@ -161,15 +159,11 @@ 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
DBG("Checking %p\n", (void *)address);
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
DBG("Error %d: %s\n", 400, err);
httpdStartResponse(connData, 400);
httpdHeader(connData, "Content-Type", "text/plain");
//httpdHeader(connData, "Content-Length", strlen(err)+2);
@ -190,3 +184,17 @@ int ICACHE_FLASH_ATTR cgiRebootFirmware(HttpdConnData *connData) {
os_timer_arm(&flash_reboot_timer, 2000, 1);
return HTTPD_CGI_DONE;
}
int ICACHE_FLASH_ATTR cgiReset(HttpdConnData *connData) {
if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
httpdStartResponse(connData, 200);
httpdHeader(connData, "Content-Length", "0");
httpdEndHeaders(connData);
// Schedule a reboot
os_timer_disarm(&flash_reboot_timer);
os_timer_setfn(&flash_reboot_timer, (os_timer_func_t *)system_restart, NULL);
os_timer_arm(&flash_reboot_timer, 2000, 1);
return HTTPD_CGI_DONE;
}

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

@ -1,5 +1,14 @@
// Copyright 2015 by Thorsten von Eicken, see LICENSE.txt
#ifdef MQTT
static char *mqtt_states[] = {
"disconnected", "reconnecting", "connecting", "connected", "disabled"
};
#if !defined(MQTT)
char *mqttState(void) {
return mqtt_states[4];
}
#else
#include <esp8266.h>
#include "cgi.h"
#include "config.h"
@ -7,9 +16,11 @@
#include "mqtt_client.h"
#include "cgimqtt.h"
static char *mqtt_states[] = {
"disconnected", "reconnecting", "connecting", "connected",
};
#ifdef CGIMQTT_DBG
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG(format, ...) do { } while(0)
#endif
char *mqttState(void) {
return mqtt_states[mqttClient.connState];
@ -64,7 +75,6 @@ int ICACHE_FLASH_ATTR cgiMqttGet(HttpdConnData *connData) {
return HTTPD_CGI_DONE;
}
// Cgi to change choice of pin assignments
int ICACHE_FLASH_ATTR cgiMqttSet(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE;
@ -119,17 +129,14 @@ int ICACHE_FLASH_ATTR cgiMqttSet(HttpdConnData *connData) {
// 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
DBG("MQTT server settings changed, enable=%d\n", flashConfig.mqtt_enable);
MQTT_Free(&mqttClient); // safe even if not connected
mqtt_client_init();
// if just enable changed we just need to bounce the client
} else if (mqtt_en_chg > 0) {
#ifdef CGIMQTT_DBG
os_printf("MQTT server enable=%d changed\n", flashConfig.mqtt_enable);
#endif
}
else if (mqtt_en_chg > 0) {
DBG("MQTT server enable=%d changed\n", flashConfig.mqtt_enable);
if (flashConfig.mqtt_enable && strlen(flashConfig.mqtt_host) > 0)
MQTT_Reconnect(&mqttClient);
else
@ -147,11 +154,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);
if (slip_update > 0)
DBG("SLIP-enable changed: %d\n", flashConfig.slip_enable);
DBG("Saving config\n");
os_printf("Saving config\n");
#endif
if (configSave()) {
httpdStartResponse(connData, 200);
httpdEndHeaders(connData);
@ -173,4 +180,4 @@ int ICACHE_FLASH_ATTR cgiMqtt(HttpdConnData *connData) {
return HTTPD_CGI_DONE;
}
}
#endif // MQTT
#endif

@ -1,10 +1,10 @@
char *mqttState(void);
#ifdef MQTT
#ifndef CGIMQTT_H
#define CGIMQTT_H
#include "httpd.h"
int cgiMqtt(HttpdConnData *connData);
char *mqttState(void);
#endif // CGIMQTT_H
#endif // MQTT

@ -16,10 +16,8 @@
#define PGM_TIMEOUT 20000 // timeout when sync is achieved, in milliseconds
#define PGM_INTERVAL 200 // send sync at this interval in ms when in programming mode
#define OPTIBOOT_DBG
#undef DBG
#ifdef OPTIBOOT_DBG
#define DBG(format, ...) os_printf(format, ## __VA_ARGS__)
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG(format, ...) do { } while(0)
#endif

@ -0,0 +1,216 @@
#include <esp8266.h>
#include "cgiwifi.h"
#include "cgi.h"
#include "config.h"
#include "syslog.h"
#include "sntp.h"
#include "cgimqtt.h"
#ifdef CGISERVICES_DBG
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG(format, ...) do { } while(0)
#endif
char* rst_codes[7] = {
"normal", "wdt reset", "exception", "soft wdt", "restart", "deep sleep", "external",
};
char* flash_maps[7] = {
"512KB:256/256", "256KB", "1MB:512/512", "2MB:512/512", "4MB:512/512",
"2MB:1024/1024", "4MB:1024/1024"
};
static ETSTimer reassTimer;
// Cgi to update system info (name/description)
int ICACHE_FLASH_ATTR cgiSystemSet(HttpdConnData *connData) {
if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
int8_t n = getStringArg(connData, "name", flashConfig.hostname, sizeof(flashConfig.hostname));
int8_t d = getStringArg(connData, "description", flashConfig.sys_descr, sizeof(flashConfig.sys_descr));
if (n < 0 || d < 0) return HTTPD_CGI_DONE; // getStringArg has produced an error response
if (n > 0) {
// schedule hostname change-over
os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, configWifiIP, NULL);
os_timer_arm(&reassTimer, 1000, 0); // 1 second for the response of this request to make it
}
if (configSave()) {
httpdStartResponse(connData, 204);
httpdEndHeaders(connData);
}
else {
httpdStartResponse(connData, 500);
httpdEndHeaders(connData);
httpdSend(connData, "Failed to save config", -1);
}
return HTTPD_CGI_DONE;
}
// Cgi to return various System information
int ICACHE_FLASH_ATTR cgiSystemInfo(HttpdConnData *connData) {
char buff[1024];
if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
uint8 part_id = system_upgrade_userbin_check();
uint32_t fid = spi_flash_get_id();
struct rst_info *rst_info = system_get_rst_info();
os_sprintf(buff,
"{ "
"\"name\": \"%s\", "
"\"reset cause\": \"%d=%s\", "
"\"size\": \"%s\", "
"\"id\": \"0x%02lX 0x%04lX\", "
"\"partition\": \"%s\", "
"\"slip\": \"%s\", "
"\"mqtt\": \"%s/%s\", "
"\"baud\": \"%ld\", "
"\"description\": \"%s\""
" }",
flashConfig.hostname,
rst_info->reason,
rst_codes[rst_info->reason],
flash_maps[system_get_flash_size_map()],
fid & 0xff, (fid & 0xff00) | ((fid >> 16) & 0xff),
part_id ? "user2.bin" : "user1.bin",
flashConfig.slip_enable ? "enabled" : "disabled",
flashConfig.mqtt_enable ? "enabled" : "disabled",
mqttState(),
flashConfig.baud_rate,
flashConfig.sys_descr
);
jsonHeader(connData, 200);
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
}
void ICACHE_FLASH_ATTR cgiServicesSNTPInit() {
if (flashConfig.sntp_server[0] != '\0') {
sntp_stop();
if (true == sntp_set_timezone(flashConfig.timezone_offset)) {
sntp_setservername(0, flashConfig.sntp_server);
sntp_init();
}
DBG("SNTP timesource set to %s with offset %d\n", flashConfig.sntp_server, flashConfig.timezone_offset);
}
}
int ICACHE_FLASH_ATTR cgiServicesInfo(HttpdConnData *connData) {
char buff[1024];
if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
os_sprintf(buff,
"{ "
"\"syslog_host\": \"%s\", "
"\"syslog_minheap\": %d, "
"\"syslog_filter\": %d, "
"\"syslog_showtick\": \"%s\", "
"\"syslog_showdate\": \"%s\", "
"\"timezone_offset\": %d, "
"\"sntp_server\": \"%s\", "
"\"mdns_enable\": \"%s\", "
"\"mdns_servername\": \"%s\""
" }",
flashConfig.syslog_host,
flashConfig.syslog_minheap,
flashConfig.syslog_filter,
flashConfig.syslog_showtick ? "enabled" : "disabled",
flashConfig.syslog_showdate ? "enabled" : "disabled",
flashConfig.timezone_offset,
flashConfig.sntp_server,
flashConfig.mdns_enable ? "enabled" : "disabled",
flashConfig.mdns_servername
);
jsonHeader(connData, 200);
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
}
int ICACHE_FLASH_ATTR cgiServicesSet(HttpdConnData *connData) {
if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
int8_t syslog = 0;
syslog |= getStringArg(connData, "syslog_host", flashConfig.syslog_host, sizeof(flashConfig.syslog_host));
if (syslog < 0) return HTTPD_CGI_DONE;
syslog |= getUInt16Arg(connData, "syslog_minheap", &flashConfig.syslog_minheap);
if (syslog < 0) return HTTPD_CGI_DONE;
syslog |= getUInt8Arg(connData, "syslog_filter", &flashConfig.syslog_filter);
if (syslog < 0) return HTTPD_CGI_DONE;
syslog |= getBoolArg(connData, "syslog_showtick", &flashConfig.syslog_showtick);
if (syslog < 0) return HTTPD_CGI_DONE;
syslog |= getBoolArg(connData, "syslog_showdate", &flashConfig.syslog_showdate);
if (syslog < 0) return HTTPD_CGI_DONE;
if (syslog > 0) {
syslog_init(flashConfig.syslog_host);
}
int8_t sntp = 0;
sntp |= getInt8Arg(connData, "timezone_offset", &flashConfig.timezone_offset);
if (sntp < 0) return HTTPD_CGI_DONE;
sntp |= getStringArg(connData, "sntp_server", flashConfig.sntp_server, sizeof(flashConfig.sntp_server));
if (sntp < 0) return HTTPD_CGI_DONE;
if (sntp > 0) {
cgiServicesSNTPInit();
}
int8_t mdns = 0;
mdns |= getBoolArg(connData, "mdns_enable", &flashConfig.mdns_enable);
if (mdns < 0) return HTTPD_CGI_DONE;
if (mdns > 0) {
if (flashConfig.mdns_enable){
DBG("Services: MDNS Enabled\n");
struct ip_info ipconfig;
wifi_get_ip_info(STATION_IF, &ipconfig);
if (wifiState == wifiGotIP && ipconfig.ip.addr != 0) {
wifiStartMDNS(ipconfig.ip);
}
}
else {
DBG("Services: MDNS Disabled\n");
espconn_mdns_server_unregister();
espconn_mdns_close();
mdns_started = true;
}
}
else {
mdns |= getStringArg(connData, "mdns_servername", flashConfig.mdns_servername, sizeof(flashConfig.mdns_servername));
if (mdns < 0) return HTTPD_CGI_DONE;
if (mdns > 0 && mdns_started) {
DBG("Services: MDNS Servername Updated\n");
espconn_mdns_server_unregister();
espconn_mdns_close();
struct ip_info ipconfig;
wifi_get_ip_info(STATION_IF, &ipconfig);
if (wifiState == wifiGotIP && ipconfig.ip.addr != 0) {
wifiStartMDNS(ipconfig.ip);
}
}
}
if (configSave()) {
httpdStartResponse(connData, 204);
httpdEndHeaders(connData);
}
else {
httpdStartResponse(connData, 500);
httpdEndHeaders(connData);
httpdSend(connData, "Failed to save config", -1);
}
return HTTPD_CGI_DONE;
}

@ -0,0 +1,16 @@
#ifndef CGISERVICES_H
#define CGISERVICES_H
#include "httpd.h"
int cgiSystemSet(HttpdConnData *connData);
int cgiSystemInfo(HttpdConnData *connData);
void cgiServicesSNTPInit();
int cgiServicesInfo(HttpdConnData *connData);
int cgiServicesSet(HttpdConnData *connData);
extern char* rst_codes[7];
extern char* flash_maps[7];
#endif // CGISERVICES_H

@ -13,7 +13,6 @@ Cgi/template routines for the /wifi url.
* ----------------------------------------------------------------------------
*/
#include <esp8266.h>
#include "cgiwifi.h"
#include "cgi.h"
@ -22,12 +21,12 @@ Cgi/template routines for the /wifi url.
#include "log.h"
#ifdef CGIWIFI_DBG
#define DBG(format, ...) os_printf(format, ## __VA_ARGS__)
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG(format, ...) do { } while(0)
#endif
static void wifiStartMDNS(struct ip_addr);
bool mdns_started = false;
// ===== wifi status change callbacks
static WifiStateChangeCb wifi_state_change_cb[4];
@ -82,6 +81,7 @@ static void ICACHE_FLASH_ATTR wifiHandleEventCb(System_Event_t *evt) {
IP2STR(&evt->event_info.got_ip.ip), IP2STR(&evt->event_info.got_ip.mask),
IP2STR(&evt->event_info.got_ip.gw));
statusWifiUpdate(wifiState);
if (!mdns_started)
wifiStartMDNS(evt->event_info.got_ip.ip);
break;
case EVENT_SOFTAPMODE_STACONNECTED:
@ -101,8 +101,7 @@ static void ICACHE_FLASH_ATTR wifiHandleEventCb(System_Event_t *evt) {
}
}
void ICACHE_FLASH_ATTR
wifiAddStateChangeCb(WifiStateChangeCb cb) {
void ICACHE_FLASH_ATTR wifiAddStateChangeCb(WifiStateChangeCb cb) {
for (int i = 0; i < 4; i++) {
if (wifi_state_change_cb[i] == cb) return;
if (wifi_state_change_cb[i] == NULL) {
@ -113,21 +112,20 @@ wifiAddStateChangeCb(WifiStateChangeCb cb) {
DBG("WIFI: max state change cb count exceeded\n");
}
static bool mdns_started = true;
static struct mdns_info mdns_info;
// cannot allocate the info struct on the stack, it crashes!
static ICACHE_FLASH_ATTR
void wifiStartMDNS(struct ip_addr ip) {
if (!mdns_started) {
os_memset(&mdns_info, 0, sizeof(struct mdns_info));
mdns_info.host_name = flashConfig.hostname;
mdns_info.server_name = "http", // service name
mdns_info.server_port = 80, // service port
mdns_info.ipAddr = ip.addr,
espconn_mdns_init(&mdns_info);
mdns_started = true;
void ICACHE_FLASH_ATTR wifiStartMDNS(struct ip_addr ip) {
if (flashConfig.mdns_enable) {
struct mdns_info *mdns_info = (struct mdns_info *)os_zalloc(sizeof(struct mdns_info));
mdns_info->host_name = flashConfig.hostname;
mdns_info->server_name = flashConfig.mdns_servername;
mdns_info->server_port = 80;
mdns_info->ipAddr = ip.addr;
espconn_mdns_init(mdns_info);
}
else {
espconn_mdns_server_unregister();
espconn_mdns_close();
}
mdns_started = true;
}
// ===== wifi scanning
@ -362,7 +360,7 @@ int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) {
return HTTPD_CGI_DONE;
}
static bool parse_ip(char *buff, ip_addr_t *ip_ptr) {
static bool ICACHE_FLASH_ATTR parse_ip(char *buff, ip_addr_t *ip_ptr) {
char *next = buff; // where to start parsing next integer
int found = 0; // number of integers parsed
uint32_t ip = 0; // the ip addres parsed
@ -621,6 +619,7 @@ int ICACHE_FLASH_ATTR cgiWifiInfo(HttpdConnData *connData) {
void ICACHE_FLASH_ATTR wifiInit() {
// wifi_set_phy_mode(2); // limit to 802.11b/g 'cause n is flaky
int x = wifi_get_opmode() & 0x3;
x = x;
DBG("Wifi init, mode=%s\n", wifiMode[x]);
configWifiIP();

@ -16,7 +16,9 @@ int cgiWiFiSpecial(HttpdConnData *connData);
void configWifiIP();
void wifiInit(void);
void wifiAddStateChangeCb(WifiStateChangeCb cb);
void wifiStartMDNS(struct ip_addr);
extern uint8_t wifiState;
extern bool mdns_started;
#endif

@ -20,7 +20,7 @@ FlashConfig flashDefault = {
.log_mode = 0,
.swap_uart = 0,
.tcp_enable = 1, .rssi_enable = 0,
.api_key = "\0",
.api_key = "",
.slip_enable = 0, .mqtt_enable = 0, .mqtt_status_enable = 0,
.mqtt_timeout = 2, .mqtt_clean_session = 1,
.mqtt_port = 1883, .mqtt_keepalive = 60,
@ -28,12 +28,9 @@ FlashConfig flashDefault = {
.mqtt_username= "\0", .mqtt_password = "\0", .mqtt_status_topic = "\0",
.sys_descr = "\0",
.rx_pullup = 1,
.sntp_server = "\0",
.syslog_host = "\0",
.syslog_minheap= 8192,
.syslog_filter = 7,
.syslog_showtick= 1,
.syslog_showdate= 0,
.sntp_server = "us.pool.ntp.org\0",
.syslog_host = "\0", .syslog_minheap = 8192, .syslog_filter = 7, .syslog_showtick = 1, .syslog_showdate = 0,
.mdns_enable = 1, .mdns_servername = "http\0", .timezone_offset = 0
};
typedef union {

@ -21,16 +21,22 @@ typedef struct {
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];
char mqtt_host[32],
mqtt_clientid[48],
mqtt_username[32],
mqtt_password[32],
mqtt_status_topic[32];
char sys_descr[129]; // system description
int8_t rx_pullup; // internal pull-up on RX pin
char sntp_server[32];
char syslog_host[32];
uint16_t syslog_minheap; // min. heap to allow queuing
uint8_t syslog_filter; // min. severity
uint8_t syslog_showtick; // show system tick (µs)
uint8_t syslog_showdate; // populate SYSLOG date field
uint8_t syslog_filter, // min. severity
syslog_showtick, // show system tick (µs)
syslog_showdate; // populate SYSLOG date field
uint8_t mdns_enable;
char mdns_servername[32];
int8_t timezone_offset;
} FlashConfig;
extern FlashConfig flashConfig;

@ -7,7 +7,7 @@
#include "log.h"
#ifdef LOG_DBG
#define DBG(format, ...) os_printf(format, ## __VA_ARGS__)
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG(format, ...) do { } while(0)
#endif

@ -9,7 +9,6 @@
* ----------------------------------------------------------------------------
*/
#include <esp8266.h>
#include "httpd.h"
#include "httpdespfs.h"
@ -29,19 +28,15 @@
#include "console.h"
#include "config.h"
#include "log.h"
#include <gpio.h>
#include "gpio.h"
#include "syslog.h"
#include "sntp.h"
static int ICACHE_FLASH_ATTR cgiSystemInfo(HttpdConnData *connData);
static int ICACHE_FLASH_ATTR cgiSystemSet(HttpdConnData *connData);
#include "cgiservices.h"
#define NOTICE(format, ...) do { \
LOG_NOTICE(format, ## __VA_ARGS__ ); \
os_printf(format "\n", ## __VA_ARGS__); \
} while ( 0 )
/*
This is the main url->function dispatching data struct.
In short, it's a struct with various URLs plus their handlers. The handlers can
@ -62,6 +57,7 @@ HttpdBuiltInUrl builtInUrls[] = {
{ "/pgm/upload", cgiOptibootData, NULL },
{ "/log/text", ajaxLog, NULL },
{ "/log/dbg", ajaxLogDbg, NULL },
{ "/log/reset", cgiReset, NULL },
{ "/console/reset", ajaxConsoleReset, NULL },
{ "/console/baud", ajaxConsoleBaud, NULL },
{ "/console/text", ajaxConsole, NULL },
@ -78,11 +74,12 @@ HttpdBuiltInUrl builtInUrls[] = {
{ "/wifi/special", cgiWiFiSpecial, NULL },
{ "/system/info", cgiSystemInfo, NULL },
{ "/system/update", cgiSystemSet, NULL },
{ "/services/info", cgiServicesInfo, NULL },
{ "/services/update", cgiServicesSet, NULL },
{ "/pins", cgiPins, NULL },
#ifdef MQTT
{ "/mqtt", cgiMqtt, NULL },
#endif
{ "*", cgiEspFsHook, NULL }, //Catch-all cgi function for the filesystem
{ NULL, NULL, NULL }
};
@ -102,105 +99,6 @@ char* esp_link_version = VERS_STR(VERSION);
// address of espfs binary blob
extern uint32_t _binary_espfs_img_start;
static char *rst_codes[] = {
"normal", "wdt reset", "exception", "soft wdt", "restart", "deep sleep", "external",
};
static char *flash_maps[] = {
"512KB:256/256", "256KB", "1MB:512/512", "2MB:512/512", "4MB:512/512",
"2MB:1024/1024", "4MB:1024/1024"
};
// enable SNTP client...
static void ICACHE_FLASH_ATTR enableSNTP() {
if (flashConfig.sntp_server[0]) {
NOTICE("SNTP timesource set to %s", flashConfig.sntp_server);
sntp_stop();
sntp_setservername(0, flashConfig.sntp_server);
// sntp_set_timezone(flashConfig.timezone); /* stay with GMT... */
sntp_init();
}
}
// Cgi to return various System information
static int ICACHE_FLASH_ATTR cgiSystemInfo(HttpdConnData *connData) {
char buff[1024];
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
uint8 part_id = system_upgrade_userbin_check();
uint32_t fid = spi_flash_get_id();
struct rst_info *rst_info = system_get_rst_info();
os_sprintf(buff, "{\"name\": \"%s\", \"reset cause\": \"%d=%s\", "
"\"size\": \"%s\"," "\"id\": \"0x%02lX 0x%04lX\"," "\"partition\": \"%s\","
"\"slip\": \"%s\"," "\"mqtt\": \"%s/%s\"," "\"baud\": \"%ld\","
"\"description\": \"%s\","
"\"syslog\": \"%s\","
"\"sntp\": \"%s\" "
"}",
flashConfig.hostname, rst_info->reason, rst_codes[rst_info->reason],
flash_maps[system_get_flash_size_map()], fid & 0xff, (fid&0xff00)|((fid>>16)&0xff),
part_id ? "user2.bin" : "user1.bin",
flashConfig.slip_enable ? "enabled" : "disabled",
flashConfig.mqtt_enable ? "enabled" : "disabled",
mqttState(), flashConfig.baud_rate, flashConfig.sys_descr,
flashConfig.syslog_host,
flashConfig.sntp_server
);
jsonHeader(connData, 200);
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
}
static ETSTimer reassTimer;
// Cgi to update system info (name/description)
static int ICACHE_FLASH_ATTR cgiSystemSet(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
int8_t n = getStringArg(connData, "name", flashConfig.hostname, sizeof(flashConfig.hostname));
int8_t d = getStringArg(connData, "description", flashConfig.sys_descr, sizeof(flashConfig.sys_descr));
int8_t t = getStringArg(connData, "sntp", flashConfig.sntp_server, sizeof(flashConfig.sntp_server));
int8_t l = getStringArg(connData, "syslog", flashConfig.syslog_host, sizeof(flashConfig.syslog_host));
if (n < 0 || d < 0 || t < 0 || l < 0) return HTTPD_CGI_DONE; // getStringArg has produced an error response
// set defaults for syslog server
// we also should add a config or services web page...
if (l > 0) {
// set defaults for syslog server
syslog_init(flashConfig.syslog_host);
flashConfig.syslog_minheap= 8192;
flashConfig.syslog_filter = SYSLOG_PRIO_DEBUG;
flashConfig.syslog_showtick= 1; // show ESP µs Ticker in log message
flashConfig.syslog_showdate= 0; // Synology does a log rotate if timestamp is in the past, so we simply don't send it
os_printf("flashConfig: syslog: %s, minheap: %d, filter: %d, showtick: %d, showdate: %d\n",
flashConfig.syslog_host, flashConfig.syslog_minheap, flashConfig.syslog_filter, flashConfig.syslog_showtick, flashConfig.syslog_showdate);
}
// (re)start SNTP client if server setting is changed
if (t > 0) {
enableSNTP();
}
if (n > 0) {
// schedule hostname change-over
os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, configWifiIP, NULL);
os_timer_arm(&reassTimer, 1000, 0); // 1 second for the response of this request to make it
}
if (configSave()) {
httpdStartResponse(connData, 204);
httpdEndHeaders(connData);
} else {
httpdStartResponse(connData, 500);
httpdEndHeaders(connData);
httpdSend(connData, "Failed to save config", -1);
}
return HTTPD_CGI_DONE;
}
extern void app_init(void);
extern void mqtt_client_init(void);
@ -278,7 +176,7 @@ void user_init(void) {
fid & 0xff, (fid&0xff00)|((fid>>16)&0xff));
NOTICE("** esp-link ready");
enableSNTP();
cgiServicesSNTPInit();
#ifdef MQTT
NOTICE("initializing MQTT");

@ -5,18 +5,13 @@
#include "mqtt.h"
#ifdef MQTTCLIENT_DBG
#define DBG_MQTTCLIENT(format, ...) os_printf(format, ## __VA_ARGS__)
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__) } while(0)
#else
#define DBG_MQTTCLIENT(format, ...) do { } while(0)
#define DBG(format, ...) do { } while(0)
#endif
MQTT_Client mqttClient; // main mqtt client used by esp-link
#ifdef BRUNNELS
char* statusTopicStr;
static char* onlineMsgStr;
#endif
static MqttCallback connected_cb;
static MqttCallback disconnected_cb;
static MqttCallback published_cb;
@ -24,12 +19,9 @@ static MqttDataCallback data_cb;
void ICACHE_FLASH_ATTR
mqttConnectedCb(uint32_t *args) {
DBG_MQTTCLIENT("MQTT Client: Connected\n");
DBG("MQTT Client: Connected\n");
//MQTT_Client* client = (MQTT_Client*)args;
//MQTT_Subscribe(client, "system/time", 0); // handy for testing
#ifdef BRUNNELS
MQTT_Publish(client, "announce/all", onlineMsgStr, 0, 0);
#endif
if (connected_cb)
connected_cb(args);
}
@ -37,7 +29,7 @@ mqttConnectedCb(uint32_t *args) {
void ICACHE_FLASH_ATTR
mqttDisconnectedCb(uint32_t *args) {
// MQTT_Client* client = (MQTT_Client*)args;
DBG_MQTTCLIENT("MQTT Client: Disconnected\n");
DBG("MQTT Client: Disconnected\n");
if (disconnected_cb)
disconnected_cb(args);
}
@ -45,7 +37,7 @@ mqttDisconnectedCb(uint32_t *args) {
void ICACHE_FLASH_ATTR
mqttPublishedCb(uint32_t *args) {
// MQTT_Client* client = (MQTT_Client*)args;
DBG_MQTTCLIENT("MQTT Client: Published\n");
DBG("MQTT Client: Published\n");
if (published_cb)
published_cb(args);
}
@ -93,29 +85,6 @@ mqtt_client_init()
flashConfig.mqtt_clientid, flashConfig.mqtt_username, flashConfig.mqtt_password,
flashConfig.mqtt_keepalive);
// removed client_id concat for now until a better solution is devised
// statusTopicStr = (char*)os_zalloc(strlen(flashConfig.mqtt_clientid) + strlen(flashConfig.mqtt_status_topic) + 2);
// os_strcpy(statusTopicStr, flashConfig.mqtt_clientid);
// os_strcat(statusTopicStr, "/");
#ifdef BRUNNELS
char* onlineMsg = " is online";
onlineMsgStr = (char*)os_zalloc(strlen(flashConfig.mqtt_clientid) + strlen(onlineMsg) + 1);
os_strcpy(onlineMsgStr, flashConfig.mqtt_clientid);
os_strcat(onlineMsgStr, onlineMsg);
char* offlineMsg = " is offline";
char* offlineMsgStr = (char*)os_zalloc(strlen(flashConfig.mqtt_clientid) + strlen(offlineMsg) + 1);
os_strcpy(offlineMsgStr, flashConfig.mqtt_clientid);
os_strcat(offlineMsgStr, offlineMsg);
char* lwt = "/lwt";
char *lwtMsgStr = (char*)os_zalloc(strlen(flashConfig.mqtt_clientid) + strlen(lwt) + 1);
os_strcpy(lwtMsgStr, flashConfig.mqtt_clientid);
os_strcat(lwtMsgStr, lwt);
MQTT_InitLWT(&mqttClient, lwtMsgStr, offlineMsg, 0, 0);
#endif
MQTT_OnConnected(&mqttClient, mqttConnectedCb);
MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb);
MQTT_OnPublished(&mqttClient, mqttPublishedCb);

@ -5,8 +5,9 @@
<div class="content flex-fill flex-vbox">
<p>
<a id="reset-button" class="pure-button button-primary" href="#">Reset µC</a>
&nbsp;&nbsp;Baud:
<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:
<select id="baud-sel" class="pure-button" href="#">
<option value="460800">460800</option>
<option value="250000">250000</option>
@ -17,20 +18,7 @@
<option value="19200">19200</option>
<option value="9600">9600</option>
</select>
<!--
&nbsp;&nbsp;Pgm baud:
<select id="baud-pgm" class="pure-button">
<option value="same">same</option>
<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="9600">9600</option>
</select> -->
&nbsp;&nbsp;Fmt: 8N1
&nbsp; Fmt: 8N1
</p>
<div class="pure-g">
<div class="pure-u-1-4"><legend><b>Console</b></legend></div>
@ -85,6 +73,12 @@
);
});
$("#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); }

@ -21,7 +21,7 @@ function updateText(resp) {
var delay = 3000;
if (resp != null && resp.len > 0) {
console.log("updateText got", resp.len, "chars at", resp.start);
// console.log("updateText got", resp.len, "chars at", resp.start);
var isScrolledToBottom = el.scrollHeight - el.clientHeight <= el.scrollTop + 1;
//console.log("isScrolledToBottom="+isScrolledToBottom, "scrollHeight="+el.scrollHeight,
// "clientHeight="+el.clientHeight, "scrollTop="+el.scrollTop,

@ -22,31 +22,17 @@
</div>
</td></tr>
<tr><td>Network SSID</td><td id="wifi-ssid"></td></tr>
<tr><td>Wifi status</td><td id="wifi-status"></td></tr>
<tr><td>Wifi address</td><td id="wifi-ip"></td></tr>
<tr><td>WiFI status</td><td id="wifi-status"></td></tr>
<tr><td>WiFI address</td><td id="wifi-ip"></td></tr>
<tr><td>SLIP status</td><td class="system-slip"></td></tr>
<tr><td>MQTT status</td><td class="system-mqtt"></td></tr>
<tr><td>Serial baud</td><td class="system-baud"></td></tr>
<tr><td class="popup-target">Syslog Server</td><td>
<div class="click-to-edit system-syslog">
<span class="edit-off"></span>
<input class="edit-on" maxlength=31 hidden></input>
<div class="popup">Click to edit!<br>Use server [hostname:port] as UDP Syslog server</div>
</div>
</td></tr>
<tr><td class="popup-target">SNTP Server</td><td>
<div class="click-to-edit system-sntp">
<span class="edit-off"></span>
<input class="edit-on" maxlength=31 hidden></input>
<div class="popup">Click to edit!<br>Use server (f.e. 0.europe.pool.ntp.org) as NTP timesource</div>
</div>
</td></tr>
</tbody></table>
</div>
<div class="card">
<h1>Info</h1>
<p style="margin-bottom:0;">The JeeLabs esp-link firmware bridges the ESP8266
serial port to Wifi and can
serial port to WiFI and can
program microcontrollers over the serial port, in particular Arduinos, AVRs, and
NXP's LPC800 and other ARM processors. Typical avrdude command line to
program an Arduino:</p>
@ -73,20 +59,21 @@
<div id="pin-table" hidden>
<form action="#" id="pinform" class="pure-form pure-form-aligned form-narrow">
<div class="pure-control-group">
<label for="pin-preset">Presets</label><select id="pin-preset" class="pure-button">
<label for="pin-preset">Presets</label>
<select id="pin-preset" class="pure-button">
<option value="" selected disabled></option>
</select></label>
</select>
</div>
<hr>
<div class="pure-control-group">
<label for="pin-reset">Reset</label>
<select id="pin-reset"></select>
<div class="popup">Connect to uC reset pin for programming and reset-uC function</div>
<div class="popup">Connect to &#xb5;C reset pin for programming and reset-&#xb5;C function</div>
</div>
<div class="pure-control-group">
<label for="pin-isp">ISP/Flash</label>
<select id="pin-isp"></select>
<div class="popup">Second signal to program uC.
<div class="popup">Second signal to program &#xb5;C.
AVR:not used, esp8266:gpio2, ARM:ISP</div>
</div>
<div class="pure-control-group">
@ -122,8 +109,8 @@
<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>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>
@ -159,8 +146,6 @@
onLoad(function() {
makeAjaxInput("system", "description");
makeAjaxInput("system", "name");
makeAjaxInput("system", "sntp");
makeAjaxInput("system", "syslog");
fetchPins();
getWifiInfo();
getSystemInfo();

@ -7,10 +7,11 @@
<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">
<p class="pure-u-1-4" style="vertical-align: baseline;width:40%">
<a id="refresh-button" class="pure-button button-primary" href="#">Refresh</a>
&nbsp;<a id="reset-button" class="dbg-btn pure-button button-primary" href="#">Reset esp-link</a>
</p>
<p class="pure-u-3-4" style="vertical-align: baseline">
<p class="pure-u-3-4" style="vertical-align: baseline;width:60%">
UART debug log:
<a id="dbg-auto" class="dbg-btn pure-button" href="#">auto</a>
<a id="dbg-off" class="dbg-btn pure-button" href="#">off</a>
@ -34,6 +35,16 @@
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,

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

@ -44,7 +44,7 @@ function displayMqtt(data) {
var i, inputs = $("input");
for (i = 0; i < inputs.length; i++) {
if (inputs[i].type == "checkbox")
inputs[i].onclick = function () { console.log(this); setMqtt(this.name, this.checked) };
inputs[i].onclick = function () { setMqtt(this.name, this.checked) };
}
}

@ -0,0 +1,106 @@
<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 class="card">
<h1>
Syslog
<div id="syslog-spinner" class="spinner spinner-small"></div>
</h1>
<form action="#" id="Syslog-form" class="pure-form" hidden>
<legend>Syslog settings</legend>
<div class="pure-form-stacked">
<label>Syslog Host</label>
<input type="text" name="syslog_host" />
<div class="popup">Use server [hostname:port] as UDP Syslog server</div>
</div>
<div class="pure-form-stacked">
<label>Min Heap</label>
<input type="text" name="syslog_minheap" />
<label>Filter</label>
<select name="syslog_filter" href="#">
<option value="0">EMERG</option>
<option value="1">ALERT</option>
<option value="2">CRIT</option>
<option value="3">ERR</option>
<option value="4">WARNING</option>
<option value="5">NOTICE</option>
<option value="6">INFO</option>
<option value="7">DEBUG</option>
</select>
</div>
<div class="form-horizontal">
<label>Show ESP &#xb5;C Ticker in log message</label>
<input type="checkbox" name="syslog_showtick" />
</div>
<div class="form-horizontal">
<label>Show date in log message</label>
<input type="checkbox" name="syslog_showdate" />
<div class="popup">Synology does a log rotate if timestamp is in the past so disable to prevent this</div>
</div>
<button id="Syslog-button" type="submit" class="pure-button button-primary">
Update Syslog settings!
</button>
</form>
</div>
<div class="card">
<h1>
mDNS
<div id="mdns-spinner" class="spinner spinner-small"></div>
</h1>
<form action="#" id="mDNS-form" class="pure-form" hidden>
<div class="form-horizontal">
<input type="checkbox" name="mdns_enable"/>
<label>Enable mDNS</label>
</div>
<br>
<legend>mDNS server settings</legend>
<div class="pure-form-stacked">
<label>Server Name</label>
<input type="text" name="mdns_servername"/>
</div>
<button id="mDNS-button" type="submit" class="pure-button button-primary">
Update mDNS settings!
</button>
</form>
</div>
</div>
<div class="pure-u-1 pure-u-md-1-2">
<div class="card">
<h1>
SNTP
<div id="sntp-spinner" class="spinner spinner-small"></div>
</h1>
<form action="#" id="SNTP-form" class="pure-form" hidden>
<legend>SNTP server settings</legend>
<div class="pure-form-stacked">
<label>Timezone Offset</label>
<input type="text" name="timezone_offset" />
<label>SNTP Server</label>
<input type="text" name="sntp_server" />
</div>
<button id="SNTP-button" type="submit" class="pure-button button-primary">
Update SNTP settings!
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<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>

@ -0,0 +1,77 @@
function changeServices(e) {
e.preventDefault();
var url = "services/update?1=1";
var i, inputs = document.querySelectorAll("#" + e.target.id + " input,select");
for (i = 0; i < inputs.length; i++) {
if (inputs[i].type == "checkbox") {
if (inputs[i].name.slice(-6) == "enable")
continue;
var val = (inputs[i].checked) ? 1 : 0;
url += "&" + inputs[i].name + "=" + val;
}
else
url += "&" + inputs[i].name + "=" + inputs[i].value;
};
hideWarning();
var n = e.target.id.replace("-form", "");
var cb = $("#" + n + "-button");
addClass(cb, "pure-button-disabled");
ajaxSpin("POST", url, function (resp) {
showNotification(n + " updated");
removeClass(cb, "pure-button-disabled");
}, function (s, st) {
showWarning("Error: " + st);
removeClass(cb, "pure-button-disabled");
window.setTimeout(fetchServices, 100);
});
}
function displayServices(data) {
Object.keys(data).forEach(function (v) {
el = $("#" + v);
if (el != null) {
if (el.nodeName === "INPUT") el.value = data[v];
else el.innerHTML = data[v];
return;
}
el = document.querySelector('input[name="' + v + '"]');
if (el == null)
el = document.querySelector('select[name="' + v + '"]');
if (el != null) {
if (el.type == "checkbox") {
el.checked = data[v] == "enabled";
} else el.value = data[v];
}
});
$("#syslog-spinner").setAttribute("hidden", "");
$("#sntp-spinner").setAttribute("hidden", "");
$("#mdns-spinner").setAttribute("hidden", "");
$("#Syslog-form").removeAttribute("hidden");
$("#SNTP-form").removeAttribute("hidden");
$("#mDNS-form").removeAttribute("hidden");
var i, inputs = $("input");
for (i = 0; i < inputs.length; i++) {
if (inputs[i].name == "mdns_enable") inputs[i].onclick = function () { setMDNS(this.checked) };
}
}
function setMDNS(v) {
ajaxSpin("POST", "/services/update?mdns_enable=" + (v ? 1 : 0), function () {
showNotification("mDNS is now " + (v ? "enabled" : "disabled"));
}, function () {
showWarning("Enable/disable failed");
window.setTimeout(fetchServices, 100);
});
}
function fetchServices() {
ajaxJson("GET", "/services/info", displayServices, function () {
window.setTimeout(fetchServices, 1000);
});
}

@ -164,14 +164,14 @@ function ajaxReq(method, url, ok_cb, err_cb) {
if (xhr.readyState != 4) { return; }
clearTimeout(timeout);
if (xhr.status >= 200 && xhr.status < 300) {
console.log("XHR done:", method, url, "->", xhr.status);
// console.log("XHR done:", method, url, "->", xhr.status);
ok_cb(xhr.responseText);
} else {
console.log("XHR ERR :", method, url, "->", xhr.status, xhr.responseText, xhr);
err_cb(xhr.status, xhr.responseText);
}
}
console.log("XHR send:", method, url);
// console.log("XHR send:", method, url);
try {
xhr.send();
} catch(err) {
@ -244,7 +244,7 @@ onLoad(function() {
// make hamburger button pull out menu
var ml = $('#menuLink'), mm = $('#menu');
bnd(ml, 'click', function (e) {
console.log("hamburger time");
// console.log("hamburger time");
var active = 'active';
e.preventDefault();
toggleClass(l, active);
@ -346,7 +346,7 @@ function makeAjaxInput(klass, field) {
}
var submitEditToClick = function(v) {
console.log("Submit POST "+url+"="+v);
// console.log("Submit POST "+url+"="+v);
ajaxSpin("POST", url+"="+v, function() {
domForEach(eon, function(el){ el.setAttribute('hidden',''); });
eoff.removeAttribute('hidden');
@ -410,7 +410,7 @@ function createPresets(sel) {
function applyPreset(v) {
var pp = pinPresets[v];
if (pp === undefined) return pp;
console.log("apply preset:", v, pp);
// console.log("apply preset:", v, pp);
function setPP(k, v) { $("#pin-"+k).value = v; };
setPP("reset", pp[0]);
setPP("isp", pp[1]);
@ -474,7 +474,7 @@ function setPins(ev) {
sep = "&";
});
url += "&rxpup=" + ($("#pin-rxpup").selected ? "1" : "0");
console.log("set pins: " + url);
// console.log("set pins: " + url);
ajaxSpin("POST", url, function() {
showNotification("Pin assignment changed");
}, function(status, errMsg) {

@ -1,27 +1,27 @@
<div id="main">
<div class="header">
<h1>Wifi Configuration</h1>
<h1>WiFi Configuration</h1>
</div>
<div class="content">
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2"><div class="card">
<h1>Wifi State</h1>
<h1>WiFi State</h1>
<div id="wifi-spinner" class="spinner spinner-small"></div>
<table id="wifi-table" class="pure-table pure-table-horizontal" hidden><tbody>
<tr><td>WiFi mode</td><td id="wifi-mode"></td></tr>
<tr><td>Wifi channel</td><td id="wifi-chan"></td></tr>
<tr><td>WiFi channel</td><td id="wifi-chan"></td></tr>
<tr><td>Configured network</td><td id="wifi-ssid"></td></tr>
<tr><td>Wifi status</td><td id="wifi-status"></td></tr>
<tr><td>Wifi address</td><td id="wifi-ip"></td></tr>
<tr><td>Wifi rssi</td><td id="wifi-rssi"></td></tr>
<tr><td>Wifi phy</td><td id="wifi-phy"></td></tr>
<tr><td>Wifi MAC</td><td id="wifi-mac"></td></tr>
<tr><td>WiFi status</td><td id="wifi-status"></td></tr>
<tr><td>WiFi address</td><td id="wifi-ip"></td></tr>
<tr><td>WiFi rssi</td><td id="wifi-rssi"></td></tr>
<tr><td>WiFi phy</td><td id="wifi-phy"></td></tr>
<tr><td>WiFi MAC</td><td id="wifi-mac"></td></tr>
<tr><td 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>
<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,
@ -30,8 +30,7 @@
<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">
<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">
@ -61,8 +60,7 @@
<label>Gateway (for static IP)</label>
<input id="wifi-gateway" type="text" name="gateway"/>
</div>
<button id="special-button" type="submit"
class="pure-button button-primary">Change!</button>
<button id="special-button" type="submit" class="pure-button button-primary">Change!</button>
</form>
</div></div>
</div>

@ -82,7 +82,7 @@ function scanResult() {
}
function scanAPs() {
console.log("scanning now");
// console.log("scanning now");
if (blockScan) {
scanTimeout = window.setTimeout(scanAPs, 1000);
return;

@ -17,7 +17,11 @@ Esp8266 http server - core routines
#include <esp8266.h>
#include "httpd.h"
//#define HTTPD_DBG
#ifdef HTTPD_DBG
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG(format, ...) do { } while(0)
#endif
//Max length of request head
@ -97,7 +101,7 @@ static void debugConn(void *arg, char *what) {
os_sprintf(connStr, "%d.%d.%d.%d:%d ",
tcp->remote_ip[0], tcp->remote_ip[1], tcp->remote_ip[2], tcp->remote_ip[3],
tcp->remote_port);
os_printf("%s %s\n", connStr, what);
DBG("%s %s\n", connStr, what);
#else
connStr[0] = 0;
#endif
@ -108,20 +112,18 @@ static void ICACHE_FLASH_ATTR httpdRetireConn(HttpdConnData *conn) {
if (conn->conn && conn->conn->reverse == conn)
conn->conn->reverse = NULL; // break reverse link
#ifdef HTTPD_DBG
// log information about the request we handled
uint32 dt = conn->startTime;
if (dt > 0) dt = (system_get_time() - dt) / 1000;
if (conn->conn && conn->url)
#if 0
os_printf("HTTP %s %s from %s -> %d in %ums, heap=%ld\n",
DBG("HTTP %s %s from %s -> %d in %ums, heap=%ld\n",
conn->requestType == HTTPD_METHOD_GET ? "GET" : "POST", conn->url, conn->priv->from,
conn->priv->code, dt, (unsigned long)system_get_free_heap_size());
#else
os_printf("HTTP %s %s: %d, %ums, h=%ld\n",
DBG("HTTP %s %s: %d, %ums, h=%ld\n",
conn->requestType == HTTPD_METHOD_GET ? "GET" : "POST", conn->url,
conn->priv->code, dt, (unsigned long)system_get_free_heap_size());
#endif
#endif
conn->conn = NULL; // don't try to send anything, the SDK crashes...
@ -276,10 +278,8 @@ int ICACHE_FLASH_ATTR cgiRedirect(HttpdConnData *connData) {
int ICACHE_FLASH_ATTR httpdSend(HttpdConnData *conn, const char *data, int len) {
if (len<0) len = strlen(data);
if (conn->priv->sendBuffLen + len>MAX_SENDBUFF_LEN) {
#ifdef HTTPD_DBG
os_printf("%sERROR! httpdSend full (%d of %d)\n",
DBG("%sERROR! httpdSend full (%d of %d)\n",
connStr, conn->priv->sendBuffLen, MAX_SENDBUFF_LEN);
#endif
return 0;
}
os_memcpy(conn->priv->sendBuff + conn->priv->sendBuffLen, data, len);
@ -292,10 +292,8 @@ static void ICACHE_FLASH_ATTR xmitSendBuff(HttpdConnData *conn) {
if (conn->priv->sendBuffLen != 0) {
sint8 status = espconn_sent(conn->conn, (uint8_t*)conn->priv->sendBuff, conn->priv->sendBuffLen);
if (status != 0) {
#ifdef HTTPD_DBG
os_printf("%sERROR! espconn_sent returned %d, trying to send %d to %s\n",
DBG("%sERROR! espconn_sent returned %d, trying to send %d to %s\n",
connStr, status, conn->priv->sendBuffLen, conn->url);
#endif
}
conn->priv->sendBuffLen = 0;
}
@ -323,9 +321,7 @@ static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) {
conn->cgi = NULL; //mark for destruction.
}
if (r == HTTPD_CGI_NOTFOUND || r == HTTPD_CGI_AUTHENTICATED) {
#ifdef HTTPD_DBG
os_printf("%sERROR! Bad CGI code %d\n", connStr, r);
#endif
DBG("%sERROR! Bad CGI code %d\n", connStr, r);
conn->cgi = NULL; //mark for destruction.
}
xmitSendBuff(conn);
@ -342,9 +338,7 @@ static void ICACHE_FLASH_ATTR httpdProcessRequest(HttpdConnData *conn) {
int r;
int i = 0;
if (conn->url == NULL) {
#ifdef HTTPD_DBG
os_printf("%sWtF? url = NULL\n", connStr);
#endif
DBG("%sWtF? url = NULL\n", connStr);
return; //Shouldn't happen
}
//See if we can find a CGI that's happy to handle the request.
@ -370,9 +364,7 @@ static void ICACHE_FLASH_ATTR httpdProcessRequest(HttpdConnData *conn) {
if (builtInUrls[i].url == NULL) {
//Drat, we're at the end of the URL table. This usually shouldn't happen. Well, just
//generate a built-in 404 to handle this.
#ifdef HTTPD_DBG
os_printf("%s%s not found. 404!\n", connStr, conn->url);
#endif
DBG("%s%s not found. 404!\n", connStr, conn->url);
httpdSend(conn, httpNotFoundHeader, -1);
xmitSendBuff(conn);
conn->cgi = NULL; //mark for destruction.
@ -436,19 +428,15 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
*e = 0; //terminate url part
// Count number of open connections
#ifdef HTTPD_DBG
//esp_tcp *tcp = conn->conn->proto.tcp;
//os_printf("%sHTTP %s %s from %s\n", connStr,
//DBG("%sHTTP %s %s from %s\n", connStr,
// conn->requestType == HTTPD_METHOD_GET ? "GET" : "POST", conn->url, conn->priv->from);
#endif
//Parse out the URL part before the GET parameters.
conn->getArgs = (char*)os_strstr(conn->url, "?");
if (conn->getArgs != 0) {
*conn->getArgs = 0;
conn->getArgs++;
#ifdef HTTPD_DBG
//os_printf("%sargs = %s\n", connStr, conn->getArgs);
#endif
//DBG("%sargs = %s\n", connStr, conn->getArgs);
}
else {
conn->getArgs = NULL;
@ -470,7 +458,7 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
else {
conn->post->buffSize = conn->post->len;
}
//os_printf("Mallocced buffer for %d + 1 bytes of post data.\n", conn->post->buffSize);
//DBG("Mallocced buffer for %d + 1 bytes of post data.\n", conn->post->buffSize);
conn->post->buff = (char*)os_malloc(conn->post->buffSize + 1);
conn->post->buffLen = 0;
}
@ -482,7 +470,7 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
conn->post->multipartBoundary = b + 7; // move the pointer 2 chars before boundary then fill them with dashes
conn->post->multipartBoundary[0] = '-';
conn->post->multipartBoundary[1] = '-';
//os_printf("boundary = %s\n", conn->post->multipartBoundary);
//DBG("boundary = %s\n", conn->post->multipartBoundary);
}
}
}
@ -562,10 +550,7 @@ static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) {
struct espconn* pCon = (struct espconn *)arg;
HttpdConnData *conn = (HttpdConnData *)pCon->reverse;
if (conn == NULL) return; // aborted connection
#ifdef HTTPD_DBG
os_printf("%s***** reset, err=%d\n", connStr, err);
#endif
DBG("%s***** reset, err=%d\n", connStr, err);
httpdRetireConn(conn);
}
@ -577,7 +562,7 @@ static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) {
// Find empty conndata in pool
int i;
for (i = 0; i<MAX_CONN; i++) if (connData[i].conn == NULL) break;
//os_printf("Con req, conn=%p, pool slot %d\n", conn, i);
//DBG("Con req, conn=%p, pool slot %d\n", conn, i);
if (i == MAX_CONN) {
os_printf("%sHTTP: conn pool overflow!\n", connStr);
espconn_disconnect(conn);
@ -587,9 +572,7 @@ static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) {
#if 0
int num = 0;
for (int j = 0; j<MAX_CONN; j++) if (connData[j].conn != NULL) num++;
#ifdef HTTPD_DBG
os_printf("%sConnect (%d open)\n", connStr, num + 1);
#endif
DBG("%sConnect (%d open)\n", connStr, num + 1);
#endif
connData[i].priv = &connPrivData[i];
@ -627,9 +610,7 @@ void ICACHE_FLASH_ATTR httpdInit(HttpdBuiltInUrl *fixedUrls, int port) {
httpdTcp.local_port = port;
httpdConn.proto.tcp = &httpdTcp;
builtInUrls = fixedUrls;
#ifdef HTTPD_DBG
os_printf("Httpd init, conn=%p\n", &httpdConn);
#endif
DBG("Httpd init, conn=%p\n", &httpdConn);
espconn_regist_connectcb(&httpdConn, httpdConnectCb);
espconn_accept(&httpdConn);
espconn_tcp_set_max_con_allow(&httpdConn, MAX_CONN);

@ -19,7 +19,7 @@
#define CONFIG_DBG
#define LOG_DBG
#define STATUS_DBG
#define HTTPD_DBG
#undef HTTPD_DBG
#define MQTT_DBG
#define MQTTCMD_DBG
#undef PKTBUF_DBG
@ -29,6 +29,10 @@
#define SERLED_DBG
#undef SLIP_DBG
#define UART_DBG
#define MDNS_DBG
#define OPTIBOOT_DBG
#define SYSLOG_DBG
#define CGISERVICES_DBG
// If defined, the default hostname for DHCP will include the chip ID to make it unique
#undef CHIP_IN_HOSTNAME

@ -8,9 +8,9 @@
#include "mqtt_cmd.h"
#ifdef MQTTCMD_DBG
#define DBG_MQTTCMD(format, ...) os_printf(format, ## __VA_ARGS__)
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG_MQTTCMD(format, ...) do { } while(0)
#define DBG(format, ...) do { } while(0)
#endif
// if MQTT_1_CLIENT is defined we only support the one client that is built into esp-link.
@ -25,7 +25,7 @@ void ICACHE_FLASH_ATTR
cmdMqttConnectedCb(uint32_t* args) {
MQTT_Client* client = (MQTT_Client*)args;
MqttCmdCb* cb = (MqttCmdCb*)client->user_data;
DBG_MQTTCMD("MQTT: Connected connectedCb=%p, disconnectedCb=%p, publishedCb=%p, dataCb=%p\n",
DBG("MQTT: Connected connectedCb=%p, disconnectedCb=%p, publishedCb=%p, dataCb=%p\n",
(void*)cb->connectedCb,
(void*)cb->disconnectedCb,
(void*)cb->publishedCb,
@ -38,7 +38,7 @@ void ICACHE_FLASH_ATTR
cmdMqttDisconnectedCb(uint32_t* args) {
MQTT_Client* client = (MQTT_Client*)args;
MqttCmdCb* cb = (MqttCmdCb*)client->user_data;
DBG_MQTTCMD("MQTT: Disconnected\n");
DBG("MQTT: Disconnected\n");
uint16_t crc = CMD_ResponseStart(CMD_MQTT_EVENTS, cb->disconnectedCb, 0, 0);
CMD_ResponseEnd(crc);
}
@ -47,7 +47,7 @@ void ICACHE_FLASH_ATTR
cmdMqttPublishedCb(uint32_t* args) {
MQTT_Client* client = (MQTT_Client*)args;
MqttCmdCb* cb = (MqttCmdCb*)client->user_data;
DBG_MQTTCMD("MQTT: Published\n");
DBG("MQTT: Published\n");
uint16_t crc = CMD_ResponseStart(CMD_MQTT_EVENTS, cb->publishedCb, 0, 0);
CMD_ResponseEnd(crc);
}
@ -79,7 +79,7 @@ MQTTCMD_Lwt(CmdPacket *cmd) {
MQTT_Client* client = &mqttClient;
#else
MQTT_Client* client = (MQTT_Client*)client_ptr;
DBG_MQTTCMD("MQTT: MQTTCMD_Lwt client ptr=%p\n", (void*)client_ptr);
DBG("MQTT: MQTTCMD_Lwt client ptr=%p\n", (void*)client_ptr);
#endif
// free old topic & message
@ -110,7 +110,7 @@ MQTTCMD_Lwt(CmdPacket *cmd) {
// get retain
CMD_PopArg(&req, (uint8_t*)&client->connect_info.will_retain, 4);
DBG_MQTTCMD("MQTT: MQTTCMD_Lwt topic=%s, message=%s, qos=%d, retain=%d\n",
DBG("MQTT: MQTTCMD_Lwt topic=%s, message=%s, qos=%d, retain=%d\n",
client->connect_info.will_topic,
client->connect_info.will_message,
client->connect_info.will_qos,
@ -136,7 +136,7 @@ MQTTCMD_Publish(CmdPacket *cmd) {
MQTT_Client* client = &mqttClient;
#else
MQTT_Client* client = (MQTT_Client*)client_ptr;
DBG_MQTTCMD("MQTT: MQTTCMD_Publish client ptr=%p\n", (void*)client_ptr);
DBG("MQTT: MQTTCMD_Publish client ptr=%p\n", (void*)client_ptr);
#endif
uint16_t len;
@ -170,7 +170,7 @@ MQTTCMD_Publish(CmdPacket *cmd) {
// get retain
CMD_PopArg(&req, (uint8_t*)&retain, 4);
DBG_MQTTCMD("MQTT: MQTTCMD_Publish topic=%s, data_len=%d, qos=%ld, retain=%ld\n",
DBG("MQTT: MQTTCMD_Publish topic=%s, data_len=%d, qos=%ld, retain=%ld\n",
topic,
os_strlen((char*)data),
qos,
@ -197,7 +197,7 @@ MQTTCMD_Subscribe(CmdPacket *cmd) {
MQTT_Client* client = &mqttClient;
#else
MQTT_Client* client = (MQTT_Client*)client_ptr;
DBG_MQTTCMD("MQTT: MQTTCMD_Subscribe client ptr=%p\n", (void*)client_ptr);
DBG("MQTT: MQTTCMD_Subscribe client ptr=%p\n", (void*)client_ptr);
#endif
uint16_t len;
@ -213,7 +213,7 @@ MQTTCMD_Subscribe(CmdPacket *cmd) {
uint32_t qos = 0;
CMD_PopArg(&req, (uint8_t*)&qos, 4);
DBG_MQTTCMD("MQTT: MQTTCMD_Subscribe topic=%s, qos=%ld\n", topic, qos);
DBG("MQTT: MQTTCMD_Subscribe topic=%s, qos=%ld\n", topic, qos);
MQTT_Subscribe(client, (char*)topic, (uint8_t)qos);
os_free(topic);
@ -273,7 +273,7 @@ MQTTCMD_Setup(CmdPacket *cmd) {
// get clean session
CMD_PopArg(&req, (uint8_t*)&clean_session, 4);
#ifdef MQTTCMD_DBG
DBG_MQTTCMD("MQTT: MQTTCMD_Setup clientid=%s, user=%s, pw=%s, keepalive=%ld, clean_session=%ld\n", client_id, user_data, pass_data, keepalive, clean_session);
DBG("MQTT: MQTTCMD_Setup clientid=%s, user=%s, pw=%s, keepalive=%ld, clean_session=%ld\n", client_id, user_data, pass_data, keepalive, clean_session);
#endif
// init client
@ -314,6 +314,14 @@ MQTTCMD_Connect(CmdPacket *cmd) {
CMD_Request(&req, cmd);
#ifdef MQTT_1_CLIENT
if (mqttClient.connState == MQTT_CONNECTED && mqttClient.cmdConnectedCb) {
mqttClient.cmdConnectedCb((uint32_t*)&mqttClient);
}
else if (mqttClient.connState == MQTT_DISCONNECTED && mqttClient.cmdDisconnectedCb) {
mqttClient.cmdDisconnectedCb((uint32_t*)&mqttClient);
}
return 1;
#else
@ -324,7 +332,7 @@ MQTTCMD_Connect(CmdPacket *cmd) {
uint32_t client_ptr;
CMD_PopArg(&req, (uint8_t*)&client_ptr, 4);
MQTT_Client* client = (MQTT_Client*)client_ptr;
DBG_MQTTCMD("MQTT: MQTTCMD_Connect client ptr=%p\n", (void*)client_ptr);
DBG("MQTT: MQTTCMD_Connect client ptr=%p\n", (void*)client_ptr);
uint16_t len;
@ -342,7 +350,7 @@ MQTTCMD_Connect(CmdPacket *cmd) {
// get security
CMD_PopArg(&req, (uint8_t*)&client->security, 4);
DBG_MQTTCMD("MQTT: MQTTCMD_Connect host=%s, port=%d, security=%d\n",
DBG("MQTT: MQTTCMD_Connect host=%s, port=%d, security=%d\n",
client->host,
client->port,
client->security);
@ -368,7 +376,7 @@ MQTTCMD_Disconnect(CmdPacket *cmd) {
uint32_t client_ptr;
CMD_PopArg(&req, (uint8_t*)&client_ptr, 4);
MQTT_Client* client = (MQTT_Client*)client_ptr;
DBG_MQTTCMD("MQTT: MQTTCMD_Disconnect client ptr=%p\n", (void*)client_ptr);
DBG("MQTT: MQTTCMD_Disconnect client ptr=%p\n", (void*)client_ptr);
// disconnect
MQTT_Disconnect(client);

@ -4,18 +4,18 @@
#include "pktbuf.h"
#ifdef PKTBUF_DBG
static void ICACHE_FLASH_ATTR
PktBuf_Print(PktBuf *buf) {
os_printf("PktBuf:");
for (int i=-16; i<0; i++)
os_printf(" %02X", ((uint8_t*)buf)[i]);
os_printf(" %p", buf);
for (int i=0; i<16; i++)
os_printf(" %02X", ((uint8_t*)buf)[i]);
os_printf("\n");
os_printf("PktBuf: next=%p len=0x%04x\n",
((void**)buf)[-4], ((uint16_t*)buf)[-6]);
}
//static void ICACHE_FLASH_ATTR
//PktBuf_Print(PktBuf *buf) {
// os_printf("PktBuf:");
// for (int i=-16; i<0; i++)
// os_printf(" %02X", ((uint8_t*)buf)[i]);
// os_printf(" %p", buf);
// for (int i=0; i<16; i++)
// os_printf(" %02X", ((uint8_t*)buf)[i]);
// os_printf("\n");
// os_printf("PktBuf: next=%p len=0x%04x\n",
// ((void**)buf)[-4], ((uint16_t*)buf)[-6]);
//}
#endif

@ -7,6 +7,12 @@
#include "console.h"
#include "cmd.h"
#ifdef SLIP_DBG
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG(format, ...) do { } while(0)
#endif
uint8_t slip_disabled; // temporarily disable slip to allow flashing of attached MCU
extern void ICACHE_FLASH_ATTR console_process(char *buf, short len);
@ -48,15 +54,15 @@ slip_process() {
} else {
os_printf("SLIP: bad CRC, crc=%x rcv=%x\n", crc, rcv);
#ifdef SLIP_DBG
for (short i=0; i<slip_len; i++) {
if (slip_buf[i] >= ' ' && slip_buf[i] <= '~')
os_printf("%c", slip_buf[i]);
else
os_printf("\\%02X", slip_buf[i]);
if (slip_buf[i] >= ' ' && slip_buf[i] <= '~') {
DBG("%c", slip_buf[i]);
}
os_printf("\n");
#endif
else {
DBG("\\%02X", slip_buf[i]);
}
}
DBG("\n");
}
}
}
@ -86,9 +92,7 @@ slip_parse_char(char c) {
if (slip_len > 0) console_process(slip_buf, slip_len);
slip_reset();
slip_inpkt = true;
#ifdef SLIP_DBG
os_printf("SLIP: start\n");
#endif
DBG("SLIP: start\n");
return;
}
} else if (slip_escaped) {

@ -10,36 +10,35 @@
#include <esp8266.h>
#include "config.h"
#include <syslog.h>
#include <time.h>
#include "syslog.h"
#include "time.h"
#include "task.h"
extern void * mem_trim(void *m, size_t s); // not well documented...
#define SYSLOG_DBG
#ifdef SYSLOG_DBG
#define DBG_SYSLOG(format, ...) os_printf(format, ## __VA_ARGS__)
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0)
#else
#define DBG_SYSLOG(format, ...) do { } while(0)
#define DBG(format, ...) do { } while(0)
#endif
#define WIFI_CHK_INTERVAL 1000 // ms to check Wifi statis
LOCAL os_timer_t wifi_chk_timer;
static os_timer_t wifi_chk_timer;
LOCAL struct espconn syslog_espconn;
LOCAL uint32_t syslog_msgid = 1;
LOCAL uint8_t syslog_task = 0;
static struct espconn syslog_espconn;
static uint32_t syslog_msgid = 1;
static uint8_t syslog_task = 0;
LOCAL syslog_host_t syslogHost;
LOCAL syslog_entry_t *syslogQueue = NULL;
static syslog_host_t syslogHost;
static syslog_entry_t *syslogQueue = NULL;
static enum syslog_state syslogState = SYSLOG_NONE;
LOCAL void ICACHE_FLASH_ATTR syslog_add_entry(syslog_entry_t *entry);
LOCAL void ICACHE_FLASH_ATTR syslog_chk_wifi_stat(void);
LOCAL void ICACHE_FLASH_ATTR syslog_udp_sent_cb(void *arg);
static void ICACHE_FLASH_ATTR syslog_add_entry(syslog_entry_t *entry);
static void ICACHE_FLASH_ATTR syslog_chk_wifi_stat(void);
static void ICACHE_FLASH_ATTR syslog_udp_sent_cb(void *arg);
#ifdef SYSLOG_UDP_RECV
LOCAL void ICACHE_FLASH_ATTR syslog_udp_recv_cb(void *arg, char *pusrdata, unsigned short length);
static void ICACHE_FLASH_ATTR syslog_udp_recv_cb(void *arg, char *pusrdata, unsigned short length);
#endif
#define syslog_send_udp() post_usr_task(syslog_task,0)
@ -50,11 +49,10 @@ LOCAL void ICACHE_FLASH_ATTR syslog_udp_recv_cb(void *arg, char *pusrdata, unsig
* Parameters : none
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
syslog_chk_wifi_stat(void)
static void ICACHE_FLASH_ATTR syslog_chk_wifi_stat(void)
{
struct ip_info ipconfig;
DBG_SYSLOG("syslog_chk_wifi_stat: state: %d ", syslogState);
DBG("syslog_chk_wifi_stat: state: %d ", syslogState);
//disarm timer first
os_timer_disarm(&wifi_chk_timer);
@ -65,7 +63,7 @@ syslog_chk_wifi_stat(void)
if (wifi_status == STATION_GOT_IP && ipconfig.ip.addr != 0)
{
if (syslogState == SYSLOG_WAIT) { // waiting for initialization
DBG_SYSLOG("connected, initializing UDP socket\n");
DBG("connected, initializing UDP socket\n");
syslog_init(flashConfig.syslog_host);
}
} else {
@ -75,15 +73,14 @@ syslog_chk_wifi_stat(void)
syslogState = SYSLOG_ERROR;
os_printf("*** connect failure!!!\n");
} else {
DBG_SYSLOG("re-arming timer...\n");
DBG("re-arming timer...\n");
os_timer_setfn(&wifi_chk_timer, (os_timer_func_t *)syslog_chk_wifi_stat, NULL);
os_timer_arm(&wifi_chk_timer, WIFI_CHK_INTERVAL, 0);
}
}
}
LOCAL void ICACHE_FLASH_ATTR
syslog_udp_send_event(os_event_t *events) {
static void ICACHE_FLASH_ATTR syslog_udp_send_event(os_event_t *events) {
if (syslogQueue == NULL)
syslogState = SYSLOG_READY;
else {
@ -103,8 +100,7 @@ syslog_udp_send_event(os_event_t *events) {
* Parameters : va_args
* Returns : the malloced syslog_entry_t
******************************************************************************/
LOCAL syslog_entry_t ICACHE_FLASH_ATTR *
syslog_compose(uint8_t facility, uint8_t severity, const char *tag, const char *fmt, ...)
static syslog_entry_t* ICACHE_FLASH_ATTR syslog_compose(uint8_t facility, uint8_t severity, const char *tag, const char *fmt, ...)
{
syslog_entry_t *se = os_zalloc(sizeof (syslog_entry_t) + 1024); // allow up to 1k datagram
char *p = se->datagram;
@ -155,8 +151,7 @@ syslog_compose(uint8_t facility, uint8_t severity, const char *tag, const char *
* Parameters : entry: the syslog_entry_t
* Returns : none
******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
syslog_add_entry(syslog_entry_t *entry)
static void ICACHE_FLASH_ATTR syslog_add_entry(syslog_entry_t *entry)
{
syslog_entry_t *pse = syslogQueue;
@ -188,8 +183,7 @@ syslog_add_entry(syslog_entry_t *entry)
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
syslog_udp_sent_cb(void *arg)
static void ICACHE_FLASH_ATTR syslog_udp_sent_cb(void *arg)
{
struct espconn *pespconn = arg;
(void) pespconn;
@ -214,18 +208,16 @@ syslog_udp_sent_cb(void *arg)
* Returns : none
******************************************************************************/
#ifdef SYSLOG_UDP_RECV
LOCAL void ICACHE_FLASH_ATTR
syslog_udp_recv_cb(void *arg, char *pusrdata, unsigned short length)
static void ICACHE_FLASH_ATTR syslog_udp_recv_cb(void *arg, char *pusrdata, unsigned short length)
{
DBG_SYSLOG("syslog_udp_recv_cb: %p, %p, %d\n", arg, pusrdata, length);
DBG("syslog_udp_recv_cb: %p, %p, %d\n", arg, pusrdata, length);
}
#endif
/******************************************************************************
*
******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
syslog_gethostbyname_cb(const char *name, ip_addr_t *ipaddr, void *arg)
static void ICACHE_FLASH_ATTR syslog_gethostbyname_cb(const char *name, ip_addr_t *ipaddr, void *arg)
{
struct espconn *pespconn = (struct espconn *)arg;
(void) pespconn;
@ -235,20 +227,23 @@ syslog_gethostbyname_cb(const char *name, ip_addr_t *ipaddr, void *arg)
syslog_send_udp();
} else {
syslogState = SYSLOG_ERROR;
DBG_SYSLOG("syslog_gethostbyname_cb: state=SYSLOG_ERROR\n");
DBG("syslog_gethostbyname_cb: state=SYSLOG_ERROR\n");
}
}
/******************************************************************************
* FunctionName : initSyslog
* Description : Initialize the syslog library
* Parameters : hostname -- the syslog server (host:port)
* Parameters : syslog_host -- the syslog host (host:port)
* host: IP-Addr | hostname
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
syslog_init(char *syslog_server)
void ICACHE_FLASH_ATTR syslog_init(char *syslog_host)
{
if (!*syslog_host) {
syslogState = SYSLOG_HALTED;
return;
}
char host[32], *port = &host[0];
syslog_task = register_usr_task(syslog_udp_send_event);
@ -256,7 +251,7 @@ syslog_init(char *syslog_server)
syslogHost.port = 514;
syslogState = SYSLOG_WAIT;
os_strncpy(host, syslog_server, 32);
os_strncpy(host, syslog_host, 32);
while (*port && *port != ':') // find port delimiter
port++;
if (*port) {
@ -283,11 +278,11 @@ syslog_init(char *syslog_server)
// syslog_send_udp is called by syslog_gethostbyname_cb()
}
#ifdef SYSLOG_UDP_RECV
DBG_SYSLOG("syslog_init: host: %s, port: %d, lport: %d, recvcb: %p, sentcb: %p, state: %d\n",
DBG("syslog_init: host: %s, port: %d, lport: %d, recvcb: %p, sentcb: %p, state: %d\n",
host, syslogHost.port, syslog_espconn.proto.udp->local_port,
syslog_udp_recv_cb, syslog_udp_sent_cb, syslogState );
#else
DBG_SYSLOG("syslog_init: host: %s, port: %d, lport: %d, rsentcb: %p, state: %d\n",
DBG("syslog_init: host: %s, port: %d, lport: %d, rsentcb: %p, state: %d\n",
host, syslogHost.port, syslog_espconn.proto.udp->local_port,
syslog_udp_sent_cb, syslogState );
#endif
@ -364,10 +359,9 @@ syslog_init(char *syslog_server)
*
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
syslog(uint8_t facility, uint8_t severity, const char *tag, const char *fmt, ...)
void ICACHE_FLASH_ATTR syslog(uint8_t facility, uint8_t severity, const char *tag, const char *fmt, ...)
{
DBG_SYSLOG("syslog: state=%d ", syslogState);
DBG("syslog: state=%d ", syslogState);
if (syslogState == SYSLOG_ERROR ||
syslogState == SYSLOG_HALTED)
return;

@ -84,7 +84,7 @@ struct syslog_entry_t {
syslog_host_t syslogserver;
void ICACHE_FLASH_ATTR syslog_init(char *syslog_server);
void ICACHE_FLASH_ATTR syslog_init(char *syslog_host);
void ICACHE_FLASH_ATTR syslog(uint8_t facility, uint8_t severity, const char tag[], const char message[], ...);
// some convenience macros

Loading…
Cancel
Save