aboutsummaryrefslogtreecommitdiffstats
path: root/bts
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2019-05-27 22:29:35 +0200
committerHarald Welte <laforge@gnumonks.org>2019-05-29 06:07:07 +0000
commitbe03048ae8a120c21e3a27d2921a32c85ab22d80 (patch)
tree558e2163ca69ee486b32101d6e9507cb0e6fddf7 /bts
parent58cf682d82e68193aa78f2789e2e4aa9fd8fdddc (diff)
bts: Verify SI3 GPRS indication reflects PCU interface status
When no PCU is connected to the BTS, the BTS should mask the GPRS indicator from the SI3 rest octets to indicate "no GPRS support" in the cell. This will cause phones not even trying to send us RACH requests for GPRS ATTACH, RAU, etc. Change-Id: I37efb712ee0c513aea230beeb35e7dabce698a34 Related: OS#4023 Related: OS#3075
Diffstat (limited to 'bts')
-rw-r--r--bts/BTS_Tests.ttcn173
1 files changed, 172 insertions, 1 deletions
diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn
index f60da241..0506e645 100644
--- a/bts/BTS_Tests.ttcn
+++ b/bts/BTS_Tests.ttcn
@@ -245,7 +245,7 @@ template (value) SystemInformation ts_SI3_default := {
},
cell_sel_par := ts_CellSelPar_default,
rach_control := ts_RachCtrl_default,
- rest_octets := '2B2B2B2B'O
+ rest_octets := '2C2B2B2B'O /* GPRS present */
}
}
}
@@ -3983,6 +3983,174 @@ testcase TC_pcu_socket_reconnect() runs on test_CT {
Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
+/* Ensure that GPRS capability is not advertised before PCU socket conncet */
+private function f_get_si3(L1CTL_PT pt) runs on test_CT return SystemInformationType3 {
+ var L1ctlDlMessage l1_dl;
+ var SystemInformation si;
+ timer T := 5.0;
+ T.start;
+ alt {
+ [] pt.receive(tr_L1CTL_DATA_IND(t_RslChanNr_BCCH(0), ?)) -> value l1_dl {
+ /* somehow dec_SystemInformation will try to decode even non-RR as SI */
+ if (not (l1_dl.payload.data_ind.payload[1] == '06'O)) {
+ log("Ignoring non-RR SI ", l1_dl);
+ repeat;
+ }
+ si := dec_SystemInformation(l1_dl.payload.data_ind.payload)
+ if (not ischosen(si.payload.si3)) {
+ repeat;
+ }
+ }
+ [] pt.receive {
+ repeat;
+ }
+ [] T.timeout {
+ setverdict(fail, "Timeout waiting for SI3");
+ }
+ }
+ return si.payload.si3;
+}
+
+/* CSN.1 L/H logic: is the bit at the current position using "inverted logic" (true) or not? */
+private function f_bitpos_is_inv(integer idx) return boolean {
+ select (idx mod 8) {
+ case ((2, 4, 6, 7)) { return true; } /* 1-bits of 0x2B */
+ case else { return false; } /* 0-bits of 0x2B */
+ }
+}
+/* determine if the bit at position 'idx' in 'str' is a CSN.1 'H' (true) or 'L' (false) */
+private function f_bit_is_high(bitstring str, integer idx) return boolean {
+ var boolean invert := f_bitpos_is_inv(idx);
+ if (invert) {
+ if (str[idx] == '1'B) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ if (str[idx] == '1'B) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+/* As the TITAN RAW codec cannot expres the CSN.1 L/H concept yet, we have to do this
+ manually. Let's hope https://www.eclipse.org/forums/index.php/t/1099087/ takes off and
+ we can replace this piece of code soon ... */
+private function f_si3_has_gprs_indicator(OCT4 si3_restoctets) return boolean {
+ var bitstring bits := oct2bit(si3_restoctets);
+ var integer idx := 0;
+
+ if (f_bit_is_high(bits, idx)) {
+ /* skip Optional selection parameters */
+ idx := idx + 16;
+ } else {
+ idx := idx + 1;
+ }
+
+ if (f_bit_is_high(bits, idx)) {
+ /* skip Optional power offset */
+ idx := idx + 3;
+ } else {
+ idx := idx + 1;
+ }
+
+ /* skip SI2ter Indicator */
+ idx := idx + 1;
+
+ /* skip Early CM Sending Control */
+ idx := idx + 1;
+
+ /* skip Scheduling if and where */
+ if (f_bit_is_high(bits, idx)) {
+ idx := idx + 4;
+ } else {
+ idx := idx + 1;
+ }
+
+ return f_bit_is_high(bits, idx);
+}
+
+testcase TC_pcu_socket_noconnect_nosi3gprs() runs on test_CT {
+ var SystemInformationType3 si3;
+ timer T := 5.0;
+
+ /* don't call f_init() as this would connect PCU socket */
+ f_init_rsl(testcasename());
+ T.start;
+ alt {
+ [] RSL_CCHAN.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP});
+ [] T.timeout {
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for ASP_IPA_EVENT_UP");
+ }
+ }
+ f_rsl_bcch_fill(RSL_SYSTEM_INFO_3, ts_SI3_default);
+
+ f_init_l1ctl();
+ f_l1_tune(L1CTL);
+
+ f_sleep(2.0);
+ L1CTL.clear;
+ si3 := f_get_si3(L1CTL);
+ if (f_si3_has_gprs_indicator(si3.rest_octets)) {
+ setverdict(fail, "SI3 indicates GPRS even before PCU socket connected");
+ } else {
+ setverdict(pass);
+ }
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
+}
+
+/* Ensure that GPRS capability is advertised after PCU socket connect */
+testcase TC_pcu_socket_connect_si3gprs() runs on test_CT {
+ var SystemInformationType3 si3;
+
+ /* this (among other things) establishes the first connection to the PCUIF socket */
+ f_init();
+ f_init_l1ctl();
+ f_l1_tune(L1CTL);
+
+ f_sleep(2.0);
+ L1CTL.clear;
+ si3 := f_get_si3(L1CTL);
+ if (not f_si3_has_gprs_indicator(si3.rest_octets)) {
+ setverdict(fail, "SI3 indicates no GPRS despite PCU socket connected");
+ } else {
+ setverdict(pass);
+ }
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
+}
+
+/* Ensure that GPRS capability is no longer advertised after PCU socket disconnect */
+testcase TC_pcu_socket_disconnect_nosi3gprs() runs on test_CT {
+ var SystemInformationType3 si3;
+
+ /* this (among other things) establishes the first connection to the PCUIF socket */
+ f_init();
+ f_init_l1ctl();
+ f_l1_tune(L1CTL);
+
+ f_pcuif_close(PCU, g_pcu_conn_id);
+ g_pcu_conn_id := -1;
+
+ f_sleep(1.0);
+
+ /* re-connect */
+ PCU.clear;
+ f_init_pcu(PCU, testcasename(), g_pcu_conn_id, g_pcu_last_info);
+
+ f_sleep(2.0);
+ L1CTL.clear;
+ si3 := f_get_si3(L1CTL);
+ if (f_si3_has_gprs_indicator(si3.rest_octets)) {
+ setverdict(fail, "SI3 indicates GPRS after PCU socket disconnected");
+ } else {
+ setverdict(pass);
+ }
+
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
+}
+
/***********************************************************************
* Osmocom Style Dynamic Timeslot Support
@@ -5360,6 +5528,9 @@ control {
execute( TC_pcu_rr_suspend() );
execute( TC_pcu_socket_connect_multi() );
execute( TC_pcu_socket_reconnect() );
+ execute( TC_pcu_socket_noconnect_nosi3gprs() );
+ execute( TC_pcu_socket_connect_si3gprs() );
+ execute( TC_pcu_socket_disconnect_nosi3gprs() );
} else {
log("PCU socket path not available, skipping PCU tests");
}