Skip to content

Commit 244c123

Browse files
committed
Commands: Added connect command, fixed reconnect behaviour and scanning
Implemented command Connect (0x0d = 13), i.e. set WiFi credentials based on the index of the network in the last scan result and the passphrase supplied by the user. For this is was necessary to refactor Connection and the Scan command, since scanning can not be done while connection attempts are being made, and we formerly always tried to reconnect when receiving a disconnect event. It was somewhat pointless to keep trying to reconnect forever if the connection kept failing due to wrong credentials as well. Thus we now actively manage the automatic reconnect in Connection in the member variable m_reconnecting, and only set it to true once a connection is actually established. The disconnect() method now disconnects and sets m_reconnecting to false, so it's an explicit request to disconnect and *not* try to reconnect until a successive connect() call results in an actual connection. Implemented scanNetworks() in Connection to first disconnect(), call WiFi.scanNetworks() and then connect() again to make sure scanning for networks always works. There seem to be some quirks related to scanning and multiple contradicting workarounds are suggested here: espressif/arduino-esp32#3294 These workarounds involve manual delays, which seems a bit voodoo, so I have decided that simply disconnecting before a scan and reconnecting again once it is done is the most pragmatic approach here. Scan: Now use connection->scanNetworks() instead of directly calling WiFi.scanNetworks(). Also added responding with "no networks found" like the previous firmware does, additionally logging whether the scan failed in the first place or whether it succeeded and there are really no networks available (see comment). Data: Added method field(index) to access 0x01-separated fields. This is the equivalent to the getValue()-function in th previous firmware. Also renamed appendSeparated() to appendField().
1 parent bf2d337 commit 244c123

File tree

10 files changed

+149
-28
lines changed

10 files changed

+149
-28
lines changed

