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

ACIP server-side protocol API. More...

Go to the source code of this file.

Functions

asciichat_error_t acip_server_receive_and_dispatch (acip_transport_t *transport, void *client_ctx, const acip_server_callbacks_t *callbacks)
 Receive packet from client and dispatch to callbacks.
 
asciichat_error_t acip_send_ascii_frame (acip_transport_t *transport, const char *frame_data, size_t frame_size, uint32_t width, uint32_t height, const char *client_id)
 Send ASCII frame to client (server → client)
 
asciichat_error_t acip_send_clear_console (acip_transport_t *transport)
 Send clear console command to client (server → client)
 
asciichat_error_t acip_send_server_state (acip_transport_t *transport, const server_state_packet_t *state)
 Send server state update to client (server → client)
 

Detailed Description

ACIP server-side protocol API.

Server-side API for ascii-chat protocol. Provides functions for:

  • Receiving and dispatching packets from clients
  • Sending ASCII frames to clients
  • Sending server state updates
  • Sending console control commands
Author
Zachary Fogg me@zf.nosp@m.o.gg
Date
January 2026

Definition in file include/ascii-chat/network/acip/server.h.

Function Documentation

◆ acip_send_ascii_frame()

asciichat_error_t acip_send_ascii_frame ( acip_transport_t *  transport,
const char *  frame_data,
size_t  frame_size,
uint32_t  width,
uint32_t  height,
const char *  client_id 
)

Send ASCII frame to client (server → client)

Sends rendered ASCII art frame to client for display.

Parameters
transportTransport instance
frame_dataASCII frame data (null-terminated string)
frame_sizeFrame data size in bytes
widthFrame width in characters
heightFrame height in characters
client_idClient ID to include in packet header
Returns
ASCIICHAT_OK on success, error code on failure

Definition at line 201 of file lib/network/acip/server.c.

