Page 1 of 1

WiFi on AP mode stopped working (forever?) after softAPdisconnect()

Posted: Mon Jan 15, 2024 11:08 am
by ssraposo
Hi!

I've been working on a Wi-Fi AP project and doing several changes to experiment results and after using softAPdisconnect(), I've noticed ESP32 was not transmitting anymore, even after resetting, turning it off and on and erasing flash.
At a initial moment, I could not realize that this problem happened after using softAPdisconnect().

I've removed little by little the last changes but nothing made the AP work again.

So, I've taken a second ESP32 module and the AP project came back to life. I spared the first ESP32 for a later investigation.

Back to the development of the AP project, at certain moment I included again softAPdisconnect() and the previous problem arose again. This time I could realize that it was related to this function, but I have no clue why, even after checking WiFiAP.cpp to understand what this fucttion does.

Again, a new ESP32 module was taken and the AP functions again. This time softAPdisconnect() was removed.

I do not know if what caused the problem was either softAPdisconnect( true ) or softAPdisconnect( false ). Both?

I've spending A LOT of time trying to recover those 2 ESP32 modules in order to be used as AP again. All failed till now. As a station (client), it works.

BTW, Functions "enableSTA(true)", "WiFi.mode( WIFI_MODE_STA )", "esp_wifi_set_mode( mode )" ("mode" previously set to "WIFI_MODE_STA") do not change mode value. It's always "WIFI_MODE_NULL", according to the result of "esp_wifi_get_mode( &mode )". It ALWAYS returns "ESP_OK" and put the "WIFI_MODE_NULL" value on "mode" variable.
Notice: this constant return of "WIFI_MODE_NULL" happens even on a ESP32 module that is AP operative.

So, the questions:
1) How I will make those two ESP32 modules back to normal?
2) What should I do to stop ESP32 of working as AP but without preventing it from work as AP again?

Re: WiFi on AP mode stopped working (forever?) after softAPdisconnect()

Posted: Mon Jan 15, 2024 5:53 pm
by ssraposo
Code is very simple but enough to show that an ESP32 has not been submited to the function softAPdisconnect() works and the two ones that softAPdisconnect() was executed, not.



//---------------------------------------------------------------------------------------------------------------------------------
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#include "esp_wifi.h"
#include "WiFiGeneric.h"
#include "WiFiServer.h"
#include <stdio.h>
#include <Strings.h>

//
// Defines
//

#define MAXIMUM_CONNECTED_STATIONS 50

//
// Variables
//

int msgCounter = 0;

const char* ssid = "uPesy_AP"; // SSID Name
const char* password = "super_strong_password"; // SSID Password - Set to NULL to have an open AP
const int channel = 10; // WiFi Channel number between 1 and 13
const bool hide_SSID = false; // To disable SSID broadcast -> SSID will not appear in a basic WiFi scan
const int max_connection = 2; // Maximum simultaneous connected clients on the AP

void showCurrentMode( const char *texto )
{
wifi_mode_t mode;

msgCounter++;
ets_printf( "\n%03d %s\n\tData returned from esp_wifi_get_mode: ", msgCounter, texto );
switch( esp_wifi_get_mode( &mode ))
{
case ESP_OK:
{
ets_printf( "ESP_OK\n" );
break;
}
case ESP_ERR_WIFI_NOT_INIT:
{
ets_printf( "ESP_ERR_WIFI_NOT_INIT\n" );
break;
}
case ESP_ERR_INVALID_ARG:
{
ets_printf( "ESP_ERR_INVALID_ARG\n" );
break;
}
default:
{
ets_printf( "resultado desconhecido\n" );
}
}
ets_printf( "\tMode: " );
switch( esp_wifi_get_mode( &mode ))
{
case WIFI_MODE_NULL:
{
ets_printf( "WIFI_MODE_NULL %d\n", WIFI_MODE_NULL );
break;
}
case WIFI_MODE_STA:
{
ets_printf( "WIFI_MODE_STA - %d\n", WIFI_MODE_STA );
break;
}
case WIFI_MODE_AP:
{
ets_printf( "WIFI_MODE_AP - %d\n", WIFI_MODE_AP );
break;
}
case WIFI_MODE_APSTA:
{
ets_printf( "WIFI_MODE_APSTA - %d\n", WIFI_MODE_APSTA );
break;
}
case WIFI_MODE_MAX:
{
ets_printf( "WIFI_MODE_MAX - %d\n", WIFI_MODE_MAX );
break;
}
default:
{
ets_printf( "Unkown value\n" );
}
}
}

