ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
client.h File Reference

Go to the source code of this file.

Data Structures

struct  client_info
 Per-client state structure for server-side client management. More...
 
struct  app_client_audio_packet_t
 Audio packet for async transmission. More...
 
struct  app_client
 Client-side application state. More...
 

Macros

#define APP_CLIENT_AUDIO_QUEUE_SIZE   256
 

Typedefs

typedef struct client_info client_info_t
 Per-client state structure for server-side client management.
 
typedef struct app_client app_client_t
 Client-side application state.
 

Enumerations

enum  participant_type_t { PARTICIPANT_TYPE_NETWORK , PARTICIPANT_TYPE_MEMORY }
 Participant type for distinguishing network vs memory participants. More...
 

Functions

app_client_t * app_client_create (void)
 Create and initialize client application context.
 
void app_client_destroy (app_client_t **client_ptr)
 Destroy client application context and free all resources.
 

Macro Definition Documentation

◆ APP_CLIENT_AUDIO_QUEUE_SIZE

#define APP_CLIENT_AUDIO_QUEUE_SIZE   256

Definition at line 224 of file include/ascii-chat/network/client.h.

Typedef Documentation

◆ app_client_t

typedef struct app_client app_client_t

Client-side application state.

Transport-agnostic container for application-layer state previously mixed in tcp_client_t. Holds audio queues, thread handles, crypto context, and display state. Connection ownership is tracked through connection_handle_t.

◆ client_info_t

typedef struct client_info client_info_t

Per-client state structure for server-side client management.

Represents complete state for a single connected client in the ascii-chat server. This structure stores all client-specific information including network connection, media capabilities, terminal settings, threading state, and synchronization primitives.

CORE FIELDS:

  • Network: Socket, IP address, port, thread handles
  • Media: Video/audio capabilities, stream state, buffers
  • Terminal: Capabilities, palette cache, dimensions
  • Threading: Send/receive/render thread handles and flags
  • Synchronization: Mutexes for thread-safe state access
  • Crypto: Cryptographic handshake context for secure communication

THREADING MODEL:

Each client has dedicated threads:

  • receive_thread: Handles incoming packets (protocol processing)
  • send_thread: Manages outgoing packet delivery (packet queues)
  • video_render_thread: Generates ASCII frames at 60fps
  • audio_render_thread: Mixes audio streams at 172fps

BUFFER MANAGEMENT:

  • incoming_video_buffer: Double-buffered video frames from client
  • incoming_audio_buffer: Ring buffer for client's audio samples
  • outgoing_video_buffer: Double-buffered ASCII frames to send
  • audio_queue: Packet queue for audio packets to send

MEMORY MANAGEMENT:

  • Pre-allocated buffers to avoid malloc/free in hot paths
  • send_buffer: For packet assembly
  • crypto_plaintext_buffer: For encryption plaintext
  • crypto_ciphertext_buffer: For encryption ciphertext
Note
All atomic fields are thread-safe for concurrent access.
Buffer pointers are set once during client creation and never change.
Thread handles are valid only when threads are running.

Enumeration Type Documentation

◆ participant_type_t

Participant type for distinguishing network vs memory participants.

Network participants communicate over TCP/IP or WebRTC, while memory participants inject media directly into the host's mixer (used when the host participates in the session with their own webcam/audio).

Enumerator
PARTICIPANT_TYPE_NETWORK 
PARTICIPANT_TYPE_MEMORY 

Definition at line 36 of file include/ascii-chat/network/client.h.