wic64/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ idf_component_register(
1313
SRCS "commands/httpGet.cpp"
1414
SRCS "commands/getIP.cpp"
1515
SRCS "commands/scan.cpp"
16+
SRCS "commands/connect.cpp"
1617
SRCS "commands/echo.cpp"
1718
SRCS "display.cpp"
1819
SRCS "webserver.cpp"

wic64/commands/commands.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "httpGet.h"
66
#include "getIP.h"
77
#include "scan.h"
8+
#include "connect.h"
89
#include "echo.h"
910

1011
namespace WiC64 {
@@ -13,6 +14,7 @@ namespace WiC64 {
1314
WIC64_COMMAND(0x0f, HttpGet),
1415
WIC64_COMMAND(0x06, GetIP),
1516
WIC64_COMMAND(0x0c, Scan),
17+
WIC64_COMMAND(0x0d, Connect),
1618
WIC64_COMMAND(0xff, Echo),
1719
};
1820
}

wic64/commands/connect.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include "connection.h"
2+
#include "connect.h"
3+
4+
#include "WiFi.h"
5+
6+
namespace WiC64 {
7+
const char* Connect::TAG = "CONNECT";
8+
9+
extern Connection *connection;
10+
11+
void Connect::execute(void) {
12+
uint8_t indexInLastScanResult = atoi(request()->argument()->field(0));
13+
const char* password = request()->argument()->field(1);
14+
15+
const String& ssid = WiFi.SSID(indexInLastScanResult).c_str();
16+
17+
connection->connect(ssid.c_str(), password);
18+
19+
response()->copy("Wlan config changed");
20+
responseReady();
21+
}
22+
}

wic64/commands/connect.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef WIC64_CONNECT_H
2+
#define WIC64_CONNECT_H
3+
4+
#include "command.h"
5+
6+
namespace WiC64 {
7+
class Connect : public Command {
8+
public:
9+
static const char* TAG;
10+
11+
using Command::Command;
12+
void execute(void);
13+
};
14+
}
15+
#endif // WIC64_CONNECT_H

wic64/commands/scan.cpp

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,49 @@
11
#include "scan.h"
2+
#include "connection.h"
23
#include "utilities.h"
34

45
#include "WiFi.h"
56

67
namespace WiC64 {
7-
88
const char* Scan::TAG = "SCAN";
99

10+
extern Connection *connection;
11+
1012
void Scan::execute(void) {
1113
int num_networks;
1214

13-
ESP_LOGD(TAG, "Scanning for WiFi networks...");
15+
ESP_LOGI(TAG, "Scanning for WiFi networks...");
1416

15-
num_networks = WiFi.scanNetworks();
17+
num_networks = connection->scanNetworks();
1618
num_networks = MIN(num_networks, 15);
1719

18-
for(uint8_t i=0; i<num_networks; i++) {
20+
// The previous firmware only checked for num_networks == 0
21+
// and returned "no networks found". We also test <= 0
22+
// and issue the appropriate log message, but we still just
23+
// return "no networks found", which remains true in either
24+
// case, although it's not entirely accurate.
25+
26+
if (num_networks <= 0 ) {
27+
if (num_networks < 0) {
28+
ESP_LOGE(TAG, "Scan failed with error code %d", num_networks);
29+
}
30+
else {
31+
ESP_LOGW(TAG, "Scan successful, still 0 networks found");
32+
}
33+
response()->copy("no networks found");
34+
}
35+
else {
36+
ESP_LOGI(TAG, "Scan successful, %d networks found", num_networks);
37+
38+
for(uint8_t i=0; i<num_networks; i++) {
1939

20-
ESP_LOGD(TAG, "Network %d: [%s] %ddbm",
21-
i, WiFi.SSID(i).c_str(), WiFi.RSSI(i));
40+
ESP_LOGD(TAG, "Network %d: [%s] %ddbm",
41+
i, WiFi.SSID(i).c_str(), WiFi.RSSI(i));
2242

23-
response()->appendSeparated(String(i));
24-
response()->appendSeparated(WiFi.SSID(i));
25-
response()->appendSeparated(String(WiFi.RSSI(i)));
43+
response()->appendField(String(i));
44+
response()->appendField(WiFi.SSID(i));
45+
response()->appendField(String(WiFi.RSSI(i)));
46+
}
2647
}
2748
responseReady();
2849
}

wic64/connection.cpp

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ namespace WiC64 {
4141
display->RSSI(WiFi.RSSI());
4242
display->ip("0.0.0.0");
4343
display->status("Connected");
44+
45+
connection->reconnecting(true);
4446
}
4547

4648
void Connection::onDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
@@ -49,9 +51,13 @@ namespace WiC64 {
4951
display->SSID(getStoredSSID());
5052
display->RSSI(WiFi.RSSI());
5153
display->ip("0.0.0.0");
52-
display->status("Connecting...");
5354

54-
connection->connect();
55+
if (connection->reconnecting()) {
56+
display->status("Reconnecting...");
57+
connection->connect();
58+
} else {
59+
display->status("Disconnected");
60+
}
5561
}
5662

5763
void Connection::onGotIpAddress(WiFiEvent_t event, WiFiEventInfo_t info) {
@@ -62,15 +68,24 @@ namespace WiC64 {
6268
display->ip(connection->ipAddress());
6369
}
6470

65-
bool Connection::isConnected() {
66-
return WiFi.isConnected();
67-
}
68-
6971
void Connection::connect() {
7072
ESP_LOGI(TAG, "Connecting to WiFi network...");
7173
WiFi.begin();
7274
}
7375

76+
void Connection::disconnect(void) {
77+
reconnecting(false);
78+
WiFi.disconnect();
79+
}
80+
81+
void Connection::connect(const char* ssid, const char* password) {
82+
ESP_LOGI(TAG, "Connecting with WiFi credentials SSID [%s] Passphrase [%s]",
83+
ssid, password);
84+
85+
disconnect();
86+
WiFi.begin(ssid, password);
87+
}
88+
7489
const char* Connection::ipAddress() {
7590
static char ip[16+1];
7691
strncpy(ip, WiFi.localIP().toString().c_str(), 16);
@@ -82,4 +97,14 @@ namespace WiC64 {
8297
strncpy(mac, WiFi.macAddress().c_str(), 18);
8398
return mac;
8499
}
100+
101+
uint16_t Connection::scanNetworks(void) {
102+
uint16_t num_networks;
103+
104+
disconnect();
105+
num_networks = WiFi.scanNetworks();
106+
connect();
107+
108+
return num_networks;
109+
}
85110
}

wic64/connection.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,26 @@ namespace WiC64 {
88
public: static const char* TAG;
99

1010
private:
11+
bool m_reconnecting = false;
12+
1113
static String getStoredSSID(void);
1214
static void onConnected(WiFiEvent_t event, WiFiEventInfo_t info);
1315
static void onDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
1416
static void onGotIpAddress(WiFiEvent_t event, WiFiEventInfo_t info);
1517

1618
public:
17-
Connection();
19+
Connection(void);
20+
bool reconnecting(void) { return m_reconnecting; }
21+
void reconnecting(bool reconnecting) { m_reconnecting = reconnecting; }
1822

19-
bool isConnected(void);
20-
void connect(void);
23+
const char* ipAddress(void);
24+
const char* macAddress(void);
2125

22-
const char* ipAddress();
23-
const char* macAddress();
26+
uint16_t scanNetworks(void);
27+
28+
void connect(void);
29+
void connect(const char* ssid, const char* passphrase);
30+
void disconnect(void);
2431
};
2532

2633
}

wic64/data.cpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,50 @@ namespace WiC64 {
3232
m_data[m_size] = '\0';
3333
}
3434

35-
void Data::copyFrom(const char *c_str) {
35+
void Data::copy(const char *c_str) {
3636
m_data = transferBuffer;
3737
m_size = strlen(c_str);
3838
strncpy((char*) transferBuffer, c_str, m_size+1);
3939
}
4040

41-
void Data::appendSeparated(const String& string, const char separator) {
41+
void Data::appendField(const String& string) {
4242
size_t len = string.length();
4343
memcpy(m_data + m_index, string.c_str(), len);
4444

4545
m_index += len;
46-
m_data[m_index] = separator;
46+
m_data[m_index] = '\1';
4747
m_index++;
4848
m_size += len + 1;
4949
}
5050

51-
void Data::appendSeparated(const String &string) {
52-
appendSeparated(string, '\1');
51+
const char* Data::field(uint8_t index) {
52+
static char value[256];
53+
54+
char* begin = (char*) m_data;
55+
char* end = begin;
56+
char* previous_end;
57+
58+
for (uint16_t i=0; i<=index; i++) {
59+
previous_end = end;
60+
61+
if ((end = strstr(end, "\01")) != NULL) {
62+
if (index == i) {
63+
begin = previous_end;
64+
65+
uint8_t size =
66+
(end - (char*) m_data) -
67+
(begin - (char*) m_data);
68+
69+
memcpy(value, begin, size);
70+
value[size] = '\0';
71+
72+
return value;
73+
}
74+
end++;
75+
}
76+
}
77+
value[0] = '\0';
78+
return value;
5379
}
5480

5581
void Data::queue(QueueHandle_t queue, uint16_t size) {

wic64/data.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ namespace WiC64 {
2727

2828
void wrap(uint8_t* data, uint16_t size);
2929
void wrap(const char* c_str);
30-
void copyFrom(const char* c_str);
30+
void copy(const char* c_str);
3131

32-
void appendSeparated(const String& string, const char separator);
33-
void appendSeparated(const String& string);
32+
void appendField(const String& string);
33+
const char* field(uint8_t index);
3434

3535
uint16_t size() { return m_size; }
3636

wic64/wic64.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "version.h"
1111
#include "commands/httpGet.h"
1212
#include "commands/scan.h"
13+
#include "commands/connect.h"
1314

1415
#include "esp_log.h"
1516

@@ -61,5 +62,6 @@ namespace WiC64 {
6162
esp_log_level_set(Command::TAG, loglevel);
6263
esp_log_level_set(HttpGet::TAG, loglevel);
6364
esp_log_level_set(Scan::TAG, loglevel);
65+
esp_log_level_set(Connect::TAG, loglevel);
6466
}
6567
}

0 commit comments

Comments
 (0)