daniel has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/27114 )
Change subject: hnbgw: First working RAB Assignment ......................................................................
hnbgw: First working RAB Assignment
Change-Id: I5eae9f23ba6cf5e85a7daa025c4672c0a02031ca --- M hnbgw/HNBGW_Tests.ttcn 1 file changed, 240 insertions(+), 28 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/14/27114/1
diff --git a/hnbgw/HNBGW_Tests.ttcn b/hnbgw/HNBGW_Tests.ttcn index 42b16fc..3973a0e 100644 --- a/hnbgw/HNBGW_Tests.ttcn +++ b/hnbgw/HNBGW_Tests.ttcn @@ -111,10 +111,50 @@ sccp_addr_peer := omit }
+type record CrcxResponse { + integer resp, + HostName mgw_rtp_ip, + PortNumber mgw_rtp_port, + MgcpConnectionId mgcp_connection_id +} +type record MgcpParameters { + integer got_crcx_count, + MgcpCallId mgcp_call_id optional, + MgcpEndpoint mgcp_ep, + CrcxResponse mgw_conn_1, + CrcxResponse mgw_conn_2, + uint7_t rtp_payload_type, + charstring rtp_sdp_format, + boolean use_osmux, + integer got_osmux_count +} + +template (value) MgcpParameters t_MgcpParams := { + got_crcx_count := 0, + mgcp_call_id := omit, + mgcp_ep := "rtpbridge/1@mgw", + mgw_conn_1 := { + resp := 1, + mgw_rtp_ip := "1.1.1.1", + mgw_rtp_port := 10000, + mgcp_connection_id := '11111'H + }, + mgw_conn_2 := { + resp := 1, + mgw_rtp_ip := "2.2.2.2", + mgw_rtp_port := 11000, + mgcp_connection_id := '22222'H + }, + rtp_payload_type := 23, + rtp_sdp_format := "FOO", + use_osmux := false, + got_osmux_count := 0 +} type record TestHdlrParams { integer hnb_idx, hexstring imsi, boolean ps_domain, + MgcpParameters mgcp_pars optional, HnbConfig hnb optional };
@@ -350,6 +390,7 @@ /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */ pars.hnb := g_hnb_cfg[pars.hnb_idx]; + pars.mgcp_pars := valueof(t_MgcpParams); vc_conn.start(derefers(fn)(id, pars)); }
@@ -530,6 +571,15 @@ } }
+/* build a RANAP RAB AssignmentRespons based on the TestHdlrParams */ +friend function f_build_rab_ass_resp(TestHdlrParams pars) return RANAP_PDU { + var template RAB_SetupOrModifiedList rab_sml; + + rab_sml := ts_RAB_SMdL(t_RAB_id(23), f_ts_RAB_TLA("192.168.1.23"), t_RAB_binding_port(1234)); + + return valueof(ts_RANAP_RabAssResp(rab_sml)); +} +
/*********************************************************************** * HNBAP Testing @@ -568,34 +618,6 @@ * RUA / RANAP Testing ***********************************************************************/
-testcase TC_RAB_Assignment() runs on test_CT { - //var HNBGW_ConnHdlr vc_conn; - f_init(); -/* - f_sleep(3.0); - HNBAP.send(tr_HNBAP_HNBRegisterRequest(char2oct("TTCN3 HNodeB"), - '00F110'O, - int2bit(1, 28), - int2oct(2, 2), - int2oct(3, 1), - int2oct(4, 2))); - - alt { - [] HNBAP.receive(tr_HNBAP_HNBRegisterAccept(?)) { - setverdict(pass); - } - [] HNBAP.receive(IUHEM_Event:?) { - repeat; - } - } - - //RUA.send(tr_RUA_Connect(cs_domain, int2bit(23, 24), normal_call, hex2oct(ranap_cm_service_req))); - //RANAP.receive(); -*/ - f_sleep(2.0); - f_shutdown_helper(); -} - private template (value) TestHdlrParams t_pars(integer imsi_suffix, boolean ps_domain := false,integer hnb_idx := 0) := { hnb_idx := hnb_idx, @@ -629,6 +651,195 @@ vc_conn.done; }
+/* Reply to a received CRCX with an OK (or the reply configured in cpars), using the given parameters. + * Return true when an OK reply was sent, false otherwise. + * Count occurence of Osmux, include Osmux parameters in the reply if necessary. */ +function f_handle_crcx(inout MgcpParameters pars, MgcpCommand mgcp_cmd) return template MgcpResponse { + var CrcxResponse conn := pars.mgw_conn_1; + if (pars.got_crcx_count > 0) { + conn := pars.mgw_conn_2; + } + pars.got_crcx_count := pars.got_crcx_count + 1; + + var MgcpMessage mgcp_msg := { + command := mgcp_cmd + } + var template MgcpResponse mgcp_resp; + var MgcpOsmuxCID osmux_cid; + var MgcpCallId call_id := f_MgcpCmd_extract_call_id(mgcp_cmd); + if (ispresent(pars.mgcp_call_id)) { + if (pars.mgcp_call_id != call_id) { + setverdict(fail, "CRCX contained unexpected call id. Expected:", pars.mgcp_call_id, " got:", call_id); + mtc.stop; + } + } else { + pars.mgcp_call_id := call_id; + } + + /* When the endpoint contains a wildcard we keep the endpoint + * identifier we have set up in pars. Otherwise we use the + * endpoint name that the call agent has supplied */ + if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard) == false) { + pars.mgcp_ep := mgcp_cmd.line.ep; + } + + if (conn.resp == -1) { + /* Reply with rror */ + var MgcpResponse mgcp_rsp := { + line := { + code := "542", + trans_id := mgcp_cmd.line.trans_id, + string := "FORCED_FAIL" + }, + sdp := omit + + } + var MgcpParameter mgcp_rsp_param := { + code := "Z", + val := pars.mgcp_ep + }; + mgcp_rsp.params[0] := mgcp_rsp_param; + return mgcp_rsp; + } + + if (conn.resp == 0) { + /* Do not reply at all */ + return omit; + } + + if (conn.resp != 1) { + setverdict(fail, "Unexpected value for pars.mgw_conn_*.resp, expect -1, 0 or 1"); + mtc.stop; + } + + var SDP_Message sdp := valueof(ts_SDP(conn.mgw_rtp_ip, conn.mgw_rtp_ip, + hex2str(pars.mgcp_call_id), "42", + conn.mgw_rtp_port, + { int2str(pars.rtp_payload_type) }, + { valueof(ts_SDP_rtpmap(pars.rtp_payload_type, + pars.rtp_sdp_format)), + valueof(ts_SDP_ptime(20)) })); + + if (f_mgcp_contains_par(mgcp_msg, "X-OSMUX")) { + if (not pars.use_osmux) { + setverdict(fail, "MSC sent X-Osmux parameter in MGCP, but not expecting any Osmux"); + mtc.stop; + } + pars.got_osmux_count := pars.got_osmux_count + 1; + /* we expect MSC to use wildcard here, i.e. osmux_cid == -1 */ + osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd); + log("f_handle_crcx(): got Osmux CID: ", osmux_cid); + if (osmux_cid != -1) { + setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != -1"); + mtc.stop; + } + + osmux_cid := 0; + mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, conn.mgcp_connection_id, osmux_cid, sdp); + } else { + mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, conn.mgcp_connection_id, sdp); + } + + f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(pars.mgcp_ep)); + + return mgcp_resp; +} + +friend function f_tc_rab_assignment(charstring id, TestHdlrParams pars) runs on ConnHdlr { + var MgcpCommand mgcp_cmd; + var RANAP_PDU tx; + var template RAB_SetupOrModifyList rab_sml; + var template RAB_SetupOrModifiedList rab_smdl; + timer T := 5.0; + + f_init_handler(pars); + f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit}); + + tx := f_build_initial_ue(g_pars); + f_iuh2iu_connect(tx); + + /** BSSAP send: RAB Assignment Request + * MGCP receive: CRCXf_handle_crcx + * MGCP send: ACK + * RUA receive: RAB Assignment Request (*) + * RUA send: RAB Assignment Response + * MGCP receive: MDCX + * MGCP send: ACK + * BSSAP receive: RAB Assignment Response (*) + */ + + + rab_sml := ts_RAB_SML(t_RAB_id(23), f_ts_RAB_TLA("192.168.0.1"), t_RAB_binding_port(1234)); + tx := valueof(ts_RANAP_RabAssReq(rab_sml)); + BSSAP.send(tx); + T.start; + + alt { + [] MGCP.receive(tr_CRCX) -> value mgcp_cmd { + var template MgcpResponse mgcp_rsp := f_handle_crcx(pars.mgcp_pars, mgcp_cmd); + MGCP.send(valueof(mgcp_rsp)); + } + [] T.timeout { + setverdict(fail, "Timeout waiting for MGCP"); + } + } + + rab_sml := ts_RAB_SML(t_RAB_id(23), f_ts_RAB_TLA(pars.mgcp_pars.mgw_conn_1.mgw_rtp_ip), t_RAB_binding_port(pars.mgcp_pars.mgw_conn_1.mgw_rtp_port)); + tx := valueof(ts_RANAP_RabAssReq(rab_sml)); + + alt { + [] RUA.receive(tx) { + setverdict(pass); + } + [] T.timeout { + setverdict(fail, "Timeout waiting for Iuh ", tx); + } + } + + rab_smdl := ts_RAB_SMdL(t_RAB_id(23), f_ts_RAB_TLA("192.168.0.2"), t_RAB_binding_port(1235)); + tx := valueof(ts_RANAP_RabAssResp(rab_smdl)); + RUA.send(tx); + T.start; + + interleave { + [] MGCP.receive(tr_MDCX) -> value mgcp_cmd { + log("MDCX1", mgcp_cmd); + var SDP_Message sdp := valueof(ts_SDP(pars.mgcp_pars.mgw_conn_1.mgw_rtp_ip, pars.mgcp_pars.mgw_conn_1.mgw_rtp_ip, hex2str(pars.mgcp_pars.mgcp_call_id), "42", pars.mgcp_pars.mgw_conn_1.mgw_rtp_port, + { int2str(pars.mgcp_pars.rtp_payload_type) }, { valueof(ts_SDP_rtpmap(pars.mgcp_pars.rtp_payload_type, pars.mgcp_pars.rtp_sdp_format)), valueof(ts_SDP_ptime(20)) } )); + var template MgcpResponse mgcp_rsp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, pars.mgcp_pars.mgw_conn_1.mgcp_connection_id, sdp); + MGCP.send(valueof(mgcp_rsp)); + } + /* Second CRCX */ + [] MGCP.receive(tr_CRCX(pars.mgcp_pars.mgcp_ep)) -> value mgcp_cmd { + log("CRCX2", mgcp_cmd); + var template MgcpResponse mgcp_rsp := f_handle_crcx(pars.mgcp_pars, mgcp_cmd); + MGCP.send(valueof(mgcp_rsp)); + } + } + + rab_smdl := ts_RAB_SMdL(t_RAB_id(23), f_ts_RAB_TLA(pars.mgcp_pars.mgw_conn_2.mgw_rtp_ip), t_RAB_binding_port(pars.mgcp_pars.mgw_conn_2.mgw_rtp_port)); + tx := valueof(ts_RANAP_RabAssResp(rab_smdl)); + + log("Resp:", tx); + alt { + [] BSSAP.receive(tx) { + log("Got RAB Resp") + setverdict(pass); + } + [] T.timeout { + setverdict(fail, "Timeout waiting for Iuh ", tx); + } + } +} + +testcase TC_rab_assignment() runs on test_CT { + var ConnHdlr vc_conn; + f_init(); + f_start_hnbs(); + + vc_conn := f_start_handler_with_pars(refers(f_tc_rab_assignment), t_pars(3)); + vc_conn.done; +}
/* Create an Iuh connection; send InitialUE; transceive data both directions */ friend function f_tc_ranap_bidir(charstring id, TestHdlrParams pars) runs on ConnHdlr { @@ -707,6 +918,7 @@ execute(TC_ranap_ps_initial_ue()); execute(TC_ranap_cs_bidir()); execute(TC_ranap_ps_bidir()); + execute(TC_rab_assignment()); execute(TC_ranap_cs_mo_disconnect()); execute(TC_ranap_ps_mo_disconnect()); }