bsc: add first test to verify System Information on RSL startup
Change-Id: I6a8ef404087efee491390dc1d2452ac323f145f0
diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn
index 784375a..c7a6e38 100644
--- a/bsc/BSC_Tests.ttcn
+++ b/bsc/BSC_Tests.ttcn
@@ -59,6 +59,9 @@
import from SCCPasp_Types all;
+import from GSM_SystemInformation all;
+import from GSM_RestOctets all;
+
const integer NUM_BTS := 3;
const integer NUM_MSC := 3;
const float T3101_MAX := 12.0;
@@ -84,6 +87,358 @@
{ "mscpool:subscr:paged", 0 }
};
+/* Set of all System Information received during one RSL port's startup.
+ * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
+ * broadcast that SI type. That will be reflected as 'omit' here.
+ */
+type record SystemInformationConfig {
+ SystemInformationType1 si1 optional,
+ SystemInformationType2 si2 optional,
+ SystemInformationType2bis si2bis optional,
+ SystemInformationType2ter si2ter optional,
+ record of SI2quaterRestOctets si2quater optional,
+ SystemInformationType3 si3 optional,
+ SystemInformationType4 si4 optional,
+ /* TODO: replace with proper decoding of SI13, implement SI13 in GSM_SystemInformation.ttcn */
+ octetstring si13 optional,
+ SystemInformationType5 si5 optional,
+ SystemInformationType5bis si5bis optional,
+ SystemInformationType5ter si5ter optional,
+ SystemInformationType6 si6 optional
+};
+
+const SystemInformationConfig SystemInformationConfig_omit := {
+ si1 := omit,
+ si2 := omit,
+ si2bis := omit,
+ si2ter := omit,
+ si2quater := omit,
+ si3 := omit,
+ si4 := omit,
+ si13 := omit,
+ si5 := omit,
+ si5bis := omit,
+ si5ter := omit,
+ si6 := omit
+};
+
+/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
+template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
+ template uint3_t meas_bw := 3)
+:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
+ meas_bw_presence := '1'B,
+ meas_bw := meas_bw);
+
+/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
+template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
+ template uint3_t prio := 3,
+ template (present) uint5_t thresh_high := 20,
+ template uint5_t thresh_low := 10,
+ template uint5_t qrxlevmin := 22)
+:= tr_EUTRAN_NeighbourCells(
+ cell_desc_list := cell_desc_list,
+ prio_presence := '1'B,
+ prio := prio,
+ thresh_high := thresh_high,
+ thresh_low_presence := '1'B,
+ thresh_low := thresh_low,
+ qrxlevmin_presence := '1'B,
+ qrxlevmin := qrxlevmin);
+
+template SystemInformationConfig SystemInformationConfig_default := {
+ si1 := {
+ cell_chan_desc := '8FB38000000000000000000000000000'O,
+ rach_control := {
+ max_retrans := RACH_MAX_RETRANS_7,
+ tx_integer := '1001'B,
+ cell_barr_access := false,
+ re_not_allowed := true,
+ acc := '0000010000000000'B
+ },
+ rest_octets := ?
+ },
+ si2 := {
+ bcch_freq_list := '00000000000000000000000000000000'O,
+ ncc_permitted := '11111111'B,
+ rach_control := {
+ max_retrans := RACH_MAX_RETRANS_7,
+ tx_integer := '1001'B,
+ cell_barr_access := false,
+ re_not_allowed := true,
+ acc := '0000010000000000'B
+ }
+ },
+ si2bis := omit,
+ si2ter := {
+ extd_bcch_freq_list := '8E320000000000000000000000000800'O,
+ rest_octets := ?
+ },
+ si2quater := {
+ tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
+ },
+ si3 := {
+ cell_id := 0,
+ lai := {
+ mcc_mnc := '001F01'H,
+ lac := 1
+ },
+ ctrl_chan_desc := {
+ msc_r99 := true,
+ att := true,
+ bs_ag_blks_res := 1,
+ ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
+ si22ind := false,
+ cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
+ spare := '00'B,
+ bs_pa_mfrms := 3,
+ t3212 := 30
+ },
+ cell_options := {
+ dn_ind := false,
+ pwrc := false,
+ dtx := MS_SHALL_USE_UL_DTX,
+ radio_link_tout_div4 := 7
+ },
+ cell_sel_par := {
+ cell_resel_hyst_2dB := 2,
+ ms_txpwr_max_cch := 7,
+ acs := '0'B,
+ neci := true,
+ rxlev_access_min := 0
+ },
+ rach_control := {
+ max_retrans := RACH_MAX_RETRANS_7,
+ tx_integer := '1001'B,
+ cell_barr_access := false,
+ re_not_allowed := true,
+ acc := '0000010000000000'B
+ },
+ rest_octets := {
+ sel_params := {
+ presence := '0'B,
+ params := omit
+ },
+ pwr_offset := {
+ presence := '0'B,
+ offset := omit
+ },
+ si_2ter_ind := '1'B,
+ early_cm_ind := '0'B,
+ sched_where := {
+ presence := '0'B,
+ where := omit
+ },
+ gprs_ind := {
+ presence := '1'B,
+ ind := {
+ ra_colour := 0,
+ si13_pos := '0'B
+ }
+ },
+ umts_early_cm_ind := '1'B,
+ si2_quater_ind := {
+ presence := '1'B,
+ ind := '0'B
+ },
+ iu_mode_ind := omit,
+ si21_ind := {
+ presence := '0'B,
+ pos := omit
+ }
+ }
+ },
+ si4 := {
+ lai := {
+ mcc_mnc := '001F01'H,
+ lac := 1
+ },
+ cell_sel_par := {
+ cell_resel_hyst_2dB := 2,
+ ms_txpwr_max_cch := 7,
+ acs := '0'B,
+ neci := true,
+ rxlev_access_min := 0
+ },
+ rach_control := {
+ max_retrans := RACH_MAX_RETRANS_7,
+ tx_integer := '1001'B,
+ cell_barr_access := false,
+ re_not_allowed := true,
+ acc := '0000010000000000'B
+ },
+ cbch_chan_desc := omit,
+ cbch_mobile_alloc := omit,
+ rest_octets := {
+ sel_params := {
+ presence := '0'B,
+ params := omit
+ },
+ pwr_offset := {
+ presence := '0'B,
+ offset := omit
+ },
+ gprs_ind := {
+ presence := '1'B,
+ ind := {
+ ra_colour := 0,
+ si13_pos := '0'B
+ }
+ },
+ s_presence := '0'B,
+ s := omit
+ }
+ },
+ si13 := '9000185A6FC9E08410AB2B2B2B2B2B2B2B2B2B2B'O,
+ si5 := {
+ bcch_freq_list := '10000000000000000000000000000000'O
+ },
+ si5bis := omit,
+ si5ter := {
+ extd_bcch_freq_list := '9E050020000000000000000000000000'O
+ },
+ si6 := {
+ cell_id := 0,
+ lai := {
+ mcc_mnc := '001F01'H,
+ lac := 1
+ },
+ cell_options := {
+ dtx_ext := '1'B,
+ pwrc := false,
+ dtx := '01'B,
+ radio_link_timeout := '0111'B
+ },
+ ncc_permitted := '11111111'B,
+ rest_octets := ?
+ }
+ };
+
+
+/* List of all the System Information received on all RSL ports */
+type record of SystemInformationConfig SystemInformationConfig_list;
+
+function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
+{
+ var RSL_IE_Body sysinfo_type_ie;
+ var RSL_IE_SysinfoType si_type;
+ var octetstring data;
+
+ if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
+ setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
+ mtc.stop;
+ }
+ si_type := sysinfo_type_ie.sysinfo_type;
+
+ if (rsl.msg_type == RSL_MT_BCCH_INFO) {
+ var RSL_IE_Body bcch_ie;
+ if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
+ data := bcch_ie.other.payload;
+ }
+ } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
+ var RSL_IE_Body l3_ie;
+ if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
+ data := l3_ie.l3_info.payload;
+ }
+ } else {
+ setverdict(fail, "Don't understand this System Information message");
+ mtc.stop;
+ }
+
+ var boolean handled := false;
+
+ if (rsl.msg_type == RSL_MT_BCCH_INFO) {
+ handled := true;
+
+ if (si_type == RSL_SYSTEM_INFO_1) {
+ if (not isbound(data)) {
+ si.si1 := omit;
+ } else {
+ si.si1 := dec_SystemInformation(data).payload.si1;
+ }
+ } else if (si_type == RSL_SYSTEM_INFO_2) {
+ if (not isbound(data)) {
+ si.si2 := omit;
+ } else {
+ si.si2 := dec_SystemInformation(data).payload.si2;
+ }
+ } else if (si_type == RSL_SYSTEM_INFO_2bis) {
+ if (not isbound(data)) {
+ si.si2bis := omit;
+ } else {
+ si.si2bis := dec_SystemInformation(data).payload.si2bis;
+ }
+ } else if (si_type == RSL_SYSTEM_INFO_2ter) {
+ if (not isbound(data)) {
+ si.si2ter := omit;
+ } else {
+ si.si2ter := dec_SystemInformation(data).payload.si2ter;
+ }
+ } else if (si_type == RSL_SYSTEM_INFO_2quater) {
+ if (not isbound(data)) {
+ si.si2quater := {};
+ } else {
+ var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
+ /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
+ si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
+ }
+ } else if (si_type == RSL_SYSTEM_INFO_3) {
+ if (not isbound(data)) {
+ si.si3 := omit;
+ } else {
+ si.si3 := dec_SystemInformation(data).payload.si3;
+ }
+ } else if (si_type == RSL_SYSTEM_INFO_4) {
+ if (not isbound(data)) {
+ si.si4 := omit;
+ } else {
+ si.si4 := dec_SystemInformation(data).payload.si4;
+ }
+ } else if (si_type == RSL_SYSTEM_INFO_13) {
+ if (not isbound(data)) {
+ si.si13 := omit;
+ } else {
+ si.si13 := dec_SystemInformation(data).payload.other;
+ }
+ } else {
+ handled := false;
+ }
+ } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
+ handled := true;
+
+ if (si_type == RSL_SYSTEM_INFO_5) {
+ if (not isbound(data)) {
+ si.si5 := omit;
+ } else {
+ si.si5 := dec_SystemInformation(data).payload.si5;
+ }
+ } else if (si_type == RSL_SYSTEM_INFO_5bis) {
+ if (not isbound(data)) {
+ si.si5bis := omit;
+ } else {
+ si.si5bis := dec_SystemInformation(data).payload.si5bis;
+ }
+ } else if (si_type == RSL_SYSTEM_INFO_5ter) {
+ if (not isbound(data)) {
+ si.si5ter := omit;
+ } else {
+ si.si5ter := dec_SystemInformation(data).payload.si5ter;
+ }
+ } else if (si_type == RSL_SYSTEM_INFO_6) {
+ if (not isbound(data)) {
+ si.si6 := omit;
+ } else {
+ si.si6 := dec_SystemInformation(data).payload.si6;
+ }
+ } else {
+ handled := false;
+ }
+ }
+
+ if (not handled) {
+ setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
+ }
+}
+
type component test_CT extends CTRL_Adapter_CT {
/* Array of per-BTS state */
var BTS_State bts[NUM_BTS];
@@ -117,6 +472,9 @@
timer T_guard := 30.0;
var CounterNameValsList g_ctr_msc;
+
+ /* System Information bytes as received during RSL startup, for each RSL[idx]. */
+ var SystemInformationConfig_list g_system_information := {};
}
modulepar {
@@ -425,6 +783,54 @@
f_vty_transceive(BSCVTY, "logp lglobal notice " & log_msg);
}
+private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
+{
+ if (rsl_idx >= lengthof(g_system_information)) {
+ g_system_information[rsl_idx] := SystemInformationConfig_omit
+ }
+ f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
+}
+
+altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
+ var ASP_RSL_Unitdata rx_rsl_ud;
+
+ /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
+ [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
+ f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
+ repeat;
+ }
+ [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
+ f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
+ repeat;
+ }
+ [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
+ f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
+ repeat;
+ }
+ [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
+ f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
+ repeat;
+ }
+
+ /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
+ [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
+ f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
+ repeat;
+ }
+ [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
+ f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
+ repeat;
+ }
+ [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
+ f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
+ repeat;
+ }
+ [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
+ f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
+ repeat;
+ }
+}
+
/* global initialization function
* \param nr_bts Number of BTSs we should start/bring up
* \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
@@ -484,6 +890,32 @@
f_wait_oml(bts_idx, "connected", 5.0);
}
+function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
+ template SystemInformationConfig expect_si)
+runs on test_CT {
+ var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
+
+ f_init_bts(bts_idx, handler_mode);
+
+ /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
+ * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
+ * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
+ */
+ f_sleep(5.0);
+ log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
+
+ deactivate(sysinfo);
+
+ if (match(g_system_information[bts_idx], expect_si)) {
+ setverdict(pass);
+ } else {
+ log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
+ log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
+ setverdict(fail, "received SI does not match expectations");
+ return;
+ }
+}
+
/* expect to receive a RSL message matching a specified template on a given BTS / stream */
function f_exp_ipa_rx(integer bts_nr, template RSL_Message t_rx, float t_secs := 2.0, IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
runs on test_CT return RSL_Message {
@@ -1273,8 +1705,10 @@
setverdict(pass);
}
-
-
+testcase TC_si_default() runs on test_CT {
+ f_init(0);
+ f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
+}
testcase TC_ctrl_msc_connection_status() runs on test_CT {
var charstring ctrl_resp;
@@ -5237,6 +5671,8 @@
execute( TC_ctrl_location() );
}
+ execute( TC_si_default() );
+
/* RSL DCHAN Channel ACtivation / Deactivation */
execute( TC_chan_act_noreply() );
execute( TC_chan_act_counter() );
diff --git a/bsc/gen_links.sh b/bsc/gen_links.sh
index a936ef3..343cc1c 100755
--- a/bsc/gen_links.sh
+++ b/bsc/gen_links.sh
@@ -67,7 +67,7 @@
gen_links $DIR $FILES
DIR=../library
-FILES="Misc_Helpers.ttcn General_Types.ttcn Osmocom_Types.ttcn GSM_Types.ttcn Osmocom_VTY_Functions.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc IPA_Emulation.ttcnpp L3_Templates.ttcn BSSMAP_Templates.ttcn RAN_Emulation.ttcnpp RLCMAC_CSN1_Templates.ttcn RLCMAC_CSN1_Types.ttcn GSM_RR_Types.ttcn RSL_Types.ttcn RSL_Emulation.ttcn MGCP_Emulation.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_CodecPort_CtrlFunctDef.cc BSSAP_CodecPort.ttcn RAN_Adapter.ttcnpp Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunct.ttcn RTP_CodecPort_CtrlFunctDef.cc RTP_Emulation.ttcn IuUP_Types.ttcn IuUP_EncDec.cc IuUP_Emulation.ttcn SCCP_Templates.ttcn IPA_Testing.ttcn "
+FILES="Misc_Helpers.ttcn General_Types.ttcn Osmocom_Types.ttcn GSM_Types.ttcn Osmocom_VTY_Functions.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc IPA_Emulation.ttcnpp L3_Templates.ttcn BSSMAP_Templates.ttcn RAN_Emulation.ttcnpp RLCMAC_CSN1_Templates.ttcn RLCMAC_CSN1_Types.ttcn GSM_RR_Types.ttcn RSL_Types.ttcn RSL_Emulation.ttcn MGCP_Emulation.ttcn MGCP_Types.ttcn MGCP_Templates.ttcn MGCP_CodecPort.ttcn MGCP_CodecPort_CtrlFunct.ttcn MGCP_CodecPort_CtrlFunctDef.cc BSSAP_CodecPort.ttcn RAN_Adapter.ttcnpp Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn RTP_CodecPort.ttcn RTP_CodecPort_CtrlFunct.ttcn RTP_CodecPort_CtrlFunctDef.cc RTP_Emulation.ttcn IuUP_Types.ttcn IuUP_EncDec.cc IuUP_Emulation.ttcn SCCP_Templates.ttcn IPA_Testing.ttcn GSM_SystemInformation.ttcn GSM_RestOctets.ttcn "
FILES+="CBSP_Types.ttcn CBSP_Templates.ttcn "
FILES+="CBSP_CodecPort.ttcn CBSP_CodecPort_CtrlFunct.ttcn CBSP_CodecPort_CtrlFunctdef.cc CBSP_Adapter.ttcn "
gen_links $DIR $FILES