Files
video-setup/include/transport.h
mikael-lovqvists-claude-agent 197ab7d5db Simplify frame header to message_type + payload_length (6 bytes)
Removes channel_id from the header. All message-specific identifiers
(stream_id, request_id, etc.) now live at the start of the payload,
interpreted by each message type handler. A relay seeing an unknown
type can skip or forward it using only payload_length, with no
knowledge of the payload structure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 22:00:43 +00:00

92 lines
3.0 KiB
C

#pragma once
#include <stdint.h>
#include "error.h"
#define TRANSPORT_FRAME_HEADER_SIZE 6u
#define TRANSPORT_DEFAULT_MAX_PAYLOAD (16u * 1024u * 1024u)
struct Transport_Conn;
struct Transport_Server;
/*
* A received frame. payload is malloc'd by the transport layer;
* the on_frame callback takes ownership and must free it.
* payload is NULL when payload_length is 0.
*
* The header carries only message_type and payload_length.
* All message-specific fields (stream_id, request_id, etc.) are
* the first bytes of the payload, interpreted by the message handler.
*/
struct Transport_Frame {
uint16_t message_type;
uint32_t payload_length;
uint8_t *payload;
};
typedef void (*Transport_Frame_Cb)(
struct Transport_Conn *conn,
struct Transport_Frame *frame,
void *userdata);
typedef void (*Transport_Connect_Cb)(
struct Transport_Conn *conn,
void *userdata);
typedef void (*Transport_Disconnect_Cb)(
struct Transport_Conn *conn,
void *userdata);
struct Transport_Server_Config {
uint16_t port;
int max_connections; /* inbound limit; excess connections are closed immediately */
uint32_t max_payload; /* max payload bytes; frames exceeding this disconnect the peer */
Transport_Frame_Cb on_frame; /* required */
Transport_Connect_Cb on_connect; /* optional; called before read loop starts */
Transport_Disconnect_Cb on_disconnect; /* optional; called from read thread before conn is freed */
void *userdata;
};
/* Create a server (does not start listening yet). */
struct App_Error transport_server_create(struct Transport_Server **out,
struct Transport_Server_Config *config);
/* Bind, listen, and spawn the accept thread. */
struct App_Error transport_server_start(struct Transport_Server *server);
/*
* Stop accepting new connections and free the server.
* Active connections continue until they disconnect naturally.
*/
void transport_server_destroy(struct Transport_Server *server);
/*
* Connect outbound to host:port and spawn a read thread.
* on_disconnect is optional. on_frame is required.
* The conn is freed when the read thread exits.
* Do not use conn after on_disconnect has been called.
*/
struct App_Error transport_connect(struct Transport_Conn **out,
const char *host,
uint16_t port,
uint32_t max_payload,
Transport_Frame_Cb on_frame,
Transport_Disconnect_Cb on_disconnect,
void *userdata);
/*
* Send a frame. Thread-safe.
* payload may be NULL when length is 0.
*/
struct App_Error transport_send_frame(struct Transport_Conn *conn,
uint16_t message_type,
const uint8_t *payload,
uint32_t length);
/*
* Close the connection fd. The read thread will detect the error,
* call on_disconnect, then free the conn.
* Do not use conn after calling this.
*/
void transport_conn_close(struct Transport_Conn *conn);