wifi improvements

v0.9.0
Thorsten von Eicken 10 years ago
parent 57662b0824
commit f3fe029705
  1. 2
      espfs/espfs.c
  2. 2
      html/wifi/connecting.html
  3. 5
      html/wifi/wifi.tpl
  4. 12
      httpd/httpd.c
  5. 2
      serial/uart.h
  6. 4
      user/cgiflash.c
  7. 90
      user/cgiwifi.c
  8. 1
      user/cgiwifi.h
  9. 2
      user/console.c
  10. 42
      user/status.c
  11. 3
      user/user_main.c
  12. 4
      wiflash

@ -176,7 +176,7 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
//Decoder params are stored in 1st byte. //Decoder params are stored in 1st byte.
memcpyAligned(&parm, r->posComp, 1); memcpyAligned(&parm, r->posComp, 1);
r->posComp++; r->posComp++;
os_printf("Heatshrink compressed file; decode parms = %x\n", parm); //os_printf("Heatshrink compressed file; decode parms = %x\n", parm);
dec=heatshrink_decoder_alloc(16, (parm>>4)&0xf, parm&0xf); dec=heatshrink_decoder_alloc(16, (parm>>4)&0xf, parm&0xf);
r->decompData=dec; r->decompData=dec;
#endif #endif

@ -1,5 +1,5 @@
<html><head><title>Connecting... - ESP Link</title> <html><head><title>Connecting... - ESP Link</title>
<link rel="stylesheet" type="text/css" href="style.css"> <link rel="stylesheet" type="text/css" href="/style.css">
<script type="text/javascript" src="140medley.min.js"></script> <script type="text/javascript" src="140medley.min.js"></script>
<script type="text/javascript"> <script type="text/javascript">

