Add Transport-Neutral Serial Session Broker
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SESSION_BROKER_MAX_CLIENTS 8U
|
||||
#define SESSION_BROKER_CLIENT_NAME_MAX 23U
|
||||
#define SESSION_BROKER_OUTPUT_SIZE 4096U
|
||||
#define SESSION_BROKER_EVENT_QUEUE_LENGTH 16U
|
||||
|
||||
typedef uint32_t session_broker_client_id_t;
|
||||
|
||||
/* ID zero is reserved for "no client" and, specifically, "no writer". */
|
||||
#define SESSION_BROKER_NO_CLIENT ((session_broker_client_id_t)0U)
|
||||
|
||||
typedef enum {
|
||||
SESSION_BROKER_CLIENT_CONSOLE = 0,
|
||||
SESSION_BROKER_CLIENT_USB,
|
||||
SESSION_BROKER_CLIENT_WEB,
|
||||
SESSION_BROKER_CLIENT_SSH,
|
||||
SESSION_BROKER_CLIENT_INTERNAL,
|
||||
} session_broker_client_type_t;
|
||||
|
||||
typedef enum {
|
||||
SESSION_BROKER_EVENT_CONNECT = 0,
|
||||
SESSION_BROKER_EVENT_DISCONNECT,
|
||||
SESSION_BROKER_EVENT_WRITER_GRANTED,
|
||||
SESSION_BROKER_EVENT_WRITER_RELEASED,
|
||||
SESSION_BROKER_EVENT_WRITER_REVOKED,
|
||||
SESSION_BROKER_EVENT_WRITER_DENIED,
|
||||
} session_broker_event_type_t;
|
||||
|
||||
/*
|
||||
* Events contain no pointers, so transports can encode them without lifetime
|
||||
* concerns. sequence is broker-global and strictly increases per event.
|
||||
* client_id identifies the subject; writer_id is the writer after the event.
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t sequence;
|
||||
session_broker_event_type_t type;
|
||||
session_broker_client_id_t client_id;
|
||||
session_broker_client_id_t writer_id;
|
||||
} session_broker_event_t;
|
||||
|
||||
typedef struct {
|
||||
/* UART bytes considered for delivery while this client was connected. */
|
||||
uint64_t uart_rx_bytes;
|
||||
uint64_t output_queued_bytes;
|
||||
uint64_t output_read_bytes;
|
||||
uint64_t output_dropped_bytes;
|
||||
uint64_t tx_accepted_bytes;
|
||||
uint64_t tx_rejected_bytes;
|
||||
uint64_t connections;
|
||||
uint64_t writer_requests;
|
||||
uint64_t writer_grants;
|
||||
uint64_t writer_releases;
|
||||
uint64_t writer_revocations;
|
||||
uint64_t writer_denials;
|
||||
uint64_t writer_changes;
|
||||
uint64_t events_queued;
|
||||
uint64_t events_popped;
|
||||
uint64_t event_drops;
|
||||
} session_broker_client_counters_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t uart_rx_bytes;
|
||||
/* UART RX drained when there were no connected observers. */
|
||||
uint64_t unobserved_rx_bytes;
|
||||
/* Queue/read/drop totals count one copy per client observer. */
|
||||
uint64_t output_queued_bytes;
|
||||
uint64_t output_read_bytes;
|
||||
uint64_t output_dropped_bytes;
|
||||
uint64_t tx_accepted_bytes;
|
||||
uint64_t tx_rejected_bytes;
|
||||
uint64_t connections;
|
||||
uint64_t disconnections;
|
||||
uint64_t writer_requests;
|
||||
uint64_t writer_grants;
|
||||
uint64_t writer_releases;
|
||||
uint64_t writer_revocations;
|
||||
uint64_t writer_denials;
|
||||
uint64_t writer_changes;
|
||||
uint64_t events_generated;
|
||||
uint64_t events_queued;
|
||||
uint64_t events_popped;
|
||||
uint64_t event_drops;
|
||||
} session_broker_global_counters_t;
|
||||
|
||||
typedef struct {
|
||||
session_broker_client_id_t id;
|
||||
session_broker_client_type_t type;
|
||||
char name[SESSION_BROKER_CLIENT_NAME_MAX + 1U];
|
||||
bool is_writer;
|
||||
size_t output_bytes_pending;
|
||||
uint32_t events_pending;
|
||||
session_broker_client_counters_t counters;
|
||||
} session_broker_client_snapshot_t;
|
||||
|
||||
typedef struct {
|
||||
session_broker_client_id_t writer_id;
|
||||
uint32_t connected_clients;
|
||||
uint64_t latest_event_sequence;
|
||||
session_broker_global_counters_t counters;
|
||||
} session_broker_global_snapshot_t;
|
||||
|
||||
/*
|
||||
* Allocates all eight output streams and event queues, then starts the
|
||||
* permanent broker task. The serial service must already be initialized
|
||||
* before the first client connects.
|
||||
*/
|
||||
esp_err_t session_broker_init(void);
|
||||
|
||||
esp_err_t session_broker_connect(session_broker_client_type_t type,
|
||||
const char *name,
|
||||
session_broker_client_id_t *client_id);
|
||||
esp_err_t session_broker_disconnect(session_broker_client_id_t client_id);
|
||||
|
||||
/*
|
||||
* There is exactly one writer lease. Requests are granted only while idle;
|
||||
* a competing request emits WRITER_DENIED. Force with ID zero revokes the
|
||||
* current writer without assigning a replacement.
|
||||
*/
|
||||
esp_err_t session_broker_request_writer(session_broker_client_id_t client_id);
|
||||
esp_err_t session_broker_release_writer(session_broker_client_id_t client_id);
|
||||
esp_err_t session_broker_force_writer(session_broker_client_id_t client_id);
|
||||
session_broker_client_id_t session_broker_get_writer_id(void);
|
||||
|
||||
/*
|
||||
* Binary-transparent, zero-time data operations. write is accepted only from
|
||||
* the current writer. read has one logical caller per connected transport.
|
||||
* Partial transfers are normal and are reported through the output count.
|
||||
*/
|
||||
esp_err_t session_broker_write(session_broker_client_id_t client_id,
|
||||
const uint8_t *data,
|
||||
size_t size,
|
||||
size_t *accepted);
|
||||
esp_err_t session_broker_read(session_broker_client_id_t client_id,
|
||||
uint8_t *data,
|
||||
size_t size,
|
||||
size_t *received);
|
||||
esp_err_t session_broker_pop_event(session_broker_client_id_t client_id,
|
||||
session_broker_event_t *event);
|
||||
|
||||
esp_err_t session_broker_get_client_snapshot(session_broker_client_id_t client_id,
|
||||
session_broker_client_snapshot_t *snapshot);
|
||||
esp_err_t session_broker_get_global_snapshot(session_broker_global_snapshot_t *snapshot);
|
||||
|
||||
/* Returns the number copied. Pass NULL with capacity zero to count clients. */
|
||||
size_t session_broker_list_clients(session_broker_client_snapshot_t *clients,
|
||||
size_t capacity);
|
||||
|
||||
/* Counter clearing does not reset client IDs, queued data, or event sequence. */
|
||||
esp_err_t session_broker_clear_counters(void);
|
||||
esp_err_t session_broker_clear_client_counters(session_broker_client_id_t client_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user