36 {
37 PARTICIPANT_TYPE_NETWORK, // Remote participant via socket/transport
38 PARTICIPANT_TYPE_MEMORY // Local host participant (direct memory access)
participant_type_t
Participant type for distinguishing network vs memory participants.

Function Documentation

◆ app_client_create()

app_client_t * app_client_create ( void  )

Create and initialize client application context.

Returns
Pointer to initialized context, or NULL on failure

Definition at line 25 of file lib/network/client.c.

25 {
27 if (!client) {
28 log_error("Failed to allocate app_client_t");
29 return NULL;
30 }
31
32 // Zero-initialize all fields
33 memset(client, 0, sizeof(*client));
34
35 /* Transport */
36 connection_handle_init(&client->connection);
37
38 /* Audio State */
39 memset(&client->audio_ctx, 0, sizeof(client->audio_ctx));
40 memset(client->audio_send_queue, 0, sizeof(client->audio_send_queue));
41 client->audio_send_queue_head = 0;
42 client->audio_send_queue_tail = 0;
43 client->audio_send_queue_initialized = false;
44 atomic_store_bool(&client->audio_sender_should_exit, false);
45 client->audio_capture_thread_created = false;
46 client->audio_sender_thread_created = false;
47 atomic_store_bool(&client->audio_capture_thread_exited, false);
48
49 // Initialize audio queue mutex and condition variable
50 if (mutex_init(&client->audio_send_queue_mutex, "audio_queue") != 0) {
51 log_error("Failed to initialize audio queue mutex");
52 SAFE_FREE(client);
53 return NULL;
54 }
55
56 if (cond_init(&client->audio_send_queue_cond, "audio_queue") != 0) {
57 log_error("Failed to initialize audio queue cond");
58 mutex_destroy(&client->audio_send_queue_mutex);
59 SAFE_FREE(client);
60 return NULL;
61 }
62
63 /* Protocol State */
64 client->data_thread_created = false;
65 atomic_store_bool(&client->data_thread_exited, false);
66 client->last_active_count = 0;
67 client->server_state_initialized = false;
68 client->should_clear_before_next_frame = false;
69 client->my_client_id = 0;
70 client->encryption_enabled = false;
71
72 /* Capture State */
73 client->capture_thread_created = false;
74 atomic_store_bool(&client->capture_thread_exited, false);
75
76 /* Keepalive State */
77 client->ping_thread_created = false;
78 atomic_store_bool(&client->ping_thread_exited, false);
79
80 /* Display State */
81 client->has_tty = false;
82 atomic_store_bool(&client->is_first_frame_of_connection, false);
83 memset(&client->tty_info, 0, sizeof(client->tty_info));
84
85 /* Crypto State */
86 memset(&client->crypto_ctx, 0, sizeof(client->crypto_ctx));
87 client->crypto_initialized = false;
88
89 // Register atomic fields for sync state monitoring with fully descriptive names
90 char atomic_name[256];
91
92 // Audio subsystem control and status
93 snprintf(atomic_name, sizeof(atomic_name), "app_client.audio_sender_thread_should_exit_signal");
94 NAMED_REGISTER_ATOMIC(&client->audio_sender_should_exit, atomic_name, NULL);
95
96 snprintf(atomic_name, sizeof(atomic_name), "app_client.audio_capture_thread_has_exited_status");
97 NAMED_REGISTER_ATOMIC(&client->audio_capture_thread_exited, atomic_name, NULL);
98
99 // Protocol and network data handling
100 snprintf(atomic_name, sizeof(atomic_name), "app_client.protocol_data_dispatch_thread_has_exited_status");
101 NAMED_REGISTER_ATOMIC(&client->data_thread_exited, atomic_name, NULL);
102
103 // Media capture control and status
104 snprintf(atomic_name, sizeof(atomic_name), "app_client.media_capture_thread_has_exited_status");
105 NAMED_REGISTER_ATOMIC(&client->capture_thread_exited, atomic_name, NULL);
106
107 // Keepalive and connection health monitoring
108 snprintf(atomic_name, sizeof(atomic_name), "app_client.keepalive_ping_thread_has_exited_status");
109 NAMED_REGISTER_ATOMIC(&client->ping_thread_exited, atomic_name, NULL);
110
111 // Display frame sequencing
112 snprintf(atomic_name, sizeof(atomic_name), "app_client.is_first_frame_of_new_connection_flag");
113 NAMED_REGISTER_ATOMIC(&client->is_first_frame_of_connection, atomic_name, NULL);
114
115 log_debug("App client created");
116
117 return client;
118}
void atomic_store_bool(atomic_t *a, bool value)
Atomically store a boolean value.
Definition atomic.c:177
void connection_handle_init(connection_handle_t *handle)
#define SAFE_FREE(ptr)
Definition common.h:376
#define SAFE_MALLOC(size, cast)
Definition common.h:264
#define NAMED_REGISTER_ATOMIC(a, name, parent_ptr)
Register an atomic_t with automatic format specifier.
#define log_error(...)
Log an ERROR message.
Definition log/log.h:587
#define log_debug(...)
Log a DEBUG message.
Definition log/log.h:548
int mutex_init(mutex_t *mutex, const char *name)
Initialize a mutex with a name.
Definition threading.c:16
int cond_init(cond_t *cond, const char *name)
Initialize a condition variable with a name.
int mutex_destroy(mutex_t *mutex)
Destroy a mutex.
Definition threading.c:22

References atomic_store_bool(), cond_init(), connection_handle_init(), log_debug, log_error, mutex_destroy(), mutex_init(), NAMED_REGISTER_ATOMIC, SAFE_FREE, and SAFE_MALLOC.

◆ app_client_destroy()

void app_client_destroy ( app_client_t **  client_ptr)

Destroy client application context and free all resources.

Parameters
client_ptrPointer to client pointer (set to NULL after free)

Definition at line 123 of file lib/network/client.c.

123 {
124 if (!client_ptr || !*client_ptr) {
125 return; // No-op if NULL
126 }
127
128 app_client_t *client = *client_ptr;
129
130 log_debug("Destroying app client");
131
132 // Unregister atomic fields
133 NAMED_UNREGISTER(&client->audio_sender_should_exit);
134 NAMED_UNREGISTER(&client->audio_capture_thread_exited);
135 NAMED_UNREGISTER(&client->data_thread_exited);
136 NAMED_UNREGISTER(&client->capture_thread_exited);
137 NAMED_UNREGISTER(&client->ping_thread_exited);
138 NAMED_UNREGISTER(&client->is_first_frame_of_connection);
139
140 // Destroy mutexes and condition variables
141 mutex_destroy(&client->audio_send_queue_mutex);
142 cond_destroy(&client->audio_send_queue_cond);
143
144 connection_handle_cleanup(&client->connection);
145
146 SAFE_FREE(*client_ptr);
147}
void connection_handle_cleanup(connection_handle_t *handle)
#define NAMED_UNREGISTER(ptr)
Unregister a pointer.
int cond_destroy(cond_t *cond)
Destroy a condition variable.

References cond_destroy(), connection_handle_cleanup(), log_debug, mutex_destroy(), NAMED_UNREGISTER, and SAFE_FREE.