Can someone tell me what modifications I need to make to allow it to work with SDK > 2.2 and newer?
It is a simple Testing Web Server (only 230 lines). In old SDK (and current manual) espconn_regist_disconcb gets called and all works great. In 2.2 and newer it never gets called and fails after the 5th browser refresh.
Thanks.
Code: Select all
#include "user_interface.h"
#include "espconn.h"
#include "osapi.h"
#include "driver/uart.h"
#include "mem.h"
#define SSID "<your SSID>"
#define PW "<your Password>"
#define HOST "ws"
#define dbg(f, ...) os_printf(f, ## __VA_ARGS__)
static os_timer_t ptimer;
// This PAGE only sends a one time page.
const char* PAGE = "<!DOCTYPE html><html><head><title>Native Server Test</title> <meta name='viewport' content='width=device-width, initial-scale=1'></head><body> <h1>Welcome to my Native Server Test</h1></body></html>";
// This PAGE sends back a page that keeps reloading, so we can check for errors and/or memory leaks.
// const char* PAGE = "<!DOCTYPE html><html><head><title>Native Server Test</title> <meta name='viewport' content='width=device-width, initial-scale=1'><script>window.addEventListener('load',()=>{ setTimeout(()=>{location.reload();},500);},false);</script></head><body> <h1>Welcome to my Native Server Test</h1></body></html>";
ICACHE_FLASH_ATTR void printIfErr(s8 esp, const char* msg)
{
if (esp)
os_printf("ERR - %s = %d\n", msg, esp);
}
ICACHE_FLASH_ATTR void hack(const char* msg)
{
static u32 last = 0;
u32 now = system_get_time();
if (msg)
os_printf("%s=%uus ", msg, now - last);
last = now;
}
ICACHE_FLASH_ATTR void onDisconnect(void* c)
{
hack("onDisconnect");
}
ICACHE_FLASH_ATTR void doDisconnect(void* c)
{
hack("doDisconnect");
struct espconn* conn = (struct espconn*)c;
// ******** THIS IS WHERE I THINK THE PROBLEM IS ******************
// In SDK <= 2.1.0 espconn_disconnect
// * does disconnect
// * does call espconn_regist_disconcb callback
// * does allow new connection after the first 5
// In SDK > 2.1.0 espconn_disconnect
// * does NOT disconnect
// * does NOT call espconn_regist_disconcb callback
// * does NOT allow new connection after the first 5
printIfErr(espconn_disconnect(conn), "disconnect");
}
ICACHE_FLASH_ATTR void onSent(void* c)
{
hack("onSent");
struct espconn* conn = (struct espconn*)c;
os_timer_disarm(&ptimer);
os_timer_setfn(&ptimer, (os_timer_func_t *)doDisconnect, conn);
os_timer_arm(&ptimer, 5, 0);
}
ICACHE_FLASH_ATTR void onReceive(void* c, char* buf, u16 length)
{
hack("onReceive");
struct espconn* conn = (struct espconn*)c;
// Print out the request just to make sure its what we think it is.
static char buffer[1024];
os_memcpy(buffer, buf, length);
*(buffer + length) = 0;
// os_printf(buffer);
os_sprintf(buffer, "HTTP/1.1 200 OK\r\n"
"Server: InqPortal/5.0\r\n"
"Content-Length: %d\r\n"
"Content-type: text/html\r\n"
"Pragma: no-cache\r\n\r\n%s", strlen(PAGE), PAGE);
printIfErr(espconn_send(conn, (u8*)buffer, strlen(buffer)), "send");
}
ICACHE_FLASH_ATTR void onConnection(void* c)
{
hack(NULL);
static u32 cnt = 0;
os_printf("\n%3u ", ++cnt);
struct espconn* conn = (struct espconn*)c;
espconn_regist_recvcb(conn, onReceive);
espconn_regist_sentcb(conn, onSent);
espconn_regist_disconcb(conn, onDisconnect);
}
ICACHE_FLASH_ATTR void startServer()
{
// Setup and start web server listener
LOCAL struct espconn listen;
LOCAL esp_tcp tcp;
os_memset(&listen, 0, sizeof(struct espconn));
listen.type = ESPCONN_TCP;
listen.state = ESPCONN_NONE;
listen.proto.tcp = &tcp;
listen.proto.tcp->local_port = 80;
espconn_regist_connectcb(&listen, onConnection);
printIfErr(espconn_accept(&listen), "listen");
}
ICACHE_FLASH_ATTR void chkAP(void* arg)
{
if (wifi_station_get_connect_status() != STATION_GOT_IP)
{
os_printf(".");
return;
}
os_timer_disarm(&ptimer);
struct ip_info info;
wifi_get_ip_info(STATION_IF, &info);
// This is just cook-book Station connection stuff.
dbg("\n\nSDK version: %s\n", system_get_sdk_version());
os_printf("\nBrowse to (http://%s/index.html) or (http://" IPSTR
"/index.html)\n",
HOST, IP2STR(&(info.ip)));
}
ICACHE_FLASH_ATTR void startStation()
{
os_printf("\nConnecting to your router");
struct station_config sc;
os_memset(&sc, 0, sizeof(struct station_config));
sc.bssid_set = 0;
os_memcpy(&sc.ssid, SSID, 32);
os_memcpy(&sc.password, PW, 64);
wifi_station_set_config_current(&sc);
wifi_station_set_hostname(HOST);
wifi_station_connect();
os_timer_disarm(&ptimer);
os_timer_setfn(&ptimer, (os_timer_func_t *)chkAP, NULL);
os_timer_arm(&ptimer, 1000, 1);
}
ICACHE_FLASH_ATTR void startSoftAP()
{
// Start up the communications Host/Station and Client/Soft
// ssid - Not NULL terminated in code - Can be 32 characters coming in!
// Password length must be blank OR >= 8! Truncated if >= 64 characters.
// Address
wifi_softap_dhcps_stop();
struct ip_info info;
os_memset(&info, 0, sizeof(struct ip_info));
// Don't set Gateway since we can't offer Internet / DNS
// We're hardcoding our InqPortal server to always be 10.10.10.10.
IP4_ADDR(&info.ip, 10, 10, 10, 10);
IP4_ADDR(&info.gw, 10, 10, 10, 10);
IP4_ADDR(&info.netmask, 255, 255, 255, 0);
wifi_set_ip_info(SOFTAP_IF, &info);
// Start up the DHCP server.
wifi_softap_dhcps_start();
struct softap_config cfg;
os_memset((u8*)&cfg, 0, sizeof(struct softap_config));
os_sprintf((char*)cfg.ssid, "%s-%X",
"ESP8266", system_get_chip_id());
cfg.ssid_len = strlen((char*)cfg.ssid);
// Password is null terminated (no length) specified. Use this filling.
os_sprintf((char*)cfg.password, "");
cfg.channel = 1;
cfg.authmode = AUTH_OPEN;
cfg.ssid_hidden = 0;
cfg.max_connection = 4; // Note: default 4, max 4
cfg.beacon_interval = 100; // Note: support 100 ~ 60000 ms, default 100
wifi_softap_set_config(&cfg);
wifi_set_sleep_type(NONE_SLEEP_T);
}
ICACHE_FLASH_ATTR void user_init(void)
{
uart_init(BIT_RATE_115200, BIT_RATE_115200);
wifi_set_opmode(STATIONAP_MODE);
startSoftAP();
startStation();
startServer();
os_printf("Ready\n");
}
ICACHE_FLASH_ATTR uint32 user_rf_cal_sector_set(void)
{
enum flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
case FLASH_SIZE_64M_MAP_1024_1024:
rf_cal_sec = 2048 - 5;
break;
case FLASH_SIZE_128M_MAP_1024_1024:
rf_cal_sec = 4096 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}