@ -28,7 +28,7 @@ function createInputForAp(ap) {
input.id="opt-"+ap.essid; input.id="opt-"+ap.essid;
var label=document.createElement("label"); var label=document.createElement("label");
label.htmlFor="opt-"+ap.essid; label.htmlFor="opt-"+ap.essid;
label.textContent=ap.essid; label.textContent=ap.essid+" ("+ap.rssi+")";
div.appendChild(input); div.appendChild(input);
div.appendChild(rssi); div.appendChild(rssi);
div.appendChild(encrypt); div.appendChild(encrypt);
@ -78,7 +78,8 @@ window.onload=function(e) {
<h1>ESP Link - Wifi Configuration</h1> <h1>ESP Link - Wifi Configuration</h1>
<p> <p>
Current WiFi mode: %WiFiMode% Current WiFi mode: %WiFiMode%<br>
Current network: %currSsid%
</p> </p>
<p> <p>
Note: %WiFiapwarn% Note: %WiFiapwarn%

@ -144,12 +144,12 @@ int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLe
if (line==NULL) return 0; if (line==NULL) return 0;
p=line; p=line;
while(p!=NULL && *p!='\n' && *p!='\r' && *p!=0) { while(p!=NULL && *p!='\n' && *p!='\r' && *p!=0) {
os_printf("findArg: %s\n", p); //os_printf("findArg: %s\n", p);
if (os_strncmp(p, arg, os_strlen(arg))==0 && p[strlen(arg)]=='=') { if (os_strncmp(p, arg, os_strlen(arg))==0 && p[strlen(arg)]=='=') {
p+=os_strlen(arg)+1; //move p to start of value p+=os_strlen(arg)+1; //move p to start of value
e=(char*)os_strstr(p, "&"); e=(char*)os_strstr(p, "&");
if (e==NULL) e=p+os_strlen(p); if (e==NULL) e=p+os_strlen(p);
os_printf("findArg: val %s len %d\n", p, (e-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, "&"); p=(char*)os_strstr(p, "&");
@ -260,7 +260,7 @@ static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) {
conn->priv->sendBuffLen=0; conn->priv->sendBuffLen=0;
if (conn->cgi==NULL) { //Marked for destruction? if (conn->cgi==NULL) { //Marked for destruction?
os_printf("Conn %p is done. Closing.\n", conn->conn); //os_printf("Conn %p is done. Closing.\n", conn->conn);
espconn_disconnect(conn->conn); espconn_disconnect(conn->conn);
httpdRetireConn(conn); httpdRetireConn(conn);
return; //No need to call xmitSendBuff. return; //No need to call xmitSendBuff.
@ -301,7 +301,7 @@ static void ICACHE_FLASH_ATTR httpdProcessRequest(HttpdConnData *conn) {
if (builtInUrls[i].url[os_strlen(builtInUrls[i].url)-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; os_strncmp(builtInUrls[i].url, conn->url, os_strlen(builtInUrls[i].url)-1)==0) match=1;
if (match) { if (match) {
os_printf("Is url index %d\n", i); //os_printf("Is url index %d\n", i);
conn->cgiData=NULL; conn->cgiData=NULL;
conn->cgi=builtInUrls[i].cgiCb; conn->cgi=builtInUrls[i].cgiCb;
conn->cgiArg=builtInUrls[i].cgiArg; conn->cgiArg=builtInUrls[i].cgiArg;
@ -365,7 +365,7 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
if (e==NULL) return; //wtf? if (e==NULL) return; //wtf?
*e=0; //terminate url part *e=0; //terminate url part
os_printf("URL = %s\n", conn->url); os_printf("%s %s\n", HTTPD_METHOD_GET?"GET":"POST", conn->url);
//Parse out the URL part before the GET parameters. //Parse out the URL part before the GET parameters.
conn->getArgs=(char*)os_strstr(conn->url, "?"); conn->getArgs=(char*)os_strstr(conn->url, "?");
if (conn->getArgs!=0) { if (conn->getArgs!=0) {
@ -497,7 +497,7 @@ static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) {
int i; int i;
//Find empty conndata in pool //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); //os_printf("Con req, conn=%p, pool slot %d\n", conn, i);
if (i==MAX_CONN) { if (i==MAX_CONN) {
os_printf("Aiee, conn pool overflow!\n"); os_printf("Aiee, conn pool overflow!\n");
espconn_disconnect(conn); espconn_disconnect(conn);

@ -13,6 +13,8 @@ void ICACHE_FLASH_ATTR uart_init(UartBautRate uart0_br, UartBautRate uart1_br);
// Transmit a buffer of characters on UART0 // Transmit a buffer of characters on UART0
void ICACHE_FLASH_ATTR uart0_tx_buffer(char *buf, uint16 len); void ICACHE_FLASH_ATTR uart0_tx_buffer(char *buf, uint16 len);
void ICACHE_FLASH_ATTR uart0_write_char(char c);
// Add a receive callback function, this is called on the uart receive task each time a chunk // Add a receive callback function, this is called on the uart receive task each time a chunk
// of bytes are received. A small number of callbacks can be added and they are all called // of bytes are received. A small number of callbacks can be added and they are all called
// with all new characters. // with all new characters.

@ -125,8 +125,8 @@ int ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) {
} }
// Write the data // Write the data
os_printf("Writing %d bytes at 0x%05x (%d of %d)\n", connData->post->buffSize, address, //os_printf("Writing %d bytes at 0x%05x (%d of %d)\n", connData->post->buffSize, address,
connData->post->received, connData->post->len); // connData->post->received, connData->post->len);
spi_flash_write(address, (uint32 *)connData->post->buff, connData->post->buffLen); spi_flash_write(address, (uint32 *)connData->post->buff, connData->post->buffLen);
if (connData->post->received == connData->post->len){ if (connData->post->received == connData->post->len){

@ -48,8 +48,9 @@ static ETSTimer resetTimer;
void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) { void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) {
int n; int n;
struct bss_info *bss_link = (struct bss_info *)arg; struct bss_info *bss_link = (struct bss_info *)arg;
os_printf("wifiScanDoneCb %d\n", status);
if (status!=OK) { if (status!=OK) {
os_printf("wifiScanDoneCb status=%d\n", status);
cgiWifiAps.scanInProgress=0; cgiWifiAps.scanInProgress=0;
return; return;
} }
@ -158,16 +159,23 @@ static struct station_config stconf;
//the connect succeeds, this gets the module in STA-only mode. //the connect succeeds, this gets the module in STA-only mode.
static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) { static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) {
int x=wifi_station_get_connect_status(); int x=wifi_station_get_connect_status();
int m = wifi_get_opmode();
if (x==STATION_GOT_IP) { if (x==STATION_GOT_IP) {
//Go to STA mode. This needs a reset, so do that. //Go to STA mode. This needs a reset, so do that.
os_printf("Got IP. Going into STA mode..\n"); connTryStatus=CONNTRY_SUCCESS;
wifi_set_opmode(1); if (m != 1) {
system_restart(); os_printf("Got IP. Going into STA mode..\n");
wifi_set_opmode(1);
}
} else { } else {
connTryStatus=CONNTRY_FAIL; connTryStatus=CONNTRY_FAIL;
os_printf("Connect fail. Not going into STA-only mode.\n"); if (m != 3) {
os_printf("Connect fail. Going into STA+AP mode..\n");
wifi_set_opmode(3);
}
//Maybe also pass this through on the webpage? //Maybe also pass this through on the webpage?
} }
os_timer_arm(&resetTimer, 15000, 0);
} }
@ -180,10 +188,10 @@ static void ICACHE_FLASH_ATTR reassTimerCb(void *arg) {
os_printf("Try to connect to AP....\n"); os_printf("Try to connect to AP....\n");
wifi_station_disconnect(); wifi_station_disconnect();
wifi_station_set_config(&stconf); wifi_station_set_config(&stconf);
wifi_station_connect(); //wifi_station_connect();
x=wifi_get_opmode(); x=wifi_get_opmode();
connTryStatus=CONNTRY_WORKING; connTryStatus=CONNTRY_WORKING;
if (x!=1) { if (x == 1) {
//Schedule disconnect/connect //Schedule disconnect/connect
os_timer_disarm(&resetTimer); os_timer_disarm(&resetTimer);
os_timer_setfn(&resetTimer, resetTimerCb, NULL); os_timer_setfn(&resetTimer, resetTimerCb, NULL);
@ -192,6 +200,20 @@ static void ICACHE_FLASH_ATTR reassTimerCb(void *arg) {
} }
// Init the wireless, which consists of setting a timer if we expect to connect to an AP
// so we can revert to STA+AP mode if we can't connect.
void ICACHE_FLASH_ATTR wifiInit() {
int x=wifi_get_opmode();
os_printf("Wifi init, mode=%d\n", x);
if (x == 1) {
// STA-only mode, reset into STA+AP after a timeout
os_timer_disarm(&resetTimer);
os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, 15000, 0);
}
}
//This cgi uses the routines above to connect to a specific access point with the //This cgi uses the routines above to connect to a specific access point with the
//given ESSID using the given password. //given ESSID using the given password.
int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) {
@ -218,7 +240,7 @@ int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) {
#ifdef DEMO_MODE #ifdef DEMO_MODE
httpdRedirect(connData, "/wifi"); httpdRedirect(connData, "/wifi");
#else #else
os_timer_arm(&reassTimer, 500, 0); os_timer_arm(&reassTimer, 1000, 0);
httpdRedirect(connData, "connecting.html"); httpdRedirect(connData, "connecting.html");
#endif #endif
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
@ -237,16 +259,25 @@ int ICACHE_FLASH_ATTR cgiWiFiSetMode(HttpdConnData *connData) {
len=httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff)); len=httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff));
if (len!=0) { if (len!=0) {
os_printf("cgiWifiSetMode: %s\n", buff); int m = atoi(buff);
os_printf("Switching to wifi mode %d\n", m);
#ifndef DEMO_MODE #ifndef DEMO_MODE
wifi_set_opmode(atoi(buff)); wifi_set_opmode(m);
system_restart(); if (m == 1) {
// STA-only mode, reset into STA+AP after a timeout
os_timer_disarm(&resetTimer);
os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, 15000, 0);
}
#endif #endif
} }
httpdRedirect(connData, "/wifi"); httpdRedirect(connData, "/wifi");
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
char *connStatuses[] = { "idle", "connecting", "wrong password", "AP not found",
"failed", "success" };
int ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData) {
char buff[1024]; char buff[1024];
int len; int len;
@ -255,23 +286,26 @@ int ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData) {
httpdStartResponse(connData, 200); httpdStartResponse(connData, 200);
httpdHeader(connData, "Content-Type", "text/json"); httpdHeader(connData, "Content-Type", "text/json");
httpdEndHeaders(connData); httpdEndHeaders(connData);
if (connTryStatus==CONNTRY_IDLE) {
len=os_sprintf(buff, "{\n \"status\": \"idle\"\n }\n"); len = os_sprintf(buff, "{\"status\": \"")-1;
} else if (connTryStatus==CONNTRY_WORKING || connTryStatus==CONNTRY_SUCCESS) { if (st > 0 && st < sizeof(connStatuses)) {
if (st==STATION_GOT_IP) { len += os_sprintf(buff+len, "%s", connStatuses[st])-1;
wifi_get_ip_info(0, &info); } else {
len=os_sprintf(buff, "{\n \"status\": \"success\",\n \"ip\": \"%d.%d.%d.%d\" }\n", len += os_sprintf(buff+len, "unknown")-1;
(info.ip.addr>>0)&0xff, (info.ip.addr>>8)&0xff, }
(info.ip.addr>>16)&0xff, (info.ip.addr>>24)&0xff); if (st == STATION_GOT_IP) {
wifi_get_ip_info(0, &info);
len+=os_sprintf(buff, "\", \"ip\": \"%d.%d.%d.%d\" }\n",
(info.ip.addr>>0)&0xff, (info.ip.addr>>8)&0xff,
(info.ip.addr>>16)&0xff, (info.ip.addr>>24)&0xff);
if (connTryStatus==CONNTRY_WORKING || connTryStatus==CONNTRY_SUCCESS) {
//Reset into AP-only mode sooner. //Reset into AP-only mode sooner.
os_timer_disarm(&resetTimer); os_timer_disarm(&resetTimer);
os_timer_setfn(&resetTimer, resetTimerCb, NULL); os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, 1000, 0); os_timer_arm(&resetTimer, 1000, 0);
} else {
len=os_sprintf(buff, "{\n \"status\": \"working\"\n }\n");
} }
} else { } else {
len=os_sprintf(buff, "{\n \"status\": \"fail\"\n }\n"); len+=os_sprintf(buff, "\" }\n");
} }
httpdSend(connData, buff, len); httpdSend(connData, buff, len);
@ -298,10 +332,16 @@ int ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg)
os_strcpy(buff, (char*)stconf.password); os_strcpy(buff, (char*)stconf.password);
} else if (os_strcmp(token, "WiFiapwarn")==0) { } else if (os_strcmp(token, "WiFiapwarn")==0) {
x=wifi_get_opmode(); x=wifi_get_opmode();
if (x==2) { switch (x) {
case 1:
os_strcpy(buff, "Click <a href=\"setmode.cgi?mode=3\">here</a> to go to STA+AP mode.");
break;
case 2:
os_strcpy(buff, "<b>Can't scan in this mode.</b> Click <a href=\"setmode.cgi?mode=3\">here</a> to go to STA+AP mode."); os_strcpy(buff, "<b>Can't scan in this mode.</b> Click <a href=\"setmode.cgi?mode=3\">here</a> to go to STA+AP mode.");
} else { break;
os_strcpy(buff, "Click <a href=\"setmode.cgi?mode=2\">here</a> to go to standalone AP mode."); case 3:
os_strcpy(buff, "Click <a href=\"setmode.cgi?mode=1\">here</a> to go to STA mode.");
break;
} }
} }
httpdSend(connData, buff, -1); httpdSend(connData, buff, -1);

@ -9,5 +9,6 @@ int cgiWiFi(HttpdConnData *connData);
int cgiWiFiConnect(HttpdConnData *connData); int cgiWiFiConnect(HttpdConnData *connData);
int cgiWiFiSetMode(HttpdConnData *connData); int cgiWiFiSetMode(HttpdConnData *connData);
int cgiWiFiConnStatus(HttpdConnData *connData); int cgiWiFiConnStatus(HttpdConnData *connData);
void wifiInit(void);
#endif #endif

@ -1,4 +1,5 @@
#include <esp8266.h> #include <esp8266.h>
#include "uart.h"
#include "console.h" #include "console.h"
// Web console for the esp8266 to replace outputting to uart1. // Web console for the esp8266 to replace outputting to uart1.
@ -30,6 +31,7 @@ console_read(void) {
static void ICACHE_FLASH_ATTR static void ICACHE_FLASH_ATTR
console_write_char(char c) { console_write_char(char c) {
uart0_write_char(c);
if (c == '\n') console_write('\r'); if (c == '\n') console_write('\r');
console_write(c); console_write(c);
} }

@ -5,6 +5,7 @@
static ETSTimer ledTimer; static ETSTimer ledTimer;
void ICACHE_FLASH_ATTR setLed(int on) { void ICACHE_FLASH_ATTR setLed(int on) {
if (on) { if (on) {
gpio_output_set((1<<LEDGPIO), 0, (1<<LEDGPIO), 0); gpio_output_set((1<<LEDGPIO), 0, (1<<LEDGPIO), 0);
} else { } else {
@ -15,8 +16,43 @@ void ICACHE_FLASH_ATTR setLed(int on) {
static uint8_t ledState = 0; static uint8_t ledState = 0;
static void ICACHE_FLASH_ATTR ledTimerCb(void *arg) { static void ICACHE_FLASH_ATTR ledTimerCb(void *arg) {
//os_printf("Timer Hello\n"); int m = wifi_get_opmode();
setLed((ledState++)&1); int c = m == 2 ? 0 : wifi_station_get_connect_status();
if (c != 5) os_printf("Status: mode=%d conn=%d\n", m, c);
int time = 1000;
if (c == STATION_GOT_IP) {
// connected, all is good, solid light
ledState = 1-ledState;
time = ledState ? 2900 : 100;
} else if (c == STATION_CONNECTING) {
// connecting, go on/off every second
ledState = 1 - ledState;
time = 1000;
} else if (c > STATION_CONNECTING) {
// some failure, rapid blinking
ledState = 1-ledState;
time = 100;
} else {
// idle
switch (m) {
case 1: // STA
ledState = 0;
break;
case 2: // AP
ledState = 1-ledState;
time = ledState ? 100 : 1900;
break;
case 3: // STA+AP
ledState = 1-ledState;
time = ledState ? 100 : 900;
break;
}
}
setLed(1-ledState); // low=on
os_timer_arm(&ledTimer, time, 0);
} }
void statusInit() { void statusInit() {
@ -24,7 +60,7 @@ void statusInit() {
gpio_output_set(0, 0, (1<<LEDGPIO), 0); gpio_output_set(0, 0, (1<<LEDGPIO), 0);
os_timer_disarm(&ledTimer); os_timer_disarm(&ledTimer);
os_timer_setfn(&ledTimer, ledTimerCb, NULL); os_timer_setfn(&ledTimer, ledTimerCb, NULL);
os_timer_arm(&ledTimer, 500, 1); os_timer_arm(&ledTimer, 500, 0);
} }

@ -111,8 +111,9 @@ void user_init(void) {
os_printf("\n\nInitializing esp-link\n"); os_printf("\n\nInitializing esp-link\n");
// Status LEDs // Status LEDs
statusInit(); statusInit();
// Wifi
wifiInit();
// init the flash filesystem with the html stuff // init the flash filesystem with the html stuff
os_delay_us(100000L);
EspFsInitResult res = espFsInit(&_binary_espfs_img_start); EspFsInitResult res = espFsInit(&_binary_espfs_img_start);
os_printf("espFsInit(0x%08lx) returned %d\n", (uint32_t)&_binary_espfs_img_start, res); os_printf("espFsInit(0x%08lx) returned %d\n", (uint32_t)&_binary_espfs_img_start, res);
// mount the http handlers // mount the http handlers

@ -100,7 +100,9 @@ while true; do
esac esac
done done
res=`curl -s -XPOST --data-binary "@$fw" "http://$hostname/flash/upload"` silent=-s
[[ -n "$verbose" ]] && silent=
res=`curl $silent -XPOST --data-binary "@$fw" "http://$hostname/flash/upload"`
if [[ $? != 0 ]]; then if [[ $? != 0 ]]; then
echo "Error flashing $fw" >&2 echo "Error flashing $fw" >&2
exit 1 exit 1

Loading…
Cancel
Save