|
|
|
|
@ -71,6 +71,8 @@ static struct call_audio* ca_of(struct UTUN_INSTANCE* inst) {
|
|
|
|
|
return inst ? (struct call_audio*)inst->call_audio : NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void ca_close_client(struct call_audio_client* cli); |
|
|
|
|
|
|
|
|
|
/* ── отправка фрейма клиенту (с буферизацией как в control-сокете) ── */ |
|
|
|
|
|
|
|
|
|
static void ca_send_raw(struct call_audio_client* cli, const uint8_t* data, size_t len) { |
|
|
|
|
@ -94,6 +96,10 @@ static void ca_send_raw(struct call_audio_client* cli, const uint8_t* data, size
|
|
|
|
|
if (remain <= sizeof(cli->send_buf)) { memcpy(cli->send_buf, data + r, remain); cli->send_len = (int)remain; cli->send_offset = 0; } |
|
|
|
|
if (ca && ca->ua) uasync_set_socket_write(ca->ua, cli->socket_id, 1); |
|
|
|
|
} |
|
|
|
|
if (r < 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "%s: send failed err=%d, closing client", CH_ID, socket_get_error()); |
|
|
|
|
ca_close_client(cli); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void ca_write_frame(struct call_audio_client* cli, uint8_t type, uint64_t call_id, |
|
|
|
|
@ -165,8 +171,6 @@ static void ca_media_recv(struct UTUN_INSTANCE* inst, uint64_t call_id,
|
|
|
|
|
|
|
|
|
|
/* ── разбор входящих фреймов ── */ |
|
|
|
|
|
|
|
|
|
static void ca_close_client(struct call_audio_client* cli); |
|
|
|
|
|
|
|
|
|
static void ca_parse_frames(struct call_audio_client* cli) { |
|
|
|
|
struct call_audio* ca = cli->ca; |
|
|
|
|
uint8_t* p = cli->recv_buf; |
|
|
|
|
@ -228,7 +232,11 @@ static void ca_write_callback(socket_t fd, void* arg) {
|
|
|
|
|
if (cli->send_len <= 0) { if (ca && ca->ua) uasync_set_socket_write(ca->ua, cli->socket_id, 0); return; } |
|
|
|
|
ssize_t r = send(cli->fd, cli->send_buf + cli->send_offset, cli->send_len - cli->send_offset, 0); |
|
|
|
|
if (r < 0 && (socket_get_error() == ERR_AGAIN || socket_get_error() == ERR_WOULDBLOCK)) return; |
|
|
|
|
if (r <= 0) { cli->send_len = 0; cli->send_offset = 0; if (ca && ca->ua) uasync_set_socket_write(ca->ua, cli->socket_id, 0); return; } |
|
|
|
|
if (r <= 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "%s: send failed (r=%zd err=%d) — closing client", CH_ID, r, socket_get_error()); |
|
|
|
|
ca_close_client(cli); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
cli->send_offset += (int)r; |
|
|
|
|
if (cli->send_offset >= cli->send_len) { cli->send_len = 0; cli->send_offset = 0; if (ca && ca->ua) uasync_set_socket_write(ca->ua, cli->socket_id, 0); } |
|
|
|
|
} |
|
|
|
|
|