@ -2,8 +2,8 @@
* AutoConnect class implementation .
* @ file AutoConnect . cpp
* @ author hieromon @ gmail . com
* @ version 1.1 .1
* @ date 2019 - 10 - 17
* @ version 1.1 .5
* @ date 2019 - 03 - 17
* @ copyright MIT license .
*/
@ -95,15 +95,6 @@ bool AutoConnect::begin(const char* ssid, const char* passphrase, unsigned long
_ticker - > start ( AUTOCONNECT_FLICKER_PERIODDC , ( uint8_t ) AUTOCONNECT_FLICKER_WIDTHDC ) ;
}
// Advance configuration for STA mode. Restore previous configuration of STA.
station_config_t current ;
if ( _getConfigSTA ( & current ) ) {
AC_DBG ( " Current:%.32s \n " , current . ssid ) ;
_loadAvailCredential ( reinterpret_cast < const char * > ( current . ssid ) ) ;
}
if ( ! _configSTA ( _apConfig . staip , _apConfig . staGateway , _apConfig . staNetmask , _apConfig . dns1 , _apConfig . dns2 ) )
return false ;
// If the portal is requested promptly skip the first WiFi.begin and
// immediately start the portal.
if ( _apConfig . immediateStart ) {
@ -112,29 +103,47 @@ bool AutoConnect::begin(const char* ssid, const char* passphrase, unsigned long
AC_DBG ( " Start the portal immediately \n " ) ;
}
else {
// Try to connect by STA immediately.
if ( ssid = = nullptr & & passphrase = = nullptr )
WiFi . begin ( ) ;
else {
_disconnectWiFi ( false ) ;
WiFi . begin ( ssid , passphrase ) ;
cs = true ;
// Prepare valid configuration according to the WiFi connection right order.
const char * c_ssid = ssid ;
const char * c_password = passphrase ;
station_config_t current ;
if ( _getConfigSTA ( & current ) )
AC_DBG ( " Current:%.32s \n " , current . ssid ) ;
if ( _apConfig . wifiDisp = = AC_WIFIDISP_RSSI & & ( ssid = = nullptr & & passphrase = = nullptr ) ) {
// AC_WIFIDISP_RSSI is available when SSID and password are not provided.
// Find the strongest signal from the broadcast among the saved credentials.
if ( ( cs = _loadAvailCredential ( nullptr , AC_WIFIDISP_RSSI , false ) ) ) {
memcpy ( current . ssid , _credential . ssid , sizeof ( station_config_t : : ssid ) ) ;
memcpy ( current . password , _credential . password , sizeof ( station_config_t : : password ) ) ;
c_ssid = reinterpret_cast < const char * > ( current . ssid ) ;
c_password = reinterpret_cast < const char * > ( current . password ) ;
AC_DBG ( " Adopted:%.32s \n " , c_ssid ) ;
}
}
AC_DBG ( " WiFi.begin(%s%s%s) \n " , ssid = = nullptr ? " " : ssid , passphrase = = nullptr ? " " : " , " , passphrase = = nullptr ? " " : passphrase ) ;
cs = _waitForConnect ( _connectTimeout ) = = WL_CONNECTED ;
# ifdef INC_RSSI_USE_SUP //!!!
if ( cs = = true ) {
if ( WiFi . RSSI ( ) < _apConfig . conMinRSSI | | _apConfig . conFindMaxRSSI = = true ) {
_disconnectWiFi ( false ) ;
cs = false ;
if ( cs ) {
// Advance configuration for STA mode. Restore previous configuration of STA.
_loadAvailCredential ( reinterpret_cast < const char * > ( current . ssid ) ) ;
if ( ! _configSTA ( _apConfig . staip , _apConfig . staGateway , _apConfig . staNetmask , _apConfig . dns1 , _apConfig . dns2 ) )
return false ;
// Try to connect by STA immediately.
if ( c_ssid = = nullptr & & c_password = = nullptr )
WiFi . begin ( ) ;
else {
_disconnectWiFi ( false ) ;
WiFi . begin ( c_ssid , c_password ) ;
}
AC_DBG ( " WiFi.begin(%s%s%s) \n " , c_ssid = = nullptr ? " " : c_ssid , c_password = = nullptr ? " " : " , " , c_password = = nullptr ? " " : c_password ) ;
cs = _waitForConnect ( _connectTimeout ) = = WL_CONNECTED ;
}
# endif
}
// Reconnect with a valid credential as the autoReconnect option is enabled.
if ( ! cs & & _apConfig . autoReconnect & & ( ssid = = nullptr & & passphrase = = nullptr ) ) {
// Load a valid credential.
if ( _loadAvailCredential ( nullptr ) ) {
if ( _loadAvailCredential ( nullptr , _apConfig . wifiDisp , true ) ) {
// Try to reconnect with a stored credential.
char ssid_c [ sizeof ( station_config_t : : ssid ) + sizeof ( ' \0 ' ) ] ;
char password_c [ sizeof ( station_config_t : : password ) + sizeof ( ' \0 ' ) ] ;
@ -142,7 +151,7 @@ bool AutoConnect::begin(const char* ssid, const char* passphrase, unsigned long
strncat ( ssid_c , reinterpret_cast < const char * > ( _credential . ssid ) , sizeof ( ssid_c ) - sizeof ( ' \0 ' ) ) ;
* password_c = ' \0 ' ;
strncat ( password_c , reinterpret_cast < const char * > ( _credential . password ) , sizeof ( password_c ) - sizeof ( ' \0 ' ) ) ;
AC_DBG ( " autoReconnect loaded SSID :%s \n " , ssid_c ) ;
AC_DBG ( " autoReconnect loaded:%s(%s) \n " , ssid_c , _apConfig . wifiDisp = = AC_WIFIDISP_RECENT ? " RECENT " : " RSSI " ) ;
const char * psk = strlen ( password_c ) ? password_c : nullptr ;
_configSTA ( IPAddress ( _credential . config . sta . ip ) , IPAddress ( _credential . config . sta . gateway ) , IPAddress ( _credential . config . sta . netmask ) , IPAddress ( _credential . config . sta . dns1 ) , IPAddress ( _credential . config . sta . dns2 ) ) ;
WiFi . begin ( ssid_c , psk ) ;
@ -620,9 +629,11 @@ void AutoConnect::onNotFound(WebServerClass::THandlerFunction fn) {
/**
* Load stored credentials that match nearby WLANs .
* @ param ssid SSID which should be loaded . If nullptr is assigned , search SSID with WiFi . scan .
* @ param wifiDisp WiFi connection disposition .
* @ param excludeCurrent Skip loading the current SSID .
* @ return true A matched credential of BSSID was loaded .
*/
bool AutoConnect : : _loadAvailCredential ( const char * ssid ) {
bool AutoConnect : : _loadAvailCredential ( const char * ssid , const AC_WIFIDISP_t wifiDisp , const bool excludeCurrent ) {
AutoConnectCredential credential ( _apConfig . boundaryOffset ) ;
if ( credential . entries ( ) > 0 ) {
@ -632,49 +643,55 @@ bool AutoConnect::_loadAvailCredential(const char* ssid) {
int8_t nn = WiFi . scanNetworks ( false , true ) ;
AC_DBG ( " %d network(s) found \n " , ( int ) nn ) ;
if ( nn > 0 ) {
// Determine valid credentials by BSSID.
# ifdef INC_RSSI_USE_SUP //!!!
int maxRSSIWifiIndex = - 1 ;
int maxRSSICredIndex = - 1 ;
# endif
station_config_t validConfig ; // Temporary to find the strongest RSSI.
int32_t minRSSI = - 120 ; // Min value to find the strongest RSSI.
// Seek SSID
const char * currentSSID = WiFi . SSID ( ) . c_str ( ) ;
const bool skipCurrent = excludeCurrent & ( strlen ( currentSSID ) > 0 ) ;
for ( uint8_t i = 0 ; i < credential . entries ( ) ; i + + ) {
credential . load ( i , & _credential ) ;
// Seek valid configuration according to the WiFi connection disposition.
// Verify that an available SSIDs meet AC_WIFIDISP_t requirements.
for ( uint8_t n = 0 ; n < nn ; n + + ) {
# ifdef INC_RSSI_USE_SUP //!!!
if ( skipCurrent & & ! strcmp ( currentSSID , WiFi . SSID ( n ) . c_str ( ) ) )
continue ;
if ( ! memcmp ( _credential . bssid , WiFi . BSSID ( n ) , sizeof ( station_config_t : : bssid ) ) ) {
if ( WiFi . RSSI ( n ) > = _apConfig . conMinRSSI ) {
if ( _apConfig . conFindMaxRSSI ! = true ) {
return true ;
}
if ( maxRSSIWifiIndex < 0 ) {
maxRSSIWifiIndex = n ;
maxRSSICredIndex = i ;
} else {
if ( WiFi . RSSI ( n ) > WiFi . RSSI ( maxRSSIWifiIndex ) ) {
maxRSSIWifiIndex = n ;
maxRSSICredIndex = i ;
}
}
}
}
# else
if ( ! memcmp ( _credential . bssid , WiFi . BSSID ( n ) , sizeof ( station_config_t : : bssid ) ) )
return true ;
# endif
// Excepts SSID that has weak RSSI under the lower limit.
if ( WiFi . RSSI ( n ) < _apConfig . minRSSI ) {
AC_DBG ( " %s:% " PRId32 " dBm, rejected \n " , reinterpret_cast < const char * > ( _credential . ssid ) , WiFi . RSSI ( n ) ) ;
continue ;
}
// Determine valid credential
switch ( wifiDisp ) {
case AC_WIFIDISP_RECENT :
// By BSSID, exit to keep the credential just loaded.
return true ;
case AC_WIFIDISP_RSSI :
// Verify that most strong radio signal.
// Continue seeking to find the strongest WIFI signal SSID.
if ( WiFi . RSSI ( n ) > minRSSI ) {
minRSSI = WiFi . RSSI ( n ) ;
memcpy ( & validConfig , & _credential , sizeof ( station_config_t ) ) ;
}
break ;
}
break ;
}
}
}
# ifdef INC_RSSI_USE_SUP //!!!
if ( maxRSSIWifiIndex > = 0 ) {
credential . load ( maxRSSICredIndex , & _credential ) ;
return true ;
}
# endif
// Increasing the minSSI will indicate the successfully sought for AC_WIFIDISP_RSSI.
// Restore the credential that has maximum RSSI.
if ( minRSSI > - 120 ) {
memcpy ( & _credential , & validConfig , sizeof ( station_config_t ) ) ;
return true ;
}
}
}
// The SSID to load was specified.
// Set the IP configuration globally from the saved credential.
else if ( strlen ( ssid ) )
if ( credential . load ( ssid , & _credential ) > = 0 ) {
if ( _credential . dhcp = = STA_STATIC ) {