summaryrefslogtreecommitdiffstats
path: root/bsc
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2019-06-18 17:45:20 +0200
committerlaforge <laforge@gnumonks.org>2019-06-24 13:53:25 +0000
commitfd02ad474ea878c469408c200a1214114de55f13 (patch)
treee9bc19804e867c7416b907f82be67993c4411bb6 /bsc
parent1a026a52d3e7c2914f8775c15245dbfbef5bdd40 (diff)
bsc: Test MGCP-over-IPA forwarding in SCCPlite tests
* MGCP-over-IPA handling in MSC_ConnectionHandler means we need to use the new MGCP_CLIENT_MULTI port since we'll be managing MGCP messages from 2 different UDP connections, and we need to be able to route answers correctly. As a result, parameter multi_conn_mode is enabled for SCCPlite and all code adapted to use that port in that type of scenario. * iDuring calls when on SCCPlite, send a full (all-required-params-in) CRCX through the MGCP-over-IPA connection towards the BSC in order to emulate the MSC, and expect the correct answer back. This way we test BSC funcionality to forward MGCP messages coming from MSC works as expected. Related: OS#2536 Depends: osmo-bsc.git I38ad8fa645c08900e0e1f1b4b96136bc6d96b3ab Change-Id: I31fed700772dd0b063f913b1e1639fd428c46e7d
Diffstat (limited to 'bsc')
-rw-r--r--bsc/BSC_Tests.ttcn28
-rw-r--r--bsc/MSC_ConnectionHandler.ttcn125
2 files changed, 135 insertions, 18 deletions
diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn
index 4c86e51..ec1be13 100644
--- a/bsc/BSC_Tests.ttcn
+++ b/bsc/BSC_Tests.ttcn
@@ -38,6 +38,7 @@ import from RSL_Emulation all;
import from MGCP_Emulation all;
import from MGCP_Templates all;
import from MGCP_Types all;
+import from MGCP_CodecPort all;
import from Osmocom_CTRL_Functions all;
import from Osmocom_CTRL_Types all;
@@ -295,7 +296,9 @@ function f_init_mgcp(charstring id) runs on test_CT {
callagent_udp_port := -1,
mgw_ip := mp_test_ip,
mgw_udp_port := 2427,
- multi_conn_mode := false
+ /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
+ the on with MGCP over IPA forwarded from MSC one) */
+ multi_conn_mode := (mp_bssap_cfg.transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
};
vc_MGCP := MGCP_Emulation_CT.create(id);
@@ -1718,6 +1721,7 @@ private function f_connect_handler(inout MSC_ConnHdlr vc_conn) runs on test_CT {
}
connect(vc_conn:BSSAP, g_bssap.vc_RAN:CLIENT);
connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
+ connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
}
function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
@@ -2891,18 +2895,32 @@ testcase TC_ho_int() runs on test_CT {
/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
private function f_expect_dlcx_conns(boolean exp_clear_cmpl := true) runs on MSC_ConnHdlr {
var MgcpCommand mgcp;
+ var template MgcpResponse mgcp_resp;
+ var MGCP_RecvFrom mrf;
+ var template MgcpMessage msg_resp;
+ var template MgcpMessage msg_dlcx := {
+ command := tr_DLCX()
+ }
- MGCP.receive(tr_DLCX()) -> value mgcp {
+ if (g_pars.aoip) {
+ MGCP.receive(tr_DLCX()) -> value mgcp {
log("Got first DLCX: ", mgcp);
MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
- };
+ };
- /* For SCCPLite, BSC doesn't handle the MSC-side */
- if (g_pars.aoip) {
MGCP.receive(tr_DLCX()) -> value mgcp {
log("Got second DLCX: ", mgcp);
MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
};
+ } else {
+ /* For SCCPLite, BSC doesn't handle the MSC-side */
+ MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
+ log("Got first DLCX: ", mrf.msg.command);
+ msg_resp := {
+ response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
+ }
+ MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
+ };
}
if (exp_clear_cmpl) {
diff --git a/bsc/MSC_ConnectionHandler.ttcn b/bsc/MSC_ConnectionHandler.ttcn
index 4f9870f..57706c9 100644
--- a/bsc/MSC_ConnectionHandler.ttcn
+++ b/bsc/MSC_ConnectionHandler.ttcn
@@ -15,6 +15,7 @@ import from Misc_Helpers all;
import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
+import from IPA_Emulation all;
import from SCCPasp_Types all;
import from BSSAP_Types all;
import from RAN_Emulation all;
@@ -23,6 +24,7 @@ import from BSSMAP_Templates all;
import from IPL4asp_Types all;
import from Native_Functions all;
+import from MGCP_CodecPort all;
import from MGCP_Types all;
import from MGCP_Templates all;
import from MGCP_Emulation all;
@@ -330,13 +332,35 @@ function f_rx_mdcx(MgcpCommand mgcp_cmd)
return ts_MDCX_ACK(mgcp_cmd.line.trans_id, mgcp_conn.conn_id, sdp);
}
+function tr_MGCP_RecvFrom_any(template MgcpMessage msg)
+runs on MSC_ConnHdlr return template MGCP_RecvFrom {
+ var template MGCP_RecvFrom mrf := {
+ connId := ?,
+ remName := ?,
+ remPort := ?,
+ locName := ?,
+ locPort := ?,
+ msg := msg
+ }
+ return mrf;
+}
+
/* altstep for handling of MGCP media related commands. Activated by as_Media() to test
* MGW level media handling */
+
altstep as_Media_mgw(boolean norepeat := false) runs on MSC_ConnHdlr {
var MgcpCommand mgcp_cmd;
var template MgcpResponse mgcp_resp;
+ var MGCP_RecvFrom mrf;
+ var template MgcpMessage msg_crcx := {
+ command := tr_CRCX
+ }
+ var template MgcpMessage msg_mdcx := {
+ command := tr_MDCX
+ }
+ var template MgcpMessage msg_resp;
- [] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
+ [g_pars.aoip] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
mgcp_resp := f_rx_crcx(mgcp_cmd);
MGCP.send(mgcp_resp);
if(norepeat == false) {
@@ -344,13 +368,35 @@ altstep as_Media_mgw(boolean norepeat := false) runs on MSC_ConnHdlr {
}
}
- [] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
+ [not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_crcx)) -> value mrf {
+ mgcp_resp := f_rx_crcx(mrf.msg.command);
+ msg_resp := {
+ response := mgcp_resp
+ }
+ MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
+ if(norepeat == false) {
+ repeat;
+ }
+ }
+
+ [g_pars.aoip] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
mgcp_resp := f_rx_mdcx(mgcp_cmd);
MGCP.send(mgcp_resp);
if(norepeat == false) {
repeat;
}
}
+
+ [not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_mdcx)) -> value mrf {
+ mgcp_resp := f_rx_mdcx(mrf.msg.command);
+ msg_resp := {
+ response := mgcp_resp
+ }
+ MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
+ if(norepeat == false) {
+ repeat;
+ }
+ }
}
/* Altsteps for handling of media related commands. Can be activated by a given
@@ -371,11 +417,17 @@ type component MSC_ConnHdlr extends RAN_ConnHdlr, RSL_DchanHdlr, MGCP_ConnHdlr {
port RAN_PROC_PT RAN;
port TELNETasp_PT BSCVTY;
+ /* Proxy MGCP-over-IPA and MGCP-over-UDP */
+ port IPA_MGCP_PT MGCP_MSC_CLIENT;
+ var integer g_trans_id := 0;
+
var MediaState g_media;
var TestHdlrParams g_pars;
var charstring host_bts := "127.0.0.2";
var charstring host_mgw := "127.0.0.3";
+ var charstring host_msc := "127.0.0.4";
+
var boolean g_vty_initialized := false;
}
@@ -390,6 +442,12 @@ function f_MscConnHdlr_init(integer i, HostName bts, HostName mgw, BSSMAP_FIELD_
}
}
+private function get_next_trans_id() runs on MSC_ConnHdlr return MgcpTransId {
+ var MgcpTransId tid := int2str(g_trans_id);
+ g_trans_id := g_trans_id + 1;
+ return tid;
+}
+
/* Callback function from general RAN_Emulation whenever a connectionless
* BSSMAP message arrives. Can retunr a PDU_BSSAP that should be sent in return */
private function UnitdataCallback(PDU_BSSAP bssap)
@@ -862,6 +920,31 @@ function f_ass_patch_lcls(inout template (omit) PDU_BSSAP ass_tpl,
}
}
+/* Send a MGCP request through MGCP-over-IPA from MSC side and receive a (matching!) response */
+function mgcp_transceive_mgw(template MgcpCommand cmd, template MgcpResponse resp := ?) runs on MSC_ConnHdlr {
+ template MgcpResponse resp_any := ?
+ var MgcpResponse resp_val;
+ resp.line.trans_id := cmd.line.trans_id;
+ timer T := 5.0;
+
+ BSSAP.send(cmd);
+ T.start;
+ alt {
+ [] as_Media_mgw();
+ [] BSSAP.receive(resp) -> value resp_val { }
+ [] BSSAP.receive(resp_any) {
+ setverdict(fail, "Response didn't match template");
+ mtc.stop;
+ }
+ [] BSSAP.receive { repeat; }
+ [] T.timeout {
+ setverdict(fail, "Timeout waiting for response to ", cmd);
+ mtc.stop;
+ }
+ }
+ T.stop;
+}
+
/* Helper function to check if the activity on the MGCP matches what we
* expected */
function f_check_mgcp_expectations() runs on MSC_ConnHdlr {
@@ -975,17 +1058,10 @@ runs on MSC_ConnHdlr {
g_media.mgcp_conn[1].mdcx_seen_exp := 0;
} else if (st.voice_call) {
/* For voice calls we expect the following MGCP activity */
- if (g_pars.aoip == false) {
- g_media.mgcp_conn[0].crcx_seen_exp := 1;
- g_media.mgcp_conn[0].mdcx_seen_exp := 1;
- g_media.mgcp_conn[1].crcx_seen_exp := 0;
- g_media.mgcp_conn[1].mdcx_seen_exp := 0;
- } else {
- g_media.mgcp_conn[0].crcx_seen_exp := 1;
- g_media.mgcp_conn[0].mdcx_seen_exp := 1;
- g_media.mgcp_conn[1].crcx_seen_exp := 1;
- g_media.mgcp_conn[1].mdcx_seen_exp := 0;
- }
+ g_media.mgcp_conn[0].crcx_seen_exp := 1;
+ g_media.mgcp_conn[0].mdcx_seen_exp := 1;
+ g_media.mgcp_conn[1].crcx_seen_exp := 1;
+ g_media.mgcp_conn[1].mdcx_seen_exp := 0;
}
f_create_mgcp_expect(mgcpcrit);
@@ -1044,6 +1120,29 @@ runs on MSC_ConnHdlr {
}
}
+ if (not exp_fail and st.voice_call and not g_pars.aoip) {
+ /* With SCCPLite, connect to BSC-located MGW using a CRCX + SDP.
+ It is sent in MGCP over IPA in the BSC<->MSC (BSC-NAT)
+ connection. BSC will forward it to its MGW. */
+ var template MgcpCommand cmd;
+ var template MgcpResponse resp;
+ var integer cic := f_bssmap_ie_cic_2_int(ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode);
+ var MgcpEndpoint ep := int2str(cic) & "@mgw"; /* 1: matches value configured in BSC_Tests.ttcn pass in AssignReq */
+ var MgcpCallId call_id := '51234'H;
+ var SDP_attribute_list attributes := { valueof(ts_SDP_ptime(20)) };
+ if (g_pars.use_osmux) {
+ cmd := ts_CRCX_osmux(get_next_trans_id(), ep, "sendrecv", call_id, cic);
+ resp := tr_CRCX_ACK_osmux;
+ } else {
+ cmd := ts_CRCX(get_next_trans_id(), ep, "sendrecv", call_id);
+ resp := tr_CRCX_ACK;
+ }
+ cmd.sdp := ts_SDP(host_msc, host_mgw, "23", "42",
+ 14000, { int2str(g_media.mgcp_conn[1].rtp_pt) },
+ { valueof(ts_SDP_ptime(20)) });
+ mgcp_transceive_mgw(cmd, resp);
+ }
+
f_check_mgcp_expectations();
if (st.is_assignment and st.assignment_done) {