Skip to content

Commit a31bd32

Browse files
committed
WiFi: ESP32 DHCP WA, reconnection fix
- implemented WA for the ESP32 issue espressif/arduino-esp32#2537 - Delayed reconnection, allows websocket to finish section transaction. Fix #1 Signed-off-by: Emil Muratov <gpm@hotplug.ru>
1 parent b136f84 commit a31bd32

File tree

3 files changed

+64
-36
lines changed

3 files changed

+64
-36
lines changed

EmbUI/wi-fi.cpp

+58-32
Original file line numberDiff line numberDiff line change
@@ -61,50 +61,66 @@ void EmbUI::onWiFiMode(WiFiEventModeChange event_info){
6161
#endif //ESP8266
6262

6363
#ifdef ESP32
64-
// need to test it under ESP32 (might not need any scheduler to handle both Client and AP at the same time)
65-
void EmbUI::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) // , WiFiEventInfo_t info
64+
void EmbUI::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
6665
{
6766
switch (event){
6867
case SYSTEM_EVENT_AP_START:
6968
LOG(println, F("UI WiFi: Access-point started"));
7069
setup_mDns();
7170
break;
71+
7272
case SYSTEM_EVENT_STA_CONNECTED:
73-
LOG(print, F("UI WiFi: STA connected - "));
73+
LOG(println, F("UI WiFi: STA connected"));
74+
7475
if(_cb_STAConnected)
7576
_cb_STAConnected(); // execule callback
7677
break;
78+
7779
case SYSTEM_EVENT_STA_GOT_IP:
7880
WiFi.mode(WIFI_STA); // Shutdown internal Access Point
81+
82+
/* this is a weird hack to mitigate DHCP-client hostname issue
83+
* https://github.com/espressif/arduino-esp32/issues/2537
84+
* we use some IDF functions to restart dhcp-client, that has been disabled before STA connect
85+
*/
86+
tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA);
87+
tcpip_adapter_ip_info_t iface;
88+
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &iface);
89+
if(!iface.ip.addr){
90+
LOG(println, F("UI WiFi: DHCP discover..."));
91+
return;
92+
}
93+
7994
LOG(printf_P, PSTR("SSID:'%s', IP: "), WiFi.SSID().c_str()); // IPAddress(info.got_ip.ip_info.ip.addr)
80-
LOG(println, WiFi.localIP());
95+
LOG(println, IPAddress(iface.ip.addr));
8196

8297
if(WiFi.getMode() != WIFI_MODE_STA){ // Switch to STA only mode once IP obtained
83-
WiFi.mode(WIFI_MODE_STA);
98+
WiFi.mode(WIFI_MODE_STA);
8499
LOG(println, F("UI WiFi: switch to STA mode"));
85100
}
86-
if(_cb_STAGotIP)
87-
_cb_STAGotIP(); // execule callback
88101

102+
embuischedw.detach();
89103
setup_mDns();
104+
if(_cb_STAGotIP)
105+
_cb_STAGotIP(); // execule callback
90106
break;
107+
91108
case SYSTEM_EVENT_STA_DISCONNECTED:
92109
LOG(printf_P, PSTR("UI WiFi: Disconnected, reason: %d\n"), info.disconnected.reason);
93110
// https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/include/esp32/esp_wifi_types.h
94111
if(WiFi.getMode() != WIFI_MODE_APSTA){
95-
WiFi.mode(WIFI_MODE_APSTA); // Enable internal AP if station connection is lost
96-
LOG(println, F("UI WiFi: Switch to AP-Station mode"));
112+
embuischedw.once(WIFI_BEGIN_DELAY, [this](){ WiFi.mode(WIFI_MODE_APSTA);
113+
LOG(println, F("UI WiFi: Switch to AP-Station mode"));
114+
embuischedw.detach();} );
97115
}
98116
if(_cb_STADisconnected)
99117
_cb_STADisconnected(); // execule callback
100-
101-
embuischedw.once(WIFI_RECONNECT_TIMER, [this](){ WiFi.begin(); } ); // esp32 doesn't auto-reconnects, so reschedule it
102118
break;
119+
103120
default:
104121
break;
105122
}
106-
// handle network events for timelib
107-
timeProcessor.WiFiEvent(event, info);
123+
timeProcessor.WiFiEvent(event, info); // handle network events for timelib
108124
}
109125
#endif //ESP32
110126

@@ -117,13 +133,6 @@ void EmbUI::wifi_init(){
117133
var(FPSTR(P_hostname), hn, true);
118134
}
119135

120-
#ifdef ESP8266
121-
WiFi.hostname(hn);
122-
#elif defined ESP32
123-
WiFi.setHostname(hn.c_str());
124-
//WiFi.softAPsetHostname(hn);
125-
#endif
126-
127136
if (appwd.length()<WIFI_PSK_MIN_LENGTH)
128137
appwd = "";
129138

