diff options
author | Harald Welte <laforge@gnumonks.org> | 2018-02-10 15:34:46 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2018-02-11 11:49:48 +0100 |
commit | 33ec09bf342892f3686e2a6387b418adc282857a (patch) | |
tree | cb8198828247af102caf30c81bd40bd5f86b6179 | |
parent | 49518bf84238e366ebedd271ddf7ca276325f195 (diff) |
msc: Mobile Terminated Voice Call test
Change-Id: I4fa353623991ac98726217559fea9f83f64715ea
-rw-r--r-- | library/L3_Templates.ttcn | 134 | ||||
-rw-r--r-- | library/MNCC_Types.ttcn | 33 | ||||
-rw-r--r-- | msc/BSC_ConnectionHandler.ttcn | 112 | ||||
-rw-r--r-- | msc/MSC_Tests.ttcn | 23 |
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() ); + } |