aboutsummaryrefslogtreecommitdiffstats
path: root/hlr/HLR_Tests.ttcn
diff options
context:
space:
mode:
Diffstat (limited to 'hlr/HLR_Tests.ttcn')
-rw-r--r--hlr/HLR_Tests.ttcn223
1 files changed, 189 insertions, 34 deletions
diff --git a/hlr/HLR_Tests.ttcn b/hlr/HLR_Tests.ttcn
index 36e28b8a..46b98c29 100644
--- a/hlr/HLR_Tests.ttcn
+++ b/hlr/HLR_Tests.ttcn
@@ -15,6 +15,7 @@ module HLR_Tests {
import from GSUP_Types all;
+import from GSUP_Templates all;
import from GSUP_Emulation all;
import from IPA_Emulation all;
@@ -70,9 +71,6 @@ modulepar {
/* emulated GSUP server (second HLR) */
charstring mp_hlr_ts_ip := "127.0.0.99";
integer mp_hlr_ts_port := 4222;
-
- /* drop after osmo-hlr release > 1.2.0 */
- boolean mp_hlr_supports_dgsm := true;
};
type record HlrSubscrAud2G {
@@ -154,9 +152,8 @@ function f_init_vty() runs on test_CT {
map(self:VTY, system:VTY);
f_vty_set_prompts(VTY);
f_vty_transceive(VTY, "enable");
- if (mp_hlr_supports_dgsm) {
- f_vty_config(VTY, "mslookup", "no mdns bind");
- }
+ f_vty_config(VTY, "mslookup", "no mdns bind");
+ f_vty_config(VTY, "hlr", "reject-cause not-found imsi-unknown");
}
private altstep as_Tguard() runs on test_CT {
@@ -245,7 +242,7 @@ function f_init(boolean legacy := true, boolean gsup_server := false) runs on te
f_init_gsup_server("HLR_Test");
}
- f_ipa_ctrl_start(mp_hlr_ip, mp_hlr_ctrl_port);
+ f_ipa_ctrl_start_client(mp_hlr_ip, mp_hlr_ctrl_port);
}
/*! Start HLR_ConnHdlr from testCT in a separate thread.
@@ -540,12 +537,15 @@ runs on HLR_ConnHdlr return GSUP_PDU {
return ret;
}
+/* return_isd -> return the Insert Subscriber Data instead of the Update Location Result */
function f_perform_UL(hexstring imsi, template hexstring msisdn,
template (omit) integer exp_err_cause := omit,
GSUP_CnDomain dom := OSMO_GSUP_CN_DOMAIN_PS,
template (omit) octetstring source_name := omit)
-runs on HLR_ConnHdlr return GSUP_PDU {
- var GSUP_PDU ret;
+runs on HLR_ConnHdlr return GSUP_PDUs {
+ var GSUP_PDU pdu;
+ var GSUP_PDU isd;
+ var GSUP_PDUs ret;
timer T := 3.0;
var boolean exp_fail := false;
var boolean isd_done := false;
@@ -556,31 +556,31 @@ runs on HLR_ConnHdlr return GSUP_PDU {
GSUP.send(valueof(ts_GSUP_UL_REQ(imsi, dom, source_name := source_name)));
T.start;
alt {
- [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, exp_err_cause, destination_name := source_name)) -> value ret {
+ [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, exp_err_cause, destination_name := source_name)) -> value pdu {
setverdict(pass);
}
- [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?, destination_name := source_name)) -> value ret {
+ [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?, destination_name := source_name)) -> value pdu {
setverdict(fail, "Unexpected UL ERROR Cause");
mtc.stop;
}
- [exp_fail] GSUP.receive(tr_GSUP_UL_RES(imsi, destination_name := source_name)) -> value ret {
+ [exp_fail] GSUP.receive(tr_GSUP_UL_RES(imsi, destination_name := source_name)) -> value pdu {
setverdict(fail, "Unexpected UL.res for unknown IMSI");
mtc.stop;
}
- [exp_fail] GSUP.receive(tr_GSUP_ISD_REQ(imsi, destination_name := source_name)) -> value ret {
+ [exp_fail] GSUP.receive(tr_GSUP_ISD_REQ(imsi, destination_name := source_name)) -> value pdu {
setverdict(fail, "Unexpected ISD.req in error case");
mtc.stop;
}
- [not exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?, destination_name := source_name)) -> value ret {
+ [not exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?, destination_name := source_name)) -> value pdu {
setverdict(fail, "Unexpected UL ERROR");
mtc.stop;
}
- [not exp_fail and not isd_done] GSUP.receive(tr_GSUP_ISD_REQ(imsi, msisdn, destination_name := source_name)) -> value ret {
+ [not exp_fail and not isd_done] GSUP.receive(tr_GSUP_ISD_REQ(imsi, msisdn, destination_name := source_name)) -> value isd {
GSUP.send(ts_GSUP_ISD_RES(imsi, source_name := source_name));
isd_done := true;
repeat;
}
- [not exp_fail and isd_done] GSUP.receive(tr_GSUP_UL_RES(imsi, destination_name := source_name)) -> value ret {
+ [not exp_fail and isd_done] GSUP.receive(tr_GSUP_UL_RES(imsi, destination_name := source_name)) -> value pdu {
setverdict(pass);
}
[] GSUP.receive { repeat; }
@@ -589,6 +589,12 @@ runs on HLR_ConnHdlr return GSUP_PDU {
mtc.stop;
}
}
+
+ ret := { pdu };
+ if (isd_done) {
+ ret := ret & { isd };
+ }
+
return ret;
}
@@ -983,6 +989,7 @@ testcase TC_gsup_ul_unknown_imsi() runs on test_CT {
vc_conn := f_start_handler(refers(f_TC_ul_unknown_imsi), pars);
vc_conn.done;
}
+
testcase TC_gsup_ul_unknown_imsi_via_proxy() runs on test_CT {
var hexstring imsi := f_rnd_imsi('26242'H);
var HLR_ConnHdlrPars pars := valueof(t_Pars_via_proxy(imsi));
@@ -993,15 +1000,35 @@ testcase TC_gsup_ul_unknown_imsi_via_proxy() runs on test_CT {
vc_conn.done;
}
+/* Test if the HLR can be configured to a different error code if the subscriber can't be found.
+ * E.g. on event networks the HLR should return Roaming Not Allowed to unknown subscribers instead
+ * of Subscriber Unknown in HLR.
+ */
+private function f_TC_ul_unknown_imsi_roaming_not_allowed() runs on HLR_ConnHdlr {
+ f_vty_config(VTY, "hlr", "reject-cause not-found roaming-not-allowed");
+ f_perform_UL(g_pars.sub.imsi, ?, 13, source_name := g_pars.source_name);
+ setverdict(pass);
+}
+testcase TC_gsup_ul_unknown_imsi_roaming_not_allowed() runs on test_CT {
+ var hexstring imsi := f_rnd_imsi('26242'H);
+ var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
+ var HLR_ConnHdlr vc_conn;
+
+ f_init(false);
+ vc_conn := f_start_handler(refers(f_TC_ul_unknown_imsi_roaming_not_allowed), pars);
+ vc_conn.done;
+}
+
/* test UL for a number of different subscriber cases (algo, 2g/3g, ...) */
private function f_TC_gsup_ul() runs on HLR_ConnHdlr {
- var GSUP_PDU res;
+ var GSUP_PDUs res;
res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn, source_name := g_pars.source_name);
setverdict(pass);
}
+
testcase TC_gsup_ul() runs on test_CT {
var HlrSubscriberList sl;
- var GSUP_PDU res;
+ var GSUP_PDUs res;
f_init(false);
sl := f_gen_subs();
@@ -1020,6 +1047,72 @@ testcase TC_gsup_ul_via_proxy() runs on test_CT {
setverdict(pass);
}
+private function f_TC_gsup_ul_subscriber_data() runs on HLR_ConnHdlr {
+ var GSUP_PDUs pdus;
+ var GSUP_PDU isd;
+ log("GSUP ul subscriber_data", isd);
+ pdus := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn, source_name := g_pars.source_name);
+ isd := pdus[1];
+
+ template GSUP_IEs tr_pdp_info_internet := {
+ tr_GSUP_IE_PDP_CONTEXT_ID('01'O),
+ tr_GSUP_IE_APN(str2apn("internet"))
+ }
+ template GSUP_IEs tr_pdp_info_wildcard := {
+ tr_GSUP_IE_PDP_CONTEXT_ID('02'O),
+ tr_GSUP_IE_APN(str2apn("*"))
+ }
+
+ /* Search for PDP info 'internet', '*' */
+ var boolean found := false;
+ var GSUP_IeValue ievalue;
+ var GSUP_IEs pdp_info;
+ found := f_gsup_find_nested_ie_multiple(isd.ies, OSMO_GSUP_PDP_INFO_IE, 0, ievalue);
+ if (not found) {
+ setverdict(fail, "Multiple APNs: Coulnd't find first PDP Info IE in: ", isd);
+ return;
+ }
+ pdp_info := ievalue.pdp_info;
+ if (not match(pdp_info, tr_pdp_info_internet)) {
+ setverdict(fail, "Multiple APNs: first PDP Info doesn't match: ", pdp_info, "on Template: ", tr_pdp_info_internet);
+ return;
+ }
+
+ /* wildcard '*' */
+ found := f_gsup_find_nested_ie_multiple(isd.ies, OSMO_GSUP_PDP_INFO_IE, 1, ievalue);
+ if (not found) {
+ setverdict(fail, "Multiple APNs: Coulnd't find second PDP Info IE in: ", isd);
+ return;
+ }
+ pdp_info := ievalue.pdp_info;
+ if (not match(pdp_info, tr_pdp_info_wildcard)) {
+ setverdict(fail, "Multiple APNs: second PDP Info doesn't match: ", pdp_info, "on Template: ", tr_pdp_info_wildcard);
+ return;
+ }
+
+ setverdict(pass);
+}
+
+testcase TC_gsup_ul_subscriber_data() runs on test_CT {
+ /* Do a GSUP Update Location Request to get a Insert Subscriber Data Request (ISD).
+ * Check for multiple APN in the ISD:
+ * SGSN -> HLR: Update Location Request
+ * SGSN <- HLR: Insert Subscriber Data Request (Check the TLV)
+ * SGSN -> HLR: Insert Subscriber Data Result
+ * SGSN <- HLR: Update Location Result
+ */
+ var HlrSubscriberList sl;
+
+ f_init(false);
+ f_vty_config2(VTY, {"hlr", "ps"} , "no pdp-profiles default");
+ f_vty_config2(VTY, {"hlr", "ps", "pdp-profiles default", "profile 1"}, "apn internet");
+ f_vty_config2(VTY, {"hlr", "ps", "pdp-profiles default", "profile 2"}, "apn *");
+ sl := f_gen_subs();
+ f_start_handler_per_sub(refers(f_TC_gsup_ul_subscriber_data), sl);
+
+ setverdict(pass);
+}
+
/* Test only the VTY commands */
testcase TC_vty() runs on test_CT {
var HlrSubscriber sub;
@@ -1051,7 +1144,7 @@ testcase TC_vty() runs on test_CT {
/* VTY changes to MSISDN should result in ISD to current VLR */
private function f_TC_vty_msisdn_isd() runs on HLR_ConnHdlr {
var hexstring new_msisdn;
- var GSUP_PDU res;
+ var GSUP_PDUs res;
timer T := 5.0;
/* Create Subscriber */
@@ -1096,9 +1189,10 @@ testcase TC_vty_msisdn_isd() runs on test_CT {
/* Test PURGE MS for CS services */
private function f_TC_gsup_purge_cs() runs on HLR_ConnHdlr {
- var GSUP_PDU res;
+ var GSUP_PDUs res;
+ var GSUP_PDU pdu;
res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
- res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_CS);
+ pdu := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_CS);
}
testcase TC_gsup_purge_cs() runs on test_CT {
var HlrSubscriberList sl;
@@ -1113,9 +1207,10 @@ testcase TC_gsup_purge_cs() runs on test_CT {
/* Test PURGE MS for PS services */
private function f_TC_gsup_purge_ps() runs on HLR_ConnHdlr {
- var GSUP_PDU res;
+ var GSUP_PDUs res;
+ var GSUP_PDU pdu;
res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
- res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_PS);
+ pdu := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_PS);
}
testcase TC_gsup_purge_ps() runs on test_CT {
var HlrSubscriberList sl;
@@ -1545,7 +1640,7 @@ testcase TC_gsup_check_imei_unknown_imsi() runs on test_CT {
/* Test create-subscriber-on-demand during Check IMEI (OsmoMSC would be set to "check-imei-rqd early") */
private function f_TC_subscr_create_on_demand_check_imei_early() runs on HLR_ConnHdlr {
- var GSUP_PDU res; /* save various return values to prevent ttcn3 compiler warnings */
+ var GSUP_PDUs res; /* save various return values to prevent ttcn3 compiler warnings */
var charstring imsi_pattern := "*IMSI: " & hex2str(g_pars.sub.imsi) & "*";
/* Random MSISDN and CS+PS NAM (LU must pass) */
@@ -1618,7 +1713,7 @@ testcase TC_subscr_create_on_demand_check_imei_early() runs on test_CT {
/* Test create-subscriber-on-demand during LU (Location Update) */
private function f_TC_subscr_create_on_demand_ul() runs on HLR_ConnHdlr {
- var GSUP_PDU res;
+ var GSUP_PDUs res;
var charstring imsi_pattern := "*IMSI: " & hex2str(g_pars.sub.imsi) & "*";
/* Random MSISDN and CS+PS NAM (LU must pass) */
@@ -1685,13 +1780,14 @@ testcase TC_subscr_create_on_demand_ul() runs on test_CT {
/* Test create-subscriber-on-demand during SAI (SendAuthInfo) */
private function f_TC_subscr_create_on_demand_sai() runs on HLR_ConnHdlr {
- var GSUP_PDU res;
+ var GSUP_PDUs res;
+ var GSUP_PDU pdu;
var charstring imsi_pattern := "*IMSI: " & hex2str(g_pars.sub.imsi) & "*";
/* HLR creates the subscriber on demand. Then the IMSI is known, but there is no auth data, so the HLR returns
* the "slightly inaccurate cause 'IMSI Unknown' via GSUP". The MS is able to do a LU afterwards. */
f_vty_config(VTY, "hlr", "subscriber-create-on-demand 3 cs+ps");
- res := f_perform_SAI(g_pars.sub.imsi, 2 /* IMSI Unknown */ );
+ pdu := f_perform_SAI(g_pars.sub.imsi, 2 /* IMSI Unknown */ );
/* Verify that it was created before the LU */
f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
@@ -1922,6 +2018,65 @@ testcase TC_MSLookup_mDNS_service_other_proxy() runs on test_CT {
}
}
+
+/* strchr similar to C's/posix strchr but returns the position of the first matching.
+ * if the char c isn't found it returns -1.
+ */
+function strchr(in charstring s, in charstring c) return integer {
+ for (var integer i := 0; i < lengthof(s); i := i+1) {
+ if (s[i] == c) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+/* str2apn returns octetstring
+ * internet -> '08'O & char2oct("internet")
+ * internet.foo -> '08'O & char2oct("internet") & '03'O & char2oct("foo")
+ * internet.-> '08'O & char2oct("internet")
+ */
+function str2apn(in charstring apn) return octetstring {
+ var octetstring result := ''O;
+ var charstring remain := apn;
+ var integer pos := strchr(remain, ".");
+
+ while (pos != -1) {
+ /* ends on a dot. e.g. "internet.", we must ignore the ending dot and this is then the last element */
+ if (pos == 0) {
+ /* it's not allowed to start with a dot. */
+ return ''O;
+ }
+
+ if (pos + 1 == lengthof(remain)) {
+ /* remove the dot */
+ remain := substr(remain, 0, pos)
+ break;
+ }
+
+ result := result & int2oct(pos, 1) & char2oct(substr(remain, 0, pos));
+ remain := substr(remain, pos + 1, lengthof(remain) - pos - 1);
+ pos := strchr(remain, ".");
+ }
+ /* last element */
+ var integer len := lengthof(remain);
+ result := result & int2oct(len, 1) & char2oct(remain);
+ return result;
+}
+
+private function test_assert(boolean term) {
+ if (term == false) {
+ setverdict(fail, "Values mismatch");
+ }
+}
+
+private function test_str2apn() {
+ test_assert(str2apn("internet") == '08'O & char2oct("internet"));
+ test_assert(str2apn("internet.") == '08'O & char2oct("internet"));
+ test_assert(str2apn("internet.foo") == '08'O & char2oct("internet") & '03'O & char2oct("foo"));
+ test_assert(str2apn(".internet.foo") == ''O);
+}
+
/* TODO:
* UL with ISD error
* UL with ISD timeout
@@ -1943,9 +2098,11 @@ control {
execute( TC_gsup_sai_eps() );
execute( TC_gsup_ul_unknown_imsi() );
execute( TC_gsup_ul_unknown_imsi_via_proxy() );
+ execute( TC_gsup_ul_unknown_imsi_roaming_not_allowed() );
execute( TC_gsup_sai_err_unknown_imsi() );
execute( TC_gsup_ul() );
execute( TC_gsup_ul_via_proxy() );
+ execute( TC_gsup_ul_subscriber_data() );
execute( TC_vty() );
execute( TC_vty_msisdn_isd() );
execute( TC_gsup_purge_cs() );
@@ -1973,13 +2130,11 @@ control {
execute( TC_subscr_create_on_demand_ul() );
execute( TC_subscr_create_on_demand_sai() );
- if (mp_hlr_supports_dgsm) {
- execute( TC_MSLookup_mDNS_service_other_home() );
- execute( TC_MSLookup_GSUP_proxy() );
- execute( TC_MSLookup_mDNS_service_GSUP_HLR_home() );
- execute( TC_MSLookup_mDNS_service_GSUP_HLR_proxy() );
- execute( TC_MSLookup_mDNS_service_other_proxy() );
- }
+ execute( TC_MSLookup_mDNS_service_other_home() );
+ execute( TC_MSLookup_GSUP_proxy() );
+ execute( TC_MSLookup_mDNS_service_GSUP_HLR_home() );
+ execute( TC_MSLookup_mDNS_service_GSUP_HLR_proxy() );
+ execute( TC_MSLookup_mDNS_service_other_proxy() );
};
};