summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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) {