202 {
203 if (!transport || !frame_data) {
204 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid transport or frame_data");
205 }
206
207 if (frame_size == 0) {
208 return SET_ERRNO(ERROR_INVALID_PARAM, "Empty frame data");
209 }
210
211 if (frame_size > UINT32_MAX) {
212 return SET_ERRNO(ERROR_NETWORK_SIZE, "ASCII frame is too large: %zu bytes", frame_size);
213 }
214
215 log_dev("SEND_ASCII_FRAME: client_id=%s, width=%u, height=%u, frame_size=%zu bytes", client_id, width, height,
216 frame_size);
217
218 // Calculate CRC32 checksum of frame data for integrity verification
219 uint32_t checksum_value = asciichat_crc32(frame_data, frame_size);
220 log_debug("★ SEND_ASCII_FRAME: CRC32 checksum calculated: 0x%08x for %zu bytes", checksum_value, frame_size);
221
222 // Compress ANSI text before sending it. Native and browser clients decode zstd frames.
223 const void *payload_data = frame_data;
224 size_t payload_size = frame_size;
225 void *compressed_data = NULL;
226 bool is_compressed = false;
227 size_t compressed_size = 0;
228 if (frame_size >= COMPRESSION_MIN_SIZE &&
229 compress_data(frame_data, frame_size, &compressed_data, &compressed_size, 1) == ASCIICHAT_OK &&
230 compressed_data && compressed_size < frame_size && should_compress(frame_size, compressed_size)) {
231 payload_data = compressed_data;
232 payload_size = compressed_size;
233 is_compressed = true;
234 }
235
236 // Create ASCII frame packet header
238 header.width = HOST_TO_NET_U32(width);
239 header.height = HOST_TO_NET_U32(height);
240 header.original_size = HOST_TO_NET_U32((uint32_t)frame_size);
241 header.compressed_size = HOST_TO_NET_U32(is_compressed ? (uint32_t)payload_size : 0);
242 header.checksum = HOST_TO_NET_U32(checksum_value);
243 header.flags = HOST_TO_NET_U32(is_compressed ? FRAME_FLAG_IS_COMPRESSED : 0);
244
245 // Calculate total packet size
246 size_t total_size;
247 if (checked_size_add(sizeof(header), payload_size, &total_size) != ASCIICHAT_OK) {
248 SAFE_FREE(compressed_data);
249 log_error("★ SEND_ASCII_FRAME: Packet size overflow when adding header (%zu) + frame (%zu)", sizeof(header),
250 payload_size);
251 return SET_ERRNO(ERROR_INVALID_PARAM, "Packet size overflow");
252 }
253
254 log_debug("★ SEND_ASCII_FRAME: Building packet - header=%zu bytes, frame=%zu bytes, total=%zu bytes", sizeof(header),
255 frame_size, total_size);
256
257 // Allocate buffer
258 uint8_t *buffer = buffer_pool_alloc(NULL, total_size);
259 if (!buffer) {
260 SAFE_FREE(compressed_data);
261 log_error("★ SEND_ASCII_FRAME: Memory allocation FAILED for %zu bytes", total_size);
262 return SET_ERRNO(ERROR_MEMORY, "Failed to allocate buffer: %zu bytes", total_size);
263 }
264
265 log_debug("★ SEND_ASCII_FRAME: Buffer allocated at %p", (void *)buffer);
266
267 // Build packet: header + data
268 memcpy(buffer, &header, sizeof(header));
269 memcpy(buffer + sizeof(header), payload_data, payload_size);
270
271 // Send via transport with client_id for logging
272 log_dev("SEND_ASCII_FRAME: sending PACKET_TYPE_ASCII_FRAME");
273 asciichat_error_t result = packet_send_via_transport(transport, PACKET_TYPE_ASCII_FRAME, buffer, total_size, 0);
274
275 if (result == ASCIICHAT_OK) {
276 log_dev("SEND_ASCII_FRAME: sent client_id=%s bytes=%zu", client_id, total_size);
277 } else {
278 log_error("★ SEND_ASCII_FRAME FAILED: Error code %d (%s) for client_id=%s", result, asciichat_error_string(result),
279 client_id);
280 }
281
282 buffer_pool_free(NULL, buffer, total_size);
283 SAFE_FREE(compressed_data);
284 return result;
285}
#define HOST_TO_NET_U32(val)
Definition endian.h:66
void buffer_pool_free(buffer_pool_t *pool, const void *data, size_t size)
Free a buffer back to the pool (lock-free)
void * buffer_pool_alloc(buffer_pool_t *pool, size_t size)
Allocate a buffer from the pool (lock-free fast path)
unsigned int uint32_t
Definition common.h:58
#define SAFE_FREE(ptr)
Definition common.h:376
unsigned char uint8_t
Definition common.h:56
#define COMPRESSION_MIN_SIZE
Minimum packet size to attempt compression (1KB)
Definition compression.h:61
bool should_compress(size_t original_size, size_t compressed_size)
Determine if compression should be used for given data sizes.
Definition compression.c:74
asciichat_error_t compress_data(const void *input, size_t input_size, void **output, size_t *output_size, int compression_level)
Compress data using zstd with configurable compression level.
Definition compression.c:14
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it, returning the error code.
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:49
@ ERROR_MEMORY
Definition error_codes.h:56
@ ASCIICHAT_OK
Definition error_codes.h:51
@ ERROR_NETWORK_SIZE
Definition error_codes.h:82
@ ERROR_INVALID_PARAM
#define log_dev(...)
Log a DEV message (most verbose, development only)
Definition log/log.h:534
#define log_error(...)
Log an ERROR message.
Definition log/log.h:587
#define log_debug(...)
Log a DEBUG message.
Definition log/log.h:548
@ PACKET_TYPE_ASCII_FRAME
Complete ASCII frame with all metadata.
Definition packet.h:361
#define FRAME_FLAG_IS_COMPRESSED
Frame data is compressed.
#define asciichat_crc32(data, len)
Main CRC32 dispatcher macro - use this in application code.
Definition crc32.h:144
asciichat_error_t packet_send_via_transport(acip_transport_t *transport, packet_type_t type, const void *payload, size_t payload_len, uint32_t client_id)
Send packet via transport with proper header (exported for generic wrappers)
Definition send.c:41
ASCII frame packet structure (Packet Type 2)
Definition packet.h:848
uint32_t width
Terminal width in characters.
Definition packet.h:850
uint32_t checksum
CRC32 checksum of original ASCII data.
Definition packet.h:858
uint32_t original_size
Size of original uncompressed ASCII data in bytes.
Definition packet.h:854
uint32_t height
Terminal height in characters.
Definition packet.h:852
uint32_t compressed_size
Size of compressed data (0 = not compressed)
Definition packet.h:856
uint32_t flags
Frame flags bitmask (HAS_COLOR, IS_COMPRESSED, etc.)
Definition packet.h:860

