29 const acip_client_callbacks_t *callbacks) {
30 if (!transport || !callbacks) {
31 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid transport or callbacks");
35 if (!transport->methods->is_connected(transport)) {
36 return SET_ERRNO(ERROR_NETWORK,
"Transport not connected");
39 packet_envelope_t envelope;
40 bool enforce_encryption = (transport->crypto_ctx != NULL);
43 socket_t sock = transport->methods->get_socket(transport);
45 if (sock != INVALID_SOCKET_VALUE) {
47 packet_recv_result_t result =
receive_packet_secure(sock, transport->crypto_ctx, enforce_encryption, &envelope);
50 if (result != PACKET_RECV_SUCCESS) {
51 if (result == PACKET_RECV_EOF) {
52 return SET_ERRNO(ERROR_NETWORK,
"Connection closed (EOF)");
53 }
else if (result == PACKET_RECV_SECURITY_VIOLATION) {
54 return SET_ERRNO(ERROR_CRYPTO,
"Security violation: unencrypted packet when encryption required");
56 return SET_ERRNO(ERROR_NETWORK,
"Failed to receive packet");
61 void *packet_data = NULL;
62 void *allocated_buffer = NULL;
63 size_t packet_len = 0;
65 asciichat_error_t recv_result = transport->methods->recv(transport, &packet_data, &packet_len, &allocated_buffer);
66 if (recv_result != ASCIICHAT_OK) {
67 return SET_ERRNO(ERROR_NETWORK,
"Transport recv() failed");
71 if (packet_len <
sizeof(packet_header_t)) {
73 return SET_ERRNO(ERROR_NETWORK,
"Packet too small: %zu < %zu", packet_len,
sizeof(packet_header_t));
76 const packet_header_t *header = (
const packet_header_t *)packet_data;
77 envelope.type = NET_TO_HOST_U16(header->type);
78 envelope.len = NET_TO_HOST_U32(header->length);
79 envelope.data = (uint8_t *)packet_data +
sizeof(packet_header_t);
80 envelope.allocated_buffer = allocated_buffer;
81 envelope.allocated_size = packet_len;
82 envelope.was_encrypted =
false;
84 log_dev_every(4500 * US_PER_MS_INT,
"WebRTC received packet: type=%u, len=%u, total_size=%zu", envelope.type,
85 envelope.len, packet_len);
88 if (envelope.len != packet_len -
sizeof(packet_header_t)) {
90 return SET_ERRNO(ERROR_NETWORK,
"Packet length mismatch: header says %u, actual %zu", envelope.len,
91 packet_len -
sizeof(packet_header_t));
96 asciichat_error_t dispatch_result =
99 if (dispatch_result != ASCIICHAT_OK) {
100 log_error(
"Packet dispatch failed for type %u: error %d", envelope.type, dispatch_result);
102 log_debug(
"Packet type %u dispatched successfully", envelope.type);
106 if (envelope.allocated_buffer) {
111 return dispatch_result;
119 uint32_t height, uint32_t pixel_format) {
120 log_debug(
"★ ACIP_SEND_IMAGE_FRAME: Called with %ux%u, transport=%p, pixel_data=%p", width, height, (
void *)transport,
123 if (!transport || !pixel_data) {
124 log_debug(
"★ ACIP_SEND_IMAGE_FRAME: Invalid params");
125 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid transport or pixel_data");
129 size_t pixel_size = (size_t)width * height * 3;
130 log_debug(
"★ ACIP_SEND_IMAGE_FRAME: pixel_size=%zu", pixel_size);
133 image_frame_packet_t header;
134 header.width = HOST_TO_NET_U32(width);
135 header.height = HOST_TO_NET_U32(height);
136 header.pixel_format = HOST_TO_NET_U32(pixel_format);
137 header.compressed_size = 0;
139 header.timestamp = 0;
143 if (checked_size_add(
sizeof(header), pixel_size, &total_size) != ASCIICHAT_OK) {
144 log_debug(
"★ ACIP_SEND_IMAGE_FRAME: Overflow in size calculation");
145 return SET_ERRNO(ERROR_INVALID_PARAM,
"Packet size overflow");
148 log_debug(
"★ ACIP_SEND_IMAGE_FRAME: total_size=%zu, allocating buffer", total_size);
153 log_debug(
"★ ACIP_SEND_IMAGE_FRAME: Failed to allocate %zu bytes", total_size);
154 return SET_ERRNO(ERROR_MEMORY,
"Failed to allocate buffer: %zu bytes", total_size);
158 memcpy(buffer, &header,
sizeof(header));
159 memcpy(buffer +
sizeof(header), pixel_data, pixel_size);
161 log_debug(
"★ ACIP_SEND_IMAGE_FRAME: About to send packet");
165 log_debug(
"★ ACIP_SEND_IMAGE_FRAME: packet_send_via_transport returned %d", result);
218 if (!transport || !version) {
219 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid transport or version");
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.
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)