feat(lobby): implement bounded WebSocket sessions and countdown

This commit is contained in:
2026-09-04 02:13:26 +03:00
parent b10c7f5972
commit 996bda9567
21 changed files with 2040 additions and 64 deletions
+29 -19
View File
@@ -10,21 +10,21 @@
#endif
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "maze32_health.h"
#include "maze32_config_store.h"
#include "maze32_health.h"
#include "maze32_network.h"
#include "maze32_web.h"
static const char *TAG = "maze32";
static const char* TAG = "maze32";
static maze32_health_t health;
static httpd_handle_t web_server;
static maze32_network_t network;
static maze32_gateway_t gateway;
#ifdef MAZE32_MILESTONE_003_DEVICE_TEST
static int device_test_has_persisted_credentials;
static esp_err_t run_device_test_before_network(void)
{
static esp_err_t run_device_test_before_network(void) {
const maze32_wifi_credentials_t expected = {
.ssid = "maze32-unavailable-test",
.password = "test-only-password",
@@ -49,8 +49,7 @@ static esp_err_t run_device_test_before_network(void)
return ESP_OK;
}
static esp_err_t finish_device_test(void)
{
static esp_err_t finish_device_test(void) {
if (!device_test_has_persisted_credentials) {
return ESP_ERR_INVALID_STATE;
}
@@ -62,15 +61,17 @@ static esp_err_t finish_device_test(void)
}
#endif
static int prepare_for_network_reconfiguration(void *context)
{
(void)context;
ESP_LOGW(TAG, "Runtime accepted network reconfiguration; no active match exists");
static int prepare_for_network_reconfiguration(void* context) {
const maze32_gateway_t* current_gateway = context;
if (!maze32_gateway_can_reconfigure(current_gateway)) {
ESP_LOGW(TAG, "Network reconfiguration rejected while lobby is active");
return -1;
}
ESP_LOGW(TAG, "Runtime accepted network reconfiguration while lobby is waiting");
return 0;
}
static esp_err_t mount_littlefs(void)
{
static esp_err_t mount_littlefs(void) {
const esp_vfs_littlefs_conf_t configuration = {
.base_path = "/littlefs",
.partition_label = "littlefs",
@@ -91,14 +92,13 @@ static esp_err_t mount_littlefs(void)
return result;
}
ESP_LOGI(TAG, "LittleFS mounted: total=%u bytes, used=%u bytes",
(unsigned int)total_bytes, (unsigned int)used_bytes);
ESP_LOGI(TAG, "LittleFS mounted: total=%u bytes, used=%u bytes", (unsigned int)total_bytes,
(unsigned int)used_bytes);
return ESP_OK;
}
void app_main(void)
{
const esp_app_desc_t *application = esp_app_get_description();
void app_main(void) {
const esp_app_desc_t* application = esp_app_get_description();
maze32_health_init(&health, application->version);
vTaskDelay(pdMS_TO_TICKS(1500));
@@ -143,7 +143,14 @@ void app_main(void)
return;
}
result = maze32_network_init(&network, prepare_for_network_reconfiguration, NULL);
result = maze32_gateway_init(&gateway);
if (result != ESP_OK) {
maze32_health_set(&health, MAZE32_HEALTH_ERROR, (int)result);
ESP_LOGE(TAG, "WebSocket gateway initialization failed: %s", esp_err_to_name(result));
return;
}
result = maze32_network_init(&network, prepare_for_network_reconfiguration, &gateway);
if (result == ESP_OK) {
result = maze32_network_start(&network);
}
@@ -161,7 +168,10 @@ void app_main(void)
}
#endif
result = maze32_web_start(&web_server, &health);
result = maze32_web_start(&web_server, &health, &gateway);
if (result == ESP_OK) {
result = maze32_gateway_register(web_server, &gateway);
}
if (result == ESP_OK) {
result = maze32_provisioning_register(web_server, &network);
}