BTS_Tests.ttcn: add a test case for PTCCH/D and PTCCH/U
This test case is aimed to verify handling of both PTCCH/U and PTCCH/D logical channels, recently implemented in [1]. This is done by sending 16 Access Bursts on PTCCH/U, and then by sending a random data block on PTCCH/D. The existing TC_pcu_data_req_ptcch does not cover PTCCH/U, and moreover involves TBF handling which has nothing to do with PTCCH. Let's keep it anyway. [1] I232e5f514fbad2c51daaa59ff516004aba97c8a3 Change-Id: I011ffdfa63b698ce6085968d15ffb4ff4bd23ee5 Related: OS#4102
This commit is contained in:
parent
20f8700767
commit
8c242f041a
|
@ -4143,6 +4143,7 @@ testcase TC_pcu_data_req_pdtch() runs on test_CT {
|
|||
f_pcu_to_l1(0, 0, 7, PCU_IF_SAPI_PDTCH, data); //c_PCU_DATA);
|
||||
}
|
||||
|
||||
/* FIXME: PTTCH has nothing to do with TBFs */
|
||||
testcase TC_pcu_data_req_ptcch() runs on test_CT {
|
||||
var TfiUsfArr tua := f_TfiUsfArrInit();
|
||||
var octetstring data := '0000'O & f_rnd_octstring(21);
|
||||
|
@ -4157,6 +4158,94 @@ testcase TC_pcu_data_req_ptcch() runs on test_CT {
|
|||
f_pcu_to_l1(0, 0, 7, PCU_IF_SAPI_PTCCH, data);
|
||||
}
|
||||
|
||||
private function f_TC_pcu_ptcch_ul(uint16_t ra)
|
||||
runs on test_CT {
|
||||
var template PCUIF_Message pcu_rach_ind;
|
||||
var PCUIF_send_data sd;
|
||||
var GsmFrameNumber fn;
|
||||
timer T;
|
||||
|
||||
/* Send an Access Burst on PTCCH/U over the Um-interface */
|
||||
fn := f_L1CTL_RACH(L1CTL, ra := ra, combined := 0, offset := 0,
|
||||
chan_nr := ts_RslChanNr_PDCH(7),
|
||||
link_id := ts_RslLinkID_OSMO_PTCCH(0));
|
||||
|
||||
/* TODO: check time-slot and TRX number as soon as we extend the PCU interface */
|
||||
pcu_rach_ind := tr_PCUIF_RACH_IND(ra := ra, fn := fn, sapi := PCU_IF_SAPI_PTCCH);
|
||||
|
||||
/* Expect a RACH.ind on the PCU interface (timeout is one multi-frame) */
|
||||
T.start(52.0 * 4.615 / 1000.0);
|
||||
alt {
|
||||
[] PCU.receive(t_SD_PCUIF(g_pcu_conn_id, pcu_rach_ind)) -> value sd {
|
||||
log("Rx an Access Burst on the PCU interface: ", sd.data);
|
||||
setverdict(pass);
|
||||
T.stop;
|
||||
}
|
||||
[] PCU.receive { repeat; }
|
||||
[] T.timeout {
|
||||
setverdict(fail, "Timeout waiting for RACH.ind on the PCU interface");
|
||||
/* Keep going, that's not the end of the world */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testcase TC_pcu_ptcch() runs on test_CT {
|
||||
var L1ctlDlMessage dl;
|
||||
var octetstring data;
|
||||
timer T;
|
||||
|
||||
f_init_pcu_test();
|
||||
f_init_l1ctl();
|
||||
f_l1_tune(L1CTL);
|
||||
|
||||
/* Activate PDCH channel on TS7 */
|
||||
f_TC_pcu_act_req(0, 0, 7, true);
|
||||
|
||||
/* Tune trxcon to that PDCH channel */
|
||||
L1CTL.send(ts_L1CTL_DM_EST_REQ(arfcn := { false, mp_trx0_arfcn },
|
||||
chan_nr := valueof(ts_RslChanNr_PDCH(7)),
|
||||
tsc := 7));
|
||||
|
||||
/* Verify PTCCH/U: send several access bursts, make sure they're received */
|
||||
for (var integer i := 0; i < 16; i := i + 1) {
|
||||
log("Sending an Access Burst towards the L1CTL interface");
|
||||
f_TC_pcu_ptcch_ul(oct2int(f_rnd_ra_ps()));
|
||||
}
|
||||
|
||||
/* Generate a random payload for PTCCH/D (23 octets, CS-1) */
|
||||
data := f_rnd_octstring(23);
|
||||
|
||||
/* Verify PTCCH/D: send a random data block, make sure it's received */
|
||||
log("Sending a PTCCH/D block towards the PCU interface: ", data);
|
||||
f_pcu_wait_rts_and_data_req(0, 0, 7, PCU_IF_SAPI_PTCCH, data);
|
||||
|
||||
/* PTCCH/D period is 2 multi-frames (2 * 52 * 4.615 ms), but
|
||||
* let's give it more time in case if we miss the beginning. */
|
||||
T.start(2.0 * 2.0 * 52.0 * 4.615 / 1000.0);
|
||||
alt {
|
||||
/* PDCH is considered as traffic in trxcon => expect TRAFFIC.ind */
|
||||
[] L1CTL.receive(tr_L1CTL_TRAFFIC_IND(chan_nr := t_RslChanNr_PDCH(7),
|
||||
link_id := tr_RslLinkID_OSMO_PTCCH(?),
|
||||
frame := data)) -> value dl {
|
||||
log("Rx PTCCH/D data (traffic) block on L1CTL: ", dl);
|
||||
setverdict(pass);
|
||||
T.stop;
|
||||
}
|
||||
/* Other PHYs (e.g. virt_phy) may consider PDCH as data => expect DATA.ind */
|
||||
[] L1CTL.receive(tr_L1CTL_DATA_IND(chan_nr := t_RslChanNr_PDCH(7),
|
||||
link_id := tr_RslLinkID_OSMO_PTCCH(?),
|
||||
l2_data := data)) -> value dl {
|
||||
log("Rx PTCCH/D data block on L1CTL: ", dl);
|
||||
setverdict(pass);
|
||||
T.stop;
|
||||
}
|
||||
[] L1CTL.receive { repeat; }
|
||||
[] T.timeout {
|
||||
setverdict(fail, "Timeout waiting for DATA.ind on L1CTL");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Send AGCH from PCU; check it appears on Um side */
|
||||
testcase TC_pcu_data_req_agch() runs on test_CT {
|
||||
timer T := 3.0;
|
||||
|
@ -6267,6 +6356,7 @@ control {
|
|||
execute( TC_pcu_deact_req_wrong_ts() );
|
||||
execute( TC_pcu_ver_si13() );
|
||||
if (mp_l1_supports_gprs) {
|
||||
execute( TC_pcu_ptcch() );
|
||||
execute( TC_pcu_data_req_pdtch() );
|
||||
execute( TC_pcu_data_req_ptcch() );
|
||||
execute( TC_pcu_data_req_wrong_bts() );
|
||||
|
|
|
@ -158,7 +158,8 @@ module GSM_Types {
|
|||
/* TS 48.058 9.3.2 Link ID */
|
||||
type enumerated RslLinkIdC {
|
||||
FACCH_SDCCH (0),
|
||||
SACCH (1)
|
||||
SACCH (1),
|
||||
OSMO_PTCCH (2) /* Osmocom (trxcon) specific extension */
|
||||
} with { variant "FIELDLENGTH(2)" };
|
||||
|
||||
type enumerated RslSapi0Prio {
|
||||
|
@ -195,6 +196,12 @@ module GSM_Types {
|
|||
sapi := sapi
|
||||
};
|
||||
|
||||
template RslLinkId tr_RslLinkID_OSMO_PTCCH(template GsmSapi sapi) modifies tr_RslLinkId := {
|
||||
c := OSMO_PTCCH,
|
||||
na := false,
|
||||
sapi := sapi
|
||||
};
|
||||
|
||||
template (value) RslLinkId ts_RslLinkID_DCCH(GsmSapi sapi) := {
|
||||
c := FACCH_SDCCH,
|
||||
na := false,
|
||||
|
@ -209,6 +216,13 @@ module GSM_Types {
|
|||
sapi := sapi
|
||||
};
|
||||
|
||||
template (value) RslLinkId ts_RslLinkID_OSMO_PTCCH(GsmSapi sapi) := {
|
||||
c := OSMO_PTCCH,
|
||||
na := false,
|
||||
prio := SAPI0_PRIO_NORMAL,
|
||||
sapi := sapi
|
||||
};
|
||||
|
||||
function f_hex_is_odd_length(hexstring digits) return bitstring {
|
||||
if (lengthof(digits) rem 2 == 1) {
|
||||
return '1'B;
|
||||
|
|
Loading…
Reference in New Issue