pcu/GPRS_Components: allow passing/matching of TS/TRX/BTS/BLK numbers

This change will facilitate adding test cases for multi-slot TBF
allocation across several TS and/or TRX instances of a BTS.

Change-Id: I9bff9e912bf73ad6259946a6ea5b08f3e2f728c8
Related: OS#4756
This commit is contained in:
Vadim Yanitskiy 2020-09-21 04:15:39 +07:00
parent 09f1c6da7d
commit 4b7473d99c
1 changed files with 84 additions and 39 deletions

View File

@ -44,6 +44,32 @@ import from IPL4asp_Types all;
import from Native_Functions all;
import from SGSN_Components all;
type record TsTrxBtsNum {
uint3_t ts_nr,
uint3_t trx_nr,
uint8_t bts_nr,
uint8_t blk_nr
};
template (value) TsTrxBtsNum ts_TsTrxBtsNum(uint3_t ts_nr := 7,
uint3_t trx_nr := 0,
uint8_t bts_nr := 0,
uint8_t blk_nr := 0) := {
ts_nr := ts_nr,
trx_nr := trx_nr,
bts_nr := bts_nr,
blk_nr := blk_nr
};
template TsTrxBtsNum tr_TsTrxBtsNum(template uint3_t ts_nr := ?,
template uint3_t trx_nr := ?,
template uint8_t bts_nr := ?,
template uint8_t blk_nr := ?) := {
ts_nr := ts_nr,
trx_nr := trx_nr,
bts_nr := bts_nr,
blk_nr := blk_nr
};
type union PacketDlAssignChan {
PacketDlAssign ccch,
PacketDlAssignment pacch
@ -281,12 +307,13 @@ runs on MS_BTS_IFACE_CT {
}
function f_ms_rx_pkt_ass_pacch(inout GprsMS ms, out uint32_t poll_fn,
template RlcmacDlBlock t_pkt_ass := ?)
template RlcmacDlBlock t_pkt_ass := ?,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return RlcmacDlBlock {
var RlcmacDlBlock dl_block;
var uint32_t dl_fn;
f_rx_rlcmac_dl_block(dl_block, dl_fn);
f_rx_rlcmac_dl_block(dl_block, dl_fn, nr := nr);
if (not match(dl_block, t_pkt_ass)) {
setverdict(fail, "Failed to match Packet Assignment:", t_pkt_ass);
f_shutdown(__BFILE__, __LINE__);
@ -311,30 +338,34 @@ runs on MS_BTS_IFACE_CT return RlcmacDlBlock {
return dl_block;
}
function f_ms_establish_ul_tbf(inout GprsMS ms)
function f_ms_establish_ul_tbf(inout GprsMS ms, template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
var GsmRrMessage rr_imm_ass;
rr_imm_ass := f_pcuif_tx_rach_rx_imm_ass(ms.ra, ms.ra_is_11bit, ms.burst_type, ms.ta);
rr_imm_ass := f_pcuif_tx_rach_rx_imm_ass(ms.ra, ms.ra_is_11bit, ms.burst_type, ms.ta, nr := nr);
ms.ul_tbf := f_ultbf_new_from_rr_imm_ass(rr_imm_ass);
}
function f_ms_exp_dl_tbf_ass_ccch(inout GprsMS ms, template PCUIF_Sapi sapi := PCU_IF_SAPI_AGCH,
template GsmRrMessage t_imm_ass := tr_IMM_TBF_ASS(true, ?, ?))
template GsmRrMessage t_imm_ass := tr_IMM_TBF_ASS(true, ?, ?),
template (present) TsTrxBtsNum nr := tr_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
var GsmRrMessage rr_imm_ass;
rr_imm_ass := f_pcuif_rx_imm_ass(sapi, t_imm_ass);
rr_imm_ass := f_pcuif_rx_imm_ass(sapi, t_imm_ass, nr := nr);
ms.dl_tbf := f_dltbf_new_from_rr_imm_ass(rr_imm_ass, tr_PacketDlAssign(ms.tlli));
}
/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
function f_ms_tx_data_ind(inout GprsMS ms, octetstring data, uint32_t fn := 0)
function f_ms_tx_data_ind(inout GprsMS ms, octetstring data, uint32_t fn := 0,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
f_pcuif_tx_data_ind(data, ms.lqual_cb, fn);
f_pcuif_tx_data_ind(data, ms.lqual_cb, fn, nr := nr);
}
function f_ms_tx_ul_block(inout GprsMS ms, template (value) RlcmacUlBlock ul_data, uint32_t fn := 0, template (omit) CodingScheme force_cs_mcs := omit)
function f_ms_tx_ul_block(inout GprsMS ms, template (value) RlcmacUlBlock ul_data,
uint32_t fn := 0, template (omit) CodingScheme force_cs_mcs := omit,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return integer {
var octetstring data;
var integer padding_len;
@ -362,12 +393,14 @@ runs on MS_BTS_IFACE_CT return integer {
data := f_pad_oct(data, cs_mcs_len, '00'O);
/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
f_ms_tx_data_ind(ms, data, fn);
f_ms_tx_data_ind(ms, data, fn, nr := nr);
return padding_len;
}
/* FIXME: Only supports sending CS-1 so far */
function f_ms_tx_ul_data_block(inout GprsMS ms, octetstring payload, uint4_t cv := 15, boolean with_tlli := false, uint32_t fn := 0)
function f_ms_tx_ul_data_block(inout GprsMS ms, octetstring payload,
uint4_t cv := 15, boolean with_tlli := false, uint32_t fn := 0,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return integer {
var template (value) RlcmacUlBlock ul_data;
ul_data := t_RLCMAC_UL_DATA(tfi := ms.ul_tbf.tfi,
@ -379,11 +412,12 @@ runs on MS_BTS_IFACE_CT return integer {
ul_data.data.tlli := ms.tlli;
}
f_ultbf_inc_bsn(ms.ul_tbf);
return f_ms_tx_ul_block(ms, ul_data, fn);
return f_ms_tx_ul_block(ms, ul_data, fn, nr := nr);
}
/* Send random payload for last "num_blocks" blocks in Ul TBF (ending with CV=0). */
function f_ms_tx_ul_data_block_multi(inout GprsMS ms, integer num_blocks := 1, boolean with_tlli := false)
function f_ms_tx_ul_data_block_multi(inout GprsMS ms, integer num_blocks := 1, boolean with_tlli := false,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return octetstring {
var octetstring total_payload := ''O;
@ -395,7 +429,7 @@ runs on MS_BTS_IFACE_CT return octetstring {
if (cv > g_bs_cv_max) {
cv := 15;
}
padding_len := f_ms_tx_ul_data_block(ms, payload, cv := cv, with_tlli := with_tlli)
padding_len := f_ms_tx_ul_data_block(ms, payload, cv := cv, with_tlli := with_tlli, nr := nr);
total_payload := total_payload & payload & f_pad_oct(''O, padding_len, '00'O);
}
return total_payload;
@ -494,11 +528,12 @@ runs on MS_BTS_IFACE_CT {
}
////////////////////////
// OLD APIs
// Low level APIs
////////////////////////
function f_pcuif_rx_imm_ass(template PCUIF_Sapi sapi := PCU_IF_SAPI_AGCH,
template GsmRrMessage t_imm_ass := ?)
template GsmRrMessage t_imm_ass := ?,
template (present) TsTrxBtsNum nr := tr_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return GsmRrMessage {
var GsmRrMessage rr_imm_ass;
var PCUIF_Message pcu_msg;
@ -507,7 +542,7 @@ runs on MS_BTS_IFACE_CT return GsmRrMessage {
T.start(2.0);
alt {
[] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,
[] BTS.receive(tr_PCUIF_DATA_REQ(nr.bts_nr, nr.trx_nr, ts_nr := 0,
sapi := sapi, data := ?)) -> value pcu_msg {
/* On PCH the payload is prefixed with paging group (3 octets): skip it.
* TODO: add an additional template parameter, so we can match it. */
@ -549,7 +584,8 @@ const BIT8 chan_req_def := '01111000'B;
function f_pcuif_tx_rach_rx_imm_ass(uint16_t ra := bit2int(chan_req_def),
uint8_t is_11bit := 0,
PCUIF_BurstType burst_type := BURST_TYPE_0,
TimingAdvance ta := 0)
TimingAdvance ta := 0,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return GsmRrMessage {
var uint32_t fn;
@ -558,7 +594,7 @@ runs on MS_BTS_IFACE_CT return GsmRrMessage {
/* Send RACH.ind */
log("Sending RACH.ind on fn=", fn, " with RA=", ra, ", TA=", ta);
BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
BTS.send(ts_PCUIF_RACH_IND(nr.bts_nr, nr.trx_nr, ts_nr := 0,
ra := ra, is_11bit := is_11bit,
burst_type := burst_type,
fn := fn, arfcn := 871,
@ -569,15 +605,16 @@ runs on MS_BTS_IFACE_CT return GsmRrMessage {
* we assume that 11 bit RA always contains EGPRS Packet Channel Request. */
if (is_11bit != 0) { ra := 127; }
/* Expect Immediate (TBF) Assignment on TS0/AGCH */
return f_pcuif_rx_imm_ass(PCU_IF_SAPI_AGCH, tr_IMM_TBF_ASS(false, ra, fn));
/* Expect Immediate (TBF) Assignment on the same TS/TRX/BTS */
return f_pcuif_rx_imm_ass(PCU_IF_SAPI_AGCH, tr_IMM_TBF_ASS(false, ra, fn), nr);
}
/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
function f_pcuif_tx_data_ind(octetstring data, int16_t lqual_cb := 0, uint32_t fn := 0)
function f_pcuif_tx_data_ind(octetstring data, int16_t lqual_cb := 0, uint32_t fn := 0,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
var template RAW_PCU_EventParam ev_param := {tdma_fn := ? };
BTS.send(ts_PCUIF_DATA_IND(bts_nr := 0, trx_nr := 0, ts_nr := 7, block_nr := 0,
BTS.send(ts_PCUIF_DATA_IND(nr.bts_nr, nr.trx_nr, nr.ts_nr, nr.blk_nr,
sapi := PCU_IF_SAPI_PDTCH, data := data,
fn := fn, arfcn := 871, lqual_cb := lqual_cb));
if (fn != 0) {
@ -587,18 +624,20 @@ runs on MS_BTS_IFACE_CT {
}
/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
function f_pcuif_rx_data_req(out PCUIF_Message pcu_msg)
function f_pcuif_rx_data_req(out PCUIF_Message pcu_msg,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
arfcn := 871, block_nr := 0));
BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
arfcn := 871, block_nr := nr.blk_nr));
BTS.receive(tr_PCUIF_DATA_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
sapi := PCU_IF_SAPI_PDTCH)) -> value pcu_msg;
}
/* Expect a Paging Request Type 1 from PCU on PCUIF on specified sapi. */
function f_pcuif_rx_pch_pag_req1(template MobileIdentityV mi1 := ?,
template integer pag_group := ?)
template integer pag_group := ?,
template (present) TsTrxBtsNum nr := tr_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return GsmRrMessage {
var GsmRrMessage rr_pag_req1;
var PCUIF_Message pcu_msg;
@ -606,7 +645,7 @@ runs on MS_BTS_IFACE_CT return GsmRrMessage {
var integer pag_group_rx;
var octetstring macblock;
BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,
BTS.receive(tr_PCUIF_DATA_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;
/* First 3 bytes contain IMSI suffix to calculate paging group: */
@ -633,10 +672,12 @@ runs on MS_BTS_IFACE_CT return GsmRrMessage {
return rr_pag_req1;
}
function f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block, out uint32_t dl_fn, template (present) CodingScheme exp_cs_mcs := ?)
function f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block, out uint32_t dl_fn,
template (present) CodingScheme exp_cs_mcs := ?,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
var PCUIF_Message pcu_msg;
f_pcuif_rx_data_req(pcu_msg);
f_pcuif_rx_data_req(pcu_msg, nr := nr);
dl_block := dec_RlcmacDlBlock(pcu_msg.u.data_req.data);
dl_fn := pcu_msg.u.data_req.fn;
@ -650,11 +691,12 @@ runs on MS_BTS_IFACE_CT {
function f_rx_rlcmac_dl_block_exp_ack_nack(out RlcmacDlBlock dl_block, out uint32_t poll_fn,
template RlcmacDlBlock acknack_tmpl := (tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?),
tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?)))
tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?)),
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
var uint32_t dl_fn;
f_rx_rlcmac_dl_block(dl_block, dl_fn);
f_rx_rlcmac_dl_block(dl_block, dl_fn, nr := nr);
if (match(dl_block, acknack_tmpl)) {
poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
return;
@ -663,22 +705,24 @@ runs on MS_BTS_IFACE_CT {
f_shutdown(__BFILE__, __LINE__);
}
function f_rx_rlcmac_dl_block_exp_dummy(out RlcmacDlBlock dl_block)
function f_rx_rlcmac_dl_block_exp_dummy(out RlcmacDlBlock dl_block,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
var uint32_t dl_fn;
f_rx_rlcmac_dl_block(dl_block, dl_fn);
f_rx_rlcmac_dl_block(dl_block, dl_fn, nr := nr);
if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
setverdict(fail, "Failed to match Packet DUMMY DL");
f_shutdown(__BFILE__, __LINE__);
}
}
function f_rx_rlcmac_dl_block_exp_pkt_pag_req(out RlcmacDlBlock dl_block)
function f_rx_rlcmac_dl_block_exp_pkt_pag_req(out RlcmacDlBlock dl_block,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
var uint32_t dl_fn;
f_rx_rlcmac_dl_block(dl_block, dl_fn);
f_rx_rlcmac_dl_block(dl_block, dl_fn, nr := nr);
if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {
setverdict(fail, "Failed to match Packet Paging Request: ", dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());
f_shutdown(__BFILE__, __LINE__);
@ -754,13 +798,14 @@ runs on MS_BTS_IFACE_CT {
function f_rx_rlcmac_dl_block_exp_data(out RlcmacDlBlock dl_block, out uint32_t dl_fn,
template (present) octetstring data := ?,
template (present) uint7_t exp_bsn := ?,
template (present) CodingScheme exp_cs := ?)
template (present) CodingScheme exp_cs := ?,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
/* FIXME: ideally we should use an alt statement with timeout here, rather than
* having +100500 layers of abstraction. This would facilitate developing the
* multi-TBF/-TRX/-BTS tests, where you cannot expect that the first received
* block is exactly what you need. */
f_rx_rlcmac_dl_block(dl_block, dl_fn);
f_rx_rlcmac_dl_block(dl_block, dl_fn, nr := nr);
/* Make sure it's either GPRS or EGPRS data block */
if (not match(dl_block, tr_RLCMAC_DATA)) {