void setup()
{
wifi_mode_t mode;
Serial.begin( 921600 );

ets_printf( "\n" );
Serial.println("\n[*] Creating AP");

showCurrentMode( "Before esp_wifi_start()" );

mode = WIFI_MODE_AP;
WiFi.mode( mode );

showCurrentMode( "After WiFi.mode( mode )" );

WiFi.softAP( ssid, password );

showCurrentMode( "After WiFi.softAP( ssid, password )" );

Serial.print( "[+] AP Created with IP Gateway " );
Serial.println( WiFi.softAPIP() );
}

void loop()
{
}
//---------------------------------------------------------------------------------------------------------------------------------

Following printout is the same for the two groups of ESP32:

************************************************************************************************************************************
[*] Creating AP

001 Before esp_wifi_start()
Data returned from esp_wifi_get_mode: ESP_ERR_WIFI_NOT_INIT
Mode: Unkown value

002 After esp_wifi_start()
Data returned from esp_wifi_get_mode: ESP_ERR_WIFI_NOT_INIT
Mode: Unkown value

getMode() - !lowLevelInitDone || !_esp_wifi_started - #1

getMode() - !lowLevelInitDone - #1.1

getMode() - !_esp_wifi_started - #1.2

wifiLowLevelInit() - @1

wifiLowLevelInit() - @2

wifiLowLevelInit() - @4

wifiLowLevelInit() - @5

wifiLowLevelInit() - @6

wifiLowLevelInit() - @9

wifiLowLevelInit() - @10

espWiFiStart() - $3

mode $13

003 After WiFi.mode( mode )
Data returned from esp_wifi_get_mode: ESP_OK
Mode: WIFI_MODE_NULL 0

getMode() - fim - #3

softAP() - =6
ssid: uPesy_AP
pass: super_strong_password
cana: 1
hidd: 0
mac_: 4
stm_: 0

004 After WiFi.softAP( ssid, password )
Data returned from esp_wifi_get_mode: ESP_OK
Mode: WIFI_MODE_NULL 0
[+] AP Created with IP Gateway
getMode() - fim - #3
192.168.4.1
************************************************************************************************************************************



Wifigeneric.cpp and Wifista.cpp were modified to add some messages for tracking purpose:



