pull/205/merge
Alex 9 years ago committed by GitHub
commit 716f1d2793
  1. 49
      .travis.yml
  2. 64
      Makefile
  3. 2
      README.md
  4. 2
      esp-link/cgi.c
  5. 1
      esp-link/cgipins.c
  6. 120
      esp-link/cgitelnet.c
  7. 8
      esp-link/cgitelnet.h
  8. 17
      esp-link/config.c
  9. 9
      esp-link/config.h
  10. 9
      esp-link/main.c
  11. 3
      espmake.cmd
  12. 36
      html/home.html
  13. 19
      html/ui.js
  14. 69
      serial/serbridge.c
  15. 4
      serial/serbridge.h

@ -1,31 +1,28 @@
# Travis-CI file for Esp-Link
language: c
before_install:
- curl -Ls http://s3.voneicken.com/xtensa-lx106-elf-20160330.tgx | tar Jxf -
- curl -Ls http://s3.voneicken.com/esp_iot_sdk_v2.0.0.p1.tgx | tar -C .. -Jxf -
after_script:
# upload to an S3 bucket, requires S3_BUCKET, AWS_ACCESS_KEY_ID and AWS_SECRET_KEY to be set
# in environment using travis' repository settings
- "if [[ -n \"$S3_BUCKET\" && -n \"$AWS_ACCESS_KEY_ID\" ]]; then
echo Uploading *.tgz to $S3_BUCKET;
curl -Ls https://github.com/rlmcpherson/s3gof3r/releases/download/v0.5.0/gof3r_0.5.0_linux_amd64.tar.gz | tar zxf - gof3r_0.5.0_linux_amd64/gof3r;
mv gof3r*/gof3r .;
ls *.tgz | xargs -I {} ./gof3r put -b $S3_BUCKET -k esp-link/{} --acl public-read -p {};
ls *.tgz | xargs -I {} echo \"URL: http://$S3_BUCKET/esp-link/{}\";
fi"
compiler: gcc
env:
- curl -Ls http://s3.voneicken.com/xtensa-lx106-elf-20160330.tgx | tar Jxf -
- curl -Ls http://s3.voneicken.com/esp_iot_sdk_v2.0.0.p1.tgx | tar -C .. -Jxf -
script:
- export XTENSA_TOOLS_ROOT=$PWD/xtensa-lx106-elf/bin/
- export BRANCH=$TRAVIS_BRANCH
#- export SDK_BASE=$PWD/esp_iot_sdk_v2.0.0.p1
- make release
- printenv
- export XTENSA_TOOLS_ROOT=$PWD/xtensa-lx106-elf/bin/
- export BRANCH=$TRAVIS_BRANCH
- echo "Travis Branch is $TRAVIS_BRANCH"
- echo "Travis Tag is $TRAVIS_TAG"
- echo "Travis COMMIT is $TRAVIS_COMMIT"
- echo "Travis COMMIT is $TRAVIS_COMMIT_RANGE"
- echo "Dont forget to set VARIABLES for S3 to function. SEE gof3r README"
- make release
notifications:
email: false
deploy:
overwrite: true
skip_cleanup: true
provider: releases
api_key:
secure: unYyTCLpk1ixcNOyoUwroBqqx0yBhii56IXm57kjo5kl3umf1GRb3FUIE6la+B0njsNwAUNR/uLn6wF4FqYTUJzNQZskJDJfZjb53vwuoHaoa5j4K/bWB9zRlQ1XZBTkV48cxz8Ef2KyNduK2IciOHwsw3LQS0em3dpK7oG/20VzELt23Gx8uhBYa+OUzlr3Y+PYPynkwM30YwVQXpCy/GMgEbrcKheGbLTAIp7tms0KDAvbb98U0BI3tWBckE5GzAYYAmrXgyDXtEsU/poCMqUj/lpPl1s/5uxGVevTO7XuL4AYtF//AixsM20bPKtIZDHZS9b7JHtVhU655bY2aAfpMgf7xzkKbJkRzeAzT9HucFDjLY48yW4vztdJxBgkAL9d064gTHhThtn4hylZAYpHnqUiM0j4DKil5A0VG2F8EVEqZ7Q2tNzy6aqq37wzTuYXsYpz3mglpazaXXp/LoSurDHy1gz6aB/mdaeBoL3MX1q09LBE8lFGYBILQ8KUkrLyJathxAVvDBnl7nXFv2NWoZ2i7CfXdpCwmOVUN2WhudNfgbbaMung+voTFB+yLq9PBQP5gdP0MKU3zDTB/msmZo1pp/SbnNETCrKAdRtxNI+bxTQ98njAIkxI+7ZiVV8SMNEPyNcWq/6ViYDcIHJMR4Gq0DZunre1voEs1F4=
file_glob: true
file: esp-link-master-*.t*gz
on:
branch: master
repo: fuzzball03/esp-link
condition: "$TRAVIS_BRANCH = master"

