Merge branch 'brunnels-ifdefs'

pull/49/head
Thorsten von Eicken 9 years ago
commit 34a6420910
  1. 1
      .gitignore
  2. 89
      Makefile
  3. 25
      cmd/cmd.c
  4. 4
      cmd/cmd.h
  5. 57
      cmd/handlers.c
  6. 24
      esp-link.vcxproj
  7. 40
      esp-link/cgi.c
  8. 2
      esp-link/cgi.h
  9. 12
      esp-link/cgiflash.c
  10. 32
      esp-link/cgimqtt.c
  11. 3
      esp-link/cgipins.c
  12. 48
      esp-link/cgiwifi.c
  13. 50
      esp-link/config.c
  14. 9
      esp-link/config.h
  15. 4
      esp-link/log.c
  16. 21
      esp-link/main.c
  17. 4
      esp-link/mqtt_client.c
  18. 2
      esp-link/status.c
  19. 8
      espfs/espfs.c
  20. BIN
      html/favicon.ico
  21. 15
      html/mqtt.html
  22. 5
      html/style.css
  23. BIN
      html/wifi/icons.png
  24. 382
      httpd/httpd.c
  25. 8
      include/esp8266.h
  26. 32
      include/user_config.h
  27. 79
      mqtt/mqtt.c
  28. 33
      mqtt/mqtt_cmd.c
  29. 0
      mqtt/mqtt_cmd.h
  30. 2
      mqtt/mqtt_msg.h
  31. 4
      mqtt/pktbuf.c
  32. 2
      mqtt/pktbuf.h
  33. 97
      rest/rest.c
  34. 1
      rest/rest.h
  35. 44
      serial/serbridge.c
  36. 2
      serial/serled.c
  37. 5
      serial/slip.c
  38. 14
      serial/uart.c

1
.gitignore vendored

@ -15,3 +15,4 @@ esp-link.opensdf
esp-link.sdf
espfs/mkespfsimage/mman-win32/libmman.a
.localhistory/
tools/

@ -10,6 +10,7 @@
#
# Makefile heavily adapted to esp-link and wireless flashing by Thorsten von Eicken
# Original from esphttpd and others...
#VERBOSE=1
# --------------- toolchain configuration ---------------
@ -135,13 +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 ?= mqtt rest
# -------------- End of config options -------------
@ -156,16 +164,34 @@ TARGET = httpd
# espressif tool to concatenate sections for OTA upload using bootloader v1.2+
APPGEN_TOOL ?= gen_appbin.py
CFLAGS=
# set defines for optional modules
ifneq (,$(findstring mqtt,$(MODULES)))
CFLAGS += -DMQTT
endif
ifneq (,$(findstring rest,$(MODULES)))
CFLAGS += -DREST
endif
ifneq (,$(findstring tcpclient,$(MODULES)))
CFLAGS += -DTCPCLIENT
endif
# which modules (subdirectories) of the project to include in compiling
MODULES = espfs httpd user serial cmd mqtt esp-link
LIBRARIES_DIR = libraries
MODULES += espfs httpd user serial cmd esp-link
MODULES += $(foreach sdir,$(LIBRARIES_DIR),$(wildcard $(sdir)/*))
EXTRA_INCDIR = include .
# libraries used in this project, mainly provided by the SDK
LIBS = c gcc hal phy pp net80211 wpa main lwip # crypto 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) \
@ -304,34 +330,51 @@ flash: all
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 \
@ -381,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

@ -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;
}
@ -113,26 +119,35 @@ CMD_parse_packet(uint8_t *buf, short len) {
uint8_t *data_ptr = (uint8_t*)&packet->args;
uint8_t *data_limit = data_ptr+len;
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
}
}

@ -55,8 +55,8 @@ typedef enum {
CMD_REST_REQUEST,
CMD_REST_SETHEADER,
CMD_REST_EVENTS,
CMD_ADD_CALLBACK, // 15
CMD_SENSOR_EVENTS
CMD_CB_ADD, // 15
CMD_CB_EVENTS
} CmdName;
typedef uint32_t (*cmdfunc_t)(CmdPacket *cmd);

@ -4,12 +4,13 @@
#include "esp8266.h"
#include "cmd.h"
#include "rest.h"
#include "crc16.h"
#include "serbridge.h"
#include "uart.h"
#include "cgiwifi.h"
#include "mqtt_cmd.h"
#include <cgiwifi.h>
#ifdef MQTT
#include <mqtt_cmd.h>
#endif
#ifdef REST
#include <rest.h>
#endif
static uint32_t CMD_Null(CmdPacket *cmd);
static uint32_t CMD_IsReady(CmdPacket *cmd);
@ -27,22 +28,20 @@ const CmdList commands[] = {
{CMD_RESET, CMD_Reset},
{CMD_IS_READY, CMD_IsReady},
{CMD_WIFI_CONNECT, CMD_WifiConnect},
/*
{CMD_MQTT_SETUP, MQTTAPP_Setup},
{CMD_MQTT_CONNECT, MQTTAPP_Connect},
{CMD_MQTT_DISCONNECT, MQTTAPP_Disconnect},
{CMD_MQTT_PUBLISH, MQTTAPP_Publish},
{CMD_MQTT_SUBSCRIBE , MQTTAPP_Subscribe},
{CMD_MQTT_LWT, MQTTAPP_Lwt},
*/
#ifdef MQTT
{CMD_MQTT_SETUP, MQTTCMD_Setup},
{CMD_MQTT_CONNECT, MQTTCMD_Connect},
{CMD_MQTT_DISCONNECT, MQTTCMD_Disconnect},
{CMD_MQTT_PUBLISH, MQTTCMD_Publish},
{CMD_MQTT_SUBSCRIBE , MQTTCMD_Subscribe},
{CMD_MQTT_LWT, MQTTCMD_Lwt},
#endif
#ifdef REST
{CMD_REST_SETUP, REST_Setup},
{CMD_REST_REQUEST, REST_Request},
{CMD_REST_SETHEADER, REST_SetHeader},
{CMD_ADD_CALLBACK, CMD_AddCallback },
#endif
{CMD_CB_ADD, CMD_AddCallback},
{CMD_NULL, NULL}
};
@ -53,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;
}
@ -69,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;
@ -84,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;
}
}
@ -100,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];
}
}
@ -112,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) {
@ -129,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;
@ -149,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;
@ -158,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
}

@ -28,7 +28,7 @@
<PropertyGroup>
<NMakeOutput />
<NMakePreprocessorDefinitions>__ets__;_STDINT_H;ICACHE_FLASH;__MINGW32__;__WIN32__</NMakePreprocessorDefinitions>
<NMakeIncludeSearchPath>.\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>
<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>
<ExecutablePath />
<ReferencePath />
<LibraryPath />
@ -39,12 +39,12 @@
<IntDir>build</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<NMakeBuildCommandLine>espmake flash</NMakeBuildCommandLine>
<NMakeBuildCommandLine>espmake all wiflash</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>espmake clean all</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>espmake clean</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<NMakeBuildCommandLine>espmake all wiflash</NMakeBuildCommandLine>
<NMakeBuildCommandLine>espmake clean all wiflash</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>espmake clean all</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>espmake clean</NMakeCleanCommandLine>
</PropertyGroup>
@ -65,9 +65,11 @@
<ItemGroup>
<ClCompile Include="cmd\cmd.c" />
<ClCompile Include="cmd\handlers.c" />
<ClCompile Include="cmd\mqtt_cmd.c" />
<ClCompile Include="cmd\rest.c" />
<ClCompile Include="cmd\tcpclient.c" />
<ClCompile Include="esp-link\cgimqtt.c" />
<ClCompile Include="esp-link\mqtt_client.c" />
<ClCompile Include="mqtt\mqtt_cmd.c" />
<ClCompile Include="mqtt\pktbuf.c" />
<ClCompile Include="rest\rest.c" />
<ClCompile Include="espfs\espfs.c" />
<ClCompile Include="espfs\mkespfsimage\main.c" />
<ClCompile Include="espfs\mkespfsimage\mman-win32\mman.c" />
@ -76,6 +78,7 @@
<ClCompile Include="httpd\base64.c" />
<ClCompile Include="httpd\httpd.c" />
<ClCompile Include="httpd\httpdespfs.c" />
<ClCompile Include="libraries\Time\Time.c" />
<ClCompile Include="mqtt\mqtt.c" />
<ClCompile Include="mqtt\mqtt_msg.c" />
<ClCompile Include="mqtt\proto.c" />
@ -108,9 +111,11 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="cmd\cmd.h" />
<ClInclude Include="cmd\mqtt_cmd.h" />
<ClInclude Include="cmd\rest.h" />
<ClInclude Include="cmd\tcpclient.h" />
<ClInclude Include="esp-link\cgimqtt.h" />
<ClInclude Include="mqtt\mqtt_cmd.h" />
<ClInclude Include="mqtt\pktbuf.h" />
<ClInclude Include="rest\rest.h" />
<ClInclude Include="serial\slip.h" />
<ClInclude Include="espfs\espfs.h" />
<ClInclude Include="espfs\espfsformat.h" />
<ClInclude Include="espfs\mkespfsimage\mman-win32\mman.h" />
@ -122,6 +127,7 @@
<ClInclude Include="include\espmissingincludes.h" />
<ClInclude Include="include\uart_hw.h" />
<ClInclude Include="include\user_config.h" />
<ClInclude Include="libraries\Time\Time.h" />
<ClInclude Include="mqtt\mqtt.h" />
<ClInclude Include="mqtt\mqtt_msg.h" />
<ClInclude Include="mqtt\proto.h" />

