From 5e686dce2d2b83e4c8fc82f64f1db0f1124c0f38 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Tue, 30 Jun 2020 01:26:53 +0200 Subject: [PATCH] bsc: add first test to verify System Information on RSL startup Change-Id: I6a8ef404087efee491390dc1d2452ac323f145f0 --- bsc/BSC_Tests.ttcn | 440 ++++++++++++++++++++++++++++++++++++++++++++- bsc/gen_links.sh | 2 +- 2 files changed, 439 insertions(+), 3 deletions(-) diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn index 784375a20..c7a6e3842 100644 --- a/bsc/BSC_Tests.ttcn +++ b/bsc/BSC_Tests.ttcn @@ -59,6 +59,9 @@ import from BSSMAP_Templates all; 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 @@ const CounterNameVals counternames_msc_mscpool := { { "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 @@ type component test_CT extends CTRL_Adapter_CT { 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 @@ private function f_logp(charstring log_msg) runs on MSC_ConnHdlr 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 @@ runs on test_CT { 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 @@ testcase TC_rll_est_ind_inval_sacch() runs on test_CT { 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 @@ control { 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 a936ef373..343cc1cd0 100755 --- a/bsc/gen_links.sh +++ b/bsc/gen_links.sh @@ -67,7 +67,7 @@ FILES="TELNETasp_PT.cc TELNETasp_PT.hh TELNETasp_PortType.ttcn" 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