bsc: Introduce Osmux infra and one test for osmo-bsc
Test verifies once osmux is enabled in osmo-bsc, BSSMAP RESET (ACK)
contains Osmux Support IE and that it correctly handles BSSMAP ASsign
Req with Osmux CID.
Related: OS#2551
Depends: osmo-bsc 6de754cdde5319af3059d8fc6abf85037ec7eacc
Depends: titan.ProtocolModules.BSSMAP Iaf1e137269c0da20b2c96fd104b57edf336693af
Change-Id: If69c716dc06d61d810c32d1720a237c7535baca8
diff --git a/bsc-nat/BSC_MS_ConnectionHandler.ttcn b/bsc-nat/BSC_MS_ConnectionHandler.ttcn
index e52b678..28ff349 100644
--- a/bsc-nat/BSC_MS_ConnectionHandler.ttcn
+++ b/bsc-nat/BSC_MS_ConnectionHandler.ttcn
@@ -54,6 +54,7 @@
decode_dtap := false,
role_ms := true,
protocol := RAN_PROTOCOL_BSSAP,
+ use_osmux := false,
sccp_addr_local := omit,
sccp_addr_peer := omit
}
diff --git a/bsc-nat/MSC_ConnectionHandler.ttcn b/bsc-nat/MSC_ConnectionHandler.ttcn
index 8635a29..36fdf85 100644
--- a/bsc-nat/MSC_ConnectionHandler.ttcn
+++ b/bsc-nat/MSC_ConnectionHandler.ttcn
@@ -60,6 +60,7 @@
decode_dtap := false,
role_ms := false,
protocol := RAN_PROTOCOL_BSSAP,
+ use_osmux := false,
sccp_addr_local := omit,
sccp_addr_peer := omit
}
diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn
index 0583b30..c731b7c 100644
--- a/bsc/BSC_Tests.ttcn
+++ b/bsc/BSC_Tests.ttcn
@@ -89,6 +89,9 @@
/* are we initialized yet */
var boolean g_initialized := false;
+ /* Osmux is enabled through VTY */
+ var boolean g_osmux_enabled := false;
+
/* global test case guard timer */
timer T_guard := 30.0;
@@ -140,16 +143,16 @@
private function f_legacy_bssap_reset() runs on test_CT {
var BSSAP_N_UNITDATA_ind ud_ind;
timer T := 5.0;
- BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0)));
+ BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0, g_osmux_enabled)));
T.start;
alt {
- [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck)) {
+ [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled))) {
log("Received RESET-ACK in response to RESET, we're ready to go!");
}
- [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
+ [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
log("Respoding to inbound RESET with RESET-ACK");
BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
- ts_BSSMAP_ResetAck));
+ ts_BSSMAP_ResetAck(g_osmux_enabled)));
repeat;
}
[] BSSAP.receive { repeat; }
@@ -257,15 +260,15 @@
mtc.stop;
}
/* always respond with RESET ACK to RESET */
- [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
+ [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
- ts_BSSMAP_ResetAck));
+ ts_BSSMAP_ResetAck(g_osmux_enabled)));
repeat;
}
}
altstep no_bssmap_reset() runs on test_CT {
- [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
+ [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
setverdict(fail, "unexpected BSSMAP Reset");
mtc.stop;
}
@@ -289,6 +292,22 @@
vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
}
+/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
+ * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
+ * OsmuxCID IE.
+ */
+private function f_vty_allow_osmux(boolean allow) runs on test_CT {
+ f_vty_enter_cfg_msc(BSCVTY, 0);
+ if (allow) {
+ f_vty_transceive(BSCVTY, "osmux on");
+ } else {
+ f_vty_transceive(BSCVTY, "osmux off");
+ }
+ f_vty_transceive(BSCVTY, "exit");
+ f_vty_transceive(BSCVTY, "exit");
+ g_osmux_enabled := allow;
+}
+
function f_init_vty(charstring id := "foo") runs on test_CT {
if (BSCVTY.checkstate("Mapped")) {
/* skip initialization if already executed once */
@@ -302,7 +321,7 @@
/* global initialization function
* \param nr_bts Number of BTSs we should start/bring up
* \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
-function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false) runs on test_CT {
+function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false) runs on test_CT {
var integer i;
if (g_initialized) {
@@ -313,10 +332,15 @@
T_guard.start;
activate(as_Tguard());
+ f_init_vty("VirtMSC");
+ f_vty_allow_osmux(allow_osmux);
+
/* Call a function of our 'parent component' RAN_Adapter_CT to start the
* MSC-side BSSAP emulation */
if (handler_mode) {
- f_ran_adapter_init(g_bssap, mp_bssap_cfg, "VirtMSC", MSC_RanOps);
+ var RanOps ranops := MSC_RanOps;
+ ranops.use_osmux := g_osmux_enabled;
+ f_ran_adapter_init(g_bssap, mp_bssap_cfg, "VirtMSC", ranops);
f_ran_adapter_start(g_bssap);
} else {
f_ran_adapter_init(g_bssap, mp_bssap_cfg, "VirtMSC", omit);
@@ -328,7 +352,6 @@
f_ipa_ctrl_start(mp_bsc_ip, mp_bsc_ctrl_port);
f_init_mgcp("VirtMSC");
- f_init_vty("VirtMSC");
for (i := 0; i < nr_bts; i := i+1) {
/* wait until osmo-bts-omldummy has respawned */
@@ -605,15 +628,24 @@
}
/* generate an assignment request for either AoIP or SCCPlite */
-function f_gen_ass_req() return PDU_BSSAP {
+function f_gen_ass_req(boolean osmux_enabled := false) return PDU_BSSAP {
var PDU_BSSAP ass_cmd;
+ var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
- ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
+ if (osmux_enabled) {
+ ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
+ } else {
+ ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
+ }
} else {
var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
- ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
+ if (osmux_enabled) {
+ ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit, osmux_cid));
+ } else {
+ ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
+ }
}
return ass_cmd;
}
@@ -632,13 +664,22 @@
}
/* generate an assignment complete template for either AoIP or SCCPlite */
-function f_gen_exp_compl() return template PDU_BSSAP {
+function f_gen_exp_compl(boolean expect_osmux := false) return template PDU_BSSAP {
var template PDU_BSSAP exp_compl;
+ var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
- exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?);
+ if (expect_osmux) {
+ exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
+ } else {
+ exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
+ }
} else {
/* CIC is optional "*" as the MSC allocated it */
- exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
+ if (expect_osmux) {
+ exp_compl := tr_BSSMAP_AssignmentComplete(*, omit, osmux_cid);
+ } else {
+ exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
+ }
}
return exp_compl;
}
@@ -1002,9 +1043,9 @@
IPA_RSL[0].clear;
/* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
- BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0)));
+ BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0, g_osmux_enabled)));
interleave {
- [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck)) { }
+ [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled))) { }
[] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
}
@@ -1491,9 +1532,9 @@
f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
/* Perform a BSSMAP Reset and wait for ACK */
- BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0)));
+ BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0, g_osmux_enabled)));
alt {
- [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck)) { }
+ [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled))) { }
[] BSSAP.receive { repeat; }
}
@@ -1945,8 +1986,8 @@
type record of CodecListTest CodecListTests
private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
- var PDU_BSSAP ass_cmd := f_gen_ass_req();
- var template PDU_BSSAP exp_compl := f_gen_exp_compl();
+ var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
+ var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
/* puzzle together the ASSIGNMENT REQ for given codec[s] */
if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
@@ -2568,6 +2609,31 @@
setverdict(pass);
}
+testcase TC_assignment_osmux() runs on test_CT {
+ var TestHdlrParams pars := f_gen_test_hdlr_pars();
+ var MSC_ConnHdlr vc_conn;
+
+ /* See note above */
+ var RSL_IE_Body mr_conf := {
+ other := {
+ len := 2,
+ payload := '2804'O
+ }
+ };
+
+ pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
+ pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
+ pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
+ pars.expect_mr_conf_ie := mr_conf;
+ pars.use_osmux := true;
+
+ f_init(1, true, true);
+ f_sleep(1.0);
+
+ vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
+ vc_conn.done;
+}
+
/* test the procedure of the MSC requesting a Classmark Update:
* a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
* b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
@@ -3993,6 +4059,8 @@
execute( TC_assignment_codec_req_hr_fr() );
execute( TC_assignment_codec_req_fr_hr() );
+ execute( TC_assignment_osmux() );
+
/* RLL Establish Indication on inactive DCHAN / SAPI */
execute( TC_rll_est_ind_inact_lchan() );
execute( TC_rll_est_ind_inval_sapi1() );
diff --git a/bsc/MSC_ConnectionHandler.ttcn b/bsc/MSC_ConnectionHandler.ttcn
index 520cc3e..0db5630 100644
--- a/bsc/MSC_ConnectionHandler.ttcn
+++ b/bsc/MSC_ConnectionHandler.ttcn
@@ -263,6 +263,7 @@
* MGW level media handling */
altstep as_Media_mgw(boolean norepeat := false) runs on MSC_ConnHdlr {
var MgcpCommand mgcp_cmd;
+ var MgcpOsmuxCID osmux_cid;
[] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
var SDP_Message sdp;
@@ -289,7 +290,12 @@
int2str(mgcp_conn.sample_rate))),
valueof(ts_SDP_ptime(mgcp_conn.ptime)) } ));
var template MgcpResponse mgcp_resp;
- mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, mgcp_conn.conn_id, sdp);
+ if (g_pars.use_osmux and f_MgcpCmd_contains_par(mgcp_cmd, "X-OSMUX")) {
+ osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
+ mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, mgcp_conn.conn_id, osmux_cid, sdp);
+ } else {
+ mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, mgcp_conn.conn_id, sdp);
+ }
f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(g_media.mgcp_ep));
MGCP.send(mgcp_resp);
g_media.mgcp_conn[cid].crcx_seen := g_media.mgcp_conn[cid].crcx_seen + 1;
@@ -364,8 +370,8 @@
var template PDU_BSSAP resp := omit;
/* answer all RESET with a RESET ACK */
- if (match(bssap, tr_BSSMAP_Reset)) {
- resp := ts_BSSMAP_ResetAck;
+ if (match(bssap, tr_BSSMAP_Reset(g_ran_ops.use_osmux))) {
+ resp := ts_BSSMAP_ResetAck(g_ran_ops.use_osmux);
}
return resp;
@@ -377,6 +383,7 @@
decode_dtap := false,
role_ms := false,
protocol := RAN_PROTOCOL_BSSAP,
+ use_osmux := false,
sccp_addr_local := omit,
sccp_addr_peer := omit
}
@@ -431,7 +438,8 @@
TestHdlrEncrParams encr optional,
TestHdlrParamsLcls lcls,
TestHdlrParamsHandover handover optional,
- boolean aoip
+ boolean aoip,
+ boolean use_osmux
};
/* Note: Do not use valueof() to get a value of this template, use
@@ -455,7 +463,8 @@
adjust_cx_exp := true
},
handover := omit,
- aoip := true
+ aoip := true,
+ use_osmux := false
}
function f_create_chan_and_exp() runs on MSC_ConnHdlr {
diff --git a/bsc/expected-results.xml b/bsc/expected-results.xml
index 33bf677..ff3cce0 100644
--- a/bsc/expected-results.xml
+++ b/bsc/expected-results.xml
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
-<testsuite name='BSC_Tests' tests='105' failures='0' errors='0' skipped='0' inconc='0' time='MASKED'>
+<testsuite name='BSC_Tests' tests='106' failures='0' errors='0' skipped='0' inconc='0' time='MASKED'>
<testcase classname='BSC_Tests' name='TC_ctrl_msc_connection_status' time='MASKED'/>
<testcase classname='BSC_Tests' name='TC_ctrl_msc0_connection_status' time='MASKED'/>
<testcase classname='BSC_Tests' name='TC_ctrl' time='MASKED'/>
@@ -46,6 +46,7 @@
<testcase classname='BSC_Tests' name='TC_assignment_codec_hr_exhausted_req_fr_hr' time='MASKED'/>
<testcase classname='BSC_Tests' name='TC_assignment_codec_req_hr_fr' time='MASKED'/>
<testcase classname='BSC_Tests' name='TC_assignment_codec_req_fr_hr' time='MASKED'/>
+ <testcase classname='BSC_Tests' name='TC_assignment_osmux' time='MASKED'/>
<testcase classname='BSC_Tests' name='TC_rll_est_ind_inact_lchan' time='MASKED'/>
<testcase classname='BSC_Tests' name='TC_rll_est_ind_inval_sapi1' time='MASKED'/>
<testcase classname='BSC_Tests' name='TC_rll_est_ind_inval_sapi3' time='MASKED'/>
diff --git a/library/MGCP_Templates.ttcn b/library/MGCP_Templates.ttcn
index 4cc2c6b..4736aaa 100644
--- a/library/MGCP_Templates.ttcn
+++ b/library/MGCP_Templates.ttcn
@@ -143,6 +143,19 @@
sdp := sdp
}
+ template MgcpResponse ts_CRCX_ACK_osmux(MgcpTransId trans_id, MgcpConnectionId conn_id, MgcpOsmuxCID osmux_cid, template SDP_Message sdp := omit) := {
+ line := {
+ code := "200",
+ trans_id := trans_id,
+ string := "OK"
+ },
+ params:= {
+ ts_MgcpParConnectionId(conn_id),
+ ts_MgcpParOsmuxCID(osmux_cid)
+ },
+ sdp := sdp
+ }
+
template MgcpCommand ts_MDCX(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, MgcpConnectionId conn_id, template SDP_Message sdp := omit) := {
line := t_MgcpCmdLine("MDCX", trans_id, ep),
params := {
diff --git a/library/RAN_Emulation.ttcnpp b/library/RAN_Emulation.ttcnpp
index 9a65eb7..41aec47 100644
--- a/library/RAN_Emulation.ttcnpp
+++ b/library/RAN_Emulation.ttcnpp
@@ -465,9 +465,9 @@
T.start;
alt {
- [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
+ [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_ran_ops.use_osmux))) -> value ud_ind {
BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
- ts_BSSMAP_ResetAck));
+ ts_BSSMAP_ResetAck(g_ran_ops.use_osmux)));
}
[] as_reset_ack();
[] BSSAP.receive {
@@ -483,10 +483,10 @@
function f_bssap_reset(SCCP_PAR_Address peer, SCCP_PAR_Address own) runs on RAN_Emulation_CT {
timer T := 5.0;
- BSSAP.send(ts_BSSAP_UNITDATA_req(peer, own, ts_BSSMAP_Reset(0)));
+ BSSAP.send(ts_BSSAP_UNITDATA_req(peer, own, ts_BSSMAP_Reset(0, g_ran_ops.use_osmux)));
T.start;
alt {
- [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(own, peer, tr_BSSMAP_ResetAck)) {
+ [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(own, peer, tr_BSSMAP_ResetAck(g_ran_ops.use_osmux))) {
log("Received RESET-ACK in response to RESET, we're ready to go!");
}
[] as_reset_ack();
@@ -650,6 +650,7 @@
boolean decode_dtap,
boolean role_ms,
RanProtocol protocol,
+ boolean use_osmux,
/* needed for performing BSSMAP RESET */
SCCP_PAR_Address sccp_addr_local optional,
SCCP_PAR_Address sccp_addr_peer optional
@@ -727,10 +728,10 @@
var RANAP_N_UNITDATA_ind rud_ind;
#endif
#ifdef RAN_EMULATION_BSSAP
- [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
+ [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_ran_ops.use_osmux))) -> value ud_ind {
log("Respoding to inbound RESET with RESET-ACK");
BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
- ts_BSSMAP_ResetAck));
+ ts_BSSMAP_ResetAck(g_ran_ops.use_osmux)));
repeat;
}
#endif
diff --git a/msc/BSC_ConnectionHandler.ttcn b/msc/BSC_ConnectionHandler.ttcn
index 796b0ce..29cde36 100644
--- a/msc/BSC_ConnectionHandler.ttcn
+++ b/msc/BSC_ConnectionHandler.ttcn
@@ -209,6 +209,7 @@
decode_dtap := true,
role_ms := true,
protocol := RAN_PROTOCOL_BSSAP,
+ use_osmux := false,
sccp_addr_local := omit,
sccp_addr_peer := omit
}