@ -52,12 +52,15 @@ ESP_HOSTNAME ?= esp-link
# Base directory for the compiler. Needs a / at the end.
# Typically you'll install https://github.com/pfalcon/esp-open-sdk
# IMPORTANT: use esp-open-sdk `make STANDALONE=n`: the SDK bundled with esp-open-sdk will *not* work!
XTENSA_TOOLS_ROOT ?= $(abspath ../esp-open-sdk/xtensa-lx106-elf/bin)/
XTENSA_TOOLS_ROOT ?= $(abspath ../espressif/xtensa-lx106-elf/bin)/
$(warning Using XTENSA TOOLS from $(XTENSA_TOOLS_ROOT))
# Firmware version
# WARNING: if you change this expect to make code adjustments elsewhere, don't expect
# that esp-link will magically work with a different version of the SDK!!!
SDK_VERS ?= esp_iot_sdk_v2.0.0.p1
# Uncomment this line if you're using windows to build with the C:\espressif structure
# SDK_VERS ?= ESP8266_SDK
# Try to find the firmware manually extracted, e.g. after downloading from Espressif's BBS,
# http://bbs.espressif.com/viewforum.php?f=46
@ -66,16 +69,17 @@ SDK_BASE ?= $(wildcard ../$(SDK_VERS))
# If the firmware isn't there, see whether it got downloaded as part of esp-open-sdk
# This used to work at some point, but is not supported, uncomment if you feel lucky ;-)
#ifeq ($(SDK_BASE),)
#SDK_BASE := $(wildcard $(XTENSA_TOOLS_ROOT)/../../$(SDK_VERS))
#endif
ifeq ($(SDK_BASE),)
SDK_BASE := $(wildcard $(XTENSA_TOOLS_ROOT)/../../$(SDK_VERS))
endif
# Clean up SDK path
SDK_BASE := $(abspath $(SDK_BASE))
$(warning Using SDK from $(SDK_BASE))
# Path to bootloader file
BOOTFILE ?= $(SDK_BASE/bin/boot_v1.6.bin)
BOOTFILE ?= $(SDK_BASE)/bin/boot_v1.6.bin
$(warning Using boot file-> $(BOOTFILE))
# Esptool.py path and port, only used for 1-time serial flashing
# Typically you'll use https://github.com/themadinventor/esptool
@ -127,8 +131,10 @@ GZIP_COMPRESSION ?= yes
# 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_COMPRESSOR_VER ?= htmlcompressor-1.5.3.jar
HTML_COMPRESSOR = tools/$(HTML_COMPRESSOR_VER)
YUI_COMPRESSOR_VER ?= yuicompressor-2.4.8.jar
YUI_COMPRESSOR = tools/$(YUI_COMPRESSOR_VER)
# -------------- End of config options -------------
@ -296,6 +302,13 @@ Q := @
vecho := @echo
endif
#Fix for issues on some windows systems that call non GNU FIND
FIND ?= $(which FIND)
ifeq (,$(findstring system32,$(FIND)))
$(warning Non GNU 'find' called. Trying alternate path /usr/bin/find)
FIND = /usr/bin/find
endif
ifneq ($(strip $(STA_SSID)),)
CFLAGS += -DSTA_SSID="$(STA_SSID)"
endif
@ -387,6 +400,7 @@ $(FW_BASE)/user2.bin: $(USER2_OUT) $(FW_BASE)
$(Q) COMPILE=gcc PATH=$(XTENSA_TOOLS_ROOT):$(PATH) python $(APPGEN_TOOL) $(USER2_OUT) 2 $(ESP_FLASH_MODE) $(ESP_FLASH_FREQ_DIV) $(ESP_SPI_SIZE) 1 >/dev/null
$(Q) rm -f eagle.app.v6.*.bin
$(Q) mv eagle.app.flash.bin $@
@echo "** user2.bin uses $$(stat -c '%s' $@) bytes of" $(ESP_FLASH_MAX) "available"
$(Q) if [ $$(stat -c '%s' $@) -gt $$(( $(ESP_FLASH_MAX) )) ]; then echo "$@ too big!"; false; fi
$(APP_AR): $(OBJ)
@ -406,18 +420,18 @@ baseflash: all
flash: all
$(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash -fs $(ET_FS) -ff $(ET_FF) \
0x00000 "$(SDK_BASE)/bin/boot_v1.5.bin" 0x01000 $(FW_BASE)/user1.bin \
0x00000 "$(BOOTFILE)" 0x01000 $(FW_BASE)/user1.bin \
$(ET_BLANK) $(SDK_BASE)/bin/blank.bin
tools/$(HTML_COMPRESSOR):
$(Q) echo "The jar files in the tools dir are missing, they should be in the source repo"
$(Q) echo "The following commands can be used to fetch them, but the URLs have changed..."
$(Q) echo mkdir -p tools
$(Q) echo "cd tools; wget --no-check-certificate https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI_COMPRESSOR) -O $(YUI_COMPRESSOR)"
$(Q) echo "cd tools; wget --no-check-certificate https://htmlcompressor.googlecode.com/files/$(HTML_COMPRESSOR) -O $(HTML_COMPRESSOR)"
$(Q) echo "cd tools; wget --no-check-certificate https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI_COMPRESSOR_VER) -O $(YUI_COMPRESSOR_VER)"
$(Q) echo "cd tools; wget --no-check-certificate https://htmlcompressor.googlecode.com/files/$(HTML_COMPRESSOR_VER) -O $(HTML_COMPRESSOR_VER)"
ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes")
$(BUILD_BASE)/espfs_img.o: tools/$(HTML_COMPRESSOR)
$(BUILD_BASE)/espfs_img.o: $(HTML_COMPRESSOR)
endif
$(BUILD_BASE)/espfs_img.o: html/ html/wifi/ espfs/mkespfsimage/mkespfsimage
@ -428,38 +442,38 @@ $(BUILD_BASE)/espfs_img.o: html/ html/wifi/ espfs/mkespfsimage/mkespfsimage
$(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 "Compressing assets with htmlcompressor. This may take a while..."
$(Q) java -jar tools/$(HTML_COMPRESSOR) \
$(Q) echo "Compressing assets with htmlcompressor. This may take a while...";
$(Q) java -jar $(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) \
$(Q) java -jar $(HTML_COMPRESSOR) \
-t html --remove-surrounding-spaces max --remove-quotes --remove-intertag-spaces \
-o $(abspath ./html_compressed)/wifi/ \
$(WIFI_PATH)*.html
$(Q) echo "Compressing assets with yui-compressor. This may take a while..."
$(Q) for file in `find html_compressed -type f -name "*.js"`; do \
java -jar tools/$(YUI_COMPRESSOR) $$file --line-break 0 -o $$file; \
done
$(Q) for file in `find html_compressed -type f -name "*.css"`; do \
java -jar tools/$(YUI_COMPRESSOR) $$file -o $$file; \
done
$(Q) java -jar $(YUI_COMPRESSOR) ./html_compressed/*.css -o '.css$:.css'
$(Q) java -jar $(YUI_COMPRESSOR) ./html_compressed/*.js -o '.js$:.js'
$(Q) java -jar $(YUI_COMPRESSOR) ./html_compressed/wifi/*.js -o '.js$:.js'
else
$(Q) cp -r html/head- html_compressed;
$(Q) cp -r html/*.html html_compressed;
$(Q) cp -r html/wifi/*.html html_compressed/wifi;
endif
ifeq (,$(findstring mqtt,$(MODULES)))
$(Q) rm -rf html_compressed/mqtt.html
$(Q) rm -rf html_compressed/mqtt.js
endif
$(Q) for file in `find html_compressed -type f -name "*.htm*"`; do \
$(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) echo "Compressing assets into espfs.img with Gzip. This may take a while..."
$(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 \
espfs.img espfs_img.o; cd ..
@ -483,7 +497,7 @@ release: all
$(Q) egrep -a 'esp-link [a-z0-9.]+ - 201' $(FW_BASE)/user1.bin | cut -b 1-80
$(Q) egrep -a 'esp-link [a-z0-9.]+ - 201' $(FW_BASE)/user2.bin | cut -b 1-80
$(Q) cp $(FW_BASE)/user1.bin $(FW_BASE)/user2.bin $(SDK_BASE)/bin/blank.bin \
"$(SDK_BASE)/bin/boot_v1.6.bin" "$(SDK_BASE)/bin/esp_init_data_default.bin" \
"$(BOOTFILE)" "$(SDK_BASE)/bin/esp_init_data_default.bin" \
wiflash avrflash release/esp-link-$(BRANCH)
$(Q) tar zcf esp-link-$(BRANCH)-$(SHA).tgz -C release esp-link-$(BRANCH)
$(Q) echo "Release file: esp-link-$(BRANCH)-$(SHA).tgz"
@ -494,7 +508,7 @@ docker:
clean:
$(Q) rm -f $(APP_AR)
$(Q) rm -f $(TARGET_OUT)
$(Q) find $(BUILD_BASE) -type f | xargs rm -f
$(Q) $(FIND) $(BUILD_BASE) -type f | xargs rm -f
$(Q) make -C espfs/mkespfsimage/ clean
$(Q) rm -rf $(FW_BASE)
$(Q) rm -f webpages.espfs
@ -502,4 +516,4 @@ ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes")
$(Q) rm -rf html_compressed
endif
$(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir))))
$(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir))))

@ -149,6 +149,8 @@ From there, more advanced steps are:
### Serial bridge
Note that the default ports of 23 & 2323 may be changed via the webinterface.
In order to connect through the esp-link to a microcontroller use port 23. For example,
on linux you can use `nc esp-hostname 23` or `telnet esp-hostname 23`.

@ -190,7 +190,7 @@ int ICACHE_FLASH_ATTR printGlobalInfo(char *buff, int buflen, char *token) {
extern char *esp_link_version; // in user_main.c
int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) {
int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) { //This is where we can modify the navigation that is auto generated
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
char buff[1024];
// don't use jsonHeader so the response does get cached

@ -1,4 +1,3 @@
#include <esp8266.h>
#include "cgi.h"
#include "espfs.h"

@ -0,0 +1,120 @@
#include <esp8266.h>
#include "cgi.h"
#include "config.h"
#include "serbridge.h"
static char *portMode[] = { "open", "disabled", "secure" };
// Cgi to return choice of Telnet ports
int ICACHE_FLASH_ATTR cgiTelnetGet(HttpdConnData *connData) {
char buff[80];
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted
int len;
os_printf("Current telnet ports: port0=%d port1=%d\n",
flashConfig.telnet_port0, flashConfig.telnet_port1);
len = os_sprintf(buff,
"{ \"port0\": \"%d\", \"port1\": \"%d\" }",
flashConfig.telnet_port0, flashConfig.telnet_port1);
jsonHeader(connData, 200);
httpdSend(connData, buff, len);
return HTTPD_CGI_DONE;
}
// Cgi to change choice of Telnet ports
int ICACHE_FLASH_ATTR cgiTelnetSet(HttpdConnData *connData) {
char buf[80];
if (connData->conn==NULL) {
return HTTPD_CGI_DONE; // Connection aborted
}
int8_t ok = 0;
uint16_t port0, port1;
ok |= getUInt16Arg(connData, "port0", &port0);
ok |= getUInt16Arg(connData, "port1", &port1);
if (ok <= 0) { //If we get at least one good value, this should be >= 1
ets_sprintf(buf, "Unable to fetch telnet ports.\n Received: port0=%d port1=%d\n",
flashConfig.telnet_port0, flashConfig.telnet_port1);
os_printf(buf);
errorResponse(connData, 400, buf);
return HTTPD_CGI_DONE;
}
if (ok > 0) {
// fill both port variables from flash or ajax provided value
if (!port0) port0 = flashConfig.telnet_port0;
if (!port1) port1 = flashConfig.telnet_port1;
// check whether ports are different
if (port0 == port1) {
os_sprintf(buf, "Ports cannot be the same.\n Tried to set: port0=%d port1=%d\n",
flashConfig.telnet_port0, flashConfig.telnet_port1);
os_printf(buf);
errorResponse(connData, 400, buf);
return HTTPD_CGI_DONE;
}
// we're good, set flashconfig
flashConfig.telnet_port0 = port0;
flashConfig.telnet_port1 = port1;
os_printf("Telnet ports changed: port0=%d port1=%d\n",
flashConfig.telnet_port0, flashConfig.telnet_port1);
// save to flash
if (configSave()) {
httpdStartResponse(connData, 204);
httpdEndHeaders(connData);
} else {
httpdStartResponse(connData, 500);
httpdEndHeaders(connData);
httpdSend(connData, "Failed to save config", -1);
}
// apply the changes
serbridgeInit();
serbridgeStart(0, flashConfig.telnet_port0, flashDefault.telnet_port0mode);
serbridgeStart(1, flashConfig.telnet_port1, flashDefault.telnet_port1mode);
}
return HTTPD_CGI_DONE;
}
int ICACHE_FLASH_ATTR cgiTelnet(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
if (connData->requestType == HTTPD_METHOD_GET) {
return cgiTelnetGet(connData);
} else if (connData->requestType == HTTPD_METHOD_POST) {
return cgiTelnetSet(connData);
} else {
jsonHeader(connData, 404);
return HTTPD_CGI_DONE;
}
}
static char *portMode2string(int8_t m) { //Should we put this into flash?
if (m < 0 || m > 2) return "?";
return portMode[m];
}
// print various Telnet information into json buffer
int ICACHE_FLASH_ATTR printTelnetSecurity(char *buff) {
int len;
len = os_sprintf(buff,
"{ \"port0mode\": \"%s\", \"port0portnumber\": \"%d\", \"port0pwd\": \"%s\", "
"\"port1mode\": \"%s\", \"port1portnumber\": \"%d\", \"port1pwd\": \"%s\" }",
portMode2string(flashConfig.telnet_port0mode), flashConfig.telnet_port0, flashConfig.telnet_port0pass,
portMode2string(flashConfig.telnet_port1mode), flashConfig.telnet_port1, flashConfig.telnet_port1pass
);
return len;
}

@ -0,0 +1,8 @@
#ifndef CGITELNET_H
#define CGITELNET_H
#include "httpd.h"
int cgiTelnet(HttpdConnData *connData);
#endif // CGITELNET_H

@ -35,6 +35,12 @@ FlashConfig flashDefault = {
.data_bits = EIGHT_BITS,
.parity = NONE_BITS,
.stop_bits = ONE_STOP_BIT,
.telnet_port0 = 23,
.telnet_port1 = 2323,
.telnet_port0mode = 0,
.telnet_port1mode = 0,
.telnet_port0pass = "\0",
.telnet_port1pass = "\0",
};
typedef union {
@ -161,6 +167,17 @@ bool ICACHE_FLASH_ATTR configRestore(void) {
flashConfig.parity = flashDefault.parity;
flashConfig.stop_bits = flashDefault.stop_bits;
}
if (flashConfig.telnet_port0 == 0) {
flashConfig.telnet_port0 = flashDefault.telnet_port0;
flashConfig.telnet_port0mode = flashDefault.telnet_port0mode;
os_memcpy(flashConfig.telnet_port0pass, flashDefault.telnet_port0pass, 32);
}
if (flashConfig.telnet_port1 == 0) {
flashConfig.telnet_port1 = flashDefault.telnet_port1;
flashConfig.telnet_port1mode = flashDefault.telnet_port1mode;
os_memcpy(flashConfig.telnet_port1pass, flashDefault.telnet_port1pass, 32);
}
return true;
}

@ -13,7 +13,7 @@ typedef struct {
char hostname[32]; // if using DHCP
uint32_t staticip, netmask, gateway; // using DHCP if staticip==0
uint8_t log_mode; // UART log debug mode
uint8_t swap_uart; // swap uart0 to gpio 13&15
uint8_t swap_uart; // swap uart0 to gpio 13&15
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
@ -41,8 +41,15 @@ typedef struct {
int8_t data_bits;
int8_t parity;
int8_t stop_bits;
uint16_t telnet_port0, // Telnet port settings
telnet_port1;
int8_t telnet_port0mode,
telnet_port1mode;
char telnet_port0pass[32],
telnet_port1pass[32];
} FlashConfig;
extern FlashConfig flashConfig;
extern FlashConfig flashDefault;
bool configSave(void);
bool configRestore(void);

@ -32,6 +32,7 @@
#include "gpio.h"
#include "cgiservices.h"
#include "web-server.h"
#include "cgitelnet.h"
#ifdef SYSLOG
#include "syslog.h"
@ -96,6 +97,7 @@ HttpdBuiltInUrl builtInUrls[] = {
{ "/services/info", cgiServicesInfo, NULL },
{ "/services/update", cgiServicesSet, NULL },
{ "/pins", cgiPins, NULL },
{ "/telnet", cgiTelnet, NULL},
#ifdef MQTT
{ "/mqtt", cgiMqtt, NULL },
#endif
@ -178,8 +180,11 @@ user_init(void) {
httpdInit(builtInUrls, 80);
WEB_Init();
// init the wifi-serial transparent bridge (port 23)
serbridgeInit(23, 2323);
// init the wifi-serial configurable transparent bridge (port defaults 23&2323)
serbridgeInit();
serbridgeStart(0, flashConfig.telnet_port0, flashDefault.telnet_port0mode);
serbridgeStart(1, flashConfig.telnet_port1, flashDefault.telnet_port1mode);
uart_add_recv_cb(&serbridgeUartCb);
#ifdef SHOW_HEAP_USE
os_timer_disarm(&prHeapTimer);

@ -1,5 +1,6 @@
@echo off
SETLOCAL
REM LOCAL IS NEEDED ELSE WE KEEP ADDING TO WINDOW PATH EACH TIME SCRIPT IS CALLED.
REM remove automatic created obj folder
rd obj /S /Q >nul 2>&1

@ -50,6 +50,38 @@
<a href="https://github.com/jeelabs/esp-link/blob/master/README.md">the online README</a>
for up-to-date help.</p>
</div>
<div class="card">
<h1>Telnet Serial-Bridge</h1>
<p style="margin-bottom:0;">There are two ports available for telnet to use by default: 23 &amp; 2323 <br>
Note - this time, only port0 may be changed &amp; used sucessfully.</p>
<div id="telnet-spinner" class="spinner spinner-small"></div>
<table id="telnet-table" class="pure-table pure-table-horizontal" hidden><tbody>
<tr><td>Current Telnet ports</td><td class="telnet-info"></td></tr>
<tr><td colspan=2 class="popup-target">Telnet port 1:<br>
<div class="click-to-edit telnet-port0">
<span class="edit-off" style="display:block; width:auto;"></span>
<input class="edit-on" maxlength=5 hidden> </input>
<div class="popup">Click to edit!<br>Default port: 23</div>
</div>
</td></tr>
<tr><td colspan=2 class="popup-target">Telnet port 2:<br>
<div class="click-to-edit telnet-port1">
<span class="edit-off" style="display:block; width:auto;"></span>
<input class="edit-on" maxlength=5 hidden> </input>
<div class="popup">Click to edit!<br>Default port: 2323</div>
</div>
</td></tr>
<tr><td colspan=2>Port0 Mode<br>
<div class="click-to-edit telnet-port0mode">
<span class="edit-off" style="display:block; width:auto;"></span>
<select class="edit-on" hidden>
<option value="0">open</option>
<option value="1">password</option>
</select>
</div>
</td></tr>
</tbody></table>
</div>
</div>
<!-- RIGHT COLUMN -->
<div class="pure-u-1 pure-u-md-1-2">
@ -152,9 +184,13 @@
onLoad(function() {
makeAjaxInput("system", "description");
makeAjaxInput("system", "name");
makeAjaxInput("telnet", "port0");
makeAjaxInput("telnet", "port1");
makeAjaxInput("telnet", "port0mode");
fetchPins();
getWifiInfo();
getSystemInfo();
getTelnetInfo();
bnd($("#pinform"), "submit", setPins);
});
</script>

@ -302,6 +302,22 @@ function getWifiInfo() {
function(s, st) { window.setTimeout(getWifiInfo, 1000); });
}
//===== Telnet info
function showTelnetInfo(data) {
Object.keys(data).forEach(function(v) {
setEditToClick("telnet-"+v, data[v]);
});
$("#telnet-spinner").setAttribute("hidden", "");
$("#telnet-table").removeAttribute("hidden");
currAp = data.ssid;
}
function getTelnetInfo() {
ajaxJson('GET', "/telnet", showTelnetInfo,
function(s, st) { window.setTimeout(getTelnetInfo, 1000); });
}
//===== System info
function showSystemInfo(data) {
@ -323,6 +339,8 @@ function makeAjaxInput(klass, field) {
var eon = $(".edit-on", div);
var eoff = $(".edit-off", div)[0];
var url = "/"+klass+"/update?"+field;
//Dirty fix to avoid to seperate name spaces to GET or PUT telnet ports
if (klass == "telnet") { var url = "/"+klass+"?"+field; }
if (eoff === undefined || eon == undefined) return;
@ -383,6 +401,7 @@ function showNotification(text) {
var el = $("#notification");
el.innerHTML = text;
el.removeAttribute('hidden');
window.scrollTo(0, 0); //Uncomment this line so window will scroll up on regular notifications
if (notifTimeout != null) clearTimeout(notifTimeout);
notifTimout = setTimeout(function() {
el.setAttribute('hidden', '');

@ -16,14 +16,14 @@
#define syslog(X1...)
#endif
static struct espconn serbridgeConn1; // plain bridging port
static struct espconn serbridgeConn2; // programming port
static esp_tcp serbridgeTcp1, serbridgeTcp2;
static struct espconn serbridgeConn[2]; // 0 = plain bridging port, 1 = programming port
static esp_tcp serbridgeTcp[2];
static int8_t mcu_reset_pin, mcu_isp_pin;
uint8_t in_mcu_flashing; // for disabling slip during MCU flashing
void (*programmingCB)(char *buffer, short length) = NULL;
void ICACHE_FLASH_ATTR serbridgeCleanup(int ix);
// Connection pool
serbridgeConnData connData[MAX_CONN];
@ -421,7 +421,7 @@ serbridgeConnectCb(void *arg)
connData[i].readytosend = true;
connData[i].conn_mode = cmInit;
// if it's the second port we start out in programming mode
if (conn->proto.tcp->local_port == serbridgeConn2.proto.tcp->local_port)
if (conn->proto.tcp->local_port == serbridgeConn[1].proto.tcp->local_port)
connData[i].conn_mode = cmPGMInit;
espconn_regist_recvcb(conn, serbridgeRecvCb);
@ -470,35 +470,46 @@ serbridgeInitPins()
// Start transparent serial bridge TCP server on specified port (typ. 23)
void ICACHE_FLASH_ATTR
serbridgeInit(int port1, int port2)
serbridgeInit()
{
serbridgeInitPins();
os_memset(connData, 0, sizeof(connData));
os_memset(&serbridgeTcp1, 0, sizeof(serbridgeTcp1));
os_memset(&serbridgeTcp2, 0, sizeof(serbridgeTcp2));
// set-up the primary port for plain bridging
serbridgeConn1.type = ESPCONN_TCP;
serbridgeConn1.state = ESPCONN_NONE;
serbridgeTcp1.local_port = port1;
serbridgeConn1.proto.tcp = &serbridgeTcp1;
espconn_regist_connectcb(&serbridgeConn1, serbridgeConnectCb);
espconn_accept(&serbridgeConn1);
espconn_tcp_set_max_con_allow(&serbridgeConn1, MAX_CONN);
espconn_regist_time(&serbridgeConn1, SER_BRIDGE_TIMEOUT, 0);
// set-up the secondary port for programming
serbridgeConn2.type = ESPCONN_TCP;
serbridgeConn2.state = ESPCONN_NONE;
serbridgeTcp2.local_port = port2;
serbridgeConn2.proto.tcp = &serbridgeTcp2;
espconn_regist_connectcb(&serbridgeConn2, serbridgeConnectCb);
espconn_accept(&serbridgeConn2);
espconn_tcp_set_max_con_allow(&serbridgeConn2, MAX_CONN);
espconn_regist_time(&serbridgeConn2, SER_BRIDGE_TIMEOUT, 0);
os_memset(&serbridgeTcp[0], 0, sizeof(serbridgeTcp[0]));
os_memset(&serbridgeTcp[1], 0, sizeof(serbridgeTcp[1]));
}
// Start transparent serial bridge TCP server on specified port (typ. 23)
void ICACHE_FLASH_ATTR
serbridgeStart(int ix, int port, int mode)
{
if (ix < 0 || ix > 2) // FIXME hardcoded limit
return;
// If we are already initialized, let's clean it up.
if (serbridgeConn[ix].type != 0) {
serbridgeCleanup(ix);
}
if (0 < port && port < 65536 && port != 80) {
serbridgeConn[ix].type = ESPCONN_TCP;
serbridgeConn[ix].state = ESPCONN_NONE;
serbridgeTcp[ix].local_port = port;
serbridgeConn[ix].proto.tcp = &serbridgeTcp[ix];
espconn_regist_connectcb(&serbridgeConn[ix], serbridgeConnectCb);
espconn_accept(&serbridgeConn[ix]);
espconn_tcp_set_max_con_allow(&serbridgeConn[ix], MAX_CONN);
espconn_regist_time(&serbridgeConn[ix], SER_BRIDGE_TIMEOUT, 0);
}
}
void ICACHE_FLASH_ATTR
serbridgeCleanup(int ix)
{
os_memset(&serbridgeTcp[ix], 0, sizeof(serbridgeTcp[ix]));
// Looks like none of the espconn_..() calls in serbridgeStart() needs cleanup here.
}
int ICACHE_FLASH_ATTR serbridgeInMCUFlashing()

@ -31,11 +31,11 @@ typedef struct serbridgeConnData {
} serbridgeConnData;
// port1 is transparent&programming, second port is programming only
void ICACHE_FLASH_ATTR serbridgeInit(int port1, int port2);
void ICACHE_FLASH_ATTR serbridgeInit();
void ICACHE_FLASH_ATTR serbridgeStart(int ix, int port, int mode);
void ICACHE_FLASH_ATTR serbridgeInitPins(void);
void ICACHE_FLASH_ATTR serbridgeUartCb(char *buf, short len);
void ICACHE_FLASH_ATTR serbridgeReset();
int ICACHE_FLASH_ATTR serbridgeInMCUFlashing();
// callback when receiving UART chars when in programming mode

Loading…
Cancel
Save