Skip to content

Commit

Permalink
wifi: separate softAp settings (#2294)
Browse files Browse the repository at this point in the history
- replace `apmode` with `wifiApMode`
- deprecate `WIFI_FALLBACK_APMODE` in favour of the AP mode setting
- allow to set custom SSID and passphrase for the softAP via `wifiApSsid` & `wifiApPass`
- identifier fallback for hostname
  • Loading branch information
mcspr authored Jul 4, 2020
1 parent 57f5c7d commit 009bdf0
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 68 deletions.
10 changes: 10 additions & 0 deletions code/espurna/config/deprecated.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,13 @@
#warning "BUTTON[1-8]_MODE is deprecated! Please use BUTTON[1-8]_CONFIG instead"
#define BUTTON8_CONFIG BUTTON8_MODE
#endif

#ifdef CSE7766_PIN
#warning "CSE7766_PIN is deprecated! Please use CSE7766_RX_PIN instead"
#define CSE7766_RX_PIN CSE7766_PIN
#endif

#ifdef WIFI_FALLBACK_APMODE
#warning "WIFI_FALLBACK_APMODE is deprecated! Please use WIFI_AP_MODE instead"
#define WIFI_AP_MODE ((1 == WIFI_FALLBACK_APMODE) ? WiFiApMode::Fallback : WiFiApMode::Disabled)
#endif
28 changes: 20 additions & 8 deletions code/espurna/config/general.h
Original file line number Diff line number Diff line change
Expand Up @@ -497,31 +497,43 @@
// -----------------------------------------------------------------------------

#ifndef WIFI_CONNECT_TIMEOUT
#define WIFI_CONNECT_TIMEOUT 60000 // Connecting timeout for WIFI in ms
#define WIFI_CONNECT_TIMEOUT 60000 // Connecting timeout for WIFI in ms
#endif

#ifndef WIFI_RECONNECT_INTERVAL
#define WIFI_RECONNECT_INTERVAL 180000 // If could not connect to WIFI, retry after this time in ms
#define WIFI_RECONNECT_INTERVAL 180000 // If could not connect to WIFI, retry after this time in ms
#endif

#ifndef WIFI_MAX_NETWORKS
#define WIFI_MAX_NETWORKS 5 // Max number of WIFI connection configurations
#define WIFI_MAX_NETWORKS 5 // Max number of WIFI connection configurations
#endif

#ifndef WIFI_AP_CAPTIVE
#define WIFI_AP_CAPTIVE 1 // Captive portal enabled when in AP mode
#define WIFI_AP_CAPTIVE 1 // Captive portal enabled when in AP mode
#endif

#ifndef WIFI_FALLBACK_APMODE
#define WIFI_FALLBACK_APMODE 1 // Fallback to AP mode if no STA connection
#ifndef WIFI_AP_MODE
#define WIFI_AP_MODE WiFiApMode::Fallback // By default, fallback to AP mode if no STA connection
// Use WiFiApMode::Enabled to start it when the device boots
// Use WiFiApMode::Disabled to disable AP mode completely
#endif

#ifndef WIFI_AP_SSID
#define WIFI_AP_SSID "" // (optional) Specify softAp SSID.
// By default or when empty, hostname (or device identifier) is used instead.
#endif

#ifndef WIFI_AP_PASS
#define WIFI_AP_PASS "" // (optional) Specify softAp passphrase
// By default or when empty, admin password is used instead.
#endif

#ifndef WIFI_SLEEP_MODE
#define WIFI_SLEEP_MODE WIFI_NONE_SLEEP // WIFI_NONE_SLEEP, WIFI_LIGHT_SLEEP or WIFI_MODEM_SLEEP
#define WIFI_SLEEP_MODE WIFI_NONE_SLEEP // WIFI_NONE_SLEEP, WIFI_LIGHT_SLEEP or WIFI_MODEM_SLEEP
#endif

#ifndef WIFI_SCAN_NETWORKS
#define WIFI_SCAN_NETWORKS 1 // Perform a network scan before connecting
#define WIFI_SCAN_NETWORKS 1 // Perform a network scan before connecting
#endif

// Optional hardcoded configuration (up to 5 networks, depending on WIFI_MAX_NETWORKS and espurna/wifi_config.h)
Expand Down
3 changes: 0 additions & 3 deletions code/espurna/config/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
#define WIFI_STATE_WPS 4
#define WIFI_STATE_SMARTCONFIG 8

#define WIFI_AP_ALLWAYS 1
#define WIFI_AP_FALLBACK 2

//------------------------------------------------------------------------------
// BUTTONS
//------------------------------------------------------------------------------
Expand Down
185 changes: 129 additions & 56 deletions code/espurna/wifi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
bool _wifi_wps_running = false;
bool _wifi_smartconfig_running = false;
bool _wifi_smartconfig_initial = false;
int _wifi_ap_mode = WIFI_AP_FALLBACK;
WiFiApMode _wifi_ap_mode = WiFiApMode::Fallback;

#if WIFI_GRATUITOUS_ARP_SUPPORT
unsigned long _wifi_gratuitous_arp_interval = 0;
Expand All @@ -26,42 +26,22 @@ unsigned long _wifi_gratuitous_arp_last = 0;
// PRIVATE
// -----------------------------------------------------------------------------

struct wifi_scan_info_t {
String ssid_scan;
int32_t rssi_scan;
uint8_t sec_scan;
uint8_t* BSSID_scan;
int32_t chan_scan;
bool hidden_scan;
char buffer[128];
};

using wifi_scan_f = std::function<void(wifi_scan_info_t& info)>;

void _wifiUpdateSoftAP() {
if (WiFi.softAPgetStationNum() == 0) {
#if USE_PASSWORD
jw.setSoftAP(getSetting("hostname").c_str(), getAdminPass().c_str());
#else
jw.setSoftAP(getSetting("hostname").c_str());
#endif
}
}
namespace settings {
namespace internal {

void _wifiCheckAP() {
if (
(WIFI_AP_FALLBACK == _wifi_ap_mode)
&& ((WiFi.getMode() & WIFI_AP) > 0)
&& jw.connected()
&& (WiFi.softAPgetStationNum() == 0)
) {
jw.enableAP(false);
template <>
WiFiApMode convert(const String& value) {
switch (value.toInt()) {
case 0:
return WiFiApMode::Disabled;
case 1:
return WiFiApMode::Enabled;
default:
case 2:
return WiFiApMode::Fallback;
}
}

namespace settings {
namespace internal {

template<>
WiFiSleepType_t convert(const String& value) {
switch (value.toInt()) {
Expand All @@ -75,21 +55,58 @@ WiFiSleepType_t convert(const String& value) {
}
}

} // namespace internal
} // namespace settings

String _wifiSettingsSoftApSsid() {
return getSetting("wifiApSsid", strlen(WIFI_AP_SSID)
? F(WIFI_AP_SSID)
: getSetting("hostname", getIdentifier()));
}

String _wifiSettingsSoftApPass() {
return getSetting("wifiApPass", strlen(WIFI_AP_PASS)
? F(WIFI_AP_PASS)
: getAdminPass());
}

void _wifiUpdateSoftAP() {
if (!WiFi.softAPgetStationNum()) {
// Note: we know that c_str() will be copied, no need to persist it ourselves
jw.setSoftAP(
_wifiSettingsSoftApSsid().c_str(),
#if USE_PASSWORD
_wifiSettingsSoftApPass().c_str()
#else
nullptr
#endif
);
}
}

void _wifiCheckAP() {
if (
(WiFiApMode::Fallback == _wifi_ap_mode)
&& ((WiFi.getMode() & WIFI_AP) > 0)
&& jw.connected()
&& (WiFi.softAPgetStationNum() == 0)
) {
jw.enableAP(false);
}
}

void _wifiConfigure() {

jw.setHostname(getSetting("hostname").c_str());
jw.setHostname(getSetting("hostname", getIdentifier()).c_str());
_wifiUpdateSoftAP();

jw.setConnectTimeout(WIFI_CONNECT_TIMEOUT);
wifiReconnectCheck();

jw.enableAPFallback(WIFI_FALLBACK_APMODE);
jw.cleanNetworks();
_wifi_ap_mode = getSetting("wifiApMode", WIFI_AP_MODE);

_wifi_ap_mode = getSetting("apmode", WIFI_AP_FALLBACK);
jw.enableAPFallback(_wifi_ap_mode != WiFiApMode::Disabled);
jw.cleanNetworks();

// If system is flagged unstable we do not init wifi networks
#if SYSTEM_CHECK_ENABLED
Expand Down Expand Up @@ -154,28 +171,45 @@ void _wifiConfigure() {

}

void _wifiScan(wifi_scan_f callback = nullptr) {
struct wifi_scan_info_t {
String ssid_scan;
int32_t rssi_scan;
uint8_t sec_scan;
uint8_t* BSSID_scan;
int32_t chan_scan;
bool hidden_scan;
char buffer[128];
};

template <typename WiFiScanCallback>
void _wifiScan(WiFiScanCallback callback) {
DEBUG_MSG_P(PSTR("[WIFI] Start scanning\n"));

unsigned char result = WiFi.scanNetworks();

if (result == WIFI_SCAN_FAILED) {
auto networks = WiFi.scanNetworks();
if (networks == WIFI_SCAN_FAILED) {
DEBUG_MSG_P(PSTR("[WIFI] Scan failed\n"));
return;
} else if (result == 0) {
} else if (0 == networks) {
DEBUG_MSG_P(PSTR("[WIFI] No networks found\n"));
return;
}

DEBUG_MSG_P(PSTR("[WIFI] %d networks found:\n"), result);
DEBUG_MSG_P(PSTR("[WIFI] %d networks found:\n"), networks);

// Populate defined networks with scan data
// SDK pre-allocates a memory region with the scan data, but the only API to get them is through this 'getter' method.
// Pick them one by one and pass into the callback as our custom struct.
wifi_scan_info_t info;

for (unsigned char i = 0; i < result; ++i) {
for (int i = 0; i < networks; ++i) {

WiFi.getNetworkInfo(i, info.ssid_scan, info.sec_scan, info.rssi_scan, info.BSSID_scan, info.chan_scan, info.hidden_scan);
WiFi.getNetworkInfo(i,
info.ssid_scan,
info.sec_scan,
info.rssi_scan,
info.BSSID_scan,
info.chan_scan,
info.hidden_scan
);

snprintf_P(info.buffer, sizeof(info.buffer),
PSTR("BSSID: %02X:%02X:%02X:%02X:%02X:%02X SEC: %s RSSI: %3d CH: %2d SSID: %s"),
Expand All @@ -186,11 +220,7 @@ void _wifiScan(wifi_scan_f callback = nullptr) {
info.ssid_scan.c_str()
);

if (callback) {
callback(info);
} else {
DEBUG_MSG_P(PSTR("[WIFI] > %s\n"), info.buffer);
}
callback(info);

}

Expand Down Expand Up @@ -377,6 +407,35 @@ void _wifiDebugCallback(justwifi_messages_t code, char * parameter) {

void _wifiInitCommands() {

terminalRegisterCommand(F("WIFI.STATIONS"), [](const terminal::CommandContext& ctx) {
char buffer[64];

size_t stations = 0;

auto* station = wifi_softap_get_station_info();

while (station) {
sprintf_P(buffer,
PSTR("[WIFI] %02X:%02X:%02X:%02X:%02X:%02X %s"),
MAC2STR(station->bssid),
IPAddress(station->ip.addr).toString().c_str()
);
ctx.output.println(buffer);
station = STAILQ_NEXT(station, next);
++stations;
}

wifi_softap_free_station_info();

if (!stations) {
terminalError(ctx, F("No stations connected"));
return;
}


terminalOK(ctx);
});

terminalRegisterCommand(F("WIFI"), [](const terminal::CommandContext&) {
wifiDebug();
terminalOK();
Expand Down Expand Up @@ -413,7 +472,9 @@ void _wifiInitCommands() {
#endif // defined(JUSTWIFI_ENABLE_SMARTCONFIG)

terminalRegisterCommand(F("WIFI.SCAN"), [](const terminal::CommandContext&) {
_wifiScan();
_wifiScan([](wifi_scan_info_t& info) {
DEBUG_MSG_P(PSTR("[WIFI] > %s\n"), info.buffer);
});
terminalOK();
});

Expand Down Expand Up @@ -525,7 +586,7 @@ void _wifiSendGratuitousArp(unsigned long interval) {

// backported WiFiAPClass methods

String _wifiSoftAPSSID() {
String _wifiRuntimeSoftApSsid() {
struct softap_config config;
wifi_softap_get_config(&config);

Expand All @@ -537,7 +598,7 @@ String _wifiSoftAPSSID() {
return String(ssid);
}

String _wifiSoftAPPSK() {
String _wifiRuntimeSoftApPass() {
struct softap_config config;
wifi_softap_get_config(&config);

Expand Down Expand Up @@ -573,8 +634,8 @@ void wifiDebug(WiFiMode_t modes) {

if (((modes & WIFI_AP) > 0) && ((WiFi.getMode() & WIFI_AP) > 0)) {
DEBUG_MSG_P(PSTR("[WIFI] -------------------------------------- MODE AP\n"));
DEBUG_MSG_P(PSTR("[WIFI] SSID %s\n"), _wifiSoftAPSSID().c_str());
DEBUG_MSG_P(PSTR("[WIFI] PASS %s\n"), _wifiSoftAPPSK().c_str());
DEBUG_MSG_P(PSTR("[WIFI] SSID %s\n"), _wifiRuntimeSoftApSsid().c_str());
DEBUG_MSG_P(PSTR("[WIFI] PASS %s\n"), _wifiRuntimeSoftApPass().c_str());
DEBUG_MSG_P(PSTR("[WIFI] IP %s\n"), WiFi.softAPIP().toString().c_str());
DEBUG_MSG_P(PSTR("[WIFI] MAC %s\n"), WiFi.softAPmacAddress().c_str());
footer = true;
Expand Down Expand Up @@ -683,14 +744,26 @@ void wifiRegister(wifi_callback_f callback) {
jw.subscribe(callback);
}

WiFiApMode wifiApMode() {
return _wifi_ap_mode;
}

// -----------------------------------------------------------------------------
// INITIALIZATION
// -----------------------------------------------------------------------------

void wifiSetup() {

// Backwards compat, we need to specify namespace
moveSetting("apmode", "wifiApMode");

_wifiConfigure();

if (WiFiApMode::Enabled ==_wifi_ap_mode) {
jw.enableAP(true);
jw.enableSTA(true);
}

#if JUSTWIFI_ENABLE_SMARTCONFIG
if (_wifi_smartconfig_initial) jw.startSmartConfig();
#endif
Expand Down
9 changes: 8 additions & 1 deletion code/espurna/wifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ extern "C" {
#define TCP_MSS (1460)
#endif

using wifi_callback_f = std::function<void(justwifi_messages_t code, char * parameter)>;
using wifi_callback_f = void(*)(justwifi_messages_t code, char * parameter);

enum class WiFiApMode {
Disabled,
Enabled,
Fallback
};

uint8_t wifiState();
void wifiReconnectCheck();
Expand All @@ -52,6 +58,7 @@ String getIP();
void wifiDebug();
void wifiDebug(WiFiMode_t modes);

WiFiApMode wifiApMode();
void wifiStartAP();
void wifiStartSTA();
void wifiDisconnect();
Expand Down

0 comments on commit 009bdf0

Please sign in to comment.