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

Go to the source code of this file.

Data Structures

struct  webrtc_recv_msg_t
 Receive queue element (variable-length message) More...
 
struct  webrtc_transport_data_t
 WebRTC transport implementation data. More...
 

Macros

#define WEBRTC_RECV_QUEUE_SIZE   512
 Maximum receive queue size (messages buffered before recv())
 

Functions

acip_transport_t * acip_webrtc_transport_create (webrtc_peer_connection_t *peer_conn, webrtc_data_channel_t *data_channel, crypto_context_t *crypto_ctx)
 

Macro Definition Documentation

◆ WEBRTC_RECV_QUEUE_SIZE

#define WEBRTC_RECV_QUEUE_SIZE   512

Maximum receive queue size (messages buffered before recv())

Power of 2 for ringbuffer optimization. 512 messages provides adequate buffering for large video frames (921KB each) with WebRTC DataChannel fragmentation. At 30 FPS: 512 / 30 = ~17 seconds of buffering for burst traffic and processing delays.

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

Function Documentation

◆ acip_webrtc_transport_create()

acip_transport_t * acip_webrtc_transport_create ( webrtc_peer_connection_t *  peer_conn,
webrtc_data_channel_t *  data_channel,
crypto_context_t *  crypto_ctx 
)

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

368 {
369 if (!peer_conn || !data_channel) {
370 SET_ERRNO(ERROR_INVALID_PARAM, "peer_conn and data_channel are required");
371 return NULL;
372 }
373
374 // Allocate transport structure
375 acip_transport_t *transport = SAFE_MALLOC(sizeof(acip_transport_t), acip_transport_t *);
376 if (!transport) {
377 SET_ERRNO(ERROR_MEMORY, "Failed to allocate WebRTC transport");
378 return NULL;
379 }
380
381 // Allocate WebRTC-specific data
383 if (!wrtc_data) {
384 SAFE_FREE(transport);
385 SET_ERRNO(ERROR_MEMORY, "Failed to allocate WebRTC transport data");
386 return NULL;
387 }
388
389 // Create receive queue
391 if (!wrtc_data->recv_queue) {
392 SAFE_FREE(wrtc_data);
393 SAFE_FREE(transport);
394 SET_ERRNO(ERROR_MEMORY, "Failed to create receive queue");
395 return NULL;
396 }
397
398 // Initialize synchronization primitives
399 if (mutex_init(&wrtc_data->queue_mutex) != 0) {
400 ringbuffer_destroy(wrtc_data->recv_queue);
401 SAFE_FREE(wrtc_data);
402 SAFE_FREE(transport);
403 SET_ERRNO(ERROR_INTERNAL, "Failed to initialize queue mutex");
404 return NULL;
405 }
406
407 if (cond_init(&wrtc_data->queue_cond) != 0) {
408 mutex_destroy(&wrtc_data->queue_mutex);
409 ringbuffer_destroy(wrtc_data->recv_queue);
410 SAFE_FREE(wrtc_data);
411 SAFE_FREE(transport);
412 SET_ERRNO(ERROR_INTERNAL, "Failed to initialize queue condition variable");
413 return NULL;
414 }
415
416 if (mutex_init(&wrtc_data->state_mutex) != 0) {
417 cond_destroy(&wrtc_data->queue_cond);
418 mutex_destroy(&wrtc_data->queue_mutex);
419 ringbuffer_destroy(wrtc_data->recv_queue);
420 SAFE_FREE(wrtc_data);
421 SAFE_FREE(transport);
422 SET_ERRNO(ERROR_INTERNAL, "Failed to initialize state mutex");
423 return NULL;
424 }
425
426 // Initialize WebRTC data
427 wrtc_data->peer_conn = peer_conn;
428 wrtc_data->data_channel = data_channel;
429 wrtc_data->is_connected = false; // Will be set to true in on_open callback
430
431 // Register DataChannel callbacks
432 webrtc_datachannel_callbacks_t callbacks = {
433 .on_open = webrtc_on_open,
434 .on_close = webrtc_on_close,
435 .on_error = webrtc_on_error,
436 .on_message = webrtc_on_message,
437 .user_data = wrtc_data,
438 };
439
440 asciichat_error_t result = webrtc_datachannel_set_callbacks(data_channel, &callbacks);
441 if (result != ASCIICHAT_OK) {
442 mutex_destroy(&wrtc_data->state_mutex);
443 cond_destroy(&wrtc_data->queue_cond);
444 mutex_destroy(&wrtc_data->queue_mutex);
445 ringbuffer_destroy(wrtc_data->recv_queue);
446 SAFE_FREE(wrtc_data);
447 SAFE_FREE(transport);
448 SET_ERRNO(ERROR_INTERNAL, "Failed to set DataChannel callbacks");
449 return NULL;
450 }
451
452 // IMPORTANT: The transport is always created from peer_manager's on_datachannel_open callback,
453 // which means the DataChannel is ALREADY OPEN when we get here. However, by setting our own
454 // callbacks above (webrtc_datachannel_set_callbacks), we replaced the callbacks that would
455 // have set dc->is_open=true. So we need to manually mark both the transport AND the DataChannel
456 // as open/connected now.
457 //
458 // We cannot rely on webrtc_on_open being called later because:
459 // 1. The DataChannel is already open
460 // 2. libdatachannel won't fire the open event again
461 // 3. Setting callbacks after open doesn't trigger a retroactive open event
462
463 // Mark DataChannel as open (needed for webrtc_datachannel_send() check)
464 webrtc_datachannel_set_open_state(data_channel, true);
465
466 // Mark transport as connected
467 mutex_lock(&wrtc_data->state_mutex);
468 wrtc_data->is_connected = true;
469 mutex_unlock(&wrtc_data->state_mutex);
470 log_debug("Transport and DataChannel marked as connected/open (already open from peer_manager callback)");
471
472 // Initialize transport
473 transport->methods = &webrtc_methods;
474 transport->crypto_ctx = crypto_ctx;
475 transport->impl_data = wrtc_data;
476
477 log_info("Created WebRTC transport (crypto: %s)", crypto_ctx ? "enabled" : "disabled");
478
479 return transport;
480}
asciichat_error_t webrtc_datachannel_set_callbacks(webrtc_data_channel_t *dc, const webrtc_datachannel_callbacks_t *callbacks)
void webrtc_datachannel_set_open_state(webrtc_data_channel_t *dc, bool is_open)
ringbuffer_t * ringbuffer_create(size_t element_size, size_t capacity)
Definition ringbuffer.c:28
void ringbuffer_destroy(ringbuffer_t *rb)
Definition ringbuffer.c:54
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.
int mutex_init(mutex_t *mutex)
Definition threading.c:16
int mutex_destroy(mutex_t *mutex)
Definition threading.c:21
#define WEBRTC_RECV_QUEUE_SIZE
Maximum receive queue size (messages buffered before recv())

References webrtc_transport_data_t::data_channel, webrtc_transport_data_t::is_connected, mutex_destroy(), mutex_init(), 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(), webrtc_transport_data_t::state_mutex, webrtc_datachannel_set_callbacks(), webrtc_datachannel_set_open_state(), and WEBRTC_RECV_QUEUE_SIZE.