From e8d750e6686261f98203a0e102f48840c539a3e6 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 10 Jun 2018 21:41:35 +0200 Subject: [PATCH] bts: More complete AGCH / IMM.ASS testing The existing test simply sent 1000 messages via RSL without checking what actually arrived on the radio interface, or without expecting/counting any RSL DELETE IND. Let's fix this by introducing test sending IMM.ASS at three different rates, with related expectations in terms of nubmer of IMM.ASS arriving on Um vs. RSL DELETE IND arriving at BSC. Change-Id: Ib6043b76ba1d7aaff107bb612f63b5a747d8720c Related: OS#2990 Related: SYS#2695 --- bts/BTS_Tests.ttcn | 96 ++++++++++++++++++++++++++++++++++++--- library/GSM_RR_Types.ttcn | 47 ++++++++++++++++++- library/RSL_Types.ttcn | 9 ++++ 3 files changed, 144 insertions(+), 8 deletions(-) diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn index 25ee3a239..5f715380a 100644 --- a/bts/BTS_Tests.ttcn +++ b/bts/BTS_Tests.ttcn @@ -1769,20 +1769,102 @@ testcase TC_paging_tmsi_200percent() runs on test_CT { /*********************************************************************** * Immediate Assignment / AGCH ***********************************************************************/ +const MobileAllocation c_MA_null := { + len := 0, + ma := ''B +} + +template (value) ChannelDescription ts_ChanDesc(template (value) RslChannelNr chan_nr, uint3_t tsc := 7, + uint12_t arfcn := 871) := { + chan_nr := chan_nr, + tsc := tsc, + h := false, + arfcn := arfcn, + maio_hsn := omit +} + +private function f_fmt_ia_stats(integer num_tx, integer num_rx, integer num_del) return charstring { + return int2str(num_tx) & " sent, " + & int2str(num_rx) & " received, " + & int2str(num_del) & " deleted"; +} + +private function f_TC_imm_ass(integer num_total, float sleep_s, float exp_pass) runs on test_CT { + var L1ctlDlMessage l1_dl; + timer T := 10.0; + var integer num_tx := 0; + var integer num_rx := 0; + var integer num_del := 0; + var charstring res_str; + var float rx_ratio; -testcase TC_imm_ass() runs on test_CT { f_init(testcasename()); - for (var integer i := 0; i < 1000; i := i+1) { - var octetstring ia_enc := f_rnd_octstring(8); + f_init_l1ctl(); + f_l1_tune(L1CTL); + + for (var integer i := 0; i < num_total; i := i+1) { + var ChannelDescription ch_desc := valueof(ts_ChanDesc(valueof(t_RslChanNr_SDCCH4(0, 0)))); + var GsmRrMessage ia := valueof(ts_IMM_ASS(42, i, 5, ch_desc, c_MA_null)); + var octetstring ia_enc := enc_GsmRrMessage(ia); RSL_CCHAN.send(ts_RSL_UD(ts_RSL_IMM_ASSIGN(ia_enc, 0))); - f_sleep(0.02); + num_tx := num_tx+1; + f_sleep(sleep_s); } /* FIXME: check if imm.ass arrive on Um side */ - /* FIXME: check for DELETE INDICATION */ - f_sleep(100.0); - f_shutdown(); + T.start; + alt { + [] RSL_CCHAN.receive(tr_RSL_UD(tr_RSL_DELETE_IND(?, 0))) { + num_del := num_del+1; + repeat; + } + [] RSL_CCHAN.receive { + 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? */ + //setverdict(fail, "Unexpected IMM-ASS values on AGCH: ", rr); + //self.stop; + } else { + num_rx := num_rx+1; + } + repeat; + } + [] L1CTL.receive { repeat; } + [] T.timeout { } + } + res_str := f_fmt_ia_stats(num_tx, num_rx, num_del); + log("AGCH test: " & res_str); + if (num_rx + num_del != num_tx) { + setverdict(fail, "RX + DEL != TX ?!?: " & res_str); + } + rx_ratio := int2float(num_rx) / int2float(num_tx); + if (rx_ratio < exp_pass*0.8 or rx_ratio > exp_pass*1.2) { + setverdict(fail, "RX ratio ("&float2str(rx_ratio)&") far from expected ("&float2str(exp_pass)&") " & res_str); + } else { + setverdict(pass); + } } +/* send a long burst of 1000 IMM.ASS with 20ms spacing (50 per s); expect 75% of them to be deleted */ +testcase TC_imm_ass_1000_20ms() runs on test_CT { + f_TC_imm_ass(1000, 0.02, 0.25); +} + +/* send a short burst of 200 IMM.ASS without any spacing; expect 95% of them to be deleted */ +testcase TC_imm_ass_200_0ms() runs on test_CT { + f_TC_imm_ass(200, 0.0, 0.05); +} + +/* send 150 IMM.ASS at rate of 13/s; expect none of them to be deleted */ +testcase TC_imm_ass_200_76ms() runs on test_CT { + f_TC_imm_ass(150, 0.076, 1.00); +} + + + /*********************************************************************** * BCCH ***********************************************************************/ diff --git a/library/GSM_RR_Types.ttcn b/library/GSM_RR_Types.ttcn index 2ceb1f81a..ef209e455 100644 --- a/library/GSM_RR_Types.ttcn +++ b/library/GSM_RR_Types.ttcn @@ -357,6 +357,26 @@ module GSM_RR_Types { req_ref.t3 := fn mod 51; return req_ref } + function tr_compute_ReqRef(template uint8_t ra, template GsmFrameNumber fn) + return template RequestReference { + var template RequestReference req_ref; + if (istemplatekind(ra, "?")) { + req_ref.ra := ?; + } else { + req_ref.ra := int2bit(valueof(ra), 8); + } + if (istemplatekind(fn, "?")) { + req_ref.t1p := ?; + req_ref.t2 := ?; + req_ref.t3 := ?; + } else { + var GsmFrameNumber fn_v := valueof(fn); + req_ref.t1p := (fn_v / 1326) mod 32; + req_ref.t2 := fn_v mod 26; + req_ref.t3 := fn_v mod 51; + } + return req_ref; + } /* 10.5.2.40 */ type integer TimingAdvance (0..219); @@ -674,7 +694,7 @@ module GSM_RR_Types { with { extension "prototype(convert) decode(RAW)" }; - template GsmRrMessage ts_IMM_ASS(uint8_t ra, GsmFrameNumber fn, TimingAdvance ta, + template (value) GsmRrMessage ts_IMM_ASS(uint8_t ra, GsmFrameNumber fn, TimingAdvance ta, ChannelDescription ch_desc, MobileAllocation ma) := { header := t_RrHeader(IMMEDIATE_ASSIGNMENT, 0), payload := { @@ -696,6 +716,31 @@ module GSM_RR_Types { } }; + template GsmRrMessage tr_IMM_ASS(template uint8_t ra := ?, template GsmFrameNumber fn := ?, + template TimingAdvance ta := ?, + template ChannelDescription ch_desc := ?, + template MobileAllocation ma := ?) := { + header := t_RrHeader(IMMEDIATE_ASSIGNMENT, 0), + payload := { + imm_ass := { + ded_or_tbf := { + spare := '0'B, + tma := false, + downlink := false, + tbf := false + }, + page_mode := PAGE_MODE_NORMAL, + chan_desc := ch_desc, + pkt_chan_desc := omit, + req_ref := tr_compute_ReqRef(ra, fn), + timing_advance := ta, + mobile_allocation := ma, + rest_octets := * + } + } + }; + + template (value) GsmRrL3Message ts_MEAS_REP(boolean valid, uint6_t rxl_f, uint6_t rxl_s, uint3_t rxq_f, uint3_t rxq_s, template (omit) NcellReports reps) := { diff --git a/library/RSL_Types.ttcn b/library/RSL_Types.ttcn index b81bbbd94..3804d403a 100644 --- a/library/RSL_Types.ttcn +++ b/library/RSL_Types.ttcn @@ -1394,6 +1394,15 @@ template RSL_Message tr_RSL_MsgTypeDR(template RSL_MessageType msg_type) modifie t_RSL_IE(RSL_IE_FULL_IMM_ASS_INFO, RSL_IE_Body:{full_imm_ass_info := ts_RSL_LV(imm_ass)}) } } + template RSL_Message tr_RSL_DELETE_IND(template octetstring imm_ass := ?, template uint3_t tn) := { + msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false), + msg_type := RSL_MT_DELETE_IND, + ies := { + tr_RSL_IE(RSL_IE_Body:{chan_nr := t_RslChanNr_PCH_AGCH(tn)}), + tr_RSL_IE(RSL_IE_Body:{full_imm_ass_info := tr_RSL_LV(imm_ass)}), + * + } + } /* 8.5.5 BSC -> BTS */ template RSL_Message tr_RSL_PAGING_CMD(template octetstring identity, template uint3_t tn := ?) := {