When the program starts, I start and initialise the wifi in AP_STA mode with the following function:
Code: Select all
void WIFI_INIT_AP_STA(void)
{
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
//ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); // since we always do this after scanning, dont need to add event loop anymore
esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
assert(ap_netif);
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&wifi_event_handler,NULL,NULL));
wifi_config_t wifi_config = {
.ap = {
.ssid = EXAMPLE_ESP_WIFI_SSID_AP,
.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID_AP),
.channel = EXAMPLE_ESP_WIFI_CHANNEL,
.password = EXAMPLE_ESP_WIFI_PASS_AP,
.max_connection = EXAMPLE_MAX_STA_CONN,
.authmode = WIFI_AUTH_WPA_WPA2_PSK
},
};
if (strlen(EXAMPLE_ESP_WIFI_PASS_AP) == 0) {
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI("WIFI AP", "wifi_init_softap finished. SSID:%s password:%s channel:%d",
EXAMPLE_ESP_WIFI_SSID_AP, EXAMPLE_ESP_WIFI_PASS_AP, EXAMPLE_ESP_WIFI_CHANNEL);
}
Code: Select all
esp_err_t start_file_server(const char *base_path)
{
static struct file_server_data *server_data = NULL;
/* Validate file storage base path */
if (!base_path || strcmp(base_path, "/spiffs") != 0) {
ESP_LOGE("START_SERVER", "File server presently supports only '/spiffs' as base path");
return ESP_ERR_INVALID_ARG;
}
if (server_data) {
ESP_LOGE("START_SERVER", "File server already started");
return ESP_ERR_INVALID_STATE;
}
/* Allocate memory for server data */
server_data = calloc(1, sizeof(struct file_server_data));
if (!server_data) {
ESP_LOGE("START_SERVER", "Failed to allocate memory for server data");
return ESP_ERR_NO_MEM;
}
strlcpy(server_data->base_path, base_path,
sizeof(server_data->base_path));
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
/* Use the URI wildcard matching function in order to
* allow the same handler to respond to multiple different
* target URIs which match the wildcard scheme */
config.uri_match_fn = httpd_uri_match_wildcard;
ESP_LOGI("START_SERVER", "Starting HTTP Server on port: '%d'", config.server_port);
if (httpd_start(&server, &config) != ESP_OK) {
ESP_LOGE("START_SERVER", "Failed to start file server!");
return ESP_FAIL;
}
//URI handler for getting uploaded files
httpd_uri_t file_download = {
.uri = "/", // Match all URIs of type /path/to/file
.method = HTTP_GET,
.handler = download_get_handler,
.user_ctx = server_data // Pass server data as context
};
httpd_register_uri_handler(server, &file_download);
httpd_uri_t image_handler = {
.uri = "/", // Match all URIs of type /path/to/file
.method = HTTP_GET,
.handler = image_get_handler,
.user_ctx = server_data // Pass server data as context
};
httpd_register_uri_handler(server, &file_download);
/* URI handler for uploading files to server */
httpd_uri_t file_upload = {
.uri = "/upload/*", // Match all URIs of type /upload/path/to/file
.method = HTTP_POST,
.handler = upload_post_handler,
.user_ctx = server_data // Pass server data as context
};
httpd_register_uri_handler(server, &file_upload);
/* URI handler for deleting files from server */
httpd_uri_t file_delete = {
.uri = "/delete/*", // Match all URIs of type /delete/path/to/file
.method = HTTP_POST,
.handler = delete_post_handler,
.user_ctx = server_data // Pass server data as context
};
httpd_register_uri_handler(server, &file_delete);
httpd_uri_t uri_post = {
.uri = "/rollback",
.method = HTTP_POST,
.handler = post_handler,
.user_ctx = NULL
};
httpd_register_uri_handler(server, &uri_post);
return ESP_OK;
}
So in my main.c, I call:
Code: Select all
WIFI_INIT_AP_STA();
ESP_ERROR_CHECK(start_file_server("/spiffs"));
Everything works as expected. Notice in my WIFI_INIT_AP_STA I have registered wifi_event_handler and there I can capture when the client connects and disconnects to my access point.
Code: Select all
static void wifi_event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data)
{
if (event_id == WIFI_EVENT_AP_STACONNECTED) {
wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
ESP_LOGI(TAG_WEBSERVER, "station "MACSTR" join, AID=%d",MAC2STR(event->mac), event->aid);
wifi_connected_clients += 1;
printf("connected clients = %u \n",wifi_connected_clients);
} else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
ESP_LOGI(TAG_WEBSERVER, "station "MACSTR" leave, AID=%d",MAC2STR(event->mac), event->aid);
wifi_connected_clients -= 1;
printf("connected clients = %u \n",wifi_connected_clients);
if(wifi_connected_clients == 0){
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server) {
ESP_LOGI(TAG_WEBSERVER, "Stopping webserver");
httpd_stop(*server);
*server = NULL;
}
}
}
}
When the client is disconnected, I want to stop the webserver so I use httpd_stop(*server);
But the program crashes immediately after calling this:
Code: Select all
connected clients = 0
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400e042f PS : 0x00060030 A0 : 0x801b7130 A1 : 0x3ffe1440
0x400e042f: wifi_event_handler at C:\Users\petrikas.lu\Work\Projects\Elstat\elstat\build/../components/WIFI/WIFI.c:527
A2 : 0x00000000 A3 : 0x3f42bf70 A4 : 0x00000000 A5 : 0x3ffbc040
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x800e042a A9 : 0x3ffe13f0
A10 : 0x00000017 A11 : 0x3ffdfc18 A12 : 0x3f4111a4 A13 : 0x00006a86
A14 : 0x3f411130 A15 : 0x00000098 SAR : 0x00000004 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
Backtrace:0x400e042c:0x3ffe14400x401b712d:0x3ffe1480 0x401b6c72:0x3ffe14b0 0x401b6d45:0x3ffe14f0 0x40090675:0x3ffe1510
0x400e042c: wifi_event_handler at C:\Users\petrikas.lu\Work\Projects\Elstat\elstat\build/../components/WIFI/WIFI.c:525
0x401b712d: handler_execute at C:/Users/petrikas.lu/esp/esp-idf/components/esp_event/esp_event.c:145
0x401b6c72: esp_event_loop_run at C:/Users/petrikas.lu/esp/esp-idf/components/esp_event/esp_event.c:590 (discriminator 3)
0x401b6d45: esp_event_loop_run_task at C:/Users/petrikas.lu/esp/esp-idf/components/esp_event/esp_event.c:115 (discriminator 15)
0x40090675: vPortTaskWrapper at C:/Users/petrikas.lu/esp/esp-idf/components/freertos/port/xtensa/port.c:131
ELF file SHA256: 6256c365e96cde0f
Rebooting...
ets Jul 29 2019 12:21:46
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:6604
ho 0 tail 12 room 4
load:0x40078000,len:14808
ho 0 tail 12 room 4
load:0x40080400,len:3792
0x40080400: _init at ??:?
entry 0x40080694