pcu: Support sending message to PCU at specific FN
Change-Id: I81a29b4885f3fc6b753a1612d5fd369cd18f5dc6
This commit is contained in:
parent
6072725622
commit
65bab9e3bc
|
@ -31,6 +31,16 @@ module RLCMAC_Types {
|
||||||
RRBP_Nplus26_mod_2715648 ('11'B)
|
RRBP_Nplus26_mod_2715648 ('11'B)
|
||||||
} with { variant "FIELDLENGTH(2)" };
|
} with { variant "FIELDLENGTH(2)" };
|
||||||
|
|
||||||
|
function f_rrbp_fn_delay(MacRrbp rrbp) return uint32_t {
|
||||||
|
select (rrbp) {
|
||||||
|
case (RRBP_Nplus13_mod_2715648) { return 13; }
|
||||||
|
case (RRBP_Nplus17_or_18_mod_2715648) { return 17; }
|
||||||
|
case (RRBP_Nplus21_or_22_mod_2715648) { return 21; }
|
||||||
|
case (RRBP_Nplus26_mod_2715648) { return 26; }
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Partof DL RLC data block and DL RLC/MAC ctrl block */
|
/* Partof DL RLC data block and DL RLC/MAC ctrl block */
|
||||||
type record DlMacHeader {
|
type record DlMacHeader {
|
||||||
MacPayloadType payload_type,
|
MacPayloadType payload_type,
|
||||||
|
|
|
@ -228,6 +228,18 @@ private function f_PCUIF_MsgQueue_dequeue(inout PCUIF_MsgQueue queue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get first message from queue. true if non-empty, false otherwise */
|
||||||
|
private function f_PCUIF_MsgQueue_first(inout PCUIF_MsgQueue queue,
|
||||||
|
out PCUIF_Message msg) return boolean
|
||||||
|
{
|
||||||
|
if (lengthof(queue) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := queue[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Multiple base stations can be connected to the PCU. This component
|
/* Multiple base stations can be connected to the PCU. This component
|
||||||
* represents one BTS with an associated TDMA clock generator. */
|
* represents one BTS with an associated TDMA clock generator. */
|
||||||
type component RAW_PCU_BTS_CT {
|
type component RAW_PCU_BTS_CT {
|
||||||
|
@ -250,6 +262,9 @@ type component RAW_PCU_BTS_CT {
|
||||||
var boolean cfg_ptcch_burst_fwd := false;
|
var boolean cfg_ptcch_burst_fwd := false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Queue received messages from Test Case, they will eventually be scheduled and
|
||||||
|
* sent according to their FN. FN value of 0 has the special meaning of "schedule
|
||||||
|
* as soon as possible". */
|
||||||
private altstep as_BTS_CT_MsgQueue(integer bts_nr)
|
private altstep as_BTS_CT_MsgQueue(integer bts_nr)
|
||||||
runs on RAW_PCU_BTS_CT {
|
runs on RAW_PCU_BTS_CT {
|
||||||
var PCUIF_Message pcu_msg;
|
var PCUIF_Message pcu_msg;
|
||||||
|
@ -274,11 +289,14 @@ runs on RAW_PCU_BTS_CT {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle schedule events and manage actions: Send msgs over PCUIF to PCU,
|
||||||
|
* advertise Test Case about sent messages, etc. */
|
||||||
private altstep as_BTS_CT_TDMASched(integer bts_nr)
|
private altstep as_BTS_CT_TDMASched(integer bts_nr)
|
||||||
runs on RAW_PCU_BTS_CT {
|
runs on RAW_PCU_BTS_CT {
|
||||||
var PCUIF_Message pcu_msg;
|
var PCUIF_Message pcu_msg;
|
||||||
var RAW_PCU_Event event;
|
var RAW_PCU_Event event;
|
||||||
var integer ev_begin_fn;
|
var integer ev_begin_fn;
|
||||||
|
var integer next_fn;
|
||||||
|
|
||||||
[] CLCK.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_BEG)) -> value event {
|
[] CLCK.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_BEG)) -> value event {
|
||||||
/* If the RTS queue for PDTCH is not empty, send a message */
|
/* If the RTS queue for PDTCH is not empty, send a message */
|
||||||
|
@ -299,6 +317,17 @@ runs on RAW_PCU_BTS_CT {
|
||||||
[lengthof(pdtch_data_queue) > 0] CLCK.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_END)) -> value event {
|
[lengthof(pdtch_data_queue) > 0] CLCK.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_END)) -> value event {
|
||||||
/* FN matching the beginning of current block: */
|
/* FN matching the beginning of current block: */
|
||||||
ev_begin_fn := event.data.tdma_fn - 3;
|
ev_begin_fn := event.data.tdma_fn - 3;
|
||||||
|
|
||||||
|
/* Check if we reached time to serve the first DATA.ind message in the queue: */
|
||||||
|
f_PCUIF_MsgQueue_first(pdtch_data_queue, pcu_msg);
|
||||||
|
next_fn := pcu_msg.u.data_ind.fn;
|
||||||
|
if (next_fn != 0 and next_fn != ev_begin_fn) {
|
||||||
|
if (next_fn < ev_begin_fn) {
|
||||||
|
setverdict(fail, "We are late scheduling the block! ", next_fn, " < ", ev_begin_fn);
|
||||||
|
mtc.stop;
|
||||||
|
}
|
||||||
|
repeat;
|
||||||
|
}
|
||||||
/* Dequeue a DATA.ind message */
|
/* Dequeue a DATA.ind message */
|
||||||
f_PCUIF_MsgQueue_dequeue(pdtch_data_queue, pcu_msg);
|
f_PCUIF_MsgQueue_dequeue(pdtch_data_queue, pcu_msg);
|
||||||
|
|
||||||
|
|
|
@ -663,13 +663,16 @@ runs on RAW_PCU_Test_CT return boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
|
/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
|
||||||
private function f_pcuif_tx_data_ind(octetstring data, int16_t lqual_cb := 0)
|
private function f_pcuif_tx_data_ind(octetstring data, int16_t lqual_cb := 0, uint32_t fn := 0)
|
||||||
runs on RAW_PCU_Test_CT {
|
runs on RAW_PCU_Test_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(bts_nr := 0, trx_nr := 0, ts_nr := 7, block_nr := 0,
|
||||||
sapi := PCU_IF_SAPI_PDTCH, data := data,
|
sapi := PCU_IF_SAPI_PDTCH, data := data,
|
||||||
fn := 0, arfcn := 871, lqual_cb := lqual_cb));
|
fn := fn, arfcn := 871, lqual_cb := lqual_cb));
|
||||||
BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_SENT));
|
if (fn != 0) {
|
||||||
|
ev_param := {tdma_fn := fn };
|
||||||
|
}
|
||||||
|
BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_SENT, ev_param));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
|
/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
|
||||||
|
@ -700,7 +703,7 @@ runs on RAW_PCU_Test_CT {
|
||||||
fn := 0, arfcn := 871, sapi := PCU_IF_SAPI_PCH, data := macblock));
|
fn := 0, arfcn := 871, sapi := PCU_IF_SAPI_PCH, data := macblock));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function f_tx_rlcmac_ul_block(template (value) RlcmacUlBlock ul_data, int16_t lqual_cb := 0)
|
private function f_tx_rlcmac_ul_block(template (value) RlcmacUlBlock ul_data, int16_t lqual_cb := 0, uint32_t fn := 0)
|
||||||
runs on RAW_PCU_Test_CT {
|
runs on RAW_PCU_Test_CT {
|
||||||
var octetstring data;
|
var octetstring data;
|
||||||
/* Encode the payload of DATA.ind */
|
/* Encode the payload of DATA.ind */
|
||||||
|
@ -708,7 +711,7 @@ runs on RAW_PCU_Test_CT {
|
||||||
data := f_pad_oct(data, 23, '00'O); /* CS-1 */
|
data := f_pad_oct(data, 23, '00'O); /* CS-1 */
|
||||||
|
|
||||||
/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
|
/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
|
||||||
f_pcuif_tx_data_ind(data, lqual_cb);
|
f_pcuif_tx_data_ind(data, lqual_cb, fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function f_tx_rlcmac_ul_n_blocks(PacketUlAssign ul_tbf_ass, integer num_blocks := 1)
|
private function f_tx_rlcmac_ul_n_blocks(PacketUlAssign ul_tbf_ass, integer num_blocks := 1)
|
||||||
|
@ -730,16 +733,19 @@ runs on RAW_PCU_Test_CT {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block)
|
private function f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block, out uint32_t dl_fn)
|
||||||
runs on RAW_PCU_Test_CT {
|
runs on RAW_PCU_Test_CT {
|
||||||
var PCUIF_Message pcu_msg;
|
var PCUIF_Message pcu_msg;
|
||||||
f_pcuif_rx_data_req(pcu_msg);
|
f_pcuif_rx_data_req(pcu_msg);
|
||||||
dl_block := dec_RlcmacDlBlock(pcu_msg.u.data_req.data);
|
dl_block := dec_RlcmacDlBlock(pcu_msg.u.data_req.data);
|
||||||
|
dl_fn := pcu_msg.u.data_req.fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function f_rx_rlcmac_dl_block_exp_ack_nack(out RlcmacDlBlock dl_block)
|
private function f_rx_rlcmac_dl_block_exp_ack_nack(out RlcmacDlBlock dl_block)
|
||||||
runs on RAW_PCU_Test_CT {
|
runs on RAW_PCU_Test_CT {
|
||||||
f_rx_rlcmac_dl_block(dl_block);
|
var uint32_t dl_fn;
|
||||||
|
|
||||||
|
f_rx_rlcmac_dl_block(dl_block, dl_fn);
|
||||||
if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK(ul_tfi := ?, tlli := ?))) {
|
if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK(ul_tfi := ?, tlli := ?))) {
|
||||||
setverdict(fail, "Failed to match Packet Uplink ACK / NACK");
|
setverdict(fail, "Failed to match Packet Uplink ACK / NACK");
|
||||||
mtc.stop;
|
mtc.stop;
|
||||||
|
@ -748,24 +754,30 @@ runs on RAW_PCU_Test_CT {
|
||||||
|
|
||||||
private function f_rx_rlcmac_dl_block_exp_dummy(out RlcmacDlBlock dl_block)
|
private function f_rx_rlcmac_dl_block_exp_dummy(out RlcmacDlBlock dl_block)
|
||||||
runs on RAW_PCU_Test_CT {
|
runs on RAW_PCU_Test_CT {
|
||||||
f_rx_rlcmac_dl_block(dl_block);
|
var uint32_t dl_fn;
|
||||||
|
|
||||||
|
f_rx_rlcmac_dl_block(dl_block, dl_fn);
|
||||||
if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
|
if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
|
||||||
setverdict(fail, "Failed to match Packet DUMMY DL");
|
setverdict(fail, "Failed to match Packet DUMMY DL");
|
||||||
mtc.stop;
|
mtc.stop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function f_rx_rlcmac_dl_block_exp_data(out RlcmacDlBlock dl_block, octetstring data)
|
private function f_rx_rlcmac_dl_block_exp_data(out RlcmacDlBlock dl_block, out uint32_t ack_fn, octetstring data)
|
||||||
runs on RAW_PCU_Test_CT {
|
runs on RAW_PCU_Test_CT {
|
||||||
|
var PCUIF_Message pcu_msg;
|
||||||
|
var uint32_t dl_fn;
|
||||||
var template RlcmacDlBlock dl_template := tr_RLCMAC_DATA_RRBP;
|
var template RlcmacDlBlock dl_template := tr_RLCMAC_DATA_RRBP;
|
||||||
dl_template.data.blocks := ?;
|
dl_template.data.blocks := ?;
|
||||||
|
|
||||||
f_rx_rlcmac_dl_block(dl_block);
|
f_rx_rlcmac_dl_block(dl_block, dl_fn);
|
||||||
if (not match(dl_block, dl_template)) {
|
if (not match(dl_block, dl_template)) {
|
||||||
setverdict(fail, "Failed to match Packet data: ", dl_block, " vs ", dl_template);
|
setverdict(fail, "Failed to match Packet data: ", dl_block, " vs ", dl_template);
|
||||||
mtc.stop;
|
mtc.stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ack_fn := dl_fn + f_rrbp_fn_delay(dl_block.data.mac_hdr.mac_hdr.rrbp);
|
||||||
|
|
||||||
if (lengthof(dl_block.data.blocks) < 1) {
|
if (lengthof(dl_block.data.blocks) < 1) {
|
||||||
setverdict(fail, "DL block has no LLC payload: ", dl_block);
|
setverdict(fail, "DL block has no LLC payload: ", dl_block);
|
||||||
mtc.stop;
|
mtc.stop;
|
||||||
|
@ -1358,6 +1370,7 @@ testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
|
||||||
var PCUIF_Message pcu_msg;
|
var PCUIF_Message pcu_msg;
|
||||||
var octetstring data := f_rnd_octstring(10);
|
var octetstring data := f_rnd_octstring(10);
|
||||||
var boolean ok;
|
var boolean ok;
|
||||||
|
var uint32_t sched_fn;
|
||||||
var OCT4 tlli := '00000001'O;
|
var OCT4 tlli := '00000001'O;
|
||||||
var AckNackDescription ack_nack_desc;
|
var AckNackDescription ack_nack_desc;
|
||||||
|
|
||||||
|
@ -1407,10 +1420,10 @@ testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
|
||||||
|
|
||||||
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
||||||
f_sleep(X2002);
|
f_sleep(X2002);
|
||||||
f_rx_rlcmac_dl_block_exp_data(dl_block, data);
|
f_rx_rlcmac_dl_block_exp_data(dl_block, sched_fn, data);
|
||||||
|
|
||||||
/* ACK the DL block */
|
/* ACK the DL block */
|
||||||
f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(dl_block.data.mac_hdr.hdr_ext.tfi, ack_nack_desc));
|
f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(dl_block.data.mac_hdr.hdr_ext.tfi, ack_nack_desc), 0, sched_fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
control {
|
control {
|
||||||
|
|
Loading…
Reference in New Issue