pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/29070 )
Change subject: bts: Add testscase & infra to validate Osmux support BTS<->BSC ......................................................................
bts: Add testscase & infra to validate Osmux support BTS<->BSC
Related: SYS#5987 Change-Id: I1af23c7a60b05edc3b544f1fea0023f48e89f7a7 --- M bts/BTS_Tests.ttcn M bts/gen_links.sh M bts/osmo-bts.cfg M bts/regen_makefile.sh M library/OSMUX_Types.ttcn M library/RSL_Types.ttcn 6 files changed, 351 insertions(+), 62 deletions(-)
Approvals: pespin: Looks good to me, approved osmith: Looks good to me, but someone else must approve Jenkins Builder: Verified
diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn index 68e5cf1..e71aed9 100644 --- a/bts/BTS_Tests.ttcn +++ b/bts/BTS_Tests.ttcn @@ -49,6 +49,11 @@
import from AMR_Types all;
+import from OSMUX_Types all; +import from OSMUX_CodecPort all; +import from OSMUX_CodecPort_CtrlFunct all; +import from OSMUX_Emulation all; + import from IPL4asp_Types all; import from TRXC_Types all; import from TRXC_CodecPort all; @@ -99,6 +104,8 @@ integer mp_bsc_ctrl_port := 4249; charstring mp_rtpem_bind_ip := "127.0.0.1"; integer mp_rtpem_bind_port := 6766; + charstring mp_osmuxem_bind_ip := "127.0.0.1"; + integer mp_osmuxem_bind_port := 1984; integer mp_tolerance_rxqual := 1; integer mp_tolerance_rxlev := 3; integer mp_tolerance_timing_offset_256syms := 0; @@ -219,6 +226,9 @@ var RTP_Emulation_CT vc_RTPEM; port RTPEM_CTRL_PT RTPEM_CTRL; port RTPEM_DATA_PT RTPEM_DATA; + var OSMUX_Emulation_CT vc_OsmuxEM; + port OsmuxEM_CTRL_PT OsmuxEM_CTRL; + port OsmuxEM_DATA_PT OsmuxEM_DATA; }
private function f_init_rsl(charstring id) runs on test_CT { @@ -319,7 +329,9 @@ /* Training Sequence Code */ GsmTsc tsc, /* Frequency hopping parameters */ - FreqHopPars fhp + FreqHopPars fhp, + OsmuxCID loc_osmux_cid, + OsmuxCID rem_osmux_cid optional };
/* Test-specific parameters */ @@ -907,7 +919,9 @@ maio_hsn := ts_HsnMaio(0, 0), ma_map := c_MA_null, ma := { } - } + }, + loc_osmux_cid := trx_nr, + rem_osmux_cid := omit }
/* This altstep triggers on receipt of a L1CTL DATA.ind matching the given @@ -2622,7 +2636,7 @@ /* FIXME (OS#5242): do not include Remote IP/Port IEs because * osmo-bts would respond with nonsense listen addr='0.0.0.0'. */ ts_RSL_IPA_CRCX(g_chan_nr, omit, omit), - tr_RSL_IPA_CRCX_ACK(g_chan_nr, ?, ?, ?), + tr_RSL_IPA_CRCX_ACK(g_chan_nr, ?, ?, ?, omit), "IPA CRCX ACK"); var uint16_t conn_id := crcx_ack.ies[1].body.ipa_conn_id;
@@ -2644,6 +2658,71 @@ f_rtpem_mode(RTPEM_CTRL, mode); }
+/* Initialize and start the RTP emulation component for a ConnHdlr */ +friend function f_osmuxem_activate(inout octetstring payload, + OsmuxemConfig cfg := c_OsmuxemDefaultCfg, + OsmuxemMode mode := OSMUXEM_MODE_BIDIR) +runs on ConnHdlr { + var RSL_IE_Body ie; + var OsmuxTxHandle tx_hdl; + var OsmuxRxHandle rx_hdl; + /* Step 0: initialize, connect and start the emulation component */ + vc_OsmuxEM := OSMUX_Emulation_CT.create(testcasename() & "-OsmuxEM"); + map(vc_OsmuxEM:OSMUX, system:OSMUX); + connect(vc_OsmuxEM:CTRL, self:OsmuxEM_CTRL); + connect(vc_OsmuxEM:DATA, self:OsmuxEM_DATA); + vc_OsmuxEM.start(OSMUX_Emulation.f_main()); + + /* Step 1: configure the RTP parameters */ + var integer payload_len := 31; + var octetstring hdr := ''O; + + /* Pad the payload to conform the expected length */ + payload := f_pad_oct(hdr & payload, payload_len, '00'O); + cfg.tx_fixed_payload := payload; + f_osmuxem_configure(OsmuxEM_CTRL, cfg); + + /* Step 2: bind the RTP emulation to the configured address */ + var PortNumber osmuxem_bind_port := mp_osmuxem_bind_port; + f_osmuxem_bind(OsmuxEM_CTRL, mp_osmuxem_bind_ip, osmuxem_bind_port); + rx_hdl := c_OsmuxemDefaultRxHandle; + rx_hdl.cid := g_pars.loc_osmux_cid; + f_osmuxem_register_rxhandle(OsmuxEM_CTRL, rx_hdl); + + /* Step 3a: send CRCX to create an RTP connection at the IUT */ + var RSL_Message crcx_ack := f_rsl_transceive_ret( + /* FIXME (OS#5242): do not include Remote IP/Port IEs because + * osmo-bts would respond with nonsense listen addr='0.0.0.0'. */ + ts_RSL_IPA_CRCX(g_chan_nr, omit, omit, g_pars.loc_osmux_cid), + tr_RSL_IPA_CRCX_ACK(g_chan_nr, ?, ?, ?, ?), + "IPA CRCX ACK"); + var uint16_t conn_id := crcx_ack.ies[1].body.ipa_conn_id; + f_rsl_find_ie(crcx_ack, RSL_IE_OSMO_OSMUX_CID, ie); + g_pars.rem_osmux_cid := ie.osmux_cid.cid; + + + /* Step 3b: send MDCX with the configured address/port to the IUT */ + var RSL_Message mdcx_ack := f_rsl_transceive_ret( + ts_RSL_IPA_MDCX(g_chan_nr, conn_id, + remote_ip := f_inet_addr(mp_osmuxem_bind_ip), + remote_port := osmuxem_bind_port, + rtp_pt2 := 0, + osmux_cid := g_pars.loc_osmux_cid), + tr_RSL_IPA_MDCX_ACK(g_chan_nr, conn_id, ?, ?, ?, g_pars.rem_osmux_cid), + "IPA MDCX ACK"); + + tx_hdl := valueof(t_TxHandleAMR590(g_pars.rem_osmux_cid)); + f_osmuxem_register_txhandle(OsmuxEM_CTRL, tx_hdl); + + /* Step 4: connect to the IUT's address/port parsed from MDCX ACK */ + var HostName bts_bind_ip := f_inet_ntoa(mdcx_ack.ies[2].body.ipa_local_ip); + var PortNumber bts_bind_port := mdcx_ack.ies[3].body.ipa_local_port; + f_osmuxem_connect(OsmuxEM_CTRL, bts_bind_ip, bts_bind_port); + + /* Step 5: set the given RTP emulation mode */ + f_osmuxem_mode(OsmuxEM_CTRL, mode); +} + /* establish DChan, verify existance + contents of measurement reports */ private function f_TC_meas_res_periodic(charstring id) runs on ConnHdlr { f_l1_tune(L1CTL); @@ -8211,6 +8290,120 @@ Misc_Helpers.f_shutdown(__BFILE__, __LINE__); }
+ +/* Verify handling of Downlink and Uplink Osmux speech frames */ +private function f_TC_speech_osmux(charstring id) runs on ConnHdlr { + var L1ctlDlMessage l1_dl; + var OSMUX_PDU osmux_pdu; + var octetstring pl; + var octetstring exp_rtp_pl; + timer Td, Tu; + + f_l1_tune(L1CTL); + f_est_dchan(); + + /* Activate the RTP emulation */ + pl := f_rnd_octstring(6); + f_osmuxem_activate(pl); + + /* Give the scheduler some time to fill up the buffers */ + f_sleep(2.0); + L1CTL.clear; + RSL.clear; + + /* we transmit using AMR_FT_2 (5.90), see t_TxHandleAMR590 in f_osmuxem_activate() */ + var integer amr_ft := get_start_amr_ft(); + var integer amr_pl_len := f_amrft_payload_len(amr_ft); + var octetstring hdr := enc_RTP_AMR_Hdr(valueof(ts_RTP_AMR_Hdr(amr_ft, amr_ft, '1'B))); + pl := f_osmux_gen_expected_rx_rtp_payload(amr_ft, pl); + exp_rtp_pl := hdr & pl; + + /* Make sure that Downlink frames are received at the UE */ + Td.start(2.0); + alt { + [] L1CTL.receive(tr_L1CTL_TRAFFIC_IND(g_chan_nr, frame := exp_rtp_pl)) -> value l1_dl { + log("TCH received: ", l1_dl.payload.traffic_ind.data); + L1CTL.send(ts_L1CTL_TRAFFIC_REQ(g_chan_nr, l1_dl.dl_info.link_id, + l1_dl.payload.traffic_ind.data)); + setverdict(pass); + } + [] L1CTL.receive(tr_L1CTL_TRAFFIC_IND(g_chan_nr, frame := ?)) -> value l1_dl { + setverdict(fail, "Rx unexpected Downlink speech frame ", + "(", l1_dl.payload.traffic_ind.data, ") ", + "expected (", exp_rtp_pl, ")"); + Misc_Helpers.f_shutdown(__BFILE__, __LINE__); + } + [] as_l1_sacch(); + [] L1CTL.receive { repeat; } + [] Td.timeout { + setverdict(fail, "Timeout waiting for Downlink speech frames"); + Misc_Helpers.f_shutdown(__BFILE__, __LINE__); + } + } + + /* Make sure that Uplink frames are received at the BTS */ + OsmuxEM_DATA.clear; + var template (present) OSMUX_PDU osmux_pdu_exp := tr_PDU_Osmux_AMR(cid := g_pars.loc_osmux_cid, + amr_ft := amr_ft, + amr_cmr := amr_ft); + Tu.start(2.0); + alt { + [] OsmuxEM_DATA.receive(osmux_pdu_exp) -> value osmux_pdu { + var boolean matched := false; + for (var integer i := 0; i < osmux_pdu.osmux_amr.header.ctr + 1; i := i + 1) { + var octetstring rx_pl; + rx_pl := f_osmux_amr_get_nth_amr_payload(osmux_pdu.osmux_amr, i); + log("got ", rx_pl, " vs exp ", pl); + if (rx_pl == pl) { + matched := true; + break; + } + } + if (not matched) { + repeat; + } + } + [] OsmuxEM_DATA.receive { repeat; } + [] Tu.timeout { + setverdict(fail, "Timeout waiting for Uplink speech frames"); + Misc_Helpers.f_shutdown(__BFILE__, __LINE__); + } + } + + f_osmuxem_mode(OsmuxEM_CTRL, OSMUXEM_MODE_NONE); + f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr); + f_rsl_chan_deact(); + f_rslem_unregister(0, g_chan_nr); +} +testcase TC_speech_osmux_tchf() runs on test_CT { + var ConnHdlr vc_conn; + var ConnHdlrPars pars; + + f_init(); + + /* TS5, TCH/H0, V3 (AMR codec) */ + pars := valueof(t_Pars(ts_RslChanNr_Bm(1), ts_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))); + pars.mr_conf := valueof(ts_RSL_MultirateCfg(false, 0, '00000100'B /* 5,90k */)); + vc_conn := f_start_handler(refers(f_TC_speech_osmux), pars); + vc_conn.done; + + Misc_Helpers.f_shutdown(__BFILE__, __LINE__); +} +testcase TC_speech_osmux_tchh() runs on test_CT { + var ConnHdlr vc_conn; + var ConnHdlrPars pars; + + f_init(); + + /* TS5, TCH/H0, V3 (AMR codec) */ + pars := valueof(t_Pars(ts_RslChanNr_Lm(5, 0), ts_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))); + pars.mr_conf := valueof(ts_RSL_MultirateCfg(false, 0, '00000100'B /* 5,90k */)); + vc_conn := f_start_handler(refers(f_TC_speech_osmux), pars); + vc_conn.done; + + Misc_Helpers.f_shutdown(__BFILE__, __LINE__); +} + private function f_TC_early_immediate_assignment(charstring id) runs on ConnHdlr { var GsmFrameNumber fn; var ChannelDescription ch_desc; @@ -8808,6 +9001,8 @@ execute( TC_speech_no_rtp_tchh() ); execute( TC_speech_rtp_tchf() ); execute( TC_speech_rtp_tchh() ); + execute( TC_speech_osmux_tchf() ); + execute( TC_speech_osmux_tchh() );
execute( TC_early_immediate_assignment() );
diff --git a/bts/gen_links.sh b/bts/gen_links.sh index b7ba2cc..c9eb786 100755 --- a/bts/gen_links.sh +++ b/bts/gen_links.sh @@ -47,6 +47,7 @@ FILES+="AMR_Types.ttcn " FILES+="RTP_CodecPort.ttcn RTP_Emulation.ttcn IuUP_Types.ttcn IuUP_Emulation.ttcn IuUP_EncDec.cc " FILES+="RTP_CodecPort_CtrlFunct.ttcn RTP_CodecPort_CtrlFunctDef.cc " +FILES+="OSMUX_CodecPort.ttcn OSMUX_Emulation.ttcn OSMUX_Types.ttcn OSMUX_CodecPort_CtrlFunct.ttcn OSMUX_CodecPort_CtrlFunctDef.cc " FILES+="PCUIF_Types.ttcn PCUIF_CodecPort.ttcn " FILES+="IPA_Testing.ttcn" gen_links $DIR $FILES diff --git a/bts/osmo-bts.cfg b/bts/osmo-bts.cfg index f581be0..2eb84ff 100644 --- a/bts/osmo-bts.cfg +++ b/bts/osmo-bts.cfg @@ -24,7 +24,9 @@ logging level dsp info logging level pcu debug logging level trx info + logging level osmux info logging level lmib debug + logging level lmux info ! line vty no login @@ -60,6 +62,10 @@ min-qual-norm -5 !settsc pcu-socket /tmp/pcu_sock + osmux + use on + local-ip 127.0.0.1 + local-port 1984 trx 0 power-ramp max-initial 0 mdBm power-ramp step-size 8000 mdB diff --git a/bts/regen_makefile.sh b/bts/regen_makefile.sh index 147d64f..054b750 100755 --- a/bts/regen_makefile.sh +++ b/bts/regen_makefile.sh @@ -11,6 +11,7 @@ IuUP_EncDec.cc L1CTL_PortType_CtrlFunctDef.cc Native_FunctionDefs.cc + OSMUX_CodecPort_CtrlFunctDef.cc RLCMAC_EncDec.cc RTP_CodecPort_CtrlFunctDef.cc RTP_EncDec.cc diff --git a/library/OSMUX_Types.ttcn b/library/OSMUX_Types.ttcn index 8ff7451..bc592b7 100644 --- a/library/OSMUX_Types.ttcn +++ b/library/OSMUX_Types.ttcn @@ -11,6 +11,9 @@ module OSMUX_Types {
import from General_Types all; +import from Misc_Helpers all; + +import from AMR_Types all;
external function enc_OSMUX_PDU ( in OSMUX_PDU msg ) return octetstring with { extension "prototype(convert) encode(RAW)" }; @@ -83,4 +86,44 @@ )" };
+template (present) OSMUX_PDU tr_PDU_Osmux_AMR(template (present) BIT1 marker := ?, + template (present) INT3b ctr := ?, + template (present) BIT1 amr_f := ?, + template (present) BIT1 amr_q := ?, + template (present) INT1 seq := ?, + template (present) OsmuxCID cid := ?, + template (present) INT4b amr_ft := ?, + template (present) INT4b amr_cmr := ?, + template (present) octetstring payload := ?) := { + osmux_amr := { + header := { + marker := marker, + ft := 1, + ctr := ctr, + amr_f := amr_f, + amr_q := amr_q, + seq := seq, + cid := cid, + amr_ft := amr_ft, + amr_cmr := amr_cmr + }, + data := payload + } +} + +/* Get Nth AMR payload of osmux AMR frame (starting from 0) */ +function f_osmux_amr_get_nth_amr_payload(PDU_Osmux_AMR osmux_amr, integer nth) return octetstring +{ + var integer amr_pl_len := f_amrft_payload_len(osmux_amr.header.amr_ft); + if (nth > osmux_amr.header.ctr) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "nth > ctr"); + return ''O; + } + if (amr_pl_len * (nth+1) > lengthof(osmux_amr.data)) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "osmux payload too short"); + } + var octetstring pl := substr(osmux_amr.data, amr_pl_len * nth, amr_pl_len); + return pl; +} + } with { encode "RAW"} diff --git a/library/RSL_Types.ttcn b/library/RSL_Types.ttcn index 3acd619..a86be86 100644 --- a/library/RSL_Types.ttcn +++ b/library/RSL_Types.ttcn @@ -973,6 +973,14 @@ len := ?, /* overwritten */ cid := osmux_cid }; + function f_tr_RSL_IE_OSMO_Osmux_CID(template uint8_t osmux_cid := *) + return template RSL_IE_OSMO_Osmux_CID { + var template RSL_IE_OSMO_Osmux_CID ie := omit; + if (not istemplatekind(osmux_cid, "omit")) { + ie := tr_RSL_IE_OSMO_Osmux_CID(osmux_cid); + } + return ie; + } template (value) RSL_IE_OSMO_Osmux_CID ts_RSL_IE_OSMO_Osmux_CID(template (value) uint8_t osmux_cid) := { len := 0, /* overwritten */ @@ -2157,7 +2165,8 @@
private function f_ts_RSL_IPA_CRCX_IEs(template (value) RslChannelNr chan_nr, template (omit) OCT4 remote_ip, - template (omit) uint16_t remote_port) + template (omit) uint16_t remote_port, + template (omit) uint8_t osmux_cid) return RSL_IE_List { var RSL_IE_List ies;
@@ -2185,6 +2194,15 @@ }) }; } + /* Osmux CID extension IE is optional: */ + if (not istemplatekind(osmux_cid, "omit")) { + ies := ies & { + valueof(RSL_IE:{ + iei := RSL_IE_OSMO_OSMUX_CID, + body := { osmux_cid := ts_RSL_IE_OSMO_Osmux_CID(osmux_cid) } + }) + }; + }
return ies; } @@ -2199,10 +2217,11 @@ template (value) RSL_Message ts_RSL_IPA_CRCX(template (value) RslChannelNr chan_nr, template (omit) OCT4 remote_ip := omit, - template (omit) uint16_t remote_port := omit) := { + template (omit) uint16_t remote_port := omit, + template (omit) uint8_t osmux_cid := omit) := { msg_disc := ts_RSL_MsgDisc(RSL_MDISC_IPACCESS, false), msg_type := RSL_MT_IPAC_CRCX, - ies := f_ts_RSL_IPA_CRCX_IEs(chan_nr, remote_ip, remote_port) + ies := f_ts_RSL_IPA_CRCX_IEs(chan_nr, remote_ip, remote_port, osmux_cid) }
function ts_RSL_IPA_CRCX_ACK(template (value) RslChannelNr chan_nr, @@ -2227,19 +2246,27 @@ return msg; }
- template RSL_Message tr_RSL_IPA_CRCX_ACK(template RslChannelNr chan_nr, - template uint16_t ipa_conn_id, - template OCT4 local_ip, - template uint16_t local_port) := { - msg_disc := tr_RSL_MsgDisc(RSL_MDISC_IPACCESS, false), - msg_type := RSL_MT_IPAC_CRCX_ACK, - ies := { - tr_RSL_IE(RSL_IE_Body:{chan_nr := chan_nr}), - tr_RSL_IE(RSL_IE_Body:{ipa_conn_id := ipa_conn_id}), - tr_RSL_IE(RSL_IE_Body:{ipa_local_ip := local_ip}), - tr_RSL_IE(RSL_IE_Body:{ipa_local_port := local_port}) - /* Optional: RTP Payload Type 2 IE */ + function tr_RSL_IPA_CRCX_ACK(template RslChannelNr chan_nr, + template uint16_t ipa_conn_id, + template OCT4 local_ip, + template uint16_t local_port, + template uint8_t osmux_cid := omit) + return template RSL_Message { + var template RSL_Message msg := { + msg_disc := ts_RSL_MsgDisc(RSL_MDISC_IPACCESS, false), + msg_type := RSL_MT_IPAC_CRCX_ACK, + ies := { + tr_RSL_IE(RSL_IE_Body:{chan_nr := chan_nr}), + tr_RSL_IE(RSL_IE_Body:{ipa_conn_id := ipa_conn_id}), + tr_RSL_IE(RSL_IE_Body:{ipa_local_ip := local_ip}), + tr_RSL_IE(RSL_IE_Body:{ipa_local_port := local_port}) + /* Optional: RTP Payload Type 2 IE */ + } } + if (not istemplatekind(osmux_cid, "omit")) { + msg.ies[lengthof(msg.ies)] := tr_RSL_IE(RSL_IE_Body:{osmux_cid := f_tr_RSL_IE_OSMO_Osmux_CID(osmux_cid)}); + } + return msg; }
template (value) RSL_Message ts_RSL_IPA_CRCX_NACK(template (value) RslChannelNr chan_nr, @@ -2261,20 +2288,28 @@ } }
- template (value) RSL_Message ts_RSL_IPA_MDCX(template (value) RslChannelNr chan_nr, - uint16_t ipa_conn_id, - OCT4 remote_ip, uint16_t remote_port, - uint7_t rtp_pt2) := { - msg_disc := ts_RSL_MsgDisc(RSL_MDISC_IPACCESS, false), - msg_type := RSL_MT_IPAC_MDCX, - ies := { - t_RSL_IE(RSL_IE_CHAN_NR, RSL_IE_Body:{chan_nr := chan_nr}), - t_RSL_IE(RSL_IE_IPAC_CONN_ID, RSL_IE_Body:{ipa_conn_id := ipa_conn_id}), - t_RSL_IE(RSL_IE_IPAC_REMOTE_IP, RSL_IE_Body:{ipa_remote_ip := remote_ip}), - t_RSL_IE(RSL_IE_IPAC_REMOTE_PORT, RSL_IE_Body:{ipa_remote_port := remote_port}), - /* optional: RTP Payload Type */ - t_RSL_IE(RSL_IE_IPAC_RTP_PAYLOAD2, RSL_IE_Body:{ipa_rtp_pt2 := rtp_pt2}) + function ts_RSL_IPA_MDCX(template (value) RslChannelNr chan_nr, + uint16_t ipa_conn_id, + OCT4 remote_ip, uint16_t remote_port, + uint7_t rtp_pt2, + template (omit) uint8_t osmux_cid := omit) + return template (value) RSL_Message { + var template (value) RSL_Message msg := { + msg_disc := ts_RSL_MsgDisc(RSL_MDISC_IPACCESS, false), + msg_type := RSL_MT_IPAC_MDCX, + ies := { + t_RSL_IE(RSL_IE_CHAN_NR, RSL_IE_Body:{chan_nr := chan_nr}), + t_RSL_IE(RSL_IE_IPAC_CONN_ID, RSL_IE_Body:{ipa_conn_id := ipa_conn_id}), + t_RSL_IE(RSL_IE_IPAC_REMOTE_IP, RSL_IE_Body:{ipa_remote_ip := remote_ip}), + t_RSL_IE(RSL_IE_IPAC_REMOTE_PORT, RSL_IE_Body:{ipa_remote_port := remote_port}), + /* optional: RTP Payload Type */ + t_RSL_IE(RSL_IE_IPAC_RTP_PAYLOAD2, RSL_IE_Body:{ipa_rtp_pt2 := rtp_pt2}) + } } + if (not istemplatekind(osmux_cid, "omit")) { + msg.ies[lengthof(msg.ies)] := t_RSL_IE(RSL_IE_OSMO_OSMUX_CID, RSL_IE_Body:{osmux_cid := ts_RSL_IE_OSMO_Osmux_CID(osmux_cid)}); + } + return msg; } template RSL_Message tr_RSL_IPA_MDCX(template RslChannelNr chan_nr, template uint16_t ipa_conn_id) := { @@ -2292,41 +2327,49 @@ OCT4 local_ip, uint16_t local_port, uint7_t rtp_pt2, template (omit) uint8_t osmux_cid := omit) - return template (value) RSL_Message { - var template (value) RSL_Message msg := { - msg_disc := ts_RSL_MsgDisc(RSL_MDISC_IPACCESS, false), - msg_type := RSL_MT_IPAC_MDCX_ACK, - ies := { - t_RSL_IE(RSL_IE_CHAN_NR, RSL_IE_Body:{chan_nr := chan_nr}), - /* optional */ - t_RSL_IE(RSL_IE_IPAC_CONN_ID, RSL_IE_Body:{ipa_conn_id := ipa_conn_id}), - t_RSL_IE(RSL_IE_IPAC_LOCAL_IP, RSL_IE_Body:{ipa_local_ip := local_ip}), - t_RSL_IE(RSL_IE_IPAC_LOCAL_PORT, RSL_IE_Body:{ipa_local_port := local_port}), - /* optional: RTP Payload Type */ - t_RSL_IE(RSL_IE_IPAC_RTP_PAYLOAD2, RSL_IE_Body:{ipa_rtp_pt2 := rtp_pt2}) - } + return template (value) RSL_Message { + var template (value) RSL_Message msg := { + msg_disc := ts_RSL_MsgDisc(RSL_MDISC_IPACCESS, false), + msg_type := RSL_MT_IPAC_MDCX_ACK, + ies := { + t_RSL_IE(RSL_IE_CHAN_NR, RSL_IE_Body:{chan_nr := chan_nr}), + /* optional */ + t_RSL_IE(RSL_IE_IPAC_CONN_ID, RSL_IE_Body:{ipa_conn_id := ipa_conn_id}), + t_RSL_IE(RSL_IE_IPAC_LOCAL_IP, RSL_IE_Body:{ipa_local_ip := local_ip}), + t_RSL_IE(RSL_IE_IPAC_LOCAL_PORT, RSL_IE_Body:{ipa_local_port := local_port}), + /* optional: RTP Payload Type */ + t_RSL_IE(RSL_IE_IPAC_RTP_PAYLOAD2, RSL_IE_Body:{ipa_rtp_pt2 := rtp_pt2}) } - if (not istemplatekind(osmux_cid, "omit")) { - msg.ies[lengthof(msg.ies)] := t_RSL_IE(RSL_IE_OSMO_OSMUX_CID, RSL_IE_Body:{osmux_cid := ts_RSL_IE_OSMO_Osmux_CID(osmux_cid)}); + } + if (not istemplatekind(osmux_cid, "omit")) { + msg.ies[lengthof(msg.ies)] := t_RSL_IE(RSL_IE_OSMO_OSMUX_CID, RSL_IE_Body:{osmux_cid := ts_RSL_IE_OSMO_Osmux_CID(osmux_cid)}); + } + return msg; + } + function tr_RSL_IPA_MDCX_ACK(template RslChannelNr chan_nr, + template uint16_t ipa_conn_id, + template OCT4 local_ip, + template uint16_t local_port, + template uint7_t rtp_pt2, + template uint8_t osmux_cid := omit) + return template RSL_Message { + var template RSL_Message msg := { + msg_disc := ts_RSL_MsgDisc(RSL_MDISC_IPACCESS, false), + msg_type := RSL_MT_IPAC_MDCX_ACK, + ies := { + tr_RSL_IE(RSL_IE_Body:{chan_nr := chan_nr}), + /* optional */ + tr_RSL_IE(RSL_IE_Body:{ipa_conn_id := ipa_conn_id}), + tr_RSL_IE(RSL_IE_Body:{ipa_local_ip := local_ip}), + tr_RSL_IE(RSL_IE_Body:{ipa_local_port := local_port}), + /* optional: RTP Payload Type */ + tr_RSL_IE(RSL_IE_Body:{ipa_rtp_pt2 := rtp_pt2}) } - return msg; } - template RSL_Message tr_RSL_IPA_MDCX_ACK(template RslChannelNr chan_nr, - template uint16_t ipa_conn_id, - template OCT4 local_ip, - template uint16_t local_port, - template uint7_t rtp_pt2) := { - msg_disc := tr_RSL_MsgDisc(RSL_MDISC_IPACCESS, false), - msg_type := RSL_MT_IPAC_MDCX_ACK, - ies := { - tr_RSL_IE(RSL_IE_Body:{chan_nr := chan_nr}), - /* optional */ - tr_RSL_IE(RSL_IE_Body:{ipa_conn_id := ipa_conn_id}), - tr_RSL_IE(RSL_IE_Body:{ipa_local_ip := local_ip}), - tr_RSL_IE(RSL_IE_Body:{ipa_local_port := local_port}), - /* optional: RTP Payload Type */ - tr_RSL_IE(RSL_IE_Body:{ipa_rtp_pt2 := rtp_pt2}) + if (not istemplatekind(osmux_cid, "omit")) { + msg.ies[lengthof(msg.ies)] := tr_RSL_IE(RSL_IE_Body:{osmux_cid := f_tr_RSL_IE_OSMO_Osmux_CID(osmux_cid)}); } + return msg; }
template (value) RSL_Message ts_RSL_IPA_MDCX_NACK(template (value) RslChannelNr chan_nr,