ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
transport.h File Reference

Transport abstraction layer for ACIP protocol. More...

Go to the source code of this file.

Data Structures

struct  acip_transport_methods_t
 Transport method table (virtual function table) More...
 
struct  acip_transport
 Transport instance structure. More...
 

Typedefs

typedef struct acip_transport acip_transport_t
 Forward declaration of transport implementation.
 

Enumerations

enum  acip_transport_type_t {
  ACIP_TRANSPORT_TCP = 1 , ACIP_TRANSPORT_WEBSOCKET = 2 , ACIP_TRANSPORT_WEBRTC = 3 , ACIP_TRANSPORT_HTTP = 4 ,
  ACIP_TRANSPORT_QUIC = 5
}
 Transport type enumeration. More...
 

Functions

void acip_transport_destroy (acip_transport_t *transport)
 Destroy transport and free all resources.
 
acip_transport_tacip_tcp_transport_create (socket_t sockfd, crypto_context_t *crypto_ctx)
 Create TCP transport from existing socket.
 
acip_transport_tacip_websocket_transport_create (socket_t sockfd, crypto_context_t *crypto_ctx)
 Create WebSocket transport from existing socket.
 
acip_transport_tacip_webrtc_transport_create (struct webrtc_peer_connection *peer_conn, struct webrtc_data_channel *data_channel, crypto_context_t *crypto_ctx)
 

Detailed Description

Transport abstraction layer for ACIP protocol.

Provides a transport-agnostic interface that allows ACIP protocol handlers to work with any underlying transport (TCP, WebSocket, HTTP, etc.).

DESIGN GOALS:

  1. Protocol code never calls socket()/send()/recv() directly
  2. Same ACIP handlers work with TCP, WebSocket, or any future transport
  3. Transport implementations handle their own connection state
  4. Clean separation between protocol logic and transport logic

USAGE PATTERN:

// Create TCP transport
acip_transport_t *tcp = acip_tcp_transport_create(sockfd, crypto_ctx);
// Use with ACIP protocol handlers
asciichat_error_t result = acip_send_ascii_frame(tcp, frame_data, frame_size);
// Or WebSocket transport (future)
asciichat_error_t result = acip_send_ascii_frame(ws, frame_data, frame_size);
// Cleanup
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:46
asciichat_error_t acip_send_ascii_frame(acip_transport_t *transport, const char *frame_data, uint32_t width, uint32_t height)
Send ASCII frame to client (server → client)
Transport instance structure.
Definition transport.h:169
acip_transport_t * acip_tcp_transport_create(socket_t sockfd, crypto_context_t *crypto_ctx)
Create TCP transport from existing socket.
acip_transport_t * acip_websocket_transport_create(socket_t sockfd, crypto_context_t *crypto_ctx)
Create WebSocket transport from existing socket.
void acip_transport_destroy(acip_transport_t *transport)
Destroy transport and free all resources.

MEMORY OWNERSHIP:

  • Transport owns its connection state
  • send() does NOT take ownership of data (caller must keep it valid)
  • recv() allocates buffer, caller must free via out_allocated_buffer
  • destroy() cleans up all transport resources
Author
Zachary Fogg me@zf.nosp@m.o.gg
Date
January 2026

Definition in file transport.h.

Typedef Documentation

◆ acip_transport_t

Forward declaration of transport implementation.

Opaque handle to transport-specific state. Each transport implementation defines its own state structure.

Definition at line 73 of file transport.h.

Enumeration Type Documentation

◆ acip_transport_type_t

Transport type enumeration.

Identifies which transport implementation is being used. Useful for debugging and conditional logic.

Enumerator
ACIP_TRANSPORT_TCP 

Raw TCP socket.

ACIP_TRANSPORT_WEBSOCKET 

WebSocket over TCP.

ACIP_TRANSPORT_WEBRTC 

WebRTC DataChannel (P2P)

ACIP_TRANSPORT_HTTP 

HTTP long-polling (future)

ACIP_TRANSPORT_QUIC 

QUIC/UDP (future)

Definition at line 59 of file transport.h.

