hnbgw: add mscpool paging tests
Change-Id: If4bbd5c970108b01e8556fa7744ff627db75fb13
diff --git a/hnbgw/HNBGW_Tests.ttcn b/hnbgw/HNBGW_Tests.ttcn
index b1f6cae..d2854d5 100644
--- a/hnbgw/HNBGW_Tests.ttcn
+++ b/hnbgw/HNBGW_Tests.ttcn
@@ -46,6 +46,7 @@
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 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 @@
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 @@
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 @@
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 @@
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() );
diff --git a/library/RAN_Emulation.ttcnpp b/library/RAN_Emulation.ttcnpp
index 40929ee..25727f3 100644
--- a/library/RAN_Emulation.ttcnpp
+++ b/library/RAN_Emulation.ttcnpp
@@ -168,6 +168,7 @@
#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 @@
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 @@
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);
diff --git a/library/ranap/RANAP_Templates.ttcn b/library/ranap/RANAP_Templates.ttcn
index bc56bdb..051195f 100644
--- a/library/ranap/RANAP_Templates.ttcn
+++ b/library/ranap/RANAP_Templates.ttcn
@@ -720,6 +720,47 @@
}
}
+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
+ }
+ }
+ }
+}
/*****************************************************************************************************