|
|
|
|
@ -99,6 +99,15 @@ struct media_evt {
|
|
|
|
|
uint8_t last[64]; |
|
|
|
|
}; |
|
|
|
|
static struct media_evt g_media[2]; |
|
|
|
|
static struct call_capture_time g_capture_timing; |
|
|
|
|
static const struct call_capture_time sent_timing = {1234567890123ll, 19, 312}; |
|
|
|
|
|
|
|
|
|
static void audio_recv_cb(struct UTUN_INSTANCE* inst, uint64_t call_id, uint16_t seq, uint32_t ts, |
|
|
|
|
const uint8_t* opus, int len, const struct call_capture_time* timing) { |
|
|
|
|
(void)inst; (void)call_id; (void)seq; (void)ts; (void)opus; (void)len; |
|
|
|
|
g_capture_timing = *timing; |
|
|
|
|
} |
|
|
|
|
static const struct call_audio_ops audio_ops = {.on_media = audio_recv_cb}; |
|
|
|
|
|
|
|
|
|
static void media_recv_cb(struct UTUN_INSTANCE* inst, uint64_t call_id, |
|
|
|
|
const uint8_t* opus, int len, void* arg) { |
|
|
|
|
@ -432,7 +441,12 @@ static void call_tick(void* arg) {
|
|
|
|
|
|
|
|
|
|
/* тестовый «Opus-кадр» — релей произвольных байт, не валидируем кодек */ |
|
|
|
|
static const uint8_t opus[16] = { 0xf8, 0xff, 0xfe, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d }; |
|
|
|
|
if (call_send_media(A, t->call_id, opus, sizeof(opus), NULL) != 0) { |
|
|
|
|
struct call_capture_time invalid = sent_timing; |
|
|
|
|
invalid.delay_samples = 48001; |
|
|
|
|
if (call_send_media(A, t->call_id, opus, sizeof(opus), &invalid) == 0) { |
|
|
|
|
fprintf(stderr, "A: invalid codec delay accepted\n"); t->result = 2; break; |
|
|
|
|
} |
|
|
|
|
if (call_send_media(A, t->call_id, opus, sizeof(opus), &sent_timing) != 0) { |
|
|
|
|
fprintf(stderr, "A: call_send_media failed\n"); |
|
|
|
|
t->result = 2; |
|
|
|
|
} else { |
|
|
|
|
@ -442,7 +456,13 @@ static void call_tick(void* arg) {
|
|
|
|
|
} |
|
|
|
|
case P_WAIT_MEDIA: |
|
|
|
|
if (g_media[IDX_B].frames > 0 && g_media[IDX_B].last_call_id == t->call_id |
|
|
|
|
&& g_media[IDX_B].last_len == 16) t->phase = P_HANGUP; |
|
|
|
|
&& g_media[IDX_B].last_len == 16) { |
|
|
|
|
if (g_media[IDX_B].frames != 1 || g_capture_timing.pts_us != sent_timing.pts_us |
|
|
|
|
|| g_capture_timing.epoch != sent_timing.epoch || g_capture_timing.delay_samples != sent_timing.delay_samples) { |
|
|
|
|
fprintf(stderr, "B: capture timing changed in transit\n"); t->result = 2; break; |
|
|
|
|
} |
|
|
|
|
t->phase = P_HANGUP; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case P_HANGUP: |
|
|
|
|
call_hangup(A, t->call_id); |
|
|
|
|
@ -550,6 +570,7 @@ int main(int argc, char** argv) {
|
|
|
|
|
chat_event_set_handler(t.inst[IDX_B], call_evt_handler); |
|
|
|
|
call_set_media_recv_cb(t.inst[IDX_A], media_recv_cb, &g_media[IDX_A]); |
|
|
|
|
call_set_media_recv_cb(t.inst[IDX_B], media_recv_cb, &g_media[IDX_B]); |
|
|
|
|
call_set_audio_ops(t.inst[IDX_B], &audio_ops); |
|
|
|
|
|
|
|
|
|
t.timer = uasync_set_timeout(ua, TICK_TB, &t, call_tick, "call_tick"); |
|
|
|
|
uasync_mainloop(ua); |
|
|
|
|
|