Add typed serial settings operations
Route bounded admin mutations through the existing administration dispatcher, covering apply, lifecycle, persistence, authorization, and result tracking. Add the browser controls, automatic result refresh, regression coverage, and phase documentation.
This commit is contained in:
@@ -31,6 +31,13 @@ typedef int *SemaphoreHandle_t;
|
||||
#define pdMS_TO_TICKS(x) (x)
|
||||
#define CONSOLE_COMPLETION_OUTPUT_CAPACITY 1024U
|
||||
static unsigned lock_depth, ticks, runs, actions;
|
||||
static uint32_t serial_settings_executed;
|
||||
static unsigned serial_settings_preceding_runs, queue_send_wait;
|
||||
static void web_serial_settings_execute(uint32_t id) {
|
||||
assert(!lock_depth);
|
||||
serial_settings_executed = id;
|
||||
serial_settings_preceding_runs = runs;
|
||||
}
|
||||
static bool principal_current = true, queue_full, owner_drained = true;
|
||||
static TaskHandle_t current_task = (void *)1;
|
||||
static jmp_buf loop_done;
|
||||
@@ -58,7 +65,7 @@ static unsigned ulTaskNotifyTake(int b, unsigned t) { (void)b; (void)t; return 1
|
||||
static QueueHandle_t xQueueCreateStatic(unsigned n, size_t s, uint8_t *b, StaticQueue_t *q)
|
||||
{ (void)b; q->size = s; q->capacity = n; assert(n*s <= sizeof(q->bytes)); return q; }
|
||||
static int xQueueSend(QueueHandle_t q, const void *p, unsigned t)
|
||||
{ (void)t; if (queue_full || q->count==q->capacity) return 0;
|
||||
{ queue_send_wait=t; if (queue_full || q->count==q->capacity) return 0;
|
||||
memcpy(q->bytes+q->count*q->size,p,q->size); ++q->count; return 1; }
|
||||
static int xQueueReceive(QueueHandle_t q, void *p, unsigned t)
|
||||
{ (void)t; if (!q->count) longjmp(loop_done,1); memcpy(p,q->bytes,q->size);
|
||||
|
||||
@@ -313,5 +313,32 @@ int main(void)
|
||||
assert(!lock_depth);
|
||||
test_currentness();
|
||||
test_dispatch_currentness();
|
||||
unsigned before_serial = runs;
|
||||
assert(admin_ssh_console_submit_serial_settings(0) == ESP_ERR_INVALID_STATE);
|
||||
s_dispatch_ready = false;
|
||||
assert(admin_ssh_console_submit_serial_settings(1) == ESP_ERR_INVALID_STATE);
|
||||
s_dispatch_ready = true; queue_full = true;
|
||||
assert(admin_ssh_console_submit_serial_settings(1) == ESP_ERR_TIMEOUT);
|
||||
queue_full = false;
|
||||
admin_request_t preceding_uart = {.origin = ADMIN_REQUEST_UART0};
|
||||
assert(xQueueSend(s_request_queue, &preceding_uart, 0));
|
||||
queue_send_wait = portMAX_DELAY;
|
||||
assert(admin_ssh_console_submit_serial_settings(17) == ESP_OK && !serial_settings_executed);
|
||||
assert(queue_send_wait == 0);
|
||||
admin_request_t typed;
|
||||
memcpy(&typed, s_request_queue->bytes + sizeof(typed), sizeof(typed));
|
||||
assert(typed.origin == ADMIN_REQUEST_SERIAL_SETTINGS && typed.serial_settings_id == 17);
|
||||
assert(s_request_queue->capacity == 4 && sizeof(typed.line) == 257);
|
||||
pump(worker_task);
|
||||
assert(serial_settings_executed == 17 && runs == before_serial + 1 && !s_request_queue->count);
|
||||
assert(serial_settings_preceding_runs == before_serial + 1);
|
||||
for (unsigned i = 0; i < s_request_queue->capacity; ++i)
|
||||
assert(xQueueSend(s_request_queue, &preceding_uart, 0));
|
||||
queue_send_wait = portMAX_DELAY;
|
||||
assert(admin_ssh_console_submit_serial_settings(18) == ESP_ERR_TIMEOUT);
|
||||
assert(queue_send_wait == 0 && s_request_queue->count == 4 && serial_settings_executed == 17);
|
||||
pump(worker_task);
|
||||
assert(runs == before_serial + 5 && serial_settings_executed == 17 && !s_request_queue->count);
|
||||
puts("PASS: typed Serial admission uses zero wait on success/full queue, preserves all four queued UART requests and FIFO execution, no command-string dispatch");
|
||||
puts("PASS: admission/identity, two owners, completion contention/reopen, history, queued stale/revoked work, UART dispatch, hidden/disconnected prompts, exit-to-SELF_CLOSE, deferred rejection/drain/close, 5s output backpressure");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user