hnbgw: add mscpool paging tests

Change-Id: If4bbd5c970108b01e8556fa7744ff627db75fb13
This commit is contained in:
Neels Hofmeyr 2023-06-27 02:10:04 +02:00 committed by neels
parent c8172bda14
commit b1bf16db35
3 changed files with 163 additions and 2 deletions

View File

@ -46,6 +46,7 @@ import from RANAP_PDU_Descriptions all;
import from RANAP_PDU_Contents all;
import from RANAP_IEs all;
import from RANAP_Templates all;
import from RANAP_CodecPort all;
import from RAN_Adapter all;
import from RAN_Emulation all;
@ -68,6 +69,8 @@ import from MobileL3_GMM_SM_Types all;
import from L3_Templates all;
import from L3_Common all;
import from SCCPasp_Types all;
const integer NUM_MSC := 4;
const integer NUM_SGSN := 4;
@ -274,7 +277,10 @@ type record TestHdlrParams {
boolean expect_separate_sccp_cr,
integer tx_sccp_cr_data_len,
charstring pfcp_local_addr,
octetstring nas_pdu optional
octetstring nas_pdu optional,
/* local and remote SCCP addresses, used in TC_mscpool_paging_* */
SCCP_PAR_Address sccp_addr_msc optional,
SCCP_PAR_Address sccp_addr_hnbgw optional
}
/* We extend:
@ -991,7 +997,9 @@ t_pars(integer imsi_suffix, boolean ps_domain := false, integer hnb_idx := 0,
expect_separate_sccp_cr := expect_separate_sccp_cr,
tx_sccp_cr_data_len := tx_sccp_cr_data_len,
pfcp_local_addr := mp_pfcp_ip_local,
nas_pdu := omit
nas_pdu := omit,
sccp_addr_msc := omit,
sccp_addr_hnbgw := omit
}
/* Create an Iuh connection; send InitialUE; expect it to appear on new SCCP conenction */
@ -2287,6 +2295,109 @@ function f_TC_cnpool_nri_from_other_PLMN(boolean ps_domain) runs on test_CT {
f_shutdown_helper();
}
/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
* round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
friend function f_tc_mscpool_paging_imsi(charstring id, TestHdlrParams pars) runs on ConnHdlr {
f_init_handler(pars);
var hexstring imsi := '001010000000123'H;
var RANAP_IEs.CN_DomainIndicator domain_ind;
if (pars.ps_domain) {
domain_ind := ps_domain;
} else {
domain_ind := cs_domain;
}
var template (value) RANAP_PDU paging := ts_RANAP_Paging(domain_ind, imsi_hex2oct(imsi));
BSSAP.send(ts_RANAP_UNITDATA_req(pars.sccp_addr_hnbgw, pars.sccp_addr_msc, paging));
/* TODO: Expect RUA ConnectionlessTransfer Paging (on all HNB).
* We could verify the Paging sent from osmo-hnbgw to RUA with some effort,
* but, this test does not care whether the Paging was forwarded to RUA or not, only that osmo-hnbgw *received*
* the Paging. In the CN pool decisions, osmo-hnbgw should match up Paging Response to an earlier Paging.
*/
f_sleep(1.0);
/* Despite the round robin pointing at the second MSC ('roundrobin next msc 1'), the earlier Paging for the same IMSI
* causes this Paging Response to go to the first MSC ('msc 0'). */
f_perform_compl_l3(f_gen_one_compl_l3(PAGRESP, ts_MI_IMSI_LV(imsi)));
f_sleep(1.0);
}
testcase TC_mscpool_paging_imsi() runs on test_CT {
f_init(nr_msc := 3);
f_sleep(1.0);
var boolean ps_domain := false;
/* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
* second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);
f_ctrs_cn_init(ps_domain := ps_domain);
var ConnHdlr vc_conn1;
var template (value) TestHdlrParams pars1 := t_pars(0, ps_domain := ps_domain, cn_nr := 0);
pars1.sccp_addr_hnbgw := g_cn[valueof(pars1.cn_idx)].sccp_addr_peer;
pars1.sccp_addr_msc := g_cn[valueof(pars1.cn_idx)].sccp_addr_own;
vc_conn1 := f_start_handler_with_pars(refers(f_tc_mscpool_paging_imsi), pars1);
vc_conn1.done;
f_ctrs_cn_expect(0, "cnpool:subscr:paged");
f_shutdown_helper();
}
/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
* that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
friend function f_tc_mscpool_paging_tmsi(charstring id, TestHdlrParams pars) runs on ConnHdlr {
f_init_handler(pars);
var hexstring imsi := '001010000000124'H;
var integer nri_v := 300; /* <-- second MSC's NRI */
var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
var RANAP_IEs.CN_DomainIndicator domain_ind;
if (pars.ps_domain) {
domain_ind := ps_domain;
} else {
domain_ind := cs_domain;
}
var template (value) RANAP_PDU paging := ts_RANAP_Paging_temp_id(domain_ind, imsi_hex2oct(imsi),
ts_RANAP_TemporaryUE_ID_TMSI(tmsi));
BSSAP.send(ts_RANAP_UNITDATA_req(pars.sccp_addr_hnbgw, pars.sccp_addr_msc, paging));
/* TODO: Expect RUA ConnectionlessTransfer Paging (on all HNB).
* We could verify the Paging sent from osmo-hnbgw to RUA with some effort,
* but, this test does not care whether the Paging was forwarded to RUA or not, only that osmo-hnbgw *received*
* the Paging. In the CN pool decisions, osmo-hnbgw should match up Paging Response to an earlier Paging.
*/
f_sleep(1.0);
/* Despite the round robin pointing at the third MSC ('roundrobin next msc 2'), the earlier Paging for the same
* TMSI causes this Paging Response to go to the first MSC ('msc 0'). */
f_perform_compl_l3(f_gen_one_compl_l3(PAGRESP, ts_MI_TMSI_NRI_LV(nri_v)));
f_sleep(1.0);
}
testcase TC_mscpool_paging_tmsi() runs on test_CT {
f_init(nr_msc := 3);
f_sleep(1.0);
var boolean ps_domain := false;
/* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
* third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);
f_ctrs_cn_init(ps_domain := ps_domain);
var ConnHdlr vc_conn1;
var template (value) TestHdlrParams pars1 := t_pars(0, ps_domain := ps_domain, cn_nr := 0);
pars1.sccp_addr_hnbgw := g_cn[valueof(pars1.cn_idx)].sccp_addr_peer;
pars1.sccp_addr_msc := g_cn[valueof(pars1.cn_idx)].sccp_addr_own;
vc_conn1 := f_start_handler_with_pars(refers(f_tc_mscpool_paging_tmsi), pars1);
vc_conn1.done;
f_ctrs_cn_expect(0, "cnpool:subscr:paged");
f_shutdown_helper();
}
/* For round-robin, skip a CN link that has 'no allow-attach' set. */
testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
@ -2450,6 +2561,8 @@ control {
execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
execute( TC_mscpool_paging_imsi() );
execute( TC_mscpool_paging_tmsi() );
execute( TC_mscpool_no_allow_attach_round_robin() );
execute( TC_mscpool_no_allow_attach_valid_nri() );
execute( TC_mscpool_sccp_n_pcstate_detaches_cnlink() );

View File

@ -168,6 +168,7 @@ type port RAN_Conn_PT message {
#endif
#ifdef RAN_EMULATION_RANAP
RANAP_PDU,
RANAP_N_UNITDATA_req,
/* Client requests us to create SCCP Connection */
RANAP_Conn_Req,
#endif
@ -969,6 +970,7 @@ private altstep as_main_ranap() runs on RAN_Emulation_CT {
var RANAP_N_DISCONNECT_ind rdisc_ind;
var RANAP_Conn_Req creq;
var RANAP_PDU ranap;
var RANAP_N_UNITDATA_req ranap_ud;
var RAN_ConnHdlr vc_conn;
var PDU_DTAP_PS_MO ps_mo;
var PDU_DTAP_PS_MT ps_mt;
@ -1034,6 +1036,11 @@ private altstep as_main_ranap() runs on RAN_Emulation_CT {
RANAP.send(ts_RANAP_DATA_req(conn_id, ranap));
}
/* e.g. for Paging from virtual MSC/SGSN to SUT osmo-hnbgw */
[] CLIENT.receive(RANAP_N_UNITDATA_req:?) -> value ranap_ud sender vc_conn {
RANAP.send(ranap_ud);
}
/* Disconnect request client -> SCCP */
[] CLIENT.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ) -> sender vc_conn {
var integer conn_id := f_conn_id_by_comp(vc_conn);

View File

@ -720,6 +720,47 @@ tr_RANAP_Paging(template CN_DomainIndicator dom, template IMSI imsi,
}
}
template (value) TemporaryUE_ID ts_RANAP_TemporaryUE_ID_TMSI(octetstring tmsi) := {
tMSI := tmsi
}
template (value) RANAP_PDU
ts_RANAP_Paging_temp_id(template (value) CN_DomainIndicator dom, template (value) IMSI imsi,
template (value) TemporaryUE_ID temp_id,
template (omit) Paging.protocolExtensions exts := omit) := {
initiatingMessage := {
procedureCode := id_Paging,
criticality := ignore,
value_ := {
paging := {
protocolIEs := {
{
id := id_CN_DomainIndicator,
criticality := ignore,
value_ := {
cN_DomainIndicator := dom
}
}, {
id := id_PermanentNAS_UE_ID,
criticality := ignore,
value_ := {
permanentNAS_UE_ID := {
iMSI := imsi
}
}
}, {
id := id_TemporaryUE_ID,
criticality := ignore,
value_ := {
temporaryUE_ID := temp_id
}
}
},
protocolExtensions := exts
}
}
}
}
/*****************************************************************************************************