42 size_t payload_len, uint32_t client_id) {
44 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid transport");
48#define MAX_REASONABLE_PACKET_SIZE (25 * 1024 * 1024)
50 log_error(
"PACKET SIZE VALIDATION FAILURE: Attempting to send %zu bytes (%zu MB) with type=%d (0x%04x), exceeds "
51 "max %d bytes (25 MB) - likely a bug in caller's length calculation",
53 return SET_ERRNO(ERROR_INVALID_PARAM,
"Packet payload too large: %zu bytes (max 25MB)", payload_len);
56 log_dev_every(4500 * US_PER_MS_INT,
57 "★ PACKET_SEND_VIA_TRANSPORT: type=%d, payload_len=%zu, client_id=%u, transport=%p", type, payload_len,
58 client_id, (
void *)transport);
61 packet_header_t header;
62 header.magic = HOST_TO_NET_U64(PACKET_MAGIC);
63 header.type = HOST_TO_NET_U16(type);
64 header.length = HOST_TO_NET_U32((uint32_t)payload_len);
65 header.client_id = client_id;
68 if (payload && payload_len > 0) {
69 header.crc32 = HOST_TO_NET_U32(asciichat_crc32((
const uint8_t *)payload, payload_len));
74 log_dev_every(4500 * US_PER_MS_INT,
"★ PKT_SEND: type=%d, magic=0x%016llx, length=%u, crc32=0x%08x", type,
75 header.magic, header.length, header.crc32);
78 size_t total_size =
sizeof(header) + payload_len;
82 uint8_t *packet = SAFE_MALLOC(total_size, uint8_t *);
84 return SET_ERRNO(ERROR_MEMORY,
"Failed to allocate packet buffer");
88 memcpy(packet, &header,
sizeof(header));
89 if (payload && payload_len > 0) {
90 memcpy(packet +
sizeof(header), payload, payload_len);
93 log_dev_every(4500 * US_PER_MS_INT,
"★ PACKET_SEND: total_size=%zu, calling acip_transport_send...", total_size);
95 asciichat_error_t result = acip_transport_send(transport, packet, total_size);
97 if (result == ASCIICHAT_OK) {
98 log_dev_every(4500 * US_PER_MS_INT,
"★ PACKET_SEND: SUCCESS - sent %zu bytes (type=%d)", total_size, type);
100 log_error(
"★ PACKET_SEND: FAILED - acip_transport_send returned %d (%s)", result, asciichat_error_string(result));
116 uint32_t batch_count) {
117 if (!transport || !samples || num_samples == 0) {
118 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters");
122 audio_batch_packet_t header;
123 header.batch_count = batch_count;
124 header.total_samples = (uint32_t)num_samples;
125 header.sample_rate = (uint32_t)AUDIO_SAMPLE_RATE;
129 size_t samples_size = num_samples *
sizeof(float);
130 size_t total_size =
sizeof(header) + samples_size;
134 return SET_ERRNO(ERROR_MEMORY,
"Failed to allocate buffer");
138 memcpy(buffer, &header,
sizeof(header));
139 memcpy(buffer +
sizeof(header), samples, samples_size);
148 if (!transport || !opus_data || opus_len == 0) {
149 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters");
154 uint16_t frame_sizes[1] = {(uint16_t)opus_len};
159 const uint16_t *frame_sizes, uint32_t frame_count, uint32_t sample_rate,
160 uint32_t frame_duration) {
161 if (!transport || !opus_data || !frame_sizes || frame_count == 0) {
162 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters");
167 *(uint32_t *)(header + 0) = HOST_TO_NET_U32(sample_rate);
168 *(uint32_t *)(header + 4) = HOST_TO_NET_U32(frame_duration);
169 *(uint32_t *)(header + 8) = HOST_TO_NET_U32(frame_count);
170 *(uint32_t *)(header + 12) = 0;
173 size_t sizes_len = frame_count *
sizeof(uint16_t);
174 size_t total_size =
sizeof(header) + sizes_len + opus_len;
178 return SET_ERRNO(ERROR_MEMORY,
"Failed to allocate buffer");
182 memcpy(buffer, header,
sizeof(header));
186 uint16_t *sizes_buf = (uint16_t *)(buffer +
sizeof(header));
187 for (uint32_t i = 0; i < frame_count; i++) {
188 sizes_buf[i] = HOST_TO_NET_U16(frame_sizes[i]);
191 memcpy(buffer +
sizeof(header) + sizes_len, opus_data, opus_len);
235 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid transport");
241 msg_len = strlen(message);
242 if (msg_len > MAX_ERROR_MESSAGE_LENGTH) {
243 msg_len = MAX_ERROR_MESSAGE_LENGTH;
247 error_packet_t header;
248 header.error_code = HOST_TO_NET_U32(
error_code);
249 header.message_length = HOST_TO_NET_U32((uint32_t)msg_len);
252 size_t total_size =
sizeof(header) + msg_len;
255 return SET_ERRNO(ERROR_MEMORY,
"Failed to allocate buffer");
259 memcpy(buffer, &header,
sizeof(header));
261 memcpy(buffer +
sizeof(header), message, msg_len);
271 const char *message) {
272 if (!transport || !message) {
273 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid transport or message");
276 size_t msg_len = strlen(message);
278 remote_log_packet_t header;
279 header.log_level = log_level;
280 header.direction = direction;
282 header.message_length = HOST_TO_NET_U32((uint32_t)msg_len);
284 size_t total_size =
sizeof(header) + msg_len;
288 return SET_ERRNO(ERROR_MEMORY,
"Failed to allocate buffer");
292 memcpy(buffer, &header,
sizeof(header));
293 memcpy(buffer +
sizeof(header), message, msg_len);
306 if (!transport || !response) {
307 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid transport or response");
314 if (!transport || !info) {
315 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid transport or info");
322 if (!transport || !response) {
323 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid transport or response");
asciichat_error_t acip_send_audio_opus_batch(acip_transport_t *transport, const void *opus_data, size_t opus_len, const uint16_t *frame_sizes, uint32_t frame_count, uint32_t sample_rate, uint32_t frame_duration)
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)