wifi_mode_t WiFiGenericClass::getMode()
{
if(!lowLevelInitDone || !_esp_wifi_started){
//ssrxxxteste
ets_printf( "\ngetMode() - !lowLevelInitDone || !_esp_wifi_started - #1\n" );//ssrxxxteste
if( !lowLevelInitDone )
{
ets_printf( "\ngetMode() - !lowLevelInitDone - #1.1\n" );//ssrxxxteste
}
if( !_esp_wifi_started )
{
ets_printf( "\ngetMode() - !_esp_wifi_started - #1.2\n" );//ssrxxxteste
}
//ssrxxxteste
return WIFI_MODE_NULL;
}



bool wifiLowLevelInit(bool persistent){
ets_printf( "\nwifiLowLevelInit() - @1\n" );//ssrxxxteste
if(!lowLevelInitDone){
ets_printf( "\nwifiLowLevelInit() - @2\n" );//ssrxxxteste
lowLevelInitDone = true;
if(!tcpipInit()){
ets_printf( "\nwifiLowLevelInit() - @3\n" );//ssrxxxteste
lowLevelInitDone = false;
return lowLevelInitDone;
}
if(esp_netifs[ESP_IF_WIFI_AP] == NULL){
ets_printf( "\nwifiLowLevelInit() - @4\n" );//ssrxxxteste
esp_netifs[ESP_IF_WIFI_AP] = esp_netif_create_default_wifi_ap();
}
if(esp_netifs[ESP_IF_WIFI_STA] == NULL){
ets_printf( "\nwifiLowLevelInit() - @5\n" );//ssrxxxteste
esp_netifs[ESP_IF_WIFI_STA] = esp_netif_create_default_wifi_sta();
}

wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();

if(!WiFiGenericClass::useStaticBuffers()) {
ets_printf( "\nwifiLowLevelInit() - @6\n" );//ssrxxxteste
cfg.static_tx_buf_num = 0;
cfg.dynamic_tx_buf_num = 32;
cfg.tx_buf_type = 1;
cfg.cache_tx_buf_num = 4; // can't be zero!
cfg.static_rx_buf_num = 4;
cfg.dynamic_rx_buf_num = 32;
}

esp_err_t err = esp_wifi_init(&cfg);
if(err){
log_e("esp_wifi_init %d", err);
lowLevelInitDone = false;
ets_printf( "\nwifiLowLevelInit() - @7\n" );//ssrxxxteste
return lowLevelInitDone;
}
// Temporary fix to ensure that CDC+JTAG stay on on ESP32-C3
#if CONFIG_IDF_TARGET_ESP32C3
phy_bbpll_en_usb(true);
#endif
if(!persistent){
ets_printf( "\nwifiLowLevelInit() - @8\n" );//ssrxxxteste
lowLevelInitDone = esp_wifi_set_storage(WIFI_STORAGE_RAM) == ESP_OK;
}
if(lowLevelInitDone){
ets_printf( "\nwifiLowLevelInit() - @9\n" );//ssrxxxteste
arduino_event_t arduino_event;
arduino_event.event_id = ARDUINO_EVENT_WIFI_READY;
postArduinoEvent(&arduino_event);
}
}
ets_printf( "\nwifiLowLevelInit() - @10\n" );//ssrxxxteste
return lowLevelInitDone;
}



static bool espWiFiStart(){
if(_esp_wifi_started){
ets_printf( "\nespWiFiStart() - $1\n" );//ssrxxxteste
return true;
}
_esp_wifi_started = true;
esp_err_t err = esp_wifi_start();
if (err != ESP_OK) {
ets_printf( "\nespWiFiStart() - $2\n" );//ssrxxxteste
_esp_wifi_started = false;
log_e("esp_wifi_start %d", err);
return _esp_wifi_started;
}
ets_printf( "\nespWiFiStart() - $3\n" );//ssrxxxteste
return _esp_wifi_started;
}



bool WiFiGenericClass::mode(wifi_mode_t m)
{
wifi_mode_t cm = getMode();
if(cm == m) {
ets_printf( "\n$1\n" );//ssrxxxteste
return true;
}
if(!cm && m){
if(!wifiLowLevelInit(_persistent)){
ets_printf( "\n$2\n" );//ssrxxxteste
return false;
}
} else if(cm && !m){
ets_printf( "\n$3\n" );//ssrxxxteste
return espWiFiStop();
}

esp_err_t err;
if(m & WIFI_MODE_STA){
ets_printf( "\n$4\n" );//ssrxxxteste
err = set_esp_interface_hostname(ESP_IF_WIFI_STA, get_esp_netif_hostname());
if(err){
log_e("Could not set hostname! %d", err);
ets_printf( "\n$5\n" );//ssrxxxteste
return false;
}
}
err = esp_wifi_set_mode(m);
if(err){
log_e("Could not set mode! %d", err);
ets_printf( "\n$6\n" );//ssrxxxteste
return false;
}
if(_long_range){
ets_printf( "\n$7\n" );//ssrxxxteste
if(m & WIFI_MODE_STA){
ets_printf( "\n$8\n" );//ssrxxxteste
err = esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_LR);
if(err != ESP_OK){
log_e("Could not enable long range on STA! %d", err);
ets_printf( "\n$9\n" );//ssrxxxteste
return false;
}
}
if(m & WIFI_MODE_AP){
ets_printf( "\n$10\n" );//ssrxxxteste
err = esp_wifi_set_protocol(WIFI_IF_AP, WIFI_PROTOCOL_LR);
if(err != ESP_OK){
log_e("Could not enable long range on AP! %d", err);
ets_printf( "\n$11\n" );//ssrxxxteste
return false;
}
}
}
if(!espWiFiStart()){
ets_printf( "\n$12\n" );//ssrxxxteste
return false;
}

#ifdef BOARD_HAS_DUAL_ANTENNA
if(!setDualAntennaConfig(ANT1, ANT2, WIFI_RX_ANT_AUTO, WIFI_TX_ANT_AUTO)){
log_e("Dual Antenna Config failed!");
return false;
}
#endif
ets_printf( "\nmode $13\n" );//ssrxxxteste
return true;
}



