From cb478ec0ab4782933ced1ec93defe2f0959dcb04 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Sat, 11 Jul 2020 02:37:17 +0700 Subject: [PATCH] library/GSM_SystemInformation: add dec_SystemInformationSafe() Some types of System Information (mostly the Rest Octets) are not fully implemented, so calling the generic dec_SystemInformation() may result in a DTE. Let's add dec_SystemInformationSafeBT() with "prototype(backtrack)", so it would return a non-zero integer if decoding fails. Let's add a wrapper dec_SystemInformationSafe() that would additionally check the RR Protocol Discriminator. Change-Id: Id4d73e0f3347e1d4c4c77aec75b767311d662292 Related: OS#4662 --- bts/BTS_Tests.ttcn | 22 +++++++--------------- library/GSM_SystemInformation.ttcn | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn index 587e14a98..47f8a299c 100644 --- a/bts/BTS_Tests.ttcn +++ b/bts/BTS_Tests.ttcn @@ -3534,7 +3534,6 @@ private function f_TC_imm_ass(integer num_total, float sleep_s, float exp_pass) repeat; } [] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0), ?)) -> value l1_dl { - /* somehow dec_SystemInformation will try to decode even non-RR as SI */ var GsmRrMessage rr := dec_GsmRrMessage(l1_dl.payload.data_ind.payload); if (not match(rr, tr_IMM_ASS(42, ?, 5, ?, ?))) { /* FIXME: Why are we seeing paging requests on PCH/AGCH? */ @@ -3936,15 +3935,12 @@ return SystemInformationVectorPerTc { 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); + var SystemInformationFn sig := { frame_number := l1_dl.dl_info.frame_nr }; + if (dec_SystemInformationSafe(l1_dl.payload.data_ind.payload, sig.si) != 0) { + log("Ignoring non-RR or invalid SI ", l1_dl); repeat; } - var SystemInformationFn sig := { - frame_number := l1_dl.dl_info.frame_nr, - si := dec_SystemInformation(l1_dl.payload.data_ind.payload) - } + var integer tc := f_gsm_compute_tc(sig.frame_number); log("SI received at TC=", tc, ": ", sig.si); /* append to the per-TC bucket */ @@ -5227,17 +5223,13 @@ private function f_get_si(L1CTL_PT pt, RrMessageType si_type) runs on test_CT return SystemInformation { var L1ctlDlMessage l1_dl; var SystemInformation si; + var integer rc; 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 (si.header.message_type != si_type) { + rc := dec_SystemInformationSafe(l1_dl.payload.data_ind.payload, si); + if (rc != 0 or si.header.message_type != si_type) { repeat; } } diff --git a/library/GSM_SystemInformation.ttcn b/library/GSM_SystemInformation.ttcn index 3c3d96c26..911358390 100644 --- a/library/GSM_SystemInformation.ttcn +++ b/library/GSM_SystemInformation.ttcn @@ -264,4 +264,29 @@ module GSM_SystemInformation { } } + external function dec_SystemInformationSafeBT(in octetstring stream, out SystemInformation si) + return integer /* Decoding result: successful (0) or unsuccessful (1) */ + with { extension "prototype(backtrack) decode(RAW)" }; + + /* Some types of System Information (mostly the Rest Octets) are not fully implemented, + * so calling the generic dec_SystemInformation() may result in a DTE. This function + * additionally checks RR Protocol Discriminator, and should be used in the most cases. */ + function dec_SystemInformationSafe(in octetstring stream, out SystemInformation si) + return integer { + /* Try to decode a given octetstring as System Information */ + if (dec_SystemInformationSafeBT(stream, si) != 0) { + log("Failed to decode (RR) System Information: ", stream); + return 1; + } + + /* Check the protocol discriminator (we expect RR messages) */ + if (si.header.rr_protocol_discriminator != bit2int('0110'B)) { + log("Protocol discriminator is not RR (!= '0110'B): ", + si.header.rr_protocol_discriminator); + return 1; + } + + return 0; + } + } with { encode "RAW"; variant "FIELDORDER(msb)" }