@@ -137,20 +146,41 @@ void EmbUI::wifi_init(){
137146
LOG(println, F("AP-only mode"));
138147
WiFi.mode(WIFI_AP);
139148
} else {
140-
LOG(println, F("AP/STA mode"));
141-
WiFi.mode(WIFI_AP_STA);
149+
LOG(println, F("STA mode"));
150+
WiFi.mode(WIFI_STA); // we start in STA mode, esp32 can't set client's hotname in ap/sta
151+
152+
#ifdef ESP8266
153+
WiFi.hostname(hn);
154+
WiFi.begin(); // use internaly stored last known credentials for connection
155+
#elif defined ESP32
156+
/* this is a weird hack to mitigate DHCP hostname issue
157+
* order of initialization does matter, pls keep it like this till fixed in upstream
158+
* https://github.com/espressif/arduino-esp32/issues/2537
159+
*/
160+
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
142161
WiFi.begin(); // use internaly stored last known credentials for connection
162+
if (!WiFi.setHostname(hn.c_str()))
163+
LOG(println, F("UI WiFi: Failed to set hostname :("));
164+
#endif
143165
LOG(println, F("UI WiFi: STA reconecting..."));
144166
}
145167
}
146168

147169
void EmbUI::wifi_connect(const char *ssid, const char *pwd)
148170
{
149-
if (ssid) {
150-
WiFi.begin(ssid, pwd);
151-
LOG(printf_P, PSTR("UI WiFi: client connecting to SSID:%s, pwd:%s\n"), ssid, pwd ? pwd : "");
171+
if (ssid){
172+
String _ssid(ssid); String _pwd(pwd); // I need objects to pass it to the lambda
173+
embuischedw.once(WIFI_BEGIN_DELAY, [_ssid, _pwd, this](){
174+
LOG(printf_P, PSTR("UI WiFi: client connecting to SSID:%s, pwd:%s\n"), _ssid.c_str(), _pwd.c_str());
175+
#ifdef ESP32
176+
WiFi.disconnect();
177+
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
178+
#endif
179+
WiFi.begin(_ssid.c_str(), _pwd.c_str());
180+
embuischedw.detach();
181+
});
152182
} else {
153-
WiFi.begin();
183+
embuischedw.once(WIFI_BEGIN_DELAY, [this](){ WiFi.begin(); embuischedw.detach();} );
154184
}
155185
}
156186

@@ -186,18 +216,14 @@ void EmbUI::setup_mDns(){
186216
void EmbUI::getAPmac(){
187217
if(*mc) return;
188218

189-
uint8_t _mac[7];
219+
uint8_t _mac[6];
190220

191221
#ifdef ESP32
192-
// uint64_t chipid = ESP.getEfuseMac();
193-
// memset(_mac,0,sizeof(_mac));
194-
// memcpy(_mac,&chipid,6);
195-
196222
if(WiFi.getMode() == WIFI_MODE_NULL)
197223
WiFi.mode(WIFI_MODE_AP);
198224
#endif
199225
WiFi.softAPmacAddress(_mac);
200226

201-
LOG(printf_P,PSTR("UI MAC:%02X%02X%02X\n"), _mac[3], _mac[4], _mac[5]);
227+
LOG(printf_P,PSTR("UI MAC ID:%02X%02X%02X\n"), _mac[3], _mac[4], _mac[5]);
202228
sprintf_P(mc, PSTR("%02X%02X%02X"), _mac[3], _mac[4], _mac[5]);
203229
}

EmbUI/wi-fi.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
#include <WiFi.h>
1616
#endif
1717

18-
#define WIFI_CONNECT_TIMEOUT 7
19-
#define WIFI_RECONNECT_TIMER 30
18+
#define WIFI_CONNECT_TIMEOUT 7 // timer for esp8266 STA connection attempt
19+
#define WIFI_RECONNECT_TIMER 30 // timer for esp8266, STA connect retry
20+
#define WIFI_BEGIN_DELAY 3 // scheduled delay for STA begin() connection
21+
2022
#define WIFI_PSK_MIN_LENGTH 8
2123

2224
//#endif

resources/respack.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ echo "Preparing resources for EmbUI FS image"
44

55
mkdir -p ./data/css ./data/js ./data/login ./data/extras
66
cat html/css/*.css | gzip -9 > ./data/css/all.css.gz
7-
cat html/css/wallpaper.jpg | gzip -9 > ./data/css/wallpaper.jpg.gz
7+
cp html/css/*.jpg ./data/css/
88
cat html/js/*.js | gzip -9 > ./data/js/all.js.gz
99
cat html/index.html | gzip -9 > ./data/index.html.gz
1010
cat html/favicon.ico | gzip -9 > ./data/favicon.ico.gz
11-
cat html/.exclude.files > ./data/.exclude.files
11+
cp html/.exclude.files > ./data/
1212

1313
cat html/login/index.htm | gzip -9 > ./data/login/index.htm.gz
1414
cat html/login/favicon.ico | gzip -9 > ./data/login/favicon.ico.gz

0 commit comments

Comments
 (0)