@ -16,7 +16,6 @@ Some random cgi routines.
#include <esp8266.h>
#include "cgi.h"
#include "espfs.h"
void noCacheHeaders(HttpdConnData *connData, int code) {
httpdStartResponse(connData, code);
@ -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
@ -75,6 +76,43 @@ getBoolArg(HttpdConnData *connData, char *name, bool*config) {
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

@ -1,6 +1,7 @@
#ifndef CGI_H
#define CGI_H
#include <esp8266.h>
#include "httpd.h"
void jsonHeader(HttpdConnData *connData, int code);
@ -8,5 +9,6 @@ void errorResponse(HttpdConnData *connData, int code, char *message);
int getStringArg(HttpdConnData *connData, char *name, char *config, int max_len);
int getBoolArg(HttpdConnData *connData, char *name, bool*config);
int cgiMenu(HttpdConnData *connData);
uint8_t UTILS_StrToIP(const char* str, void *ip);
#endif

@ -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);

@ -38,7 +38,10 @@ int ICACHE_FLASH_ATTR cgiMqttGet(HttpdConnData *connData) {
"\"mqtt-enable\":%d, "
"\"mqtt-state\":\"%s\", "
"\"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\", "
@ -63,22 +66,29 @@ 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) {
@ -90,9 +100,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
}
@ -107,9 +131,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);

@ -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];

@ -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);

@ -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;
}

@ -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

@ -25,14 +25,18 @@ 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 1
#ifdef LOG_DBG
os_printf("Turning OFF uart log\n");
#endif
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
}
}

@ -30,24 +30,24 @@
#include "log.h"
#include <gpio.h>
#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;

@ -12,8 +12,8 @@ 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);
}

@ -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);

@ -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;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 874 B

After

Width:  |  Height:  |  Size: 498 B

@ -28,27 +28,30 @@
<div id="mqtt-spinner" class="spinner spinner-small"></div>
</h1>
<form action="#" id="mqtt-form" class="pure-form" hidden>
<div class="form-horizontal">
<input type="checkbox" name="mqtt-enable"/>
<label>Enable MQTT client</label>
</div>
<div class="form-horizontal">
<br>
<label>MQTT client state: </label>
<b id="mqtt-state"></b>
</div>
<br>
<legend>MQTT server settings</legend>
<div class="pure-form-stacked">
<label>Server hostname/ip</label>
<label>Server hostname or IP</label>
<input type="text" name="mqtt-host"/>
<label>Server port/ip</label>
<label>Server port</label>
<input type="text" name="mqtt-port"/>
<label>Client Timeout</label>
<input type="text" name="mqtt-timeout" />
<label>Client ID</label>
<input type="text" name="mqtt-client-id"/>
<label>Username</label>
<input type="text" name="mqtt-username"/>
<label>Password</label>
<input type="password" name="mqtt-password"/>
<label>Keep Alive Interval (seconds)</label>
<input type="text" name="mqtt-keepalive" />
<input type="checkbox" name="mqtt-clean-session" />
<label>Clean Session?</label>
</div>
<button id="mqtt-button" type="submit" class="pure-button button-primary">
Update server settings!

