Move console payloads to lazy PSRAM storage

This commit is contained in:
2026-09-13 23:06:42 +02:00
parent 91267b371e
commit 4a53a21f31
12 changed files with 322 additions and 38 deletions
-6
View File
@@ -142,12 +142,6 @@ esp_err_t admin_ssh_console_dispatch_read_input(
esp_err_t admin_ssh_console_dispatch_defer(
admin_ssh_deferred_action_type_t action, uint32_t argument);
/* SSH compatibility entry point, implemented by the owner in ssh_transport.c.
* Token/principal are copied; no SSH or socket objects cross this boundary.
* Existing feed/close/read/snapshot APIs below also accept open_owned tokens.
*/
esp_err_t admin_ssh_console_open(const admin_ssh_console_token_t *token,
const user_principal_t *principal);
void admin_ssh_console_close(const admin_ssh_console_token_t *token);
/* Called by the session owner. Returns false when input must be backpressured. */
+13 -1
View File
@@ -12,6 +12,7 @@
#include "esp_console.h"
#include "esp_err.h"
#include "esp_heap_caps.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
@@ -186,7 +187,9 @@ typedef struct {
#define PING_EVENT_QUEUE_LENGTH (PING_MAX_COUNT + 1U)
static StaticQueue_t s_ping_queue_storage;
static uint8_t s_ping_queue_bytes[PING_EVENT_QUEUE_LENGTH * sizeof(ping_event_t)];
/* Dispatcher-owned lazy payload; retain for firmware lifetime so callback queue
* storage cannot dangle. Queue control stays internal. No internal-RAM fallback. */
static uint8_t *s_ping_queue_bytes;
static QueueHandle_t s_ping_queue;
static void ping_on_success(esp_ping_handle_t handle, void *arguments)
@@ -289,6 +292,15 @@ static int execute_ping(int argc, char **argv)
return 1;
}
if (s_ping_queue_bytes == NULL) {
s_ping_queue_bytes = heap_caps_malloc(
PING_EVENT_QUEUE_LENGTH * sizeof(ping_event_t),
MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
if (s_ping_queue_bytes == NULL) {
printf("ping: PSRAM event storage unavailable\n");
return 1;
}
}
if (s_ping_queue == NULL) {
s_ping_queue = xQueueCreateStatic(PING_EVENT_QUEUE_LENGTH, sizeof(ping_event_t),
s_ping_queue_bytes, &s_ping_queue_storage);
-9
View File
@@ -292,15 +292,6 @@ static const admin_console_owner_t s_admin_console_owner = {
.perform = admin_console_perform,
};
esp_err_t admin_ssh_console_open(const admin_ssh_console_token_t *token,
const user_principal_t *principal)
{
if (token == NULL || token->transport != ADMIN_CONSOLE_TRANSPORT_SSH) {
return ESP_ERR_INVALID_ARG;
}
return admin_ssh_console_open_owned(token, principal, &s_admin_console_owner);
}
static bool consume_external_close(const ssh_slot_t *slot, size_t slot_index)
{
taskENTER_CRITICAL(&s_lock);
+21 -8
View File
@@ -11,6 +11,7 @@
#include "admin_ssh_console.h"
#include "console_input.h"
#include "esp_console.h"
#include "esp_heap_caps.h"
#include "mbedtls/base64.h"
#include "secure_random.h"
#include "ssh_transport.h"
@@ -19,8 +20,9 @@
#define USER_CONSOLE_KEY_LINE_CAPACITY 256U
/* `user` commands are serialized by the administration gate. */
static user_database_snapshot_t s_user_snapshot;
/* Gate-owned public projection (no verifiers). Lazily retained for firmware
* lifetime; allocation failure must not disable mutations or UART0 recovery. */
static user_database_snapshot_t *s_user_snapshot;
static void print_usage(void)
{
@@ -92,21 +94,30 @@ static void print_user(const user_database_user_snapshot_t *user)
static int show_users(const char *selected)
{
esp_err_t error = user_database_get_snapshot(&s_user_snapshot);
if (s_user_snapshot == NULL) {
s_user_snapshot = heap_caps_malloc(sizeof(*s_user_snapshot),
MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
if (s_user_snapshot == NULL) {
printf("User status unavailable: PSRAM snapshot storage unavailable\n");
return 1;
}
}
esp_err_t error = user_database_get_snapshot(s_user_snapshot);
if (error != ESP_OK) {
printf("User database unavailable: %s\n", esp_err_to_name(error));
secure_wipe(s_user_snapshot, sizeof(*s_user_snapshot));
return 1;
}
if (selected == NULL) {
printf("User database: generation=%lu users=%u/%u admins=%u\n",
(unsigned long)s_user_snapshot.generation,
(unsigned int)s_user_snapshot.user_count,
(unsigned long)s_user_snapshot->generation,
(unsigned int)s_user_snapshot->user_count,
USER_DATABASE_MAX_USERS,
(unsigned int)s_user_snapshot.admin_count);
(unsigned int)s_user_snapshot->admin_count);
}
bool found = false;
for (size_t index = 0U; index < USER_DATABASE_MAX_USERS; ++index) {
const user_database_user_snapshot_t *user = &s_user_snapshot.users[index];
const user_database_user_snapshot_t *user = &s_user_snapshot->users[index];
if (!user->active ||
(selected != NULL &&
(strlen(selected) != user->username_length ||
@@ -118,11 +129,13 @@ static int show_users(const char *selected)
}
if (selected != NULL && !found) {
printf("User '%s' not found.\n", selected);
secure_wipe(s_user_snapshot, sizeof(*s_user_snapshot));
return 1;
}
if (s_user_snapshot.admin_count == 0U) {
if (s_user_snapshot->admin_count == 0U) {
printf("No administrators; use 'user add <username> admin' on UART0.\n");
}
secure_wipe(s_user_snapshot, sizeof(*s_user_snapshot));
return 0;
}