59 {
acip_transport_type_t
Transport type enumeration.
Definition transport.h:59
@ ACIP_TRANSPORT_TCP
Raw TCP socket.
Definition transport.h:60
@ ACIP_TRANSPORT_WEBSOCKET
WebSocket over TCP.
Definition transport.h:61
@ ACIP_TRANSPORT_WEBRTC
WebRTC DataChannel (P2P)
Definition transport.h:62
@ ACIP_TRANSPORT_HTTP
HTTP long-polling (future)
Definition transport.h:63
@ ACIP_TRANSPORT_QUIC
QUIC/UDP (future)
Definition transport.h:64

Function Documentation

◆ acip_tcp_transport_create()

acip_transport_t * acip_tcp_transport_create ( socket_t  sockfd,
crypto_context_t crypto_ctx 
)

Create TCP transport from existing socket.

Parameters
sockfdConnected socket descriptor
crypto_ctxOptional crypto context (may be NULL)
Returns
Transport instance or NULL on error
Note
Caller retains socket ownership (transport doesn't close on destroy)

Definition at line 208 of file tcp/transport.c.

208 {
209 if (sockfd == INVALID_SOCKET_VALUE) {
210 SET_ERRNO(ERROR_INVALID_PARAM, "Invalid socket descriptor");
211 return NULL;
212 }
213
214 // Allocate transport structure
216 if (!transport) {
217 SET_ERRNO(ERROR_MEMORY, "Failed to allocate TCP transport");
218 return NULL;
219 }
220
221 // Allocate TCP-specific data
223 if (!tcp_data) {
224 SAFE_FREE(transport);
225 SET_ERRNO(ERROR_MEMORY, "Failed to allocate TCP transport data");
226 return NULL;
227 }
228
229 // Initialize TCP data
230 tcp_data->sockfd = sockfd;
231 tcp_data->is_connected = true;
232
233 // Initialize transport
234 transport->methods = &tcp_methods;
235 transport->crypto_ctx = crypto_ctx;
236 transport->impl_data = tcp_data;
237
238 log_debug("Created TCP transport for socket %d (crypto: %s)", sockfd, crypto_ctx ? "enabled" : "disabled");
239
240 return transport;
241}
#define SAFE_FREE(ptr)
Definition common.h:320
#define SAFE_MALLOC(size, cast)
Definition common.h:208
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it.
@ ERROR_MEMORY
Definition error_codes.h:53
@ ERROR_INVALID_PARAM
#define log_debug(...)
Log a DEBUG message.
#define INVALID_SOCKET_VALUE
Invalid socket value (POSIX: -1)
Definition socket.h:52
void * impl_data
Transport-specific state.
Definition transport.h:172
const acip_transport_methods_t * methods
Method table (virtual functions)
Definition transport.h:170
crypto_context_t * crypto_ctx
Optional encryption context.
Definition transport.h:171
TCP transport implementation data.
socket_t sockfd
Socket descriptor (NOT owned - don't close)
bool is_connected
Connection state.

References acip_transport::crypto_ctx, ERROR_INVALID_PARAM, ERROR_MEMORY, acip_transport::impl_data, INVALID_SOCKET_VALUE, tcp_transport_data_t::is_connected, log_debug, acip_transport::methods, SAFE_FREE, SAFE_MALLOC, SET_ERRNO, and tcp_transport_data_t::sockfd.

Referenced by server_connection_establish(), and server_main().

◆ acip_transport_destroy()

void acip_transport_destroy ( acip_transport_t transport)

Destroy transport and free all resources.

Parameters
transportTransport to destroy (may be NULL)
Note
Calls close() first if still connected
Frees the transport structure itself
Safe to pass NULL

Definition at line 247 of file tcp/transport.c.

247 {
248 if (!transport) {
249 return;
250 }
251
252 // Close if still connected
253 if (transport->methods && transport->methods->close && transport->methods->is_connected &&
254 transport->methods->is_connected(transport)) {
255 transport->methods->close(transport);
256 }
257
258 // Call custom destroy implementation if provided
259 if (transport->methods && transport->methods->destroy_impl) {
260 transport->methods->destroy_impl(transport);
261 }
262
263 // Free implementation data
264 if (transport->impl_data) {
265 SAFE_FREE(transport->impl_data);
266 }
267
268 // Free transport structure
269 SAFE_FREE(transport);
270
271 log_debug("Destroyed ACIP transport");
272}
bool(* is_connected)(acip_transport_t *transport)
Check if transport is connected.
Definition transport.h:149
asciichat_error_t(* close)(acip_transport_t *transport)
Close this transport.
Definition transport.h:122
void(* destroy_impl)(acip_transport_t *transport)
Custom destroy implementation (optional)
Definition transport.h:160

References acip_transport_methods_t::close, acip_transport_methods_t::destroy_impl, acip_transport::impl_data, acip_transport_methods_t::is_connected, log_debug, acip_transport::methods, and SAFE_FREE.

Referenced by connection_context_cleanup(), server_connection_close(), server_connection_set_transport(), and server_main().

◆ acip_webrtc_transport_create()

acip_transport_t * acip_webrtc_transport_create ( struct webrtc_peer_connection peer_conn,
struct webrtc_data_channel data_channel,
crypto_context_t crypto_ctx 
)

Definition at line 374 of file webrtc/transport.c.

375 {
376 if (!peer_conn || !data_channel) {
377 SET_ERRNO(ERROR_INVALID_PARAM, "peer_conn and data_channel are required");
378 return NULL;
379 }
380
381 // Allocate transport structure
383 if (!transport) {
384 SET_ERRNO(ERROR_MEMORY, "Failed to allocate WebRTC transport");
385 return NULL;
386 }
387
388 // Allocate WebRTC-specific data
390 if (!wrtc_data) {
391 SAFE_FREE(transport);
392 SET_ERRNO(ERROR_MEMORY, "Failed to allocate WebRTC transport data");
393 return NULL;
394 }
395
396 // Create receive queue
398 if (!wrtc_data->recv_queue) {
399 SAFE_FREE(wrtc_data);
400 SAFE_FREE(transport);
401 SET_ERRNO(ERROR_MEMORY, "Failed to create receive queue");
402 return NULL;
403 }
404
405 // Initialize synchronization primitives
406 if (mutex_init(&wrtc_data->queue_mutex) != 0) {
407 ringbuffer_destroy(wrtc_data->recv_queue);
408 SAFE_FREE(wrtc_data);
409 SAFE_FREE(transport);
410 SET_ERRNO(ERROR_INTERNAL, "Failed to initialize queue mutex");
411 return NULL;
412 }
413
414 if (cond_init(&wrtc_data->queue_cond) != 0) {
415 mutex_destroy(&wrtc_data->queue_mutex);
416 ringbuffer_destroy(wrtc_data->recv_queue);
417 SAFE_FREE(wrtc_data);
418 SAFE_FREE(transport);
419 SET_ERRNO(ERROR_INTERNAL, "Failed to initialize queue condition variable");
420 return NULL;
421 }
422
423 if (mutex_init(&wrtc_data->state_mutex) != 0) {
424 cond_destroy(&wrtc_data->queue_cond);
425 mutex_destroy(&wrtc_data->queue_mutex);
426 ringbuffer_destroy(wrtc_data->recv_queue);
427 SAFE_FREE(wrtc_data);
428 SAFE_FREE(transport);
429 SET_ERRNO(ERROR_INTERNAL, "Failed to initialize state mutex");
430 return NULL;
431 }
432
433 // Initialize WebRTC data
434 wrtc_data->peer_conn = peer_conn;
435 wrtc_data->data_channel = data_channel;
436 wrtc_data->is_connected = false; // Will be set to true in on_open callback
437
438 // Register DataChannel callbacks
440 .on_open = webrtc_on_open,
441 .on_close = webrtc_on_close,
442 .on_error = webrtc_on_error,
443 .on_message = webrtc_on_message,
444 .user_data = wrtc_data,
445 };
446
447 asciichat_error_t result = webrtc_datachannel_set_callbacks(data_channel, &callbacks);
448 if (result != ASCIICHAT_OK) {
449 mutex_destroy(&wrtc_data->state_mutex);
450 cond_destroy(&wrtc_data->queue_cond);
451 mutex_destroy(&wrtc_data->queue_mutex);
452 ringbuffer_destroy(wrtc_data->recv_queue);
453 SAFE_FREE(wrtc_data);
454 SAFE_FREE(transport);
455 SET_ERRNO(ERROR_INTERNAL, "Failed to set DataChannel callbacks");
456 return NULL;
457 }
458
459 // Initialize transport
460 transport->methods = &webrtc_methods;
461 transport->crypto_ctx = crypto_ctx;
462 transport->impl_data = wrtc_data;
463
464 log_info("Created WebRTC transport (crypto: %s)", crypto_ctx ? "enabled" : "disabled");
465
466 return transport;
467}
@ ASCIICHAT_OK
Definition error_codes.h:48
@ ERROR_INTERNAL
Definition error_codes.h:84
#define log_info(...)
Log an INFO message.
int mutex_init(mutex_t *mutex)
Initialize a mutex.
int cond_init(cond_t *cond)
Initialize a condition variable.
int cond_destroy(cond_t *cond)
Destroy a condition variable.
int mutex_destroy(mutex_t *mutex)
Destroy a mutex.
ringbuffer_t * ringbuffer_create(size_t element_size, size_t capacity)
Create a new ring buffer.
Definition ringbuffer.c:28
void ringbuffer_destroy(ringbuffer_t *rb)
Destroy a ring buffer and free its memory.
Definition ringbuffer.c:54
asciichat_error_t webrtc_datachannel_set_callbacks(webrtc_data_channel_t *dc, const webrtc_datachannel_callbacks_t *callbacks)
Set DataChannel callbacks.
DataChannel callback structure.
void(* on_open)(webrtc_data_channel_t *dc, void *user_data)
Channel opened.
Receive queue element (variable-length message)
WebRTC transport implementation data.
webrtc_peer_connection_t * peer_conn
Peer connection (owned)
bool is_connected
Connection state.
mutex_t queue_mutex
Protect queue operations.
webrtc_data_channel_t * data_channel
Data channel (owned)
mutex_t state_mutex
Protect state changes.
cond_t queue_cond
Signal when messages arrive.
ringbuffer_t * recv_queue
Receive message queue.
#define WEBRTC_RECV_QUEUE_SIZE
Maximum receive queue size (messages buffered before recv())

References ASCIICHAT_OK, cond_destroy(), cond_init(), acip_transport::crypto_ctx, webrtc_transport_data_t::data_channel, ERROR_INTERNAL, ERROR_INVALID_PARAM, ERROR_MEMORY, acip_transport::impl_data, webrtc_transport_data_t::is_connected, log_info, acip_transport::methods, mutex_destroy(), mutex_init(), webrtc_datachannel_callbacks_t::on_open, webrtc_transport_data_t::peer_conn, webrtc_transport_data_t::queue_cond, webrtc_transport_data_t::queue_mutex, webrtc_transport_data_t::recv_queue, ringbuffer_create(), ringbuffer_destroy(), SAFE_FREE, SAFE_MALLOC, SET_ERRNO, webrtc_transport_data_t::state_mutex, webrtc_datachannel_set_callbacks(), and WEBRTC_RECV_QUEUE_SIZE.

◆ acip_websocket_transport_create()

acip_transport_t * acip_websocket_transport_create ( socket_t  sockfd,
crypto_context_t crypto_ctx 
)

Create WebSocket transport from existing socket.

Parameters
sockfdConnected socket descriptor (after WebSocket handshake)
crypto_ctxOptional crypto context (may be NULL)
Returns
Transport instance or NULL on error
Note
Socket must have completed WebSocket handshake
Caller retains socket ownership

Definition at line 32 of file websocket/transport.c.

32 {
33 (void)sockfd;
34 (void)crypto_ctx;
35
36 log_error("WebSocket transport not yet implemented");
37 SET_ERRNO(ERROR_INTERNAL, "WebSocket transport is not yet implemented");
38
39 return NULL;
40}
#define log_error(...)
Log an ERROR message.

References ERROR_INTERNAL, log_error, and SET_ERRNO.