aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2018-02-10 15:34:46 +0100
committerHarald Welte <laforge@gnumonks.org>2018-02-11 11:49:48 +0100
commit33ec09bf342892f3686e2a6387b418adc282857a (patch)
treecb8198828247af102caf30c81bd40bd5f86b6179
parent49518bf84238e366ebedd271ddf7ca276325f195 (diff)
msc: Mobile Terminated Voice Call test
-rw-r--r--library/L3_Templates.ttcn134
-rw-r--r--library/MNCC_Types.ttcn33
-rw-r--r--msc/BSC_ConnectionHandler.ttcn112
-rw-r--r--msc/MSC_Tests.ttcn23
4 files changed, 301 insertions, 1 deletions
diff --git a/library/L3_Templates.ttcn b/library/L3_Templates.ttcn
index a7e14e2a..d2ee605f 100644
--- a/library/L3_Templates.ttcn
+++ b/library/L3_Templates.ttcn
@@ -29,6 +29,24 @@ type enumerated CmServiceType {
CM_TYPE_LCS ('1011'B)
}
+template ML3_Cause_TLV ts_ML3_Cause(BIT7 cause, BIT4 loc := '0001'B, BIT2 std := '11'B) := {
+ elementIdentifier := '08'O,
+ lengthIndicator := 0, /* overwritten */
+ oct3 := {
+ location := loc,
+ spare1_1 := '0'B,
+ codingStandard := std,
+ ext1 := '0'B,
+ recommendation := omit,
+ ext2 := omit
+ },
+ oct4 := {
+ causeValue := cause,
+ ext3 := '1'B
+ },
+ diagnostics := omit
+}
+
/* send template fro Mobile Identity (TMSI) */
template MobileIdentityLV ts_MI_TMSI_LV(OCT4 tmsi) := {
@@ -734,6 +752,74 @@ template PDU_ML3_NW_MS tr_ML3_MT_CC_ALERTING(integer tid) := {
}
}
+template PDU_ML3_MS_NW ts_ML3_MO_CC_ALERTING(integer tid) := {
+ discriminator := '0011'B,
+ tiOrSkip := {
+ transactionId := {
+ tio := int2bit(tid, 3),
+ tiFlag := '1'B,
+ tIExtension := omit
+ }
+ },
+ msgs := {
+ cc := {
+ alerting_MS_NW := {
+ messageType := '000001'B,
+ nsd := '00'B,
+ facility := omit,
+ user_user := omit,
+ ss_VersionIndicator := omit
+ }
+ }
+ }
+}
+
+template PDU_ML3_MS_NW ts_ML3_MT_CC_ALERTING(integer tid) := {
+ discriminator := '0011'B,
+ tiOrSkip := {
+ transactionId := {
+ tio := int2bit(tid, 3),
+ tiFlag := '1'B,
+ tIExtension := omit
+ }
+ },
+ msgs := {
+ cc := {
+ alerting_MS_NW := {
+ messageType := '000001'B,
+ nsd := '00'B,
+ facility := omit,
+ user_user := omit,
+ ss_VersionIndicator := omit
+ }
+ }
+ }
+}
+
+template PDU_ML3_MS_NW ts_ML3_MO_CC_CONNECT(integer tid) := {
+ discriminator := '0011'B,
+ tiOrSkip := {
+ transactionId := {
+ tio := int2bit(tid, 3),
+ tiFlag := '1'B,
+ tIExtension := omit
+ }
+ },
+ msgs := {
+ cc := {
+ connect_MS_NW := {
+ messageType := '000111'B,
+ nsd := '00'B,
+ facility := omit,
+ connectedSubAddress := omit,
+ user_user := omit,
+ ss_VersionIndicator := omit,
+ streamIdentifier := omit
+ }
+ }
+ }
+}
+
template PDU_ML3_NW_MS tr_ML3_MT_CC_CONNECT(integer tid) := {
discriminator := '0011'B,
tiOrSkip := {
@@ -824,6 +910,31 @@ template PDU_ML3_NW_MS tr_ML3_MT_CC_RELEASE(integer tid) := {
}
}
+template PDU_ML3_MS_NW ts_ML3_MO_CC_RELEASE(integer tid, BIT1 tid_remote, BIT7 cause) := {
+ discriminator := '0011'B,
+ tiOrSkip := {
+ transactionId := {
+ tio := int2bit(tid, 3),
+ tiFlag := tid_remote,
+ tIExtension := omit
+ }
+ },
+ msgs := {
+ cc := {
+ release_MS_NW := {
+ messageType := '101101'B,
+ nsd := '00'B,
+ cause := ts_ML3_Cause(cause),
+ secondCause := omit,
+ facility := omit,
+ user_user := omit,
+ ss_VersionIndicator := omit
+ }
+ }
+ }
+}
+
+
template (value) PDU_ML3_MS_NW ts_ML3_MO_CC_REL_COMPL(integer tid) := {
discriminator := '0011'B,
tiOrSkip := {
@@ -847,6 +958,29 @@ template (value) PDU_ML3_MS_NW ts_ML3_MO_CC_REL_COMPL(integer tid) := {
}
}
+template PDU_ML3_NW_MS tr_ML3_MT_CC_REL_COMPL(integer tid) := {
+ discriminator := '0011'B,
+ tiOrSkip := {
+ transactionId := {
+ tio := int2bit(tid, 3),
+ tiFlag := ?,
+ tIExtension := omit
+ }
+ },
+ msgs := {
+ cc := {
+ releaseComplete_NW_MS := {
+ messageType := '101010'B,
+ nsd := '00'B,
+ cause := *,
+ facility := *,
+ user_user := *
+ }
+ }
+ }
+}
+
+
template PDU_ML3_NW_MS tr_ML3_MT_MM_AUTH_REQ(template OCT16 rand := ?) := {
discriminator := '0101'B,
diff --git a/library/MNCC_Types.ttcn b/library/MNCC_Types.ttcn
index bc7c4e65..001b4b8d 100644
--- a/library/MNCC_Types.ttcn
+++ b/library/MNCC_Types.ttcn
@@ -595,6 +595,37 @@ template MNCC_PDU ts_MNCC_SETUP_CNF(uint32_t call_id, template MNCC_number conne
}
}
+/* MT: MSC -> MNCC: SETUP.cnf; Response to SETUP.req */
+template MNCC_PDU tr_MNCC_SETUP_cnf(uint32_t call_id, template MNCC_number connected := *) := {
+ msg_type := MNCC_SETUP_CNF,
+ u := {
+ signal := { /* See 24.008 9.3.5 */
+ callref := call_id,
+ bearer_cap := omit,
+ called := omit,
+ calling := omit,
+ redirecting := omit,
+ connected := connected,
+ cause := omit,
+ progress := *,
+ useruser := *,
+ facility := *,
+ cccap := omit,
+ ssversion := omit,
+ clir_sup := 0,
+ clir_inv := 0,
+ signal := omit,
+ keypad := omit,
+ more := 0,
+ notify := 0,
+ emergency := *,
+ imsi := ?,
+ lchan_type := ?,
+ lchan_mode := ?
+ }
+ }
+}
+
/* MT: MSC -> MNCC: SETUP_COMPL.req; request to send CONNECT ACK */
template MNCC_PDU tr_MNCC_SETUP_COMPL_req(template uint32_t call_id) :=
tr_MNCC_SIMPLE(MNCC_SETUP_COMPL_REQ, call_id); /* See 24.008 9.3.6 */
@@ -802,7 +833,7 @@ template MNCC_PDU ts_MNCC_ALERT_req(uint32_t call_id, template MNCC_progress pro
template MNCC_PDU tr_MNCC_ALERT_ind(template uint32_t call_id, template MNCC_progress prog := omit,
template charstring fac := omit,
template MNCC_useruser uu := omit) := {
- msg_type := MNCC_ALERT_REQ,
+ msg_type := MNCC_ALERT_IND,
u := {
signal := { /* See 24.008 9.3.1 */
callref := call_id,
diff --git a/msc/BSC_ConnectionHandler.ttcn b/msc/BSC_ConnectionHandler.ttcn
index 403064b7..856b20a0 100644
--- a/msc/BSC_ConnectionHandler.ttcn
+++ b/msc/BSC_ConnectionHandler.ttcn
@@ -425,6 +425,118 @@ template (value) CallParameters t_CallParams(hexstring called, integer tid) := {
};
+function f_mt_call(inout CallParameters cpars)
+runs on BSC_ConnHdlr {
+
+ var MobileIdentityLV mi;
+ var MNCC_PDU mncc;
+ var MgcpCommand mgcp_cmd;
+
+ f_bssmap_register_imsi(g_pars.imsi, g_pars.tmsi);
+
+ /* Allocate a call reference and send SETUP via MNCC to MSC */
+ cpars.mncc_callref := f_rnd_int(2147483648);
+ MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
+ hex2str(cpars.called_party), hex2str(g_pars.imsi)));
+ /* BSC <- MSC: Expect paging. FIXME: By TMSI or not? */
+ BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
+
+ /* If we have a TMSI, use TMSI instead of IMSI */
+ if (ispresent(g_pars.tmsi)) {
+ mi := valueof(ts_MI_TMSI_LV(g_pars.tmsi));
+ } else {
+ mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
+ }
+ f_establish_fully(mi, EST_TYPE_PAG_RESP);
+
+ /* MS <- MSC: Expect CC SETUP */
+ BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
+
+ /* MS -> MSC: ALERTING */
+ BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_ALERTING(cpars.transaction_id)));
+ MNCC.receive(tr_MNCC_ALERT_ind(cpars.mncc_callref));
+
+
+ /* Create MGCP expect */
+ f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
+ /* Ask MSC via MNCC to create the RTP socket on the MSC/MGW side */
+ MNCC.send(ts_MNCC_RTP_CREATE(cpars.mncc_callref));
+
+ /* First MGCP CRCX (for BSS/RAN side) */
+ MGCP.receive(tr_CRCX) -> value mgcp_cmd {
+ cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
+ /* TODO: dynamic EP allocation case */
+ cpars.mgcp_ep := mgcp_cmd.line.ep;
+ var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_bss, cpars.mgw_rtp_ip_bss,
+ hex2str(cpars.mgcp_call_id), "42",
+ cpars.mgw_rtp_port_bss,
+ { int2str(cpars.rtp_payload_type) },
+ { valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
+ cpars.rtp_sdp_format)),
+ valueof(ts_SDP_ptime(20)) }));
+ MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, sdp));
+ }
+ /* Second MGCP CRCX (this time for MSS/CN side) */
+ MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
+ var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
+ hex2str(cpars.mgcp_call_id), "42",
+ cpars.mgw_rtp_port_mss,
+ { int2str(cpars.rtp_payload_type) },
+ { valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
+ cpars.rtp_sdp_format)),
+ valueof(ts_SDP_ptime(20)) }));
+ MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
+ /* MSC acknowledges the MNCC_CREATE to the MNCC handler */
+ MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref));
+ }
+
+ /* expect the MSC to trigger a BSSMAP ASSIGNMENT */
+ var BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
+ valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.mgw_rtp_ip_bss),cpars.mgw_rtp_port_bss));
+ BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, tla_ass)) {
+ var BSSMAP_IE_AoIP_TransportLayerAddress tla;
+ tla := valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.bss_rtp_ip), cpars.bss_rtp_port));
+ BSSAP.send(ts_BSSMAP_AssignmentComplete(omit, tla));
+ }
+
+ /* MS -> MSC: ALERTING */
+ BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CONNECT(cpars.transaction_id)));
+ MNCC.receive(tr_MNCC_SETUP_cnf(cpars.mncc_callref));
+
+ /* FIXME */
+ f_sleep(3.0);
+
+ /* Hangup by "A" side */
+ MNCC.send(ts_MNCC_DISC_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
+ BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
+
+ if (false) {
+ /* A-side (PLMN) Release of call */
+ MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(42))));
+ BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
+ BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
+ } else {
+ /* B-side (MS) Release of call */
+ BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_RELEASE(cpars.transaction_id, '1'B, '0000000'B)));
+ MNCC.receive(tr_MNCC_REL_ind(cpars.mncc_callref));
+ BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_REL_COMPL(cpars.transaction_id)));
+ }
+
+ /* clearing of radio channel */
+ interleave {
+ [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
+ BSSAP.send(ts_BSSMAP_ClearComplete);
+ BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
+ }
+ [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
+ /* TODO: For one or all connections on EP? */
+ MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
+ f_create_mgcp_delete_ep(cpars.mgcp_ep);
+ }
+ }
+ setverdict(pass);
+}
+
function f_mo_call(inout CallParameters cpars)
runs on BSC_ConnHdlr {
diff --git a/msc/MSC_Tests.ttcn b/msc/MSC_Tests.ttcn
index 5fa29cd0..9ec65f1b 100644
--- a/msc/MSC_Tests.ttcn
+++ b/msc/MSC_Tests.ttcn
@@ -1540,6 +1540,26 @@ testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
vc_conn.done;
}
+/* LU followed by MT call (including paging) */
+private function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
+ f_init_handler(pars);
+ //FIXME: odd digits var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
+ var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
+ cpars.bss_rtp_port := 1110;
+ cpars.mgcp_connection_id_bss := '10004'H;
+ cpars.mgcp_connection_id_mss := '10005'H;
+
+ f_perform_lu(true);
+ f_mt_call(cpars);
+}
+testcase TC_lu_and_mt_call() runs on MTC_CT {
+ var BSC_ConnHdlr vc_conn;
+ f_init();
+
+ vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), testcasename(), 39);
+ vc_conn.done;
+}
+
@@ -1596,6 +1616,9 @@ control {
execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
+
+ execute( TC_lu_and_mt_call() );
+
}