Merge pull request #49 from brunnels/master

mqtt_client updates from brunnels
pull/65/head
Thorsten von Eicken 9 years ago
commit b912c4babe
  1. 128
      Makefile
  2. 196
      esp-link.vcxproj
  3. 2
      esp-link/cgi.c
  4. 4
      esp-link/cgimqtt.c
  5. 5
      esp-link/cgimqtt.h
  6. 3
      esp-link/log.c
  7. 43
      esp-link/main.c
  8. 141
      esp-link/mqtt_client.c
  9. 10
      esp-link/mqtt_client.h
  10. 72
      esp-link/status.c
  11. 1
      html/mqtt.html
  12. 76
      html/mqtt.js
  13. 78
      html/ui.js
  14. 14
      include/espmissingincludes.h
  15. 2
      include/user_config.h
  16. 8
      serial/serbridge.c
  17. 5
      serial/uart.c
  18. 59
      user/user_main.c

@ -29,11 +29,71 @@ ESPTOOL ?= $(abspath ../esp-open-sdk/esptool/esptool.py)
ESPPORT ?= /dev/ttyUSB0
ESPBAUD ?= 460800
# Build time Wifi Cfg
# STA_SSID ?=
# STA_PASS ?=
# hostname or IP address for wifi flashing
ESP_HOSTNAME ?= esp-link
# --------------- chipset configuration ---------------
# Pick your flash size: "512KB", "1MB", or "4MB"
FLASH_SIZE ?= 4MB
# The pin assignments below are used when the settings in flash are invalid, they
# can be changed via the web interface
# GPIO pin used to reset attached microcontroller, acative low
MCU_RESET_PIN ?= 12
# GPIO pin used with reset to reprogram MCU (ISP=in-system-programming, unused with AVRs), active low
MCU_ISP_PIN ?= 13
# GPIO pin used for "connectivity" LED, active low
LED_CONN_PIN ?= 0
# GPIO pin used for "serial activity" LED, active low
LED_SERIAL_PIN ?= 14
# --------------- esp-link config options ---------------
# If CHANGE_TO_STA is set to "yes" the esp-link module will switch to station mode
# once successfully connected to an access point. Else it will stay in AP+STA mode.
CHANGE_TO_STA ?= yes
# --------------- esphttpd config options ---------------
# If GZIP_COMPRESSION is set to "yes" then the static css, js, and html files will be compressed
# with gzip before added to the espfs image and will be served with gzip Content-Encoding header.
# This could speed up the downloading of these files, but might break compatibility with older
# web browsers not supporting gzip encoding because Accept-Encoding is simply ignored.
# Enable this option if you have large static files to serve (for e.g. JQuery, Twitter bootstrap)
# If you have text based static files with different extensions what you want to serve compressed
# then you will need to add the extension to the following places:
# - Add the extension to this Makefile at the webpages.espfs target to the find command
# - Add the extension to the gzippedFileTypes array in the user/httpd.c file
#
# Adding JPG or PNG files (and any other compressed formats) is not recommended, because GZIP
# compression does not work effectively on compressed files.
#Static gzipping is disabled by default.
GZIP_COMPRESSION ?= 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/
# enabled by default.
COMPRESS_W_HTMLCOMPRESSOR ?= yes
HTML-COMPRESSOR ?= htmlcompressor-1.5.3.jar
YUI-COMPRESSOR ?= yuicompressor-2.4.8.jar
# Optional Modules
MODULES ?= mqtt rest
# -------------- End of config options -------------
HTML_PATH = $(abspath ./html)/
WIFI_PATH = $(HTML_PATH)wifi/
ifeq ("$(FLASH_SIZE)","512KB")
# Winbond 25Q40 512KB flash, typ for esp-01 thru esp-11
ESP_SPI_SIZE ?= 0 # 0->512KB (256KB+256KB)
@ -83,20 +143,6 @@ ET_FF ?= 80m # 80Mhz flash speed in esptool flash command
ET_BLANK ?= 0x3FE000 # where to flash blank.bin to erase wireless settings
endif
# hostname or IP address for wifi flashing
ESP_HOSTNAME ?= esp-link
# The pin assignments below are used when the settings in flash are invalid, they
# can be changed via the web interface
# GPIO pin used to reset attached microcontroller, acative low
MCU_RESET_PIN ?= 12
# GPIO pin used with reset to reprogram MCU (ISP=in-system-programming, unused with AVRs), active low
MCU_ISP_PIN ?= 13
# GPIO pin used for "connectivity" LED, active low
LED_CONN_PIN ?= 0
# GPIO pin used for "serial activity" LED, active low
LED_SERIAL_PIN ?= 14
# --------------- esp-link version ---------------
# This queries git to produce a version string like "esp-link v0.9.0 2015-06-01 34bc76"
@ -111,48 +157,6 @@ SHA := $(shell if git diff --quiet HEAD; then git rev-parse --short HEAD | c
else echo "development"; fi)
VERSION ?=esp-link $(BRANCH) - $(DATE) - $(SHA)
# --------------- esp-link config options ---------------
# If CHANGE_TO_STA is set to "yes" the esp-link module will switch to station mode
# once successfully connected to an access point. Else it will stay in AP+STA mode.
CHANGE_TO_STA ?= yes
# --------------- esphttpd config options ---------------
# If GZIP_COMPRESSION is set to "yes" then the static css, js, and html files will be compressed
# with gzip before added to the espfs image and will be served with gzip Content-Encoding header.
# This could speed up the downloading of these files, but might break compatibility with older
# web browsers not supporting gzip encoding because Accept-Encoding is simply ignored.
# Enable this option if you have large static files to serve (for e.g. JQuery, Twitter bootstrap)
# If you have text based static files with different extensions what you want to serve compressed
# then you will need to add the extension to the following places:
# - Add the extension to this Makefile at the webpages.espfs target to the find command
# - Add the extension to the gzippedFileTypes array in the user/httpd.c file
#
# Adding JPG or PNG files (and any other compressed formats) is not recommended, because GZIP
# compression does not work effectively on compressed files.
#Static gzipping is disabled by default.
GZIP_COMPRESSION ?= 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/
# 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 -------------
# Output directors to store intermediate compiled files
# relative to the project directory
BUILD_BASE = build
@ -244,6 +248,14 @@ Q := @
vecho := @echo
endif
ifneq ($(strip $(STA_SSID)),)
CFLAGS += -DSTA_SSID="$(STA_SSID)"
endif
ifneq ($(strip $(STA_PASS)),)
CFLAGS += -DSTA_PASS="$(STA_PASS)"
endif
ifeq ("$(GZIP_COMPRESSION)","yes")
CFLAGS += -DGZIP_COMPRESSION
endif
@ -364,6 +376,10 @@ ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes")
$(Q) for file in `find html_compressed -type f -name "*.css"`; do \
java -jar tools/$(YUI-COMPRESSOR) $$file -o $$file; \
done
endif
ifeq (,$(findstring mqtt,$(MODULES)))
$(Q) rm -rf html_compressed/mqtt.html
$(Q) rm -rf html_compressed/mqtt.js
endif
$(Q) for file in `find html_compressed -type f -name "*.htm*"`; do \
cat html_compressed/head- $$file >$${file}-; \