wifi_mode_t WiFiGenericClass::getMode()
{
if(!lowLevelInitDone || !_esp_wifi_started){
//ssrxxxteste
ets_printf( "\ngetMode() - !lowLevelInitDone || !_esp_wifi_started - #1\n" );//ssrxxxteste
if( !lowLevelInitDone )
{
ets_printf( "\ngetMode() - !lowLevelInitDone - #1.1\n" );//ssrxxxteste
}
if( !_esp_wifi_started )
{
ets_printf( "\ngetMode() - !_esp_wifi_started - #1.2\n" );//ssrxxxteste
}
//ssrxxxteste
return WIFI_MODE_NULL;
}
wifi_mode_t mode;
if(esp_wifi_get_mode(&mode) != ESP_OK){
ets_printf( "\ngetMode() #2\n" );//ssrxxxteste
log_w("WiFi not started");
return WIFI_MODE_NULL;
}
ets_printf( "\ngetMode() - fim - #3\n" );//ssrxxxteste
return mode;
}



bool WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden, int max_connection, bool ftm_responder)
{

if(!ssid || *ssid == 0) {
// fail SSID missing
log_e("SSID missing!");
ets_printf( "\n=1\n" );//ssrxxxteste
return false;
}

if(passphrase && (strlen(passphrase) > 0 && strlen(passphrase) < 8)) {
// fail passphrase too short
log_e("passphrase too short!");
ets_printf( "\n=2\n" );//ssrxxxteste
return false;
}

// last step after checking the SSID and password
if(!WiFi.enableAP(true)) {
// enable AP failed
log_e("enable AP first!");
ets_printf( "\n=3\n" );//ssrxxxteste
return false;
}

wifi_config_t conf;
wifi_config_t conf_current;
wifi_softap_config(&conf, ssid, passphrase, channel, WIFI_AUTH_WPA2_PSK, ssid_hidden, max_connection, ftm_responder);
esp_err_t err = esp_wifi_get_config((wifi_interface_t)WIFI_IF_AP, &conf_current);
if(err){
log_e("get AP config failed");
ets_printf( "\n=4\n" );//ssrxxxteste
return false;
}
if(!softap_config_equal(conf, conf_current)) {
err = esp_wifi_set_config((wifi_interface_t)WIFI_IF_AP, &conf);
if(err){
log_e("set AP config failed");
ets_printf( "\n=5\n" );//ssrxxxteste
return false;
}
}
//ssrxxxteste
ets_printf( "\nsoftAP() - =6\n"
"\tssid: %s\n"
"\tpass: %s\n"
"\tcana: %d\n"
"\thidd: %d\n"
"\tmac_: %d\n"
"\tstm_: %d\n",
ssid, passphrase, channel, ssid_hidden, max_connection, ftm_responder );
//ssrxxxteste
return true;
}



That is like the ESP32 module that executed softAPdisconnect() suffered some damage (what doesn't make any sense) or some especial flag/value were written on flash that prevents ESP32 tx radio from work.