References asciichat_crc32, ASCIICHAT_OK, buffer_pool_alloc(), buffer_pool_free(), ascii_frame_packet_t::checksum, compress_data(), ascii_frame_packet_t::compressed_size, COMPRESSION_MIN_SIZE, ERROR_INVALID_PARAM, ERROR_MEMORY, ERROR_NETWORK_SIZE, ascii_frame_packet_t::flags, FRAME_FLAG_IS_COMPRESSED, ascii_frame_packet_t::height, HOST_TO_NET_U32, log_debug, log_dev, log_error, ascii_frame_packet_t::original_size, packet_send_via_transport(), PACKET_TYPE_ASCII_FRAME, SAFE_FREE, SET_ERRNO, should_compress(), and ascii_frame_packet_t::width.

Referenced by client_send_thread_func(), session_host_broadcast_frame(), and session_host_send_frame().

◆ acip_send_clear_console()

asciichat_error_t acip_send_clear_console ( acip_transport_t *  transport)

Send clear console command to client (server → client)

Instructs client to clear the terminal/console.

Parameters
transportTransport instance
Returns
ASCIICHAT_OK on success, error code on failure

Definition at line 287 of file lib/network/acip/server.c.

287 {
288 if (!transport) {
289 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid transport");
290 }
291
292 return packet_send_via_transport(transport, PACKET_TYPE_CLEAR_CONSOLE, NULL, 0, 0);
293}
@ PACKET_TYPE_CLEAR_CONSOLE
Server tells client to clear console.
Definition packet.h:395

References ERROR_INVALID_PARAM, packet_send_via_transport(), PACKET_TYPE_CLEAR_CONSOLE, and SET_ERRNO.

Referenced by client_send_thread_func().

◆ acip_send_server_state()

asciichat_error_t acip_send_server_state ( acip_transport_t *  transport,
const server_state_packet_t *  state 
)

Send server state update to client (server → client)

Notifies client of server state changes (client count, grid layout, etc.)

Parameters
transportTransport instance
stateServer state structure
Returns
ASCIICHAT_OK on success, error code on failure

Definition at line 295 of file lib/network/acip/server.c.

295 {
296 if (!transport || !state) {
297 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid transport or state");
298 }
299
300 return packet_send_via_transport(transport, PACKET_TYPE_SERVER_STATE, state, sizeof(*state), 0);
301}
@ PACKET_TYPE_SERVER_STATE
Server sends current state to clients.
Definition packet.h:397

References ERROR_INVALID_PARAM, packet_send_via_transport(), PACKET_TYPE_SERVER_STATE, and SET_ERRNO.

Referenced by add_webrtc_client(), broadcast_server_state_to_all_clients(), send_server_state_to_client(), and session_host_set_client_transport().

◆ acip_server_receive_and_dispatch()

asciichat_error_t acip_server_receive_and_dispatch ( acip_transport_t *  transport,
void *  client_ctx,
const acip_server_callbacks_t *  callbacks 
)

Receive packet from client and dispatch to callbacks.

High-level receive function for server side. Receives a single packet from the transport, handles decryption, and dispatches to appropriate callback handler.

Parameters
transportTransport instance
client_ctxClient context pointer (passed to callbacks)
callbacksCallback structure for handling received packets
Returns
ASCIICHAT_OK on success, error code on failure

Definition at line 32 of file lib/network/acip/server.c.

