#!/usr/bin/perl use strict; use warnings; use NGCP::Rtpengine::Test; use NGCP::Rtpclient::SRTP; use NGCP::Rtpengine::AutoTest; use Test::More; use POSIX; autotest_start(qw(--config-file=none -t -1 -i 203.0.113.1 -i 2001:db8:4321::1 -n 2223 -c 12345 -f -L 7 -E -u 2222 --silence-detect=1 --dtx-delay=10)) or die; my $amr_tests = $ENV{RTPENGINE_EXTENDED_TESTS}; #my $amr_tests = 0; my ($sock_a, $sock_b, $sock_c, $sock_d, $port_a, $port_b, $ssrc, $ssrc_b, $resp, $sock_ax, $sock_bx, $port_ax, $port_bx, $srtp_ctx_a, $srtp_ctx_b, $srtp_ctx_a_rev, $srtp_ctx_b_rev, @ret1, @ret2, @ret3, @ret4, $srtp_key_a, $srtp_key_b, $ts, $seq); if ($amr_tests) { ($sock_a, $sock_b) = new_call([qw(198.51.100.10 4024)], [qw(198.51.100.10 4026)]); ($port_a) = offer('AMR SID', { ICE => 'remove', replace => ['origin'], codec => { transcode => ['PCMA'], 'set' => ['AMR-WB/16000/1/23850'] } }, < 'remove', replace => ['origin'] }, < ft() }); ($sock_a, $sock_b) = new_call([qw(198.51.100.10 4026)], [qw(198.51.100.10 4028)]); ($port_a) = offer('AMR SID TS gap', { ICE => 'remove', replace => ['origin'], codec => { transcode => ['PCMA'], 'set' => ['AMR-WB/16000/1/23850'] } }, < 'remove', replace => ['origin'] }, < ft() }); ($sock_a, $sock_b) = new_call([qw(198.51.100.10 4034)], [qw(198.51.100.10 4036)]); ($port_a) = offer('AMR w DTMF', { codec => { mask => ['all'], transcode => [ 'G722', 'AMR-WB/16000/1///mode-set--0,1,2;mode-change-period--2;mode-change-capability--2', 'AMR', 'PCMA', 'telephone-event' ], } }, < ['single codec'] }, < ft() }); ($sock_a, $sock_b) = new_call([qw(198.51.100.10 4042)], [qw(198.51.100.10 4044)]); ($port_a) = offer('AMR w reverse DTMF', { codec => { mask => ['all'], transcode => [ 'AMR-WB/16000/1///mode-set--0,1,2;mode-change-period--2;mode-change-capability--2/dtx--1', 'PCMA', 'telephone-event' ], } }, < [] }, < ft() }); } ($sock_a, $sock_b) = new_call([qw(198.51.100.10 5000)], [qw(198.51.100.10 5002)]); ($port_a) = offer('G.711 DTX', { replace => ['origin'], codec => { transcode => ['PCMA'], } }, < ['origin'] }, < silence rcv($sock_b, $port_a, rtpm(8, $seq + 2, 4320, $ssrc, "\xd5" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 3, 4480, $ssrc, "\xd5" x 160)); # start audio again snd($sock_a, $port_b, rtp(0, 2002, 4640, 0x5678, "\x40" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 4, 4640, $ssrc, "\x68" x 160)); rtpe_req('delete', 'G.711 DTX', { 'from-tag' => ft() }); ($sock_a, $sock_b) = new_call([qw(198.51.100.10 5032)], [qw(198.51.100.10 5034)]); ($port_a) = offer('G.711 DTX with seq skips', { replace => ['origin'], codec => { transcode => ['PCMA'], } }, < ['origin'] }, < silence rcv($sock_b, $port_a, rtpm(8, $seq + 2, $ts + 320, $ssrc, "\xd5" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 3, $ts + 480, $ssrc, "\xd5" x 160)); # start audio again snd($sock_a, $port_b, rtp(0, 4002, $ts + 640, 0x5678, "\x40" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 4, $ts + 640, $ssrc, "\x68" x 160)); snd($sock_a, $port_b, rtp(0, 4003, $ts + 800, 0x5678, "\x40" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 5, $ts + 800, $ssrc, "\x68" x 160)); snd($sock_a, $port_b, rtp(0, 4004, $ts + 960, 0x5678, "\x40" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 6, $ts + 960, $ssrc, "\x68" x 160)); snd($sock_a, $port_b, rtp(0, 4005, $ts + 1120, 0x5678, "\x40" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 7, $ts + 1120, $ssrc, "\x68" x 160)); snd($sock_a, $port_b, rtp(0, 4006, $ts + 1280, 0x5678, "\x40" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 8, $ts + 1280, $ssrc, "\x68" x 160)); snd($sock_a, $port_b, rtp(0, 4007, $ts + 1440, 0x5678, "\x40" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 9, $ts + 1440, $ssrc, "\x68" x 160)); # lost packet 4008 (skip seq), trigger DTX rcv($sock_b, $port_a, rtpm(8, $seq + 10, $ts + 1600, $ssrc, "\xd5" x 160)); # resume snd($sock_a, $port_b, rtp(0, 4009, $ts + 1760, 0x5678, "\x40" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 11, $ts + 1760, $ssrc, "\xd5" x 160)); snd($sock_a, $port_b, rtp(0, 4010, $ts + 1920, 0x5678, "\x40" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 12, $ts + 1920, $ssrc, "\x68" x 160)); snd($sock_a, $port_b, rtp(0, 4011, $ts + 2080, 0x5678, "\x40" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 13, $ts + 2080, $ssrc, "\x68" x 160)); snd($sock_a, $port_b, rtp(0, 4012, $ts + 2240, 0x5678, "\x40" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 14, $ts + 2240, $ssrc, "\x68" x 160)); rtpe_req('delete', 'G.711 DTX with seq skips', { 'from-tag' => ft() }); ($sock_a, $sock_b) = new_call([qw(198.51.100.10 5004)], [qw(198.51.100.10 5006)]); ($port_a) = offer('G.711 DTX ptime=30', { replace => ['origin'], codec => { transcode => ['PCMA'], } }, < ['origin'] }, < silence rcv($sock_b, $port_a, rtpm(8, $seq + 2, 4480, $ssrc, "\xd5" x 240)); rcv($sock_b, $port_a, rtpm(8, $seq + 3, 4720, $ssrc, "\xd5" x 240)); # start audio again snd($sock_a, $port_b, rtp(0, 2002, 4960, 0x5678, "\x40" x 240)); rcv($sock_b, $port_a, rtpm(8, $seq + 4, 4960, $ssrc, "\x68" x 240)); rtpe_req('delete', 'G.711 DTX ptime=30', { 'from-tag' => ft() }); ($sock_a, $sock_b) = new_call([qw(198.51.100.10 5008)], [qw(198.51.100.10 5010)]); ($port_a) = offer('G.711 DTX ptime change', { replace => ['origin'], codec => { transcode => ['PCMA'], } }, < ['origin'] }, < silence rcv($sock_b, $port_a, rtpm(8, $seq + 3, 4480, $ssrc, "\xd5" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 4, 4640, $ssrc, "\xd5" x 160)); rcv($sock_b, $port_a, rtpm(8, $seq + 5, 4800, $ssrc, "\xd5" x 160)); # start audio again snd($sock_a, $port_b, rtp(0, 2002, 4960, 0x5678, "\x40" x 240)); rcv($sock_b, $port_a, rtpm(8, $seq + 6, 4960, $ssrc, "\x68" x 160)); rtpe_req('delete', 'G.711 DTX ptime change', { 'from-tag' => ft() }); #done_testing;NGCP::Rtpengine::AutoTest::terminate('f00');exit; done_testing();