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
This commit is contained in:
Harald Welte 2018-06-10 21:41:35 +02:00
parent 0aaf48d893
commit e8d750e668
3 changed files with 144 additions and 8 deletions

View File

@ -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
***********************************************************************/

View File

@ -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) := {

View File

@ -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 := ?) := {