diff --git a/CommandStation-EX.ino b/CommandStation-EX.ino index 24a0aef..a6885ff 100644 --- a/CommandStation-EX.ino +++ b/CommandStation-EX.ino @@ -95,11 +95,11 @@ void setup() // Start Ethernet if it exists #ifndef ARDUINO_ARCH_ESP32 #if WIFI_ON - WifiInterface::setup(WIFI_SERIAL_LINK_SPEED, F(WIFI_SSID), F(WIFI_PASSWORD), F(WIFI_HOSTNAME), IP_PORT, WIFI_CHANNEL); + WifiInterface::setup(WIFI_SERIAL_LINK_SPEED, F(WIFI_SSID), F(WIFI_PASSWORD), F(WIFI_HOSTNAME), IP_PORT, WIFI_CHANNEL, WIFI_FORCE_AP); #endif // WIFI_ON #else // ESP32 needs wifi on always - WifiESP::setup(WIFI_SSID, WIFI_PASSWORD, WIFI_HOSTNAME, IP_PORT, WIFI_CHANNEL); + WifiESP::setup(WIFI_SSID, WIFI_PASSWORD, WIFI_HOSTNAME, IP_PORT, WIFI_CHANNEL, WIFI_FORCE_AP); #endif // ARDUINO_ARCH_ESP32 #if ETHERNET_ON diff --git a/WifiESP32.cpp b/WifiESP32.cpp index 6e09aa1..3fe91ae 100644 --- a/WifiESP32.cpp +++ b/WifiESP32.cpp @@ -117,7 +117,8 @@ bool WifiESP::setup(const char *SSid, const char *password, const char *hostname, int port, - const byte channel) { + const byte channel, + const bool forceAP) { bool havePassword = true; bool haveSSID = true; bool wifiUp = false; @@ -145,7 +146,7 @@ bool WifiESP::setup(const char *SSid, if (strncmp(yourNetwork, password, 13) == 0 || strncmp("", password, 13) == 0) havePassword = false; - if (haveSSID && havePassword) { + if (haveSSID && havePassword && !forceAP) { WiFi.setHostname(hostname); // Strangely does not work unless we do it HERE! WiFi.mode(WIFI_STA); #ifdef SERIAL_BT_COMMANDS @@ -183,18 +184,20 @@ bool WifiESP::setup(const char *SSid, } } } - if (!haveSSID) { + if (!haveSSID || forceAP) { // prepare all strings - String strSSID("DCCEX_"); - String strPass("PASS_"); - String strMac = WiFi.macAddress(); - strMac.remove(0,9); - strMac.replace(":",""); - strMac.replace(":",""); - // convert mac addr hex chars to lower case to be compatible with AT software - std::transform(strMac.begin(), strMac.end(), strMac.begin(), asciitolower); - strSSID.concat(strMac); - strPass.concat(strMac); + String strSSID(forceAP ? SSid : "DCCEX_"); + String strPass(forceAP ? password : "PASS_"); + if (!forceAP) { + String strMac = WiFi.macAddress(); + strMac.remove(0,9); + strMac.replace(":",""); + strMac.replace(":",""); + // convert mac addr hex chars to lower case to be compatible with AT software + std::transform(strMac.begin(), strMac.end(), strMac.begin(), asciitolower); + strSSID.concat(strMac); + strPass.concat(strMac); + } WiFi.mode(WIFI_AP); #ifdef SERIAL_BT_COMMANDS diff --git a/WifiESP32.h b/WifiESP32.h index 100e393..1cf0d91 100644 --- a/WifiESP32.h +++ b/WifiESP32.h @@ -31,7 +31,8 @@ public: const char *wifiPassword, const char *hostname, const int port, - const byte channel); + const byte channel, + const bool forceAP); static void loop(); private: }; diff --git a/WifiInterface.cpp b/WifiInterface.cpp index 3a88aea..c377319 100644 --- a/WifiInterface.cpp +++ b/WifiInterface.cpp @@ -83,7 +83,8 @@ bool WifiInterface::setup(long serial_link_speed, const FSH *wifiPassword, const FSH *hostname, const int port, - const byte channel) { + const byte channel, + const bool forceAP) { wifiSerialState wifiUp = WIFI_NOAT; @@ -100,7 +101,7 @@ bool WifiInterface::setup(long serial_link_speed, // See if the WiFi is attached to the first serial port #if NUM_SERIAL > 0 && !defined(SERIAL1_COMMANDS) SERIAL1.begin(serial_link_speed); - wifiUp = setup(SERIAL1, wifiESSID, wifiPassword, hostname, port, channel); + wifiUp = setup(SERIAL1, wifiESSID, wifiPassword, hostname, port, channel, forceAP); #endif // Other serials are tried, depending on hardware. @@ -110,7 +111,7 @@ bool WifiInterface::setup(long serial_link_speed, if (wifiUp == WIFI_NOAT) { Serial2.begin(serial_link_speed); - wifiUp = setup(Serial2, wifiESSID, wifiPassword, hostname, port, channel); + wifiUp = setup(Serial2, wifiESSID, wifiPassword, hostname, port, channel, forceAP); } #endif #endif @@ -121,7 +122,7 @@ bool WifiInterface::setup(long serial_link_speed, if (wifiUp == WIFI_NOAT) { SERIAL3.begin(serial_link_speed); - wifiUp = setup(SERIAL3, wifiESSID, wifiPassword, hostname, port, channel); + wifiUp = setup(SERIAL3, wifiESSID, wifiPassword, hostname, port, channel, forceAP); } #endif @@ -139,7 +140,7 @@ bool WifiInterface::setup(long serial_link_speed, } wifiSerialState WifiInterface::setup(Stream & setupStream, const FSH* SSid, const FSH* password, - const FSH* hostname, int port, byte channel) { + const FSH* hostname, int port, byte channel, bool forceAP) { wifiSerialState wifiState; static uint8_t ntry = 0; ntry++; @@ -148,7 +149,7 @@ wifiSerialState WifiInterface::setup(Stream & setupStream, const FSH* SSid, con DIAG(F("++ Wifi Setup Try %d ++"), ntry); - wifiState = setup2( SSid, password, hostname, port, channel); + wifiState = setup2( SSid, password, hostname, port, channel, forceAP); if (wifiState == WIFI_NOAT) { LCD(4, F("WiFi no AT chip")); @@ -172,7 +173,7 @@ wifiSerialState WifiInterface::setup(Stream & setupStream, const FSH* SSid, con #pragma GCC diagnostic ignored "-Wunused-parameter" #endif wifiSerialState WifiInterface::setup2(const FSH* SSid, const FSH* password, - const FSH* hostname, int port, byte channel) { + const FSH* hostname, int port, byte channel, bool forceAP) { bool ipOK = false; bool oldCmd = false; @@ -225,7 +226,7 @@ wifiSerialState WifiInterface::setup2(const FSH* SSid, const FSH* password, if (!checkForOK(1000, F("0.0.0.0"), true,false)) ipOK = true; } - } else { + } else if (!forceAP) { // SSID was configured, so we assume station (client) mode. if (oldCmd) { // AT command early version supports CWJAP/CWSAP @@ -285,14 +286,19 @@ wifiSerialState WifiInterface::setup2(const FSH* SSid, const FSH* password, i=0; do { - if (STRNCMP_P(yourNetwork, (const char*)password, 13) == 0) { - // unconfigured - StringFormatter::send(wifiStream, F("AT+CWSAP%s=\"DCCEX_%s\",\"PASS_%s\",%d,4\r\n"), - oldCmd ? "" : "_CUR", macTail, macTail, channel); + if (!forceAP) { + if (STRNCMP_P(yourNetwork, (const char*)password, 13) == 0) { + // unconfigured + StringFormatter::send(wifiStream, F("AT+CWSAP%s=\"DCCEX_%s\",\"PASS_%s\",%d,4\r\n"), + oldCmd ? "" : "_CUR", macTail, macTail, channel); + } else { + // password configured by user + StringFormatter::send(wifiStream, F("AT+CWSAP%s=\"DCCEX_%s\",\"%S\",%d,4\r\n"), oldCmd ? "" : "_CUR", + macTail, password, channel); + } } else { - // password configured by user - StringFormatter::send(wifiStream, F("AT+CWSAP%s=\"DCCEX_%s\",\"%S\",%d,4\r\n"), oldCmd ? "" : "_CUR", - macTail, password, channel); + StringFormatter::send(wifiStream, F("AT+CWSAP%s=\"%s\",\"%s\",%d,4\r\n"), + oldCmd ? "" : "_CUR", SSid, password, channel); } } while (!checkForOK(WIFI_CONNECT_TIMEOUT, true) && i++<2); // do twice if necessary but ignore failure as AP mode may still be ok if (i >= 2) diff --git a/WifiInterface.h b/WifiInterface.h index 7c0a433..33bc211 100644 --- a/WifiInterface.h +++ b/WifiInterface.h @@ -36,17 +36,18 @@ public: const FSH *wifiPassword, const FSH *hostname, const int port, - const byte channel); + const byte channel, + const bool forceAP); static void loop(); static void ATCommand(HardwareSerial * stream,const byte *command); private: static wifiSerialState setup(Stream &setupStream, const FSH *SSSid, const FSH *password, - const FSH *hostname, int port, byte channel); + const FSH *hostname, int port, byte channel, bool forceAP); static Stream *wifiStream; static DCCEXParser parser; static wifiSerialState setup2(const FSH *SSSid, const FSH *password, - const FSH *hostname, int port, byte channel); + const FSH *hostname, int port, byte channel, bool forceAP); static bool checkForOK(const unsigned int timeout, bool echo, bool escapeEcho = true); static bool checkForOK(const unsigned int timeout, const FSH *waitfor, bool echo, bool escapeEcho = true); static bool connected; diff --git a/config.example.h b/config.example.h index a945ec9..9fe6135 100644 --- a/config.example.h +++ b/config.example.h @@ -123,6 +123,11 @@ The configuration file for DCC-EX Command Station // this line exists or not. If you need to use an alternate channel (we recommend // using only 1,6, or 11) you may change it here. #define WIFI_CHANNEL 1 +// +// WIFI_FORCE_AP: If you'd like to specify your own WIFI_SSID in AP mode, set this +// true. Otherwise it is assumed that you'd like to connect to an existing network +// with that SSID. +#define WIFI_FORCE_AP false ///////////////////////////////////////////////////////////////////////////////////// //