diff --git a/library/AMR_Types.ttcn b/library/AMR_Types.ttcn index 5586a202d..f453234c8 100644 --- a/library/AMR_Types.ttcn +++ b/library/AMR_Types.ttcn @@ -67,4 +67,25 @@ external function enc_RTP_AMR_Hdr(in RTP_AMR_Hdr amr_hdr) return octetstring external function dec_RTP_AMR_Hdr(in octetstring stream) return RTP_AMR_Hdr with { extension "prototype(convert) decode(RAW)" }; + +type record RTP_AMR_BWE_Hdr { + uint4_t cmr, + BIT1 f, + uint4_t ft, + BIT1 q +} with { variant "FIELDORDER(msb)" }; +template (value) RTP_AMR_BWE_Hdr ts_RTP_AMR_BWE_Hdr(template (value) uint4_t cmr, + template (value) uint4_t ft, + template (value) BIT1 q := '1'B, + template (value) BIT1 f := '0'B) := { + cmr := cmr, + f := f, + ft := ft, + q := q +} +external function enc_RTP_AMR_BWE_Hdr(in RTP_AMR_BWE_Hdr amr_hdr) return octetstring + with { extension "prototype(convert) encode(RAW)" }; +external function dec_RTP_AMR_BWE_Hdr(in octetstring stream) return RTP_AMR_BWE_Hdr + with { extension "prototype(convert) decode(RAW)" }; + } with { encode "RAW"} diff --git a/mgw/MGCP_Test.ttcn b/mgw/MGCP_Test.ttcn index 5ff5247e9..3b49afcad 100644 --- a/mgw/MGCP_Test.ttcn +++ b/mgw/MGCP_Test.ttcn @@ -1339,7 +1339,7 @@ module MGCP_Test { return true; } - function f_TC_two_crcx_and_rtp_osmux(boolean bidir, + function f_TC_two_crcx_and_rtp_osmux(boolean bidir, boolean rtp_amr_oa, charstring local_ip_rtp, charstring remote_ip_rtp, charstring local_ip_osmux, charstring remote_ip_osmux) runs on dummy_CT { var RtpFlowData flow[2]; @@ -1350,15 +1350,35 @@ module MGCP_Test { var MgcpCallId call_id := '1226'H; var integer tolerance := 0; + var octetstring amr_payload; + var charstring fmtp; + f_init(ep, true); + var AMRFT cmr := AMR_FT_0; + var AMRFT ft := AMR_FT_2; + if (rtp_amr_oa) { + fmtp := "octet-align=1"; + var RTP_AMR_Hdr amr_oa_hdr := valueof(ts_RTP_AMR_Hdr(enum2int(cmr), enum2int(ft))); + amr_payload := enc_RTP_AMR_Hdr(amr_oa_hdr) & + f_osmux_gen_expected_rx_rtp_payload(enum2int(ft), c_OsmuxemDefaultCfg.tx_fixed_payload); + } else { + fmtp := "octet-align=0"; + /* Convert OA to BWE: */ + var RTP_AMR_BWE_Hdr amr_bwe_hdr := valueof(ts_RTP_AMR_BWE_Hdr(enum2int(cmr), enum2int(ft))); + var bitstring amr_bwe_hdr_bits := substr(oct2bit(enc_RTP_AMR_BWE_Hdr(amr_bwe_hdr)), 0 , 10); + var bitstring amr_data_bits := oct2bit(f_osmux_gen_expected_rx_rtp_payload(enum2int(ft), c_OsmuxemDefaultCfg.tx_fixed_payload)); + var bitstring amr_payload_bits := amr_bwe_hdr_bits & substr(amr_data_bits, 0, f_amrft_payload_bits_len(enum2int(ft))); + amr_payload := bit2oct(f_pad_bit(amr_payload_bits, (lengthof(amr_payload_bits)+7)/8*8, '0'B)); + }; + /* from us to MGW */ flow[0] := valueof(t_RtpFlow(local_ip_rtp, remote_ip_rtp, 112, "AMR/8000")); flow[0].rtp_cfg := c_RtpemDefaultCfg flow[0].rtp_cfg.tx_payload_type := flow[0].pt; - /* 0014 is the ToC (CMR=AMR4.75) in front of AMR Payload in RTP Payload */ - flow[0].rtp_cfg.rx_fixed_payload := '0014'O & f_osmux_gen_expected_rx_rtp_payload(2 /* AMR_FT_2, 5.90 */, c_OsmuxemDefaultCfg.tx_fixed_payload); - flow[0].rtp_cfg.tx_fixed_payload := flow[0].rtp_cfg.rx_fixed_payload; + flow[0].rtp_cfg.rx_fixed_payload := amr_payload; + flow[0].rtp_cfg.tx_fixed_payload := amr_payload; + flow[0].fmtp := fmtp; /* bind local RTP emulation sockets */ flow[0].em.portnr := 10000; f_flow_create(RTPEM[0], ep, call_id, "sendrecv", flow[0]); @@ -1409,30 +1429,39 @@ module MGCP_Test { /* create one RTP and one OSmux emulations; create two connections on MGW EP, exchange some data */ testcase TC_two_crcx_and_rtp_osmux() runs on dummy_CT { - f_TC_two_crcx_and_rtp_osmux(false, mp_local_ipv4, mp_remote_ipv4, + f_TC_two_crcx_and_rtp_osmux(false, true, mp_local_ipv4, mp_remote_ipv4, mp_local_ipv4, mp_remote_ipv4); } /* create one RTP and one OSmux emulations; create two connections on MGW EP, * exchange some data in both directions */ testcase TC_two_crcx_and_rtp_osmux_bidir() runs on dummy_CT { - f_TC_two_crcx_and_rtp_osmux(true, mp_local_ipv4, mp_remote_ipv4, + f_TC_two_crcx_and_rtp_osmux(true, true, mp_local_ipv4, mp_remote_ipv4, mp_local_ipv4, mp_remote_ipv4); } + /* create one RTP and one OSmux emulations; create two connections on MGW EP, + * exchange some data in both directions. RTP side is configured to + * rx/rx AMR in bandwidth-efficient mode. */ + testcase TC_two_crcx_and_rtp_osmux_bidir_amr_bwe() runs on dummy_CT { + f_TC_two_crcx_and_rtp_osmux(true, false, mp_local_ipv4, mp_remote_ipv4, + mp_local_ipv4, mp_remote_ipv4); + } + + /* Same as TC_two_crcx_and_rtp_osmux_bidir, but using IPv6 */ testcase TC_two_crcx_and_rtp_osmux_bidir_ipv6() runs on dummy_CT { - f_TC_two_crcx_and_rtp_osmux(true, mp_local_ipv6, mp_remote_ipv6, + f_TC_two_crcx_and_rtp_osmux(true, true, mp_local_ipv6, mp_remote_ipv6, mp_local_ipv6, mp_remote_ipv6); } /* Same as TC_two_crcx_and_rtp_osmux_bidir, but using IPv4 (RTP) and IPv6 (Osmux) */ testcase TC_two_crcx_and_rtp_osmux_bidir_ipv4_ipv6() runs on dummy_CT { - f_TC_two_crcx_and_rtp_osmux(true, mp_local_ipv4, mp_remote_ipv4, + f_TC_two_crcx_and_rtp_osmux(true, true, mp_local_ipv4, mp_remote_ipv4, mp_local_ipv6, mp_remote_ipv6); } /* Same as TC_two_crcx_and_rtp_osmux_bidir, but using IPv6 (RTP) and IPv4 (Osmux) */ testcase TC_two_crcx_and_rtp_osmux_bidir_ipv6_ipv4() runs on dummy_CT { - f_TC_two_crcx_and_rtp_osmux(true, mp_local_ipv6, mp_remote_ipv6, + f_TC_two_crcx_and_rtp_osmux(true, true, mp_local_ipv6, mp_remote_ipv6, mp_local_ipv4, mp_remote_ipv4); } @@ -2915,6 +2944,7 @@ module MGCP_Test { execute(TC_one_crcx_loopback_osmux()); execute(TC_two_crcx_and_rtp_osmux()); execute(TC_two_crcx_and_rtp_osmux_bidir()); + execute(TC_two_crcx_and_rtp_osmux_bidir_amr_bwe()); execute(TC_two_crcx_mdcx_and_rtp_osmux_wildcard()); execute(TC_two_crcx_mdcx_and_rtp_osmux_fixed());