33 {
34 uint64_t dispatch_start_ns = time_get_ns();
36 "ACIP_SERVER_DISPATCH: Entry, transport=%p, client_ctx=%p, callbacks=%p, timestamp=%llu",
37 (void *)transport, client_ctx, (const void *)callbacks, (unsigned long long)dispatch_start_ns);
38
39 if (!transport) {
40 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid transport (NULL)");
41 }
42 if (!callbacks) {
43 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid callbacks (NULL)");
44 }
45
46 // Check if transport is connected
47 if (!transport->methods->is_connected(transport)) {
48 return SET_ERRNO(ERROR_NETWORK, "Transport not connected");
49 }
50
51 packet_envelope_t envelope;
52 bool enforce_encryption = (transport->crypto_ctx != NULL);
53
54 // Try to get socket from transport
55 socket_t sock = transport->methods->get_socket(transport);
56 log_dev_every(4500 * US_PER_MS_INT, "ACIP_SERVER_DISPATCH: Socket=%d (INVALID=%d)", sock, INVALID_SOCKET_VALUE);
57
58 if (sock != INVALID_SOCKET_VALUE) {
59 // Socket-based transport (TCP): use receive_packet_secure() for socket I/O + parsing
60 packet_recv_result_t result = receive_packet_secure(sock, transport->crypto_ctx, enforce_encryption, &envelope);
61
62 // Handle receive errors
63 if (result != PACKET_RECV_SUCCESS) {
64 if (result == PACKET_RECV_EOF) {
65 return SET_ERRNO(ERROR_NETWORK, "Connection closed (EOF)");
66 } else if (result == PACKET_RECV_SECURITY_VIOLATION) {
67 return SET_ERRNO(ERROR_CRYPTO, "Security violation: unencrypted packet when encryption required");
68 } else {
69 return SET_ERRNO(ERROR_NETWORK, "Failed to receive packet");
70 }
71 }
72
73 // receive_packet_secure() keeps the complete packet for the TCP transport,
74 // while ACIP handlers receive payload-only data. Normalize the envelope
75 // before dispatching so the TCP and WebSocket paths use the same shape.
76 if (envelope.data == envelope.allocated_buffer) {
77 const packet_header_t *header = (const packet_header_t *)envelope.allocated_buffer;
78 envelope.type = NET_TO_HOST_U16(header->type);
79 envelope.len = NET_TO_HOST_U32(header->length);
80 envelope.data = (uint8_t *)envelope.allocated_buffer + sizeof(packet_header_t);
81 }
82 } else {
83 // Non-socket transport (WebRTC): use transport's recv() method to get complete packet
84 void *packet_data = NULL;
85 void *allocated_buffer = NULL;
86 size_t packet_len = 0;
87
88 uint64_t recv_start_ns = time_get_ns();
89 asciichat_error_t recv_result = transport->methods->recv(transport, &packet_data, &packet_len, &allocated_buffer);
90 uint64_t recv_end_ns = time_get_ns();
91
92 if (recv_result != ASCIICHAT_OK) {
93 char recv_duration_str[32];
94 time_pretty((uint64_t)(recv_end_ns - recv_start_ns), -1, recv_duration_str, sizeof(recv_duration_str));
95 log_warn("[ACIP_RECV_ERROR] recv() failed after %s (result=%d)", recv_duration_str, recv_result);
96 return SET_ERRNO(ERROR_NETWORK, "Transport recv() failed");
97 }
98
99 char recv_duration_str[32];
100 time_pretty((uint64_t)(recv_end_ns - recv_start_ns), -1, recv_duration_str, sizeof(recv_duration_str));
101 log_info("[ACIP_RECV_SUCCESS] Received %zu bytes in %s", packet_len, recv_duration_str);
102
103 // Parse packet header
104 if (packet_len < sizeof(packet_header_t)) {
105 buffer_pool_free(NULL, allocated_buffer, packet_len);
106 return SET_ERRNO(ERROR_NETWORK, "Packet too small: %zu < %zu", packet_len, sizeof(packet_header_t));
107 }
108
109 const packet_header_t *header = (const packet_header_t *)packet_data;
110 envelope.type = NET_TO_HOST_U16(header->type);
111 envelope.len = NET_TO_HOST_U32(header->length);
112 envelope.data = (uint8_t *)packet_data + sizeof(packet_header_t);
113 envelope.allocated_buffer = allocated_buffer;
114 envelope.allocated_size = packet_len;
115
116 log_dev_every(4500 * US_PER_MS_INT, "ACIP_SERVER_DISPATCH: WebRTC packet parsed: type=%d, len=%u", envelope.type,
117 envelope.len);
118
119 // Handle PACKET_TYPE_ENCRYPTED from WebSocket clients that encrypt at application layer
120 if (envelope.type == PACKET_TYPE_ENCRYPTED && transport->crypto_ctx) {
121 uint64_t decrypt_start_ns = time_get_ns();
122 uint8_t *ciphertext = (uint8_t *)envelope.data;
123 size_t ciphertext_len = envelope.len;
124
125 // Decrypt to get inner plaintext packet (header + payload)
126 size_t plaintext_size = ciphertext_len + 1024;
127 uint8_t *plaintext = buffer_pool_alloc(NULL, plaintext_size);
128 if (!plaintext) {
129 buffer_pool_free(NULL, allocated_buffer, packet_len);
130 return SET_ERRNO(ERROR_MEMORY, "Failed to allocate plaintext buffer for decryption");
131 }
132
133 size_t plaintext_len;
134 crypto_result_t crypto_result =
135 crypto_decrypt(transport->crypto_ctx, ciphertext, ciphertext_len, plaintext, plaintext_size, &plaintext_len);
136
137 // Free the original encrypted buffer
138 buffer_pool_free(NULL, allocated_buffer, packet_len);
139
140 if (crypto_result != CRYPTO_OK) {
141 buffer_pool_free(NULL, plaintext, plaintext_size);
142 return SET_ERRNO(ERROR_CRYPTO, "Failed to decrypt WebSocket packet: %s",
143 crypto_result_to_string(crypto_result));
144 }
145
146 if (plaintext_len < sizeof(packet_header_t)) {
147 buffer_pool_free(NULL, plaintext, plaintext_size);
148 return SET_ERRNO(ERROR_CRYPTO, "Decrypted packet too small: %zu < %zu", plaintext_len, sizeof(packet_header_t));
149 }
150
151 // Parse the inner (decrypted) header
152 const packet_header_t *inner_header = (const packet_header_t *)plaintext;
153 envelope.type = NET_TO_HOST_U16(inner_header->type);
154 envelope.len = NET_TO_HOST_U32(inner_header->length);
155 envelope.data = plaintext + sizeof(packet_header_t);
156 envelope.allocated_buffer = plaintext;
157 envelope.allocated_size = plaintext_size;
158
159 uint64_t decrypt_end_ns = time_get_ns();
160 char decrypt_duration_str[32];
161 time_pretty((uint64_t)(decrypt_end_ns - decrypt_start_ns), -1, decrypt_duration_str,
162 sizeof(decrypt_duration_str));
163 log_info("[WS_TIMING] Decrypt %zu bytes → %zu bytes in %s (inner_type=%d)", ciphertext_len, plaintext_len,
164 decrypt_duration_str, envelope.type);
165 }
166 }
167
168 // Dispatch packet to appropriate ACIP handler
169 // Server receives packets FROM clients, so use server packet handler
170 log_info("ACIP_DISPATCH_PKT: type=%d, len=%zu, client_ctx=%p", envelope.type, envelope.len, client_ctx);
171 log_info("📤 [FRAME_DISPATCH] Starting handler dispatch for packet type=%d (0x%04x), payload=%zu bytes",
172 envelope.type, envelope.type, envelope.len);
173 uint64_t dispatch_handler_start_ns = time_get_ns();
174 asciichat_error_t dispatch_result =
175 acip_handle_server_packet(transport, envelope.type, envelope.data, envelope.len, client_ctx, callbacks);
176 uint64_t dispatch_handler_end_ns = time_get_ns();
177 char handler_duration_str[32];
178 time_pretty((uint64_t)(dispatch_handler_end_ns - dispatch_handler_start_ns), -1, handler_duration_str,
179 sizeof(handler_duration_str));
180 log_info("[WS_TIMING] Handler for type=%d took %s (result=%d)", envelope.type, handler_duration_str, dispatch_result);
181
182 if (dispatch_result != ASCIICHAT_OK) {
183 log_error("❌ [FRAME_DISPATCH_FAILED] Handler returned error for type=%d: %d", envelope.type, dispatch_result);
184 } else {
185 log_info("✅ [FRAME_DISPATCH_SUCCESS] Handler completed successfully for type=%d", envelope.type);
186 }
187
188 // Always free the allocated buffer (even if handler failed)
189 if (envelope.allocated_buffer) {
190 buffer_pool_free(NULL, envelope.allocated_buffer, envelope.allocated_size);
191 }
192
193 // Return handler result
194 return dispatch_result;
195}
#define NET_TO_HOST_U16(val)
Definition endian.h:111
#define NET_TO_HOST_U32(val)
Definition endian.h:81
unsigned long long uint64_t
Definition common.h:59
const char * crypto_result_to_string(crypto_result_t result)
Convert crypto result to human-readable string.
crypto_result_t
Cryptographic operation result codes.
crypto_result_t crypto_decrypt(crypto_context_t *ctx, const uint8_t *ciphertext, size_t ciphertext_len, uint8_t *plaintext_out, size_t plaintext_out_size, size_t *plaintext_len_out)
Decrypt data using XSalsa20-Poly1305.
@ ERROR_NETWORK
Definition error_codes.h:77
@ ERROR_CRYPTO
Definition error_codes.h:96
#define log_warn(...)
Log a WARN message.
Definition log/log.h:574
#define log_info(...)
Log an INFO message.
Definition log/log.h:561
uint64_t time_get_ns(void)
Get current monotonic time in nanoseconds.
Definition util/time.c:108
int time_pretty(uint64_t nanoseconds, int decimals, char *buffer, size_t buffer_size)
Format nanoseconds as pretty duration with spaces and configurable precision.
Definition util/time.c:424
#define US_PER_MS_INT
Definition time.h:160
packet_recv_result_t receive_packet_secure(socket_t sockfd, void *crypto_ctx, bool enforce_encryption, packet_envelope_t *envelope)
Receive a packet with decryption and decompression support.
Definition packet.c:569
packet_recv_result_t
Packet reception result codes.
Definition packet.h:1152
@ PACKET_RECV_EOF
Connection closed (EOF)
Definition packet.h:1156
@ PACKET_RECV_SECURITY_VIOLATION
Encryption policy violation (e.g., unencrypted packet when encryption required)
Definition packet.h:1160
@ PACKET_RECV_SUCCESS
Packet received successfully.
Definition packet.h:1154
@ PACKET_TYPE_ENCRYPTED
Encrypted packet (after handshake completion)
Definition packet.h:333
#define INVALID_SOCKET_VALUE
Invalid socket value (POSIX: -1)
Definition socket.h:278
int socket_t
#define log_dev_every(interval_us, fmt,...)
Rate-limited DEV logging.
Definition log/log.h:699
asciichat_error_t acip_handle_server_packet(acip_transport_t *transport, packet_type_t type, const void *payload, size_t payload_len, void *client_ctx, const acip_server_callbacks_t *callbacks)
Handle incoming packet on server side.
Packet envelope containing received packet data.
Definition packet.h:1129
void * allocated_buffer
Buffer that needs to be freed by caller (may be NULL if not allocated)
Definition packet.h:1139
size_t allocated_size
Size of allocated buffer in bytes.
Definition packet.h:1141
size_t len
Length of payload data in bytes.
Definition packet.h:1135
void * data
Packet payload data (decrypted and decompressed if applicable)
Definition packet.h:1133
packet_type_t type
Packet type (from packet_types.h)
Definition packet.h:1131
Network packet header structure.
Definition packet.h:598
uint32_t length
Payload data length in bytes (0 for header-only packets)
Definition packet.h:604
uint16_t type
Packet type (packet_type_t enumeration)
Definition packet.h:602

References acip_handle_server_packet(), packet_envelope_t::allocated_buffer, packet_envelope_t::allocated_size, ASCIICHAT_OK, buffer_pool_alloc(), buffer_pool_free(), acip_transport::crypto_ctx, crypto_decrypt(), CRYPTO_OK, crypto_result_to_string(), packet_envelope_t::data, ERROR_CRYPTO, ERROR_INVALID_PARAM, ERROR_MEMORY, ERROR_NETWORK, acip_transport_methods_t::get_socket, INVALID_SOCKET_VALUE, acip_transport_methods_t::is_connected, packet_envelope_t::len, packet_header_t::length, log_dev_every, log_error, log_info, log_warn, acip_transport::methods, NET_TO_HOST_U16, NET_TO_HOST_U32, PACKET_RECV_EOF, PACKET_RECV_SECURITY_VIOLATION, PACKET_RECV_SUCCESS, PACKET_TYPE_ENCRYPTED, receive_packet_secure(), acip_transport_methods_t::recv, SET_ERRNO, time_get_ns(), time_pretty(), packet_header_t::type, packet_envelope_t::type, and US_PER_MS_INT.

Referenced by client_receive_thread().