@ -10,66 +10,20 @@
<Platform>ARM</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{A92F0CAA-F89B-4F78-AD2A-A042429BD87F}</ProjectGuid>
<Keyword>MakeFileProj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup>
<ConfigurationType>Makefile</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<NMakeOutput />
<NMakePreprocessorDefinitions>__ets__;_STDINT_H;ICACHE_FLASH;__MINGW32__;__WIN32__</NMakePreprocessorDefinitions>
<NMakeIncludeSearchPath>.\rest;.\esp-link;.\mqtt;.\cmd;.\serial;.\user;.\espfs;.\httpd;.\include;..\esp_iot_sdk_v1.3.0\include;..\xtensa-lx106-elf\xtensa-lx106-elf\include;c:\tools\mingw64\x86_64-w64-mingw32\include;c:\tools\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.3\include</NMakeIncludeSearchPath>
<ExecutablePath />
<ReferencePath />
<LibraryPath />
<LibraryWPath />
<ExcludePath />
<NMakeOutput />
<OutDir>bin</OutDir>
<IntDir>build</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<NMakeBuildCommandLine>espmake all wiflash</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>espmake clean all</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>espmake clean</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<NMakeBuildCommandLine>espmake clean all wiflash</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>espmake clean all</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>espmake clean</NMakeCleanCommandLine>
</PropertyGroup>
<ItemDefinitionGroup>
<BuildLog>
<Path />
</BuildLog>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="espfs\mkespfsimage\Makefile" />
<None Include="espfs\mkespfsimage\mman-win32\config.mak" />
<None Include="espfs\mkespfsimage\mman-win32\configure" />
<None Include="espfs\mkespfsimage\mman-win32\Makefile" />
<None Include="espmake.cmd" />
<None Include="Makefile" />
<None Include="wiflash" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="cmd\cmd.c" />
<ClCompile Include="cmd\handlers.c" />
<ClCompile Include="esp-link\cgi.c" />
<ClCompile Include="esp-link\cgiflash.c" />
<ClCompile Include="esp-link\cgimqtt.c" />
<ClCompile Include="esp-link\cgipins.c" />
<ClCompile Include="esp-link\cgitcp.c" />
<ClCompile Include="esp-link\cgiwifi.c" />
<ClCompile Include="esp-link\config.c" />
<ClCompile Include="esp-link\log.c" />
<ClCompile Include="esp-link\main.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="esp-link\status.c" />
<ClCompile Include="espfs\espfs.c" />
<ClCompile Include="espfs\mkespfsimage\main.c" />
<ClCompile Include="espfs\mkespfsimage\mman-win32\mman.c" />
@ -78,44 +32,31 @@
<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_cmd.c" />
<ClCompile Include="mqtt\mqtt_msg.c" />
<ClCompile Include="mqtt\proto.c" />
<ClCompile Include="mqtt\queue.c" />
<ClCompile Include="mqtt\ringbuf.c" />
<ClCompile Include="mqtt\pktbuf.c" />
<ClCompile Include="rest\rest.c" />
<ClCompile Include="serial\console.c" />
<ClCompile Include="serial\crc16.c" />
<ClCompile Include="serial\serbridge.c" />
<ClCompile Include="serial\serled.c" />
<ClCompile Include="serial\slip.c" />
<ClCompile Include="serial\uart.c" />
<ClCompile Include="esp-link\cgi.c" />
<ClCompile Include="esp-link\cgiflash.c" />
<ClCompile Include="esp-link\cgipins.c" />
<ClCompile Include="esp-link\cgitcp.c" />
<ClCompile Include="esp-link\cgiwifi.c" />
<ClCompile Include="esp-link\config.c" />
<ClCompile Include="esp-link\log.c" />
<ClCompile Include="esp-link\status.c" />
<ClCompile Include="esp-link\main.c" />
<ClCompile Include="user\cgi.c" />
<ClCompile Include="user\cgiflash.c" />
<ClCompile Include="user\cgipins.c" />
<ClCompile Include="user\cgitcp.c" />
<ClCompile Include="user\cgiwifi.c" />
<ClCompile Include="user\config.c" />
<ClCompile Include="user\log.c" />
<ClCompile Include="user\status.c" />
<ClCompile Include="user\user_main.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="cmd\cmd.h" />
<ClInclude Include="esp-link\cgi.h" />
<ClInclude Include="esp-link\cgiflash.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="esp-link\cgipins.h" />
<ClInclude Include="esp-link\cgitcp.h" />
<ClInclude Include="esp-link\cgiwifi.h" />
<ClInclude Include="esp-link\config.h" />
<ClInclude Include="esp-link\log.h" />
<ClInclude Include="esp-link\mqtt_client.h" />
<ClInclude Include="esp-link\status.h" />
<ClInclude Include="espfs\espfs.h" />
<ClInclude Include="espfs\espfsformat.h" />
<ClInclude Include="espfs\mkespfsimage\mman-win32\mman.h" />
@ -127,34 +68,89 @@
<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_cmd.h" />
<ClInclude Include="mqtt\mqtt_msg.h" />
<ClInclude Include="mqtt\proto.h" />
<ClInclude Include="mqtt\queue.h" />
<ClInclude Include="mqtt\ringbuf.h" />
<ClInclude Include="mqtt\pktbuf.h" />
<ClInclude Include="rest\rest.h" />
<ClInclude Include="serial\console.h" />
<ClInclude Include="serial\crc16.h" />
<ClInclude Include="serial\serbridge.h" />
<ClInclude Include="serial\serled.h" />
<ClInclude Include="serial\slip.h" />
<ClInclude Include="serial\uart.h" />
<ClInclude Include="esp-link\cgi.h" />
<ClInclude Include="esp-link\cgiflash.h" />
<ClInclude Include="esp-link\cgipins.h" />
<ClInclude Include="esp-link\cgitcp.h" />
<ClInclude Include="esp-link\cgiwifi.h" />
<ClInclude Include="esp-link\config.h" />
<ClInclude Include="esp-link\log.h" />
<ClInclude Include="esp-link\status.h" />
<ClInclude Include="user\cgi.h" />
<ClInclude Include="user\cgiflash.h" />
<ClInclude Include="user\cgipins.h" />
<ClInclude Include="user\cgitcp.h" />
<ClInclude Include="user\cgiwifi.h" />
<ClInclude Include="user\config.h" />
<ClInclude Include="user\log.h" />
<ClInclude Include="user\status.h" />
</ItemGroup>
<ItemGroup>
<None Include="BOARDS.md" />
<None Include="espmake.cmd" />
<None Include="FLASH.md" />
<None Include="html\console.html" />
<None Include="html\console.js" />
<None Include="html\head-" />
<None Include="html\home.html" />
<None Include="html\jl-400x110.png-" />
<None Include="html\log.html" />
<None Include="html\mqtt.html" />
<None Include="html\mqtt.js" />
<None Include="html\pure.css" />
<None Include="html\style.css" />
<None Include="html\ui.js" />
<None Include="html\wifi\wifi.html" />
<None Include="html\wifi\wifi.js" />
<None Include="Makefile" />
<None Include="README.md" />
<None Include="wiflash" />
</ItemGroup>
<ItemGroup>
<Text Include="esp-link.log" />
<Text Include="LICENSE.txt" />
</ItemGroup>
<ItemGroup>
<Image Include="html\favicon.ico" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{A92F0CAA-F89B-4F78-AD2A-A042429BD87F}</ProjectGuid>
<Keyword>MakeFileProj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup>
<ConfigurationType>Makefile</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<NMakeOutput />
<NMakePreprocessorDefinitions>__ets__;_STDINT_H;ICACHE_FLASH;__MINGW32__;__WIN32__</NMakePreprocessorDefinitions>
<NMakeIncludeSearchPath>.\rest;.\esp-link;.\mqtt;.\cmd;.\serial;.\user;.\espfs;.\httpd;.\include;..\esp_iot_sdk_v1.3.0\include;..\xtensa-lx106-elf\xtensa-lx106-elf\include;c:\tools\mingw64\x86_64-w64-mingw32\include;c:\tools\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.3\include</NMakeIncludeSearchPath>
<ExecutablePath />
<ReferencePath />
<LibraryPath />
<LibraryWPath />
<ExcludePath />
<NMakeOutput />
<OutDir>bin</OutDir>
<IntDir>build</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<NMakeBuildCommandLine>espmake all wiflash</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>espmake clean all</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>espmake clean</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<NMakeBuildCommandLine>espmake clean all wiflash</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>espmake clean all</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>espmake clean</NMakeCleanCommandLine>
</PropertyGroup>
<ItemDefinitionGroup>
<BuildLog>
<Path />
</BuildLog>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