@ -7,6 +7,11 @@ input[type="text"], input[type="password"] {
width: 100%;
}
input[type=checkbox] {
float: left;
margin: .35em 0.4em;
}
body {
color: #777;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 914 B

After

Width:  |  Height:  |  Size: 425 B

@ -3,15 +3,15 @@ Esp8266 http server - core routines
*/
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
* this notice you can do whatever you want with this stuff. If we meet some day,
* and you think this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
* Modified and enhanced by Thorsten von Eicken in 2015
* ----------------------------------------------------------------------------
*/
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
* this notice you can do whatever you want with this stuff. If we meet some day,
* and you think this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
* Modified and enhanced by Thorsten von Eicken in 2015
* ----------------------------------------------------------------------------
*/
#include <esp8266.h>
@ -56,29 +56,29 @@ typedef struct {
//The mappings from file extensions to mime types. If you need an extra mime type,
//add it here.
static const MimeMap mimeTypes[]={
{"htm", "text/htm"},
{"html", "text/html; charset=UTF-8"},
{"css", "text/css"},
{"js", "text/javascript"},
{"txt", "text/plain"},
{"jpg", "image/jpeg"},
{"jpeg", "image/jpeg"},
{"png", "image/png"},
{"tpl", "text/html; charset=UTF-8"},
{NULL, "text/html"}, //default value
static const MimeMap mimeTypes[] = {
{ "htm", "text/htm" },
{ "html", "text/html; charset=UTF-8" },
{ "css", "text/css" },
{ "js", "text/javascript" },
{ "txt", "text/plain" },
{ "jpg", "image/jpeg" },
{ "jpeg", "image/jpeg" },
{ "png", "image/png" },
{ "tpl", "text/html; charset=UTF-8" },
{ NULL, "text/html" }, //default value
};
//Returns a static char* to a mime type for a given url to a file.
const char ICACHE_FLASH_ATTR *httpdGetMimetype(char *url) {
int i=0;
int i = 0;
//Go find the extension
char *ext=url+(strlen(url)-1);
while (ext!=url && *ext!='.') ext--;
if (*ext=='.') ext++;
char *ext = url + (strlen(url) - 1);
while (ext != url && *ext != '.') ext--;
if (*ext == '.') ext++;
//ToDo: os_strcmp is case sensitive; we may want to do case-intensive matching here...
while (mimeTypes[i].ext!=NULL && os_strcmp(ext, mimeTypes[i].ext)!=0) i++;
while (mimeTypes[i].ext != NULL && os_strcmp(ext, mimeTypes[i].ext) != 0) i++;
return mimeTypes[i].mimetype;
}
@ -98,21 +98,25 @@ static void debugConn(void *arg, char *what) {
//Looks up the connData info for a specific esp connection
static HttpdConnData ICACHE_FLASH_ATTR *httpdFindConnData(void *arg) {
struct espconn *espconn = arg;
for (int i=0; i<MAX_CONN; i++) {
for (int i = 0; i<MAX_CONN; i++) {
if (connData[i].remote_port == espconn->proto.tcp->remote_port &&
os_memcmp(connData[i].remote_ip, espconn->proto.tcp->remote_ip, 4) == 0)
{
#if 0
#ifdef HTTPD_DBG
os_printf("FindConn: 0x%p->0x%p", arg, &connData[i]);
if (arg == connData[i].conn) os_printf("\n");
else os_printf(" *** was 0x%p\n", connData[i].conn);
#endif
#endif
if (arg != connData[i].conn) connData[i].conn = arg; // yes, this happens!?
return &connData[i];
}
}
//Shouldn't happen.
#ifdef HTTPD_DBG
os_printf("%s *** Unknown connection 0x%p\n", connStr, arg);
#endif
return NULL;
}
@ -123,22 +127,24 @@ static void ICACHE_FLASH_ATTR httpdRetireConn(HttpdConnData *conn) {
if (conn->post->buff != NULL) {
os_free(conn->post->buff);
}
conn->cgi=NULL;
conn->post->buff=NULL;
conn->cgi = NULL;
conn->post->buff = NULL;
conn->remote_port = 0;
conn->remote_ip[0] = 0;
uint32 dt = conn->startTime;
if (dt > 0) dt = (system_get_time() - dt)/1000;
if (dt > 0) dt = (system_get_time() - dt) / 1000;
#ifdef HTTPD_DBG
os_printf("%s Closed, %ums, heap=%ld\n", connStr, dt,
(unsigned long)system_get_free_heap_size());
#endif
}
//Stupid li'l helper function that returns the value of a hex char.
static int httpdHexVal(char c) {
if (c>='0' && c<='9') return c-'0';
if (c>='A' && c<='F') return c-'A'+10;
if (c>='a' && c<='f') return c-'a'+10;
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
return 0;
}
@ -147,26 +153,30 @@ static int httpdHexVal(char c) {
//are stored in the ret buffer. Returns the actual amount of bytes used in ret. Also
//zero-terminates the ret buffer.
int httpdUrlDecode(char *val, int valLen, char *ret, int retLen) {
int s=0, d=0;
int esced=0, escVal=0;
int s = 0, d = 0;
int esced = 0, escVal = 0;
while (s<valLen && d<retLen) {
if (esced==1) {
escVal=httpdHexVal(val[s])<<4;
esced=2;
} else if (esced==2) {
escVal+=httpdHexVal(val[s]);
ret[d++]=escVal;
esced=0;
} else if (val[s]=='%') {
esced=1;
} else if (val[s]=='+') {
ret[d++]=' ';
} else {
ret[d++]=val[s];
if (esced == 1) {
escVal = httpdHexVal(val[s]) << 4;
esced = 2;
}
else if (esced == 2) {
escVal += httpdHexVal(val[s]);
ret[d++] = escVal;
esced = 0;
}
else if (val[s] == '%') {
esced = 1;
}
else if (val[s] == '+') {
ret[d++] = ' ';
}
else {
ret[d++] = val[s];
}
s++;
}
if (d<retLen) ret[d]=0;
if (d<retLen) ret[d] = 0;
return d;
}
@ -177,19 +187,19 @@ int httpdUrlDecode(char *val, int valLen, char *ret, int retLen) {
//returned string will be urldecoded already.
int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen) {
char *p, *e;
if (line==NULL) return 0;
p=line;
while(p!=NULL && *p!='\n' && *p!='\r' && *p!=0) {
if (line == NULL) return 0;
p = line;
while (p != NULL && *p != '\n' && *p != '\r' && *p != 0) {
//os_printf("findArg: %s\n", p);
if (os_strncmp(p, arg, os_strlen(arg))==0 && p[strlen(arg)]=='=') {
p+=os_strlen(arg)+1; //move p to start of value
e=(char*)os_strstr(p, "&");
if (e==NULL) e=p+os_strlen(p);
if (os_strncmp(p, arg, os_strlen(arg)) == 0 && p[strlen(arg)] == '=') {
p += os_strlen(arg) + 1; //move p to start of value
e = (char*)os_strstr(p, "&");
if (e == NULL) e = p + os_strlen(p);
//os_printf("findArg: val %s len %d\n", p, (e-p));
return httpdUrlDecode(p, (e-p), buff, buffLen);
return httpdUrlDecode(p, (e - p), buff, buffLen);
}
p=(char*)os_strstr(p, "&");
if (p!=NULL) p+=1;
p = (char*)os_strstr(p, "&");
if (p != NULL) p += 1;
}
//os_printf("Finding %s in %s: Not found :/\n", arg, line);
return -1; //not found
@ -197,28 +207,28 @@ int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLe
//Get the value of a certain header in the HTTP client head
int ICACHE_FLASH_ATTR httpdGetHeader(HttpdConnData *conn, char *header, char *ret, int retLen) {
char *p=conn->priv->head;
p=p+strlen(p)+1; //skip GET/POST part
p=p+strlen(p)+1; //skip HTTP part
while (p<(conn->priv->head+conn->priv->headPos)) {
while(*p<=32 && *p!=0) p++; //skip crap at start
char *p = conn->priv->head;
p = p + strlen(p) + 1; //skip GET/POST part
p = p + strlen(p) + 1; //skip HTTP part
while (p<(conn->priv->head + conn->priv->headPos)) {
while (*p <= 32 && *p != 0) p++; //skip crap at start
//See if this is the header
if (os_strncmp(p, header, strlen(header))==0 && p[strlen(header)]==':') {
if (os_strncmp(p, header, strlen(header)) == 0 && p[strlen(header)] == ':') {
//Skip 'key:' bit of header line
p=p+strlen(header)+1;
p = p + strlen(header) + 1;
//Skip past spaces after the colon
while(*p==' ') p++;
while (*p == ' ') p++;
//Copy from p to end
while (*p!=0 && *p!='\r' && *p!='\n' && retLen>1) {
*ret++=*p++;
while (*p != 0 && *p != '\r' && *p != '\n' && retLen>1) {
*ret++ = *p++;
retLen--;
}
//Zero-terminate string
*ret=0;
*ret = 0;
//All done :)
return 1;
}
p+=strlen(p)+1; //Skip past end of string and \0 terminator
p += strlen(p) + 1; //Skip past end of string and \0 terminator
}
return 0;
}
@ -237,7 +247,7 @@ void ICACHE_FLASH_ATTR httpdHeader(HttpdConnData *conn, const char *field, const
char buff[256];
int l;
l=os_sprintf(buff, "%s: %s\r\n", field, val);
l = os_sprintf(buff, "%s: %s\r\n", field, val);
httpdSend(conn, buff, l);
}
@ -251,13 +261,13 @@ void ICACHE_FLASH_ATTR httpdEndHeaders(HttpdConnData *conn) {
void ICACHE_FLASH_ATTR httpdRedirect(HttpdConnData *conn, char *newUrl) {
char buff[1024];
int l;
l=os_sprintf(buff, "HTTP/1.0 302 Found\r\nServer: esp8266-link\r\nConnection: close\r\nLocation: %s\r\n\r\nRedirecting to %s\r\n", newUrl, newUrl);
l = os_sprintf(buff, "HTTP/1.0 302 Found\r\nServer: esp8266-link\r\nConnection: close\r\nLocation: %s\r\n\r\nRedirecting to %s\r\n", newUrl, newUrl);
httpdSend(conn, buff, l);
}
//Use this as a cgi function to redirect one url to another.
int ICACHE_FLASH_ATTR cgiRedirect(HttpdConnData *connData) {
if (connData->conn==NULL) {
if (connData->conn == NULL) {
//Connection aborted. Clean up.
return HTTPD_CGI_DONE;
}
@ -270,25 +280,29 @@ int ICACHE_FLASH_ATTR cgiRedirect(HttpdConnData *connData) {
//the data is seen as a C-string.
//Returns 1 for success, 0 for out-of-memory.
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) {
if (len<0) len = strlen(data);
if (conn->priv->sendBuffLen + len>MAX_SENDBUFF_LEN) {
#ifdef HTTPD_DBG
os_printf("%s ERROR! 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);
conn->priv->sendBuffLen+=len;
os_memcpy(conn->priv->sendBuff + conn->priv->sendBuffLen, data, len);
conn->priv->sendBuffLen += len;
return 1;
}
//Helper function to send any data in conn->priv->sendBuff
static void ICACHE_FLASH_ATTR xmitSendBuff(HttpdConnData *conn) {
if (conn->priv->sendBuffLen!=0) {
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("%s ERROR! espconn_sent returned %d\n", connStr, status);
#endif
}
conn->priv->sendBuffLen=0;
conn->priv->sendBuffLen = 0;
}
}
@ -296,31 +310,33 @@ static void ICACHE_FLASH_ATTR xmitSendBuff(HttpdConnData *conn) {
static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) {
debugConn(arg, "httpdSentCb");
int r;
HttpdConnData *conn=httpdFindConnData(arg);
HttpdConnData *conn = httpdFindConnData(arg);
char sendBuff[MAX_SENDBUFF_LEN];
if (conn==NULL) return;
conn->priv->sendBuff=sendBuff;
conn->priv->sendBuffLen=0;
if (conn == NULL) return;
conn->priv->sendBuff = sendBuff;
conn->priv->sendBuffLen = 0;
if (conn->cgi==NULL) { //Marked for destruction?
if (conn->cgi == NULL) { //Marked for destruction?
//os_printf("Closing 0x%p/0x%p->0x%p\n", arg, conn->conn, conn);
espconn_disconnect(conn->conn); // we will get a disconnect callback
return; //No need to call xmitSendBuff.
}
r=conn->cgi(conn); //Execute cgi fn.
if (r==HTTPD_CGI_DONE) {
conn->cgi=NULL; //mark for destruction.
r = conn->cgi(conn); //Execute cgi fn.
if (r == HTTPD_CGI_DONE) {
conn->cgi = NULL; //mark for destruction.
}
if (r==HTTPD_CGI_NOTFOUND || r==HTTPD_CGI_AUTHENTICATED) {
if (r == HTTPD_CGI_NOTFOUND || r == HTTPD_CGI_AUTHENTICATED) {
#ifdef HTTPD_DBG
os_printf("%s ERROR! Bad CGI code %d\n", connStr, r);
conn->cgi=NULL; //mark for destruction.
#endif
conn->cgi = NULL; //mark for destruction.
}
xmitSendBuff(conn);
}
static const char *httpNotFoundHeader="HTTP/1.0 404 Not Found\r\nConnection: close\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nNot Found.\r\n";
static const char *httpNotFoundHeader = "HTTP/1.0 404 Not Found\r\nConnection: close\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nNot Found.\r\n";
//This is called when the headers have been received and the connection is ready to send
//the result headers and data.
@ -328,53 +344,59 @@ static const char *httpNotFoundHeader="HTTP/1.0 404 Not Found\r\nConnection: clo
//find the next cgi function, wait till the cgi data is sent or close up the connection.
static void ICACHE_FLASH_ATTR httpdProcessRequest(HttpdConnData *conn) {
int r;
int i=0;
if (conn->url==NULL) {
int i = 0;
if (conn->url == NULL) {
#ifdef HTTPD_DBG
os_printf("%s WtF? url = NULL\n", connStr);
#endif
return; //Shouldn't happen
}
//See if we can find a CGI that's happy to handle the request.
while (1) {
//Look up URL in the built-in URL table.
while (builtInUrls[i].url!=NULL) {
int match=0;
while (builtInUrls[i].url != NULL) {
int match = 0;
//See if there's a literal match
if (os_strcmp(builtInUrls[i].url, conn->url)==0) match=1;
if (os_strcmp(builtInUrls[i].url, conn->url) == 0) match = 1;
//See if there's a wildcard match
if (builtInUrls[i].url[os_strlen(builtInUrls[i].url)-1]=='*' &&
os_strncmp(builtInUrls[i].url, conn->url, os_strlen(builtInUrls[i].url)-1)==0) match=1;
if (builtInUrls[i].url[os_strlen(builtInUrls[i].url) - 1] == '*' &&
os_strncmp(builtInUrls[i].url, conn->url, os_strlen(builtInUrls[i].url) - 1) == 0) match = 1;
if (match) {
//os_printf("Is url index %d\n", i);
conn->cgiData=NULL;
conn->cgi=builtInUrls[i].cgiCb;
conn->cgiArg=builtInUrls[i].cgiArg;
conn->cgiData = NULL;
conn->cgi = builtInUrls[i].cgiCb;
conn->cgiArg = builtInUrls[i].cgiArg;
break;
}
i++;
}
if (builtInUrls[i].url==NULL) {
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
httpdSend(conn, httpNotFoundHeader, -1);
xmitSendBuff(conn);
conn->cgi=NULL; //mark for destruction
conn->cgi = NULL; //mark for destruction
return;
}
//Okay, we have a CGI function that matches the URL. See if it wants to handle the
//particular URL we're supposed to handle.
r=conn->cgi(conn);
if (r==HTTPD_CGI_MORE) {
r = conn->cgi(conn);
if (r == HTTPD_CGI_MORE) {
//Yep, it's happy to do so and has more data to send.
xmitSendBuff(conn);
return;
} else if (r==HTTPD_CGI_DONE) {
}
else if (r == HTTPD_CGI_DONE) {
//Yep, it's happy to do so and already is done sending data.
xmitSendBuff(conn);
conn->cgi=NULL; //mark conn for destruction
conn->cgi = NULL; //mark conn for destruction
return;
} else if (r==HTTPD_CGI_NOTFOUND || r==HTTPD_CGI_AUTHENTICATED) {
}
else if (r == HTTPD_CGI_NOTFOUND || r == HTTPD_CGI_AUTHENTICATED) {
//URL doesn't want to handle the request: either the data isn't found or there's no
//need to generate a login screen.
i++; //look at next url the next iteration of the loop.
@ -387,10 +409,11 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
int i;
char first_line = false;
if (os_strncmp(h, "GET ", 4)==0) {
if (os_strncmp(h, "GET ", 4) == 0) {
conn->requestType = HTTPD_METHOD_GET;
first_line = true;
} else if (os_strncmp(h, "POST ", 5)==0) {
}
else if (os_strncmp(h, "POST ", 5) == 0) {
conn->requestType = HTTPD_METHOD_POST;
first_line = true;
}
@ -399,49 +422,56 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
char *e;
//Skip past the space after POST/GET
i=0;
while (h[i]!=' ') i++;
conn->url=h+i+1;
i = 0;
while (h[i] != ' ') i++;
conn->url = h + i + 1;
//Figure out end of url.
e=(char*)os_strstr(conn->url, " ");
if (e==NULL) return; //wtf?
*e=0; //terminate url part
e = (char*)os_strstr(conn->url, " ");
if (e == NULL) return; //wtf?
*e = 0; //terminate url part
// Count number of open connections
int open = 0;
for (int j=0; j<MAX_CONN; j++) if (connData[j].conn != NULL) open++;
for (int j = 0; j<MAX_CONN; j++) if (connData[j].conn != NULL) open++;
#ifdef HTTPD_DBG
os_printf("%s %s %s (%d conn open)\n", connStr,
conn->requestType == HTTPD_METHOD_GET ? "GET" : "POST", conn->url, open);
#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 = (char*)os_strstr(conn->url, "?");
if (conn->getArgs != 0) {
*conn->getArgs = 0;
conn->getArgs++;
#ifdef HTTPD_DBG
os_printf("%s args = %s\n", connStr, conn->getArgs);
} else {
conn->getArgs=NULL;
#endif
}
else {
conn->getArgs = NULL;
}
} else if (os_strncmp(h, "Content-Length:", 15)==0) {
i=15;
}
else if (os_strncmp(h, "Content-Length:", 15) == 0) {
i = 15;
//Skip trailing spaces
while (h[i]==' ') i++;
while (h[i] == ' ') i++;
//Get POST data length
conn->post->len=atoi(h+i);
conn->post->len = atoi(h + i);
// Allocate the buffer
if (conn->post->len > MAX_POST) {
// we'll stream this in in chunks
conn->post->buffSize = MAX_POST;
} else {
}
else {
conn->post->buffSize = conn->post->len;
}
//os_printf("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;
} else if (os_strncmp(h, "Content-Type: ", 14)==0) {
conn->post->buff = (char*)os_malloc(conn->post->buffSize + 1);
conn->post->buffLen = 0;
}
else if (os_strncmp(h, "Content-Type: ", 14) == 0) {
if (os_strstr(h, "multipart/form-data")) {
// It's multipart form data so let's pull out the boundary for future use
char *b;
@ -462,10 +492,10 @@ static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short
int x;
char *p, *e;
char sendBuff[MAX_SENDBUFF_LEN];
HttpdConnData *conn=httpdFindConnData(arg);
if (conn==NULL) return;
conn->priv->sendBuff=sendBuff;
conn->priv->sendBuffLen=0;
HttpdConnData *conn = httpdFindConnData(arg);
if (conn == NULL) return;
conn->priv->sendBuff = sendBuff;
conn->priv->sendBuffLen = 0;
//This is slightly evil/dirty: we abuse conn->post->len as a state variable for where in the http communications we are:
//<0 (-1): Post len unknown because we're still receiving headers
@ -473,38 +503,39 @@ static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short
//>0: Need to receive post data
//ToDo: See if we can use something more elegant for this.
for (x=0; x<len; x++) {
for (x = 0; x<len; x++) {
if (conn->post->len<0) {
//This byte is a header byte.
if (conn->priv->headPos!=MAX_HEAD_LEN) conn->priv->head[conn->priv->headPos++]=data[x];
conn->priv->head[conn->priv->headPos]=0;
if (conn->priv->headPos != MAX_HEAD_LEN) conn->priv->head[conn->priv->headPos++] = data[x];
conn->priv->head[conn->priv->headPos] = 0;
//Scan for /r/n/r/n. Receiving this indicate the headers end.
if (data[x]=='\n' && (char *)os_strstr(conn->priv->head, "\r\n\r\n")!=NULL) {
if (data[x] == '\n' && (char *)os_strstr(conn->priv->head, "\r\n\r\n") != NULL) {
//Indicate we're done with the headers.
conn->post->len=0;
conn->post->len = 0;
//Reset url data
conn->url=NULL;
conn->url = NULL;
//Iterate over all received headers and parse them.
p=conn->priv->head;
while(p<(&conn->priv->head[conn->priv->headPos-4])) {
e=(char *)os_strstr(p, "\r\n"); //Find end of header line
if (e==NULL) break; //Shouldn't happen.
e[0]=0; //Zero-terminate header
p = conn->priv->head;
while (p<(&conn->priv->head[conn->priv->headPos - 4])) {
e = (char *)os_strstr(p, "\r\n"); //Find end of header line
if (e == NULL) break; //Shouldn't happen.
e[0] = 0; //Zero-terminate header
httpdParseHeader(p, conn); //and parse it.
p=e+2; //Skip /r/n (now /0/n)
p = e + 2; //Skip /r/n (now /0/n)
}
//If we don't need to receive post data, we can send the response now.
if (conn->post->len==0) {
if (conn->post->len == 0) {
httpdProcessRequest(conn);
}
}
} else if (conn->post->len!=0) {
}
else if (conn->post->len != 0) {
//This byte is a POST byte.
conn->post->buff[conn->post->buffLen++]=data[x];
conn->post->buff[conn->post->buffLen++] = data[x];
conn->post->received++;
if (conn->post->buffLen >= conn->post->buffSize || conn->post->received == conn->post->len) {
//Received a chunk of post data
conn->post->buff[conn->post->buffLen]=0; //zero-terminate, in case the cgi handler knows it can use strings
conn->post->buff[conn->post->buffLen] = 0; //zero-terminate, in case the cgi handler knows it can use strings
//Send the response.
httpdProcessRequest(conn);
conn->post->buffLen = 0;
@ -525,7 +556,9 @@ static void ICACHE_FLASH_ATTR httpdDisconCb(void *arg) {
static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) {
debugConn(arg, "httpdReconCb");
HttpdConnData *conn = httpdFindConnData(arg);
#ifdef HTTPD_DBG
os_printf("%s ***** reset, err=%d\n", connStr, err);
#endif
if (conn == NULL) return;
httpdRetireConn(conn);
}
@ -533,33 +566,37 @@ static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) {
static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) {
debugConn(arg, "httpdConnectCb");
struct espconn *conn=arg;
struct espconn *conn = arg;
int i;
//Find empty conndata in pool
for (i=0; i<MAX_CONN; i++) if (connData[i].conn==NULL) break;
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);
if (i==MAX_CONN) {
if (i == MAX_CONN) {
#ifdef HTTPD_DBG
os_printf("%s Aiee, conn pool overflow!\n", connStr);
#endif
espconn_disconnect(conn);
return;
}
#if 0
int num = 0;
for (int j=0; j<MAX_CONN; j++) if (connData[j].conn != NULL) num++;
os_printf("%s Connect (%d open)\n", connStr, num+1);
for (int j = 0; j<MAX_CONN; j++) if (connData[j].conn != NULL) num++;
#ifdef HTTPD_DBG
os_printf("%s Connect (%d open)\n", connStr, num + 1);
#endif
#endif
connData[i].priv=&connPrivData[i];
connData[i].conn=conn;
connData[i].priv = &connPrivData[i];
connData[i].conn = conn;
connData[i].remote_port = conn->proto.tcp->remote_port;
os_memcpy(connData[i].remote_ip, conn->proto.tcp->remote_ip, 4);
connData[i].priv->headPos=0;
connData[i].post=&connPostData[i];
connData[i].post->buff=NULL;
connData[i].post->buffLen=0;
connData[i].post->received=0;
connData[i].post->len=-1;
connData[i].priv->headPos = 0;
connData[i].post = &connPostData[i];
connData[i].post->buff = NULL;
connData[i].post->buffLen = 0;
connData[i].post->received = 0;
connData[i].post->len = -1;
connData[i].startTime = system_get_time();
espconn_regist_recvcb(conn, httpdRecvCb);
@ -567,23 +604,24 @@ static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) {
espconn_regist_disconcb(conn, httpdDisconCb);
espconn_regist_sentcb(conn, httpdSentCb);
espconn_set_opt(conn, ESPCONN_REUSEADDR|ESPCONN_NODELAY);
espconn_set_opt(conn, ESPCONN_REUSEADDR | ESPCONN_NODELAY);
}
//Httpd initialization routine. Call this to kick off webserver functionality.
void ICACHE_FLASH_ATTR httpdInit(HttpdBuiltInUrl *fixedUrls, int port) {
int i;
for (i=0; i<MAX_CONN; i++) {
connData[i].conn=NULL;
for (i = 0; i<MAX_CONN; i++) {
connData[i].conn = NULL;
}
httpdConn.type=ESPCONN_TCP;
httpdConn.state=ESPCONN_NONE;
httpdTcp.local_port=port;
httpdConn.proto.tcp=&httpdTcp;
builtInUrls=fixedUrls;
httpdConn.type = ESPCONN_TCP;
httpdConn.state = ESPCONN_NONE;
httpdTcp.local_port = port;
httpdConn.proto.tcp = &httpdTcp;
builtInUrls = fixedUrls;
#ifdef HTTPD_DBG
os_printf("Httpd init, conn=%p\n", &httpdConn);
#endif
espconn_regist_connectcb(&httpdConn, httpdConnectCb);
espconn_accept(&httpdConn);
espconn_tcp_set_max_con_allow(&httpdConn, MAX_CONN);

@ -1,4 +1,7 @@
// Combined include file for esp8266
#ifndef _ESP8266_H_
#define _ESP8266_H_
#include <user_config.h>
#include <ctype.h>
#include <stdio.h>
@ -16,10 +19,9 @@
#include "espmissingincludes.h"
#include "uart_hw.h"
extern char* esp_link_version;
void ICACHE_FLASH_ATTR init(void);
#ifdef __WIN32__
#include <_mingw.h>
#endif
#endif // _ESP8266_H_

@ -1,4 +1,36 @@
#ifndef _USER_CONFIG_H_
#define _USER_CONFIG_H_
#include <c_types.h>
#ifdef __WIN32__
#include <_mingw.h>
#endif
#define DEBUGIP
#define CMD_DBG
#define ESPFS_DBG
#define CGI_DBG
#define CGIFLASH_DBG
#define CGIMQTT_DBG
#define CGIPINS_DBG
#define CGIWIFI_DBG
#define CONFIG_DBG
#define LOG_DBG
#define STATUS_DBG
#define HTTPD_DBG
#define MQTT_DBG
#define MQTTCMD_DBG
#define PKTBUF_DBG
#define REST_DBG
#define RESTCMD_DBG
#define SERBR_DBG
#define SERLED_DBG
#define SLIP_DBG
#define UART_DBG
#define CHIP_IN_HOSTNAME
extern char* esp_link_version;
extern uint8_t UTILS_StrToIP(const char* str, void *ip);
#endif

@ -59,10 +59,12 @@ sint8 espconn_secure_sent(struct espconn *espconn, uint8 *psent, uint16 length)
// max message size for sending (except publish)
#define MQTT_MAX_SHORT_MESSAGE 128
#ifdef MQTT_DBG
static char* mqtt_msg_type[] = {
"NULL", "TYPE_CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", "PUBCOMP",
"SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP", "DISCONNECT", "RESV",
};
#endif
// forward declarations
static void mqtt_enq_message(MQTT_Client *client, const uint8_t *data, uint16_t len);
@ -127,7 +129,9 @@ mqtt_tcpclient_recv(void* arg, char* pdata, unsigned short len) {
if (msg_len > client->in_buffer_size) {
// oops, too long a message for us to digest, disconnect and hope for a miracle
#ifdef MQTT_DBG
os_printf("MQTT: Too long a message (%d bytes)\n", msg_len);
#endif
mqtt_doAbort(client);
return;
}
@ -137,7 +141,9 @@ mqtt_tcpclient_recv(void* arg, char* pdata, unsigned short len) {
if (client->connState != MQTT_CONNECTED) {
// why are we receiving something??
#ifdef MQTT_DBG
os_printf("MQTT ERROR: recv in invalid state %d\n", client->connState);
#endif
mqtt_doAbort(client);
return;
}
@ -149,13 +155,16 @@ mqtt_tcpclient_recv(void* arg, char* pdata, unsigned short len) {
pending_msg_type = mqtt_get_type(client->pending_buffer->data);
pending_msg_id = mqtt_get_id(client->pending_buffer->data, client->pending_buffer->filled);
}
os_printf("MQTT: Recv type=%s id=%04X len=%d; Pend type=%s id=%04X\n",
mqtt_msg_type[msg_type], msg_id, msg_len, mqtt_msg_type[pending_msg_type], pending_msg_id);
#ifdef MQTT_DBG
os_printf("MQTT: Recv type=%s id=%04X len=%d; Pend type=%s id=%02X\n",
mqtt_msg_type[msg_type], msg_id, msg_len, mqtt_msg_type[pending_msg_type],pending_msg_id);
#endif
switch (msg_type) {
case MQTT_MSG_TYPE_CONNACK:
#ifdef MQTT_DBG
os_printf("MQTT: Connect successful\n");
#endif
// callbacks for internal and external clients
if (client->connectedCb) client->connectedCb((uint32_t*)client);
if (client->cmdConnectedCb) client->cmdConnectedCb((uint32_t*)client);
@ -163,28 +172,36 @@ mqtt_tcpclient_recv(void* arg, char* pdata, unsigned short len) {
case MQTT_MSG_TYPE_SUBACK:
if (pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && pending_msg_id == msg_id) {
#ifdef MQTT_DBG
os_printf("MQTT: Subscribe successful\n");
#endif
client->pending_buffer = PktBuf_ShiftFree(client->pending_buffer);
}
break;
case MQTT_MSG_TYPE_UNSUBACK:
if (pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && pending_msg_id == msg_id) {
#ifdef MQTT_DBG
os_printf("MQTT: Unsubscribe successful\n");
#endif
client->pending_buffer = PktBuf_ShiftFree(client->pending_buffer);
}
break;
case MQTT_MSG_TYPE_PUBACK: // ack for a publish we sent
if (pending_msg_type == MQTT_MSG_TYPE_PUBLISH && pending_msg_id == msg_id) {
#ifdef MQTT_DBG
os_printf("MQTT: QoS1 Publish successful\n");
#endif
client->pending_buffer = PktBuf_ShiftFree(client->pending_buffer);
}
break;
case MQTT_MSG_TYPE_PUBREC: // rec for a publish we sent
if (pending_msg_type == MQTT_MSG_TYPE_PUBLISH && pending_msg_id == msg_id) {
#ifdef MQTT_DBG
os_printf("MQTT: QoS2 publish cont\n");
#endif
client->pending_buffer = PktBuf_ShiftFree(client->pending_buffer);
// we need to send PUBREL
mqtt_msg_pubrel(&client->mqtt_connection, msg_id);
@ -195,7 +212,9 @@ mqtt_tcpclient_recv(void* arg, char* pdata, unsigned short len) {
case MQTT_MSG_TYPE_PUBCOMP: // comp for a pubrel we sent (originally publish we sent)
if (pending_msg_type == MQTT_MSG_TYPE_PUBREL && pending_msg_id == msg_id) {
#ifdef MQTT_DBG
os_printf("MQTT: QoS2 Publish successful\n");
#endif
client->pending_buffer = PktBuf_ShiftFree(client->pending_buffer);
}
break;
@ -203,9 +222,11 @@ mqtt_tcpclient_recv(void* arg, char* pdata, unsigned short len) {
case MQTT_MSG_TYPE_PUBLISH: { // incoming publish
// we may need to ACK the publish
uint8_t msg_qos = mqtt_get_qos(client->in_buffer);
#ifdef MQTT_DBG
uint16_t topic_length = msg_len;
os_printf("MQTT: Recv PUBLISH qos=%d %s\n", msg_qos,
mqtt_get_publish_topic(client->in_buffer, &topic_length));
#endif
if (msg_qos == 1) mqtt_msg_puback(&client->mqtt_connection, msg_id);
if (msg_qos == 2) mqtt_msg_pubrec(&client->mqtt_connection, msg_id);
if (msg_qos == 1 || msg_qos == 2) {
@ -219,7 +240,9 @@ mqtt_tcpclient_recv(void* arg, char* pdata, unsigned short len) {
case MQTT_MSG_TYPE_PUBREL: // rel for a rec we sent (originally publish received)
if (pending_msg_type == MQTT_MSG_TYPE_PUBREC && pending_msg_id == msg_id) {
#ifdef MQTT_DBG
os_printf("MQTT: Cont QoS2 recv\n");
#endif
client->pending_buffer = PktBuf_ShiftFree(client->pending_buffer);
// we need to send PUBCOMP
mqtt_msg_pubcomp(&client->mqtt_connection, msg_id);
@ -296,7 +319,9 @@ mqtt_timer(void* arg) {
// check whether our last keep-alive timed out
if (client->keepAliveAckTick > 0 && --client->keepAliveAckTick == 0) {
#ifdef MQTT_DBG
os_printf("\nMQTT ERROR: Keep-alive timed out\n");
#endif
mqtt_doAbort(client);
return;
}
@ -340,15 +365,17 @@ void ICACHE_FLASH_ATTR
mqtt_tcpclient_discon_cb(void* arg) {
struct espconn* pespconn = (struct espconn *)arg;
MQTT_Client* client = (MQTT_Client *)pespconn->reverse;
#ifdef MQTT_DBG
os_printf("MQTT: Disconnect CB, freeing espconn %p\n", arg);
#endif
if (pespconn->proto.tcp) os_free(pespconn->proto.tcp);
os_free(pespconn);
// if this is an aborted connection we're done
if (client == NULL) return;
#ifdef MQTT_DBG
os_printf("MQTT: Disconnected from %s:%d\n", client->host, client->port);
#endif
if (client->disconnectedCb) client->disconnectedCb((uint32_t*)client);
if (client->cmdDisconnectedCb) client->cmdDisconnectedCb((uint32_t*)client);
@ -367,12 +394,14 @@ static void ICACHE_FLASH_ATTR
mqtt_tcpclient_recon_cb(void* arg, int8_t err) {
struct espconn* pespconn = (struct espconn *)arg;
MQTT_Client* client = (MQTT_Client *)pespconn->reverse;
#ifdef MQTT_DBG
os_printf("MQTT: Reset CB, freeing espconn %p (err=%d)\n", arg, err);
#endif
if (pespconn->proto.tcp) os_free(pespconn->proto.tcp);
os_free(pespconn);
#ifdef MQTT_DBG
os_printf("MQTT: Connection reset from %s:%d\n", client->host, client->port);
#endif
if (client->disconnectedCb) client->disconnectedCb((uint32_t*)client);
if (client->cmdDisconnectedCb) client->cmdDisconnectedCb((uint32_t*)client);
@ -397,7 +426,9 @@ mqtt_tcpclient_connect_cb(void* arg) {
espconn_regist_disconcb(client->pCon, mqtt_tcpclient_discon_cb);
espconn_regist_recvcb(client->pCon, mqtt_tcpclient_recv);
espconn_regist_sentcb(client->pCon, mqtt_tcpclient_sent_cb);
#ifdef MQTT_DBG
os_printf("MQTT: TCP connected to %s:%d\n", client->host, client->port);
#endif
// send MQTT connect message to broker
mqtt_msg_connect(&client->mqtt_connection, &client->connect_info);
@ -438,8 +469,9 @@ mqtt_send_message(MQTT_Client* client) {
// get some details about the message
uint16_t msg_type = mqtt_get_type(buf->data);
uint8_t msg_id = mqtt_get_id(buf->data, buf->filled);
msg_id = msg_id;
#ifdef MQTT_DBG
os_printf("MQTT: Send type=%s id=%04X len=%d\n", mqtt_msg_type[msg_type], msg_id, buf->filled);
#if 0
for (int i=0; i<buf->filled; i++) {
if (buf->data[i] >= ' ' && buf->data[i] <= '~') os_printf("%c", buf->data[i]);
else os_printf("\\x%02X", buf->data[i]);
@ -484,17 +516,20 @@ mqtt_dns_found(const char* name, ip_addr_t* ipaddr, void* arg) {
MQTT_Client* client = (MQTT_Client *)pConn->reverse;
if (ipaddr == NULL) {
#ifdef MQTT_DBG
os_printf("MQTT DNS: Got no ip, try to reconnect\n");
#endif
client->timeoutTick = 10;
client->connState = TCP_RECONNECT_REQ; // the timer will kick-off a reconnection
return;
}
#ifdef MQTT_DBG
os_printf("MQTT DNS: found ip %d.%d.%d.%d\n",
*((uint8 *)&ipaddr->addr),
*((uint8 *)&ipaddr->addr + 1),
*((uint8 *)&ipaddr->addr + 2),
*((uint8 *)&ipaddr->addr + 3));
#endif
if (client->ip.addr == 0 && ipaddr->addr != 0) {
os_memcpy(client->pCon->proto.tcp->remote_ip, &ipaddr->addr, 4);
@ -504,11 +539,15 @@ mqtt_dns_found(const char* name, ip_addr_t* ipaddr, void* arg) {
else
err = espconn_connect(client->pCon);
if (err != 0) {
#ifdef MQTT_DBG
os_printf("MQTT ERROR: Failed to connect\n");
#endif
client->connState = TCP_RECONNECT_REQ;
client->timeoutTick = 10;
} else {
#ifdef MQTT_DBG
os_printf("MQTT: connecting...\n");
#endif
}
}
}
@ -542,7 +581,9 @@ MQTT_Publish(MQTT_Client* client, const char* topic, const char* data, uint8_t q
uint16_t buf_len = 3 + 2 + 2 + topic_length + data_length + 16;
PktBuf *buf = PktBuf_New(buf_len);
if (buf == NULL) {
#ifdef MQTT_DBG
os_printf("MQTT ERROR: Cannot allocate buffer for %d byte publish\n", buf_len);
#endif
return FALSE;
}
// use a temporary mqtt_message_t pointing to our buffer, this is a bit of a mess because we
@ -551,7 +592,9 @@ MQTT_Publish(MQTT_Client* client, const char* topic, const char* data, uint8_t q
msg_conn_init(&msg, &client->mqtt_connection, buf->data, buf_len);
uint16_t msg_id;
if (!mqtt_msg_publish(&msg, topic, data, data_length, qos, retain, &msg_id)){
#ifdef MQTT_DBG
os_printf("MQTT ERROR: Queuing Publish failed\n");
#endif
os_free(buf);
return FALSE;
}
@ -581,10 +624,14 @@ bool ICACHE_FLASH_ATTR
MQTT_Subscribe(MQTT_Client* client, char* topic, uint8_t qos) {
uint16_t msg_id;
if (!mqtt_msg_subscribe(&client->mqtt_connection, topic, 0, &msg_id)) {
#ifdef MQTT_DBG
os_printf("MQTT ERROR: Queuing Subscribe failed (too long)\n");
#endif
return FALSE;
}
#ifdef MQTT_DBG
os_printf("MQTT: Subscribe, topic: \"%s\"\n", topic);
#endif
mqtt_enq_message(client, client->mqtt_connection.message.data,
client->mqtt_connection.message.length);
return TRUE;
@ -602,14 +649,20 @@ MQTT_Subscribe(MQTT_Client* client, char* topic, uint8_t qos) {
* @param client_user: MQTT client user
* @param client_pass: MQTT client password
* @param keepAliveTime: MQTT keep alive timer, in second
* @param cleanSession: MQTT ...
* @param cleanSession: On connection, a client sets the "clean session" flag, which is sometimes also known as the "clean start" flag.
* If clean session is set to false, then the connection is treated as durable. This means that when the client
* disconnects, any subscriptions it has will remain and any subsequent QoS 1 or 2 messages will be stored until
* it connects again in the future. If clean session is true, then all subscriptions will be removed for the client
* when it disconnects.
* @retval None
*/
void ICACHE_FLASH_ATTR
MQTT_Init(MQTT_Client* mqttClient, char* host, uint32 port, uint8_t security, uint8_t sendTimeout,
char* client_id, char* client_user, char* client_pass,
uint8_t keepAliveTime) {
#ifdef MQTT_DBG
os_printf("MQTT_Init\n");
#endif
os_memset(mqttClient, 0, sizeof(MQTT_Client));
@ -686,7 +739,9 @@ MQTT_Connect(MQTT_Client* mqttClient) {
os_timer_arm(&mqttClient->mqttTimer, 1000, 1);
// initiate the TCP connection or DNS lookup
#ifdef MQTT_DBG
os_printf("MQTT: Connect to %s:%d %p\n", mqttClient->host, mqttClient->port, mqttClient->pCon);
#endif
if (UTILS_StrToIP((const char *)mqttClient->host,
(void*)&mqttClient->pCon->proto.tcp->remote_ip)) {
uint8_t err;
@ -695,7 +750,9 @@ MQTT_Connect(MQTT_Client* mqttClient) {
else
err = espconn_connect(mqttClient->pCon);
if (err != 0) {
#ifdef MQTT_DBG
os_printf("MQTT ERROR: Failed to connect\n");
#endif
os_free(mqttClient->pCon->proto.tcp);
os_free(mqttClient->pCon);
mqttClient->pCon = NULL;
@ -713,7 +770,9 @@ MQTT_Connect(MQTT_Client* mqttClient) {
static void ICACHE_FLASH_ATTR
mqtt_doAbort(MQTT_Client* client) {
#ifdef MQTT_DBG
os_printf("MQTT: Disconnecting from %s:%d (%p)\n", client->host, client->port, client->pCon);
#endif
client->pCon->reverse = NULL; // ensure we jettison this pCon...
if (client->security)
espconn_secure_disconnect(client->pCon);

@ -8,11 +8,13 @@ void ICACHE_FLASH_ATTR
cmdMqttConnectedCb(uint32_t* args) {
MQTT_Client* client = (MQTT_Client*)args;
MqttCmdCb* cb = (MqttCmdCb*)client->user_data;
#ifdef MQTTCMD_DBG
os_printf("MQTT: Connected connectedCb=%p, disconnectedCb=%p, publishedCb=%p, dataCb=%p\n",
(void*)cb->connectedCb,
(void*)cb->disconnectedCb,
(void*)cb->publishedCb,
(void*)cb->dataCb);
#endif
uint16_t crc = CMD_ResponseStart(CMD_MQTT_EVENTS, cb->connectedCb, 0, 0);
CMD_ResponseEnd(crc);
}
@ -21,7 +23,9 @@ void ICACHE_FLASH_ATTR
cmdMqttTcpDisconnectedCb(uint32_t *args) {
MQTT_Client* client = (MQTT_Client*)args;
MqttCmdCb *cb = (MqttCmdCb*)client->user_data;
#ifdef MQTTCMD_DBG
os_printf("MQTT: TCP Disconnected\n");
#endif
uint16_t crc = CMD_ResponseStart(CMD_MQTT_EVENTS, cb->tcpDisconnectedCb, 0, 0);
CMD_ResponseEnd(crc);
}
@ -30,7 +34,9 @@ void ICACHE_FLASH_ATTR
cmdMqttDisconnectedCb(uint32_t* args) {
MQTT_Client* client = (MQTT_Client*)args;
MqttCmdCb* cb = (MqttCmdCb*)client->user_data;
#ifdef MQTTCMD_DBG
os_printf("MQTT: Disconnected\n");
#endif
uint16_t crc = CMD_ResponseStart(CMD_MQTT_EVENTS, cb->disconnectedCb, 0, 0);
CMD_ResponseEnd(crc);
}
@ -39,7 +45,9 @@ void ICACHE_FLASH_ATTR
cmdMqttPublishedCb(uint32_t* args) {
MQTT_Client* client = (MQTT_Client*)args;
MqttCmdCb* cb = (MqttCmdCb*)client->user_data;
#ifdef MQTTCMD_DBG
os_printf("MQTT: Published\n");
#endif
uint16_t crc = CMD_ResponseStart(CMD_MQTT_EVENTS, cb->publishedCb, 0, 0);
CMD_ResponseEnd(crc);
}
@ -103,8 +111,9 @@ MQTTCMD_Setup(CmdPacket *cmd) {
// get clean session
CMD_PopArg(&req, (uint8_t*)&clean_session, 4);
#ifdef MQTTCMD_DBG
os_printf("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
// TODO: why malloc these all here, pass to MQTT_InitClient to be malloc'd again?
@ -155,7 +164,9 @@ MQTTCMD_Lwt(CmdPacket *cmd) {
uint32_t client_ptr;
CMD_PopArg(&req, (uint8_t*)&client_ptr, 4);
MQTT_Client* client = (MQTT_Client*)client_ptr;
#ifdef MQTTCMD_DBG
os_printf("MQTT: MQTTCMD_Lwt client ptr=%p\n", (void*)client_ptr);
#endif
uint16_t len;
@ -182,12 +193,13 @@ MQTTCMD_Lwt(CmdPacket *cmd) {
// get retain
CMD_PopArg(&req, (uint8_t*)&client->connect_info.will_retain, 4);
#ifdef MQTTCMD_DBG
os_printf("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,
client->connect_info.will_retain);
#endif
return 1;
}
@ -203,7 +215,9 @@ MQTTCMD_Connect(CmdPacket *cmd) {
uint32_t client_ptr;
CMD_PopArg(&req, (uint8_t*)&client_ptr, 4);
MQTT_Client* client = (MQTT_Client*)client_ptr;
#ifdef MQTTCMD_DBG
os_printf("MQTT: MQTTCMD_Connect client ptr=%p\n", (void*)client_ptr);
#endif
uint16_t len;
@ -221,11 +235,12 @@ MQTTCMD_Connect(CmdPacket *cmd) {
// get security
CMD_PopArg(&req, (uint8_t*)&client->security, 4);
#ifdef MQTTCMD_DBG
os_printf("MQTT: MQTTCMD_Connect host=%s, port=%d, security=%d\n",
client->host,
client->port,
client->security);
#endif
MQTT_Connect(client);
return 1;
@ -243,7 +258,9 @@ MQTTCMD_Disconnect(CmdPacket *cmd) {
uint32_t client_ptr;
CMD_PopArg(&req, (uint8_t*)&client_ptr, 4);
MQTT_Client* client = (MQTT_Client*)client_ptr;
#ifdef MQTTCMD_DBG
os_printf("MQTT: MQTTCMD_Disconnect client ptr=%p\n", (void*)client_ptr);
#endif
// disconnect
MQTT_Disconnect(client);
@ -262,7 +279,9 @@ MQTTCMD_Publish(CmdPacket *cmd) {
uint32_t client_ptr;
CMD_PopArg(&req, (uint8_t*)&client_ptr, 4);
MQTT_Client* client = (MQTT_Client*)client_ptr;
#ifdef MQTTCMD_DBG
os_printf("MQTT: MQTTCMD_Publish client ptr=%p\n", (void*)client_ptr);
#endif
uint16_t len;
uint8_t *topic, *data;
@ -293,12 +312,13 @@ MQTTCMD_Publish(CmdPacket *cmd) {
// get retain
CMD_PopArg(&req, (uint8_t*)&retain, 4);
#ifdef MQTTCMD_DBG
os_printf("MQTT: MQTTCMD_Publish topic=%s, data_len=%d, qos=%ld, retain=%ld\n",
topic,
os_strlen((char*)data),
qos,
retain);
#endif
MQTT_Publish(client, (char*)topic, (char*)data, (uint8_t)qos, (uint8_t)retain);
os_free(topic);
@ -318,7 +338,9 @@ MQTTCMD_Subscribe(CmdPacket *cmd) {
uint32_t client_ptr;
CMD_PopArg(&req, (uint8_t*)&client_ptr, 4);
MQTT_Client* client = (MQTT_Client*)client_ptr;
#ifdef MQTTCMD_DBG
os_printf("MQTT: MQTTCMD_Subscribe client ptr=%p\n", (void*)client_ptr);
#endif
uint16_t len;
uint8_t* topic;
@ -333,8 +355,9 @@ MQTTCMD_Subscribe(CmdPacket *cmd) {
// get qos
CMD_PopArg(&req, (uint8_t*)&qos, 4);
#ifdef MQTTCMD_DBG
os_printf("MQTT: MQTTCMD_Subscribe topic=%s, qos=%ld\n", topic, qos);
#endif
MQTT_Subscribe(client, (char*)topic, (uint8_t)qos);
os_free(topic);
return 1;

@ -73,7 +73,7 @@ typedef struct mqtt_connect_info {
char* password;
char* will_topic;
char* will_message;
uint32_t keepalive;
uint8_t keepalive;
uint8_t will_qos;
uint8_t will_retain;
uint8_t clean_session;

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

@ -24,6 +24,4 @@ PktBuf *PktBuf_Shift(PktBuf *headBuf);
// Shift first buffer off queue, free it, return new head
PktBuf *PktBuf_ShiftFree(PktBuf *headBuf);
void PktBuf_Print(PktBuf *buf);
#endif

@ -73,16 +73,20 @@ tcpclient_recv(void *arg, char *pdata, unsigned short len) {
// collect body and send it
uint16_t crc;
int body_len = len-pi;
#ifdef REST_DBG
os_printf("REST: status=%ld, body=%d\n", code, body_len);
#endif
if (pi == len) {
crc = CMD_ResponseStart(CMD_REST_EVENTS, client->resp_cb, code, 0);
} else {
crc = CMD_ResponseStart(CMD_REST_EVENTS, client->resp_cb, code, 1);
crc = CMD_ResponseBody(crc, (uint8_t*)(pdata+pi), body_len);
CMD_ResponseEnd(crc);
#ifdef REST_DBG
os_printf("REST: body=");
for (int j=pi; j<len; j++) os_printf(" %02x", pdata[j]);
os_printf("\n");
#endif
}
//if(client->security)
@ -96,7 +100,9 @@ static void ICACHE_FLASH_ATTR
tcpclient_sent_cb(void *arg) {
struct espconn *pCon = (struct espconn *)arg;
RestClient* client = (RestClient *)pCon->reverse;
#ifdef REST_DBG
os_printf("REST: Sent\n");
#endif
if (client->data_sent != client->data_len) {
// we only sent part of the buffer, send the rest
espconn_sent(client->pCon, (uint8_t*)(client->data+client->data_sent),
@ -113,14 +119,17 @@ static void ICACHE_FLASH_ATTR
tcpclient_connect_cb(void *arg) {
struct espconn *pCon = (struct espconn *)arg;
RestClient* client = (RestClient *)pCon->reverse;
#ifdef REST_DBG
os_printf("REST #%d: connected\n", client-restClient);
#endif
espconn_regist_disconcb(client->pCon, tcpclient_discon_cb);
espconn_regist_recvcb(client->pCon, tcpclient_recv);
espconn_regist_sentcb(client->pCon, tcpclient_sent_cb);
client->data_sent = client->data_len <= 1400 ? client->data_len : 1400;
#ifdef REST_DBG
os_printf("REST #%d: sending %d\n", client-restClient, client->data_sent);
#endif
//if(client->security){
// espconn_secure_sent(client->pCon, client->data, client->data_sent);
//}
@ -133,7 +142,9 @@ static void ICACHE_FLASH_ATTR
tcpclient_recon_cb(void *arg, sint8 errType) {
struct espconn *pCon = (struct espconn *)arg;
RestClient* client = (RestClient *)pCon->reverse;
#ifdef REST_DBG
os_printf("REST #%d: conn reset\n", client-restClient);
#endif
}
static void ICACHE_FLASH_ATTR
@ -142,16 +153,18 @@ rest_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) {
RestClient* client = (RestClient *)pConn->reverse;
if(ipaddr == NULL) {
#ifdef REST_DBG
os_printf("REST DNS: Got no ip, try to reconnect\n");
#endif
return;
}
#ifdef REST_DBG
os_printf("REST DNS: found ip %d.%d.%d.%d\n",
*((uint8 *) &ipaddr->addr),
*((uint8 *) &ipaddr->addr + 1),
*((uint8 *) &ipaddr->addr + 2),
*((uint8 *) &ipaddr->addr + 3));
#endif
if(client->ip.addr == 0 && ipaddr->addr != 0) {
os_memcpy(client->pCon->proto.tcp->remote_ip, &ipaddr->addr, 4);
#ifdef CLIENT_SSL_ENABLE
@ -160,7 +173,9 @@ rest_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) {
} else
#endif
espconn_connect(client->pCon);
#ifdef REST_DBG
os_printf("REST: connecting...\n");
#endif
}
}
@ -213,8 +228,9 @@ REST_Setup(CmdPacket *cmd) {
os_free(client->pCon);
}
os_memset(client, 0, sizeof(RestClient));
#ifdef CMDREST_DBG
os_printf("REST: setup #%d host=%s port=%ld security=%ld\n", clientNum, rest_host, port, security);
#endif
client->resp_cb = cmd->callback;
@ -273,7 +289,9 @@ REST_SetHeader(CmdPacket *cmd) {
client->header[len] = '\r';
client->header[len+1] = '\n';
client->header[len+2] = 0;
#ifdef CMDREST_DBG
os_printf("REST: Set header: %s\r\n", client->header);
#endif
break;
case HEADER_CONTENT_TYPE:
if(client->content_type) os_free(client->content_type);
@ -282,7 +300,9 @@ REST_SetHeader(CmdPacket *cmd) {
client->content_type[len] = '\r';
client->content_type[len+1] = '\n';
client->content_type[len+2] = 0;
#ifdef CMDREST_DBG
os_printf("REST: Set content_type: %s\r\n", client->content_type);
#endif
break;
case HEADER_USER_AGENT:
if(client->user_agent) os_free(client->user_agent);
@ -291,7 +311,9 @@ REST_SetHeader(CmdPacket *cmd) {
client->user_agent[len] = '\r';
client->user_agent[len+1] = '\n';
client->user_agent[len+2] = 0;
#ifdef CMDREST_DBG
os_printf("REST: Set user_agent: %s\r\n", client->user_agent);
#endif
break;
}
return 1;
@ -301,32 +323,36 @@ uint32_t ICACHE_FLASH_ATTR
REST_Request(CmdPacket *cmd) {
CmdRequest req;
CMD_Request(&req, cmd);
#ifdef CMDREST_DBG
os_printf("REST: request");
#endif
// Get client
uint32_t clientNum;
if (CMD_PopArg(&req, (uint8_t*)&clientNum, 4)) goto fail;
if ((clientNum & 0xffff0000) != REST_CB) goto fail;
clientNum &= 0xffff;
RestClient *client = restClient + clientNum % MAX_REST;
#ifdef CMDREST_DBG
os_printf(" #%ld", clientNum);
#endif
// Get HTTP method
uint16_t len = CMD_ArgLen(&req);
if (len > 15) goto fail;
char method[16];
CMD_PopArg(&req, method, len);
method[len] = 0;
#ifdef CMDREST_DBG
os_printf(" method=%s", method);
#endif
// Get HTTP path
len = CMD_ArgLen(&req);
if (len > 1023) goto fail;
char path[1024];
CMD_PopArg(&req, path, len);
path[len] = 0;
#ifdef CMDREST_DBG
os_printf(" path=%s", path);
#endif
// Get HTTP body
uint32_t realLen = 0;
if (CMD_GetArgc(&req) == 3) {
@ -338,7 +364,9 @@ REST_Request(CmdPacket *cmd) {
len = CMD_ArgLen(&req);
if (len > 2048 || realLen > len) goto fail;
}
#ifdef CMDREST_DBG
os_printf(" bodyLen=%ld", realLen);
#endif
// we need to allocate memory for the header plus the body. First we count the length of the
// header (including some extra counted "%s" and then we add the body length. We allocate the
@ -353,30 +381,40 @@ REST_Request(CmdPacket *cmd) {
"User-Agent: %s\r\n\r\n";
uint16_t headerLen = strlen(headerFmt) + strlen(method) + strlen(path) + strlen(client->host) +
strlen(client->header) + strlen(client->content_type) + strlen(client->user_agent);
#ifdef CMDREST_DBG
os_printf(" hdrLen=%d", headerLen);
#endif
if (client->data) os_free(client->data);
client->data = (char*)os_zalloc(headerLen + realLen);
if (client->data == NULL) goto fail;
#ifdef CMDREST_DBG
os_printf(" totLen=%ld data=%p", headerLen + realLen, client->data);
#endif
client->data_len = os_sprintf((char*)client->data, headerFmt, method, path, client->host,
client->header, realLen, client->content_type, client->user_agent);
#ifdef CMDREST_DBG
os_printf(" hdrLen=%d", client->data_len);
#endif
if (realLen > 0) {
CMD_PopArg(&req, client->data + client->data_len, realLen);
client->data_len += realLen;
}
#ifdef CMDREST_DBG
os_printf("\n");
//os_printf("REST request: %s", (char*)client->data);
os_printf("REST: pCon state=%d\n", client->pCon->state);
#endif
client->pCon->state = ESPCONN_NONE;
espconn_regist_connectcb(client->pCon, tcpclient_connect_cb);
espconn_regist_reconcb(client->pCon, tcpclient_recon_cb);
if(UTILS_StrToIP((char *)client->host, &client->pCon->proto.tcp->remote_ip)) {
#ifdef CMDREST_DBG
os_printf("REST: Connect to ip %s:%ld\n",client->host, client->port);
#endif
//if(client->security){
// espconn_secure_connect(client->pCon);
//}
@ -384,52 +422,17 @@ REST_Request(CmdPacket *cmd) {
espconn_connect(client->pCon);
//}
} else {
#ifdef CMDREST_DBG
os_printf("REST: Connect to host %s:%ld\n", client->host, client->port);
#endif
espconn_gethostbyname(client->pCon, (char *)client->host, &client->ip, rest_dns_found);
}
return 1;
fail:
#ifdef CMDREST_DBG
os_printf("\n");
#endif
return 0;
}
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;
}

@ -36,6 +36,5 @@ typedef struct {
uint32_t REST_Setup(CmdPacket *cmd);
uint32_t REST_Request(CmdPacket *cmd);
uint32_t REST_SetHeader(CmdPacket *cmd);
uint8_t UTILS_StrToIP(const char* str, void *ip);
#endif /* MODULES_INCLUDE_API_H_ */

@ -93,10 +93,15 @@ telnetUnwrap(uint8_t *inBuf, int len, uint8_t state)
switch (c) {
case DTR_ON:
if (mcu_reset_pin >= 0) {
#ifdef SERBR_DBG
os_printf("MCU reset gpio%d\n", mcu_reset_pin);
#endif
GPIO_OUTPUT_SET(mcu_reset_pin, 0);
os_delay_us(100L);
} else os_printf("MCU reset: no pin\n");
}
#ifdef SERBR_DBG
else os_printf("MCU reset: no pin\n");
#endif
break;
case DTR_OFF:
if (mcu_reset_pin >= 0) {
@ -106,10 +111,15 @@ telnetUnwrap(uint8_t *inBuf, int len, uint8_t state)
break;
case RTS_ON:
if (mcu_isp_pin >= 0) {
#ifdef SERBR_DBG
os_printf("MCU ISP gpio%d\n", mcu_isp_pin);
#endif
GPIO_OUTPUT_SET(mcu_isp_pin, 0);
os_delay_us(100L);
} else os_printf("MCU isp: no pin\n");
}
#ifdef SERBR_DBG
else os_printf("MCU isp: no pin\n");
#endif
slip_disabled++;
break;
case RTS_OFF:
@ -132,11 +142,16 @@ void ICACHE_FLASH_ATTR
serbridgeReset()
{
if (mcu_reset_pin >= 0) {
#ifdef SERBR_DBG
os_printf("MCU reset gpio%d\n", mcu_reset_pin);
#endif
GPIO_OUTPUT_SET(mcu_reset_pin, 0);
os_delay_us(100L);
GPIO_OUTPUT_SET(mcu_reset_pin, 1);
} else os_printf("MCU reset: no pin\n");
}
#ifdef SERBR_DBG
else os_printf("MCU reset: no pin\n");
#endif
}
// Receive callback
@ -159,7 +174,9 @@ serbridgeRecvCb(void *arg, char *data, unsigned short len)
if ((len == 2 && strncmp(data, "0 ", 2) == 0) ||
(len == 2 && strncmp(data, "?\n", 2) == 0) ||
(len == 3 && strncmp(data, "?\r\n", 3) == 0)) {
#ifdef SERBR_DBG
os_printf("MCU Reset=gpio%d ISP=gpio%d\n", mcu_reset_pin, mcu_isp_pin);
#endif
os_delay_us(2*1000L); // time for os_printf to happen
// send reset to arduino/ARM
if (mcu_reset_pin >= 0) GPIO_OUTPUT_SET(mcu_reset_pin, 0);
@ -174,14 +191,18 @@ serbridgeRecvCb(void *arg, char *data, unsigned short len)
slip_disabled++; // disable SLIP so it doesn't interfere with flashing
// If the connection starts with a telnet negotiation we will do telnet
} else if (len >= 3 && strncmp(data, (char[]){IAC, WILL, ComPortOpt}, 3) == 0) {
}
else if (len >= 3 && strncmp(data, (char[]){IAC, WILL, ComPortOpt}, 3) == 0) {
conn->conn_mode = cmTelnet;
conn->telnet_state = TN_normal;
// note that the three negotiation chars will be gobbled-up by telnetUnwrap
#ifdef SERBR_DBG
os_printf("telnet mode\n");
#endif
// looks like a plain-vanilla connection!
} else {
}
else {
conn->conn_mode = cmTransparent;
}
@ -210,8 +231,11 @@ sendtxbuffer(serbridgeConnData *conn)
//os_printf("%d TX %d\n", system_get_time(), conn->txbufferlen);
conn->readytosend = false;
result = espconn_sent(conn->conn, (uint8_t*)conn->txbuffer, conn->txbufferlen);
conn->txbufferlen = 0;
if (result != ESPCONN_OK) {
#ifdef SERBR_DBG
os_printf("sendtxbuffer: espconn_sent error %d on conn %p\n", result, conn);
#endif
conn->txbufferlen = 0;
} else {
conn->sentbuffer = conn->txbuffer;
@ -227,11 +251,13 @@ sendtxbuffer(serbridgeConnData *conn)
// Returns ESPCONN_OK (0) for success, -128 if buffer is full or error from espconn_sent
// Use espbuffsend instead of espconn_sent as it solves the problem that espconn_sent must
// only be called *after* receiving an espconn_sent_callback for the previous packet.
sint8 ICACHE_FLASH_ATTR
static sint8 ICACHE_FLASH_ATTR
espbuffsend(serbridgeConnData *conn, const char *data, uint16 len)
{
if (conn->txbufferlen >= MAX_TXBUFFER) {
#ifdef SERBR_DBG
os_printf("espbuffsend: txbuffer full on conn %p\n", conn);
#endif
return -128;
}
@ -344,10 +370,14 @@ serbridgeConnectCb(void *arg)
// Find empty conndata in pool
int i;
for (i=0; i<MAX_CONN; i++) if (connData[i].conn==NULL) break;
#ifdef SERBR_DBG
os_printf("Accept port 23, conn=%p, pool slot %d\n", conn, i);
#endif
if (i==MAX_CONN) {
#ifdef SERBR_DBG
os_printf("Aiee, conn pool overflow!\n");
#endif
espconn_disconnect(conn);
return;
}
@ -373,8 +403,10 @@ serbridgeInitPins()
{
mcu_reset_pin = flashConfig.reset_pin;
mcu_isp_pin = flashConfig.isp_pin;
#ifdef SERBR_DBG
os_printf("Serbridge pins: reset=%d isp=%d swap=%d\n",
mcu_reset_pin, mcu_isp_pin, flashConfig.swap_uart);
#endif
if (flashConfig.swap_uart) {
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 4);

@ -35,7 +35,9 @@ void ICACHE_FLASH_ATTR serledInit(void) {
gpio_output_set(0, 0, (1<<pin), 0);
serledFlash(1000); // turn it on for 1 second
}
#ifdef SERLED_DBG
os_printf("SER led=%d\n", pin);
#endif
}
// Make a pin be GPIO, i.e. set the mux so the pin has the gpio function

@ -46,7 +46,9 @@ slip_process() {
if (crc == rcv) {
CMD_parse_packet((uint8_t*)slip_buf, slip_len-2);
} else {
#ifdef SLIP_DBG
os_printf("SLIP: bad CRC, crc=%x rcv=%x\n", crc, rcv);
for (short i=0; i<slip_len; i++) {
if (slip_buf[i] >= ' ' && slip_buf[i] <= '~')
os_printf("%c", slip_buf[i]);
@ -54,6 +56,7 @@ slip_process() {
os_printf("\\%02X", slip_buf[i]);
}
os_printf("\n");
#endif
}
}
}
@ -83,7 +86,9 @@ 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
return;
}
} else if (slip_escaped) {

@ -190,7 +190,9 @@ uart0_rx_intr_handler(void *para)
if (READ_PERI_REG(UART_INT_RAW(uart_no)) & UART_FRM_ERR_INT_RAW) {
uint32 now = system_get_time();
if (last_frm_err == 0 || (now - last_frm_err) > one_sec) {
#ifdef UART_DBG
os_printf("UART framing error (bad baud rate?)\n");
#endif
last_frm_err = now;
}
// clear rx fifo (apparently this is not optional at this point)
@ -206,7 +208,9 @@ uart0_rx_intr_handler(void *para)
if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)
|| UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST))
{
//os_printf("stat:%02X",*(uint8 *)UART_INT_ENA(uart_no));
#ifdef UART_DBG
os_printf("stat:%02X",*(uint8 *)UART_INT_ENA(uart_no));
#endif
ETS_UART_INTR_DISABLE();
system_os_post(recvTaskPrio, 0, 0);
}
@ -229,7 +233,9 @@ uart_recvTask(os_event_t *events)
(length < 128)) {
buf[length++] = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
}
//os_printf("%d ix %d\n", system_get_time(), length);
#ifdef UART_DBG
os_printf("%d ix %d\n", system_get_time(), length);
#endif
for (int i=0; i<MAX_CB; i++) {
if (uart_recv_cb[i] != NULL) (uart_recv_cb[i])(buf, length);
@ -241,7 +247,9 @@ uart_recvTask(os_event_t *events)
void ICACHE_FLASH_ATTR
uart0_baud(int rate) {
#ifdef UART_DBG
os_printf("UART %d baud\n", rate);
#endif
uart_div_modify(UART0, UART_CLK_FREQ / rate);
}
@ -278,7 +286,9 @@ uart_add_recv_cb(UartRecv_cb cb) {
return;
}
}
#ifdef UART_DBG
os_printf("UART: max cb count exceeded\n");
#endif
}
void ICACHE_FLASH_ATTR

Loading…
Cancel
Save