@ -153,7 +153,9 @@ int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) {
"{\"menu\": [\"Home\", \"/home.html\", "
"\"Wifi\", \"/wifi/wifi.html\","
"\"\xC2\xB5" "C Console\", \"/console.html\", "
#ifdef MQTT
"\"REST/MQTT\", \"/mqtt.html\","
#endif
"\"Debug log\", \"/log.html\" ],\n"
" \"version\": \"%s\" }", esp_link_version);
httpdSend(connData, buff, -1);

@ -1,6 +1,5 @@
// Copyright 2015 by Thorsten von Eicken, see LICENSE.txt
// // TCP Client settings
#ifdef MQTT
#include <esp8266.h>
#include "cgi.h"
#include "config.h"
@ -175,3 +174,4 @@ int ICACHE_FLASH_ATTR cgiMqtt(HttpdConnData *connData) {
return HTTPD_CGI_DONE;
}
}
#endif // MQTT

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

@ -162,8 +162,9 @@ void ICACHE_FLASH_ATTR dumpMem(void *addr, int len) {
int off = 0;
while (off < len) {
os_printf("%p ", a);
for (int i=0; i<16 && off+i<len; i++)
for (int i = 0; i < 16 && off + i < len; i++) {
os_printf(" %02x", a[i]);
}
os_printf(" ");
for (int i=0; i<16 && off<len; i++,off++,a++)
os_printf("%c", *a > 0x20 && *a < 0x3f ? *a : '.');

@ -30,8 +30,6 @@
#include "log.h"
#include <gpio.h>
//#define SHOW_HEAP_USE
/*
This is the main url->function dispatching data struct.
In short, it's a struct with various URLs plus their handlers. The handlers can
@ -65,7 +63,9 @@ HttpdBuiltInUrl builtInUrls[] = {
{ "/wifi/special", cgiWiFiSpecial, NULL },
{ "/pins", cgiPins, NULL },
{ "/tcpclient", cgiTcp, NULL },
#ifdef MQTT
{ "/mqtt", cgiMqtt, NULL },
#endif
{ "*", cgiEspFsHook, NULL }, //Catch-all cgi function for the filesystem
{ NULL, NULL, NULL }
@ -79,8 +79,9 @@ static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) {
}
#endif
void user_rf_pre_init(void) {
}
# define VERS_STR_STR(V) #V
# define VERS_STR(V) VERS_STR_STR(V)
char* esp_link_version = VERS_STR(VERSION);
// address of espfs binary blob
extern uint32_t _binary_espfs_img_start;
@ -93,13 +94,14 @@ static char *flash_maps[] = {
"2MB:1024/1024", "4MB:1024/1024"
};
# define VERS_STR_STR(V) #V
# define VERS_STR(V) VERS_STR_STR(V)
char* esp_link_version = VERS_STR(VERSION);
extern void app_init(void);
extern void mqtt_client_init(void);
void user_rf_pre_init(void) {
//default is enabled
system_set_os_print(DEBUG_SDK);
}
// Main routine to initialize esp-link.
void user_init(void) {
// get the flash config so we know how to init things
@ -115,11 +117,33 @@ void user_init(void) {
os_delay_us(10000L);
os_printf("\n\n** %s\n", esp_link_version);
os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*");
#if defined(STA_SSID) && defined(STA_PASS)
int x = wifi_get_opmode() & 0x3;
if (x == 2) {
struct station_config stconf;
wifi_station_get_config(&stconf);
if (os_strlen((char*)stconf.ssid) == 0 && os_strlen((char*)stconf.password) == 0) {
os_strncpy((char*)stconf.ssid, VERS_STR(STA_SSID), 32);
os_strncpy((char*)stconf.password, VERS_STR(STA_PASS), 64);
#ifdef CGIWIFI_DBG
os_printf("Wifi pre-config trying to connect to AP %s pw %s\n", (char*)stconf.ssid, (char*)stconf.password);
#endif
wifi_set_opmode(3);
stconf.bssid_set = 0;
wifi_station_set_config(&stconf);
}
}
#endif
// Status LEDs
statusInit();
serledInit();
// Wifi
wifiInit();
// init the flash filesystem with the html stuff
espFsInit(&_binary_espfs_img_start);
//EspFsInitResult res = espFsInit(&_binary_espfs_img_start);
@ -145,8 +169,9 @@ void user_init(void) {
fid & 0xff, (fid&0xff00)|((fid>>16)&0xff));
os_printf("** esp-link ready\n");
#ifdef MQTT
mqtt_client_init();
#endif
app_init();
}

@ -1,40 +1,145 @@
#ifdef MQTT
#include <esp8266.h>
#include "cgiwifi.h"
#include "config.h"
#include "mqtt.h"
#ifdef MQTTCLIENT_DBG
#define DBG_MQTTCLIENT(format, ...) os_printf(format, ## __VA_ARGS__)
#else
#define DBG_MQTTCLIENT(format, ...) do { } while(0)
#endif
MQTT_Client mqttClient;
char* statusTopicStr;
static char* onlineMsgStr;
static ETSTimer mqttTimer;
static MqttCallback connected_cb;
static MqttCallback disconnected_cb;
static MqttCallback published_cb;
static MqttDataCallback data_cb;
static int once = 0;
static void ICACHE_FLASH_ATTR
mqttTimerCb(void *arg)
{
if (once++ > 0) return;
if (flashConfig.mqtt_enable)
MQTT_Connect(&mqttClient);
//MQTT_Subscribe(&mqttClient, "system/time", 0);
void ICACHE_FLASH_ATTR
mqttConnectedCb(uint32_t *args) {
MQTT_Client* client = (MQTT_Client*)args;
DBG_MQTTCLIENT("MQTT Client: Connected\n");
MQTT_Subscribe(client, "system/time", 0);
MQTT_Publish(client, "announce/all", onlineMsgStr, 0, 0);
if (connected_cb)
connected_cb(args);
}
void ICACHE_FLASH_ATTR
mqttDisconnectedCb(uint32_t *args) {
// MQTT_Client* client = (MQTT_Client*)args;
DBG_MQTTCLIENT("MQTT Client: Disconnected\n");
if (disconnected_cb)
disconnected_cb(args);
}
void ICACHE_FLASH_ATTR
mqttPublishedCb(uint32_t *args) {
// MQTT_Client* client = (MQTT_Client*)args;
DBG_MQTTCLIENT("MQTT Client: Published\n");
if (published_cb)
published_cb(args);
}
void ICACHE_FLASH_ATTR
mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len) {
// MQTT_Client* client = (MQTT_Client*)args;
char *topicBuf = (char*)os_zalloc(topic_len + 1);
char *dataBuf = (char*)os_zalloc(data_len + 1);
os_memcpy(topicBuf, topic, topic_len);
topicBuf[topic_len] = 0;
os_memcpy(dataBuf, data, data_len);
dataBuf[data_len] = 0;
DBG_MQTTCLIENT("MQTT Client: Received topic: %s, data: %s\n", topicBuf, dataBuf);
os_free(topicBuf);
os_free(dataBuf);
if (data_cb)
data_cb(args, topic, topic_len, data, data_len);
}
void ICACHE_FLASH_ATTR
wifiStateChangeCb(uint8_t status)
{
if (status == wifiGotIP) {
os_timer_disarm(&mqttTimer);
os_timer_setfn(&mqttTimer, mqttTimerCb, NULL);
os_timer_arm(&mqttTimer, 200, 0);
if (flashConfig.mqtt_enable) {
if (status == wifiGotIP && mqttClient.connState != TCP_CONNECTING) {
MQTT_Connect(&mqttClient);
}
else if (status == wifiIsDisconnected && mqttClient.connState == TCP_CONNECTING) {
MQTT_Disconnect(&mqttClient);
}
}
}
// initialize the custom stuff that goes beyond esp-link
void ICACHE_FLASH_ATTR
mqtt_client_init()
{
MQTT_Init(&mqttClient, flashConfig.mqtt_host, flashConfig.mqtt_port, 0,
flashConfig.mqtt_timeout, flashConfig.mqtt_clientid,
flashConfig.mqtt_username, flashConfig.mqtt_password,
if (flashConfig.mqtt_enable) {
MQTT_Init(&mqttClient, flashConfig.mqtt_host, flashConfig.mqtt_port, 0, flashConfig.mqtt_timeout,
flashConfig.mqtt_clientid, flashConfig.mqtt_username, flashConfig.mqtt_password,
flashConfig.mqtt_keepalive);
if (flashConfig.mqtt_status_enable) {
// removed client_id concat for now until a better solution is devised
// statusTopicStr = (char*)os_zalloc(strlen(flashConfig.mqtt_clientid) + strlen(flashConfig.mqtt_status_topic) + 2);
// os_strcpy(statusTopicStr, flashConfig.mqtt_clientid);
// os_strcat(statusTopicStr, "/");
statusTopicStr = (char*)os_zalloc(strlen(flashConfig.mqtt_status_topic) + 1);
os_strcpy(statusTopicStr, flashConfig.mqtt_status_topic);
}
char* onlineMsg = " is online";
onlineMsgStr = (char*)os_zalloc(strlen(flashConfig.mqtt_clientid) + strlen(onlineMsg) + 1);
os_strcpy(onlineMsgStr, flashConfig.mqtt_clientid);
os_strcat(onlineMsgStr, onlineMsg);
char* offlineMsg = " is offline";
char* offlineMsgStr = (char*)os_zalloc(strlen(flashConfig.mqtt_clientid) + strlen(offlineMsg) + 1);
os_strcpy(offlineMsgStr, flashConfig.mqtt_clientid);
os_strcat(offlineMsgStr, offlineMsg);
char* lwt = "/lwt";
char *lwtMsgStr = (char*)os_zalloc(strlen(flashConfig.mqtt_clientid) + strlen(lwt) + 1);
os_strcpy(lwtMsgStr, flashConfig.mqtt_clientid);
os_strcat(lwtMsgStr, lwt);
MQTT_InitLWT(&mqttClient, lwtMsgStr, offlineMsg, 0, 0);
MQTT_OnConnected(&mqttClient, mqttConnectedCb);
MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb);
MQTT_OnPublished(&mqttClient, mqttPublishedCb);
MQTT_OnData(&mqttClient, mqttDataCb);
}
wifiAddStateChangeCb(wifiStateChangeCb);
}
void ICACHE_FLASH_ATTR
mqtt_client_on_connected(MqttCallback connectedCb) {
connected_cb = connectedCb;
}
void ICACHE_FLASH_ATTR
mqtt_client_on_disconnected(MqttCallback disconnectedCb) {
disconnected_cb = disconnectedCb;
}
void ICACHE_FLASH_ATTR
mqtt_client_on_published(MqttCallback publishedCb) {
published_cb = publishedCb;
}
void ICACHE_FLASH_ATTR
mqtt_client_on_data(MqttDataCallback dataCb) {
data_cb = dataCb;
}
#endif // MQTT

@ -1,9 +1,15 @@
#ifdef MQTT
#ifndef MQTT_CLIENT_H
#define MQTT_CLIENT_H
#include "mqtt.h"
extern MQTT_Client mqttClient;
extern char* statusTopicStr;
void mqtt_client_init();
void mqtt_client_on_connected(MqttCallback connectedCb);
void mqtt_client_on_disconnected(MqttCallback disconnectedCb);
void mqtt_client_on_published(MqttCallback publishedCb);
void mqtt_client_on_data(MqttDataCallback dataCb);
#endif
#endif //MQTT_CLIENT_H
#endif // MQTT

@ -4,10 +4,46 @@
#include "config.h"
#include "serled.h"
#include "cgiwifi.h"
#include "mqtt.h"
#ifdef MQTT
#include "mqtt.h"
#include "mqtt_client.h"
extern MQTT_Client mqttClient;
//===== MQTT Status update
// Every minute...
#define MQTT_STATUS_INTERVAL (60*1000)
static ETSTimer mqttStatusTimer;
int ICACHE_FLASH_ATTR
mqttStatusMsg(char *buf) {
sint8 rssi = wifi_station_get_rssi();
if (rssi > 0) rssi = 0; // not connected or other error
//os_printf("timer rssi=%d\n", rssi);
// compose MQTT message
return os_sprintf(buf,
"{\"rssi\":%d, \"heap_free\":%ld}",
rssi, (unsigned long)system_get_free_heap_size());
}
// Timer callback to send an RSSI update to a monitoring system
static void ICACHE_FLASH_ATTR mqttStatusCb(void *v) {
if (!flashConfig.mqtt_status_enable || os_strlen(flashConfig.mqtt_status_topic) == 0 ||
mqttClient.connState != MQTT_CONNECTED)
return;
char buf[128];
mqttStatusMsg(buf);
MQTT_Publish(&mqttClient, statusTopicStr, buf, 1, 0);
}
#endif // MQTT
//===== "CONN" LED status indication
static ETSTimer ledTimer;
@ -68,38 +104,6 @@ void ICACHE_FLASH_ATTR statusWifiUpdate(uint8_t state) {
os_timer_arm(&ledTimer, 500, 0);
}
//===== MQTT Status update
// Every minute...
#define MQTT_STATUS_INTERVAL (60*1000)
static ETSTimer mqttStatusTimer;
int ICACHE_FLASH_ATTR
mqttStatusMsg(char *buf) {
sint8 rssi = wifi_station_get_rssi();
if (rssi > 0) rssi = 0; // not connected or other error
//os_printf("timer rssi=%d\n", rssi);
// compose MQTT message
return os_sprintf(buf,
"{\"rssi\":%d, \"heap_free\":%ld}",
rssi, (unsigned long)system_get_free_heap_size());
}
// Timer callback to send an RSSI update to a monitoring system
static void ICACHE_FLASH_ATTR mqttStatusCb(void *v) {
if (!flashConfig.mqtt_status_enable || os_strlen(flashConfig.mqtt_status_topic) == 0 ||
mqttClient.connState != MQTT_CONNECTED)
return;
char buf[128];
mqttStatusMsg(buf);
MQTT_Publish(&mqttClient, flashConfig.mqtt_status_topic, buf, 1, 0);
//espconn_disconnect(mqttClient.pCon);
}
//===== Init status stuff
void ICACHE_FLASH_ATTR statusInit(void) {
@ -115,9 +119,11 @@ void ICACHE_FLASH_ATTR statusInit(void) {
os_timer_setfn(&ledTimer, ledTimerCb, NULL);
os_timer_arm(&ledTimer, 2000, 0);
#ifdef MQTT
os_timer_disarm(&mqttStatusTimer);
os_timer_setfn(&mqttStatusTimer, mqttStatusCb, NULL);
os_timer_arm(&mqttStatusTimer, MQTT_STATUS_INTERVAL, 1); // recurring timer
#endif // MQTT
}

@ -90,6 +90,7 @@
</div>
</div>
<script src="mqtt.js"></script>
<script type="text/javascript">
onLoad(function() {
fetchMqtt();

@ -0,0 +1,76 @@
//===== MQTT cards
function changeMqtt(e) {
e.preventDefault();
var url = "mqtt?1=1";
var i, inputs = document.querySelectorAll('#mqtt-form input');
for (i = 0; i < inputs.length; i++) {
if (inputs[i].type != "checkbox")
url += "&" + inputs[i].name + "=" + inputs[i].value;
};
hideWarning();
var cb = $("#mqtt-button");
addClass(cb, 'pure-button-disabled');
ajaxSpin("POST", url, function (resp) {
showNotification("MQTT updated");
removeClass(cb, 'pure-button-disabled');
}, function (s, st) {
showWarning("Error: " + st);
removeClass(cb, 'pure-button-disabled');
window.setTimeout(fetchMqtt, 100);
});
}
function displayMqtt(data) {
Object.keys(data).forEach(function (v) {
el = $("#" + v);
if (el != null) {
if (el.nodeName === "INPUT") el.value = data[v];
else el.innerHTML = data[v];
return;
}
el = document.querySelector('input[name="' + v + '"]');
if (el != null) {
if (el.type == "checkbox") el.checked = data[v] > 0;
else el.value = data[v];
}
});
$("#mqtt-spinner").setAttribute("hidden", "");
$("#mqtt-status-spinner").setAttribute("hidden", "");
$("#mqtt-form").removeAttribute("hidden");
$("#mqtt-status-form").removeAttribute("hidden");
var i, inputs = $("input");
for (i = 0; i < inputs.length; i++) {
if (inputs[i].type == "checkbox")
inputs[i].onclick = function () { console.log(this); setMqtt(this.name, this.checked) };
}
}
function fetchMqtt() {
ajaxJson("GET", "/mqtt", displayMqtt, function () {
window.setTimeout(fetchMqtt, 1000);
});
}
function changeMqttStatus(e) {
e.preventDefault();
var v = document.querySelector('input[name="mqtt-status-topic"]').value;
ajaxSpin("POST", "/mqtt?mqtt-status-topic=" + v, function () {
showNotification("MQTT status settings updated");
}, function (s, st) {
showWarning("Error: " + st);
window.setTimeout(fetchMqtt, 100);
});
}
function setMqtt(name, v) {
ajaxSpin("POST", "/mqtt?" + name + "=" + (v ? 1 : 0), function () {
var n = name.replace("-enable", "");
showNotification(n + " is now " + (v ? "enabled" : "disabled"));
}, function () {
showWarning("Enable/disable failed");
window.setTimeout(fetchMqtt, 100);
});
}

@ -355,81 +355,3 @@ function setPins(v, name) {
window.setTimeout(fetchPins, 100);
});
}
//===== MQTT cards
function changeMqtt(e) {
e.preventDefault();
var url = "mqtt?1=1";
var i, inputs = document.querySelectorAll('#mqtt-form input');
for (i=0; i<inputs.length; i++) {
if (inputs[i].type != "checkbox")
url += "&" + inputs[i].name + "=" + inputs[i].value;
};
hideWarning();
var cb = $("#mqtt-button");
addClass(cb, 'pure-button-disabled');
ajaxSpin("POST", url, function(resp) {
showNotification("MQTT updated");
removeClass(cb, 'pure-button-disabled');
}, function(s, st) {
showWarning("Error: "+st);
removeClass(cb, 'pure-button-disabled');
window.setTimeout(fetchMqtt, 100);
});
}
function displayMqtt(data) {
Object.keys(data).forEach(function(v) {
el = $("#" + v);
if (el != null) {
if (el.nodeName === "INPUT") el.value = data[v];
else el.innerHTML = data[v];
return;
}
el = document.querySelector('input[name="' + v + '"]');
if (el != null) {
if (el.type == "checkbox") el.checked = data[v] > 0;
else el.value = data[v];
}
});
$("#mqtt-spinner").setAttribute("hidden", "");
$("#mqtt-status-spinner").setAttribute("hidden", "");
$("#mqtt-form").removeAttribute("hidden");
$("#mqtt-status-form").removeAttribute("hidden");
var i, inputs = $("input");
for (i=0; i<inputs.length; i++) {
if (inputs[i].type == "checkbox")
inputs[i].onclick = function() { console.log(this); setMqtt(this.name, this.checked) };
}
}
function fetchMqtt() {
ajaxJson("GET", "/mqtt", displayMqtt, function() {
window.setTimeout(fetchMqtt, 1000);
});
}
function changeMqttStatus(e) {
e.preventDefault();
var v = document.querySelector('input[name="mqtt-status-topic"]').value;
ajaxSpin("POST", "/mqtt?mqtt-status-topic=" + v, function() {
showNotification("MQTT status settings updated");
}, function(s, st) {
showWarning("Error: "+st);
window.setTimeout(fetchMqtt, 100);
});
}
function setMqtt(name, v) {
ajaxSpin("POST", "/mqtt?" + name + "=" + (v ? 1 : 0), function() {
var n = name.replace("-enable", "");
showNotification(n + " is now " + (v ? "enabled" : "disabled"));
}, function() {
showWarning("Enable/disable failed");
window.setTimeout(fetchMqtt, 100);
});
}

@ -36,10 +36,22 @@ void ets_timer_setfn(ETSTimer *t, ETSTimerFunc *fn, void *parg);
void ets_update_cpu_frequency(int freqmhz);
int os_printf(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
#ifdef SDK_DBG
#define DEBUG_SDK true
#else
#define DEBUG_SDK false
#endif
int os_snprintf(char *str, size_t size, const char *format, ...) __attribute__((format(printf, 3, 4)));
int os_printf_plus(const char *format, ...) __attribute__((format(printf, 1, 2)));
#undef os_printf
#define os_printf(format, ...) \
system_set_os_print(true); \
os_printf_plus(format, ## __VA_ARGS__); \
system_set_os_print(DEBUG_SDK); // int os_printf(const char *format, ...)
// memory allocation functions are "different" due to memory debugging functionality
// added in SDK 1.4.0
void vPortFree(void *ptr, char * file, int line);

@ -5,7 +5,9 @@
#include <_mingw.h>
#endif
#undef SHOW_HEAP_USE
#define DEBUGIP
#define SDK_DBG
#define CMD_DBG
#undef ESPFS_DBG

@ -1,12 +1,6 @@
// Copyright 2015 by Thorsten von Eicken, see LICENSE.txt
#include "espmissingincludes.h"
#include "c_types.h"
#include "user_interface.h"
#include "espconn.h"
#include "mem.h"
#include "osapi.h"
#include "gpio.h"
#include "esp8266.h"
#include "uart.h"
#include "crc16.h"

@ -17,10 +17,7 @@
* ----------------------------------------------------------------------------
* Heavily modified and enhanced by Thorsten von Eicken in 2015
*/
#include "espmissingincludes.h"
#include "ets_sys.h"
#include "osapi.h"
#include "user_interface.h"
#include "esp8266.h"
#include "uart.h"
#ifdef UART_DBG

@ -1,64 +1,7 @@
#include <esp8266.h>
#include "cgiwifi.h"
#include "mqtt.h"
#include <config.h>
// initialize the custom stuff that goes beyond esp-link
void app_init() {
}
#if 0
MQTT_Client mqttClient;
void ICACHE_FLASH_ATTR
mqttConnectedCb(uint32_t *args) {
MQTT_Client* client = (MQTT_Client*)args;
MQTT_Publish(client, "announce/all", "Hello World!", 0, 0);
}
void ICACHE_FLASH_ATTR
mqttDisconnectedCb(uint32_t *args) {
// MQTT_Client* client = (MQTT_Client*)args;
os_printf("MQTT Disconnected\n");
}
void ICACHE_FLASH_ATTR
mqttTcpDisconnectedCb(uint32_t *args) {
// MQTT_Client* client = (MQTT_Client*)args;
os_printf("MQTT TCP Disconnected\n");
}
void ICACHE_FLASH_ATTR
mqttPublishedCb(uint32_t *args) {
// MQTT_Client* client = (MQTT_Client*)args;
os_printf("MQTT Published\n");
}
void ICACHE_FLASH_ATTR
mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len) {
char *topicBuf = (char*)os_zalloc(topic_len + 1);
char *dataBuf = (char*)os_zalloc(data_len + 1);
// MQTT_Client* client = (MQTT_Client*)args;
os_memcpy(topicBuf, topic, topic_len);
topicBuf[topic_len] = 0;
os_memcpy(dataBuf, data, data_len);
dataBuf[data_len] = 0;
os_printf("Receive topic: %s, data: %s\n", topicBuf, dataBuf);
os_free(topicBuf);
os_free(dataBuf);
}
MQTT_InitConnection(&mqttClient, MQTT_HOST, MQTT_PORT, MQTT_SECURITY);
MQTT_InitClient(&mqttClient, MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, MQTT_KEEPALIVE, MQTT_CLSESSION);
MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0);
MQTT_OnConnected(&mqttClient, mqttConnectedCb);
MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb);
MQTT_OnDisconnected(&mqttClient, mqttTcpDisconnectedCb);
MQTT_OnPublished(&mqttClient, mqttPublishedCb);
MQTT_OnData(&mqttClient, mqttDataCb);
#endif

Loading…
Cancel
Save