pcu: Specify (M)CS to use when sending UL rlcmac data blocks
Apply padding and spare bits in the encoder according to CS/MCS format.
Change-Id: I918acac81f550077daeda3374b3de9b426ff3572
diff --git a/pcu/GPRS_Components.ttcn b/pcu/GPRS_Components.ttcn
index 1cbca4c..0f46490 100644
--- a/pcu/GPRS_Components.ttcn
+++ b/pcu/GPRS_Components.ttcn
@@ -432,6 +432,24 @@
return n;
}
+function f_ultbf_payload_fill_length(UlTbf ul_tbf, boolean tlli := false, integer li_bytes := 0)
+runs on MS_BTS_IFACE_CT return uint32_t {
+ var uint32_t blk_len := f_rlcmac_cs_mcs2block_len_no_spare_bits(ul_tbf.tx_cs_mcs);
+ var uint32_t payload_fill_len;
+
+ if (f_rlcmac_cs_mcs_is_mcs(ul_tbf.tx_cs_mcs)) {
+ payload_fill_len := blk_len - 5 - li_bytes;
+ } else {
+ /* GPRS: blk_len = 3 Header bytes + payload length. No LI byte in this case. */
+ payload_fill_len := blk_len - 3 - li_bytes;
+ }
+
+ if (tlli) {
+ payload_fill_len := payload_fill_len - 4;
+ }
+ return payload_fill_len;
+}
+
function f_ms_use_ra(inout GprsMS ms, uint16_t ra, uint8_t ra_is_11bit := 0)
runs on MS_BTS_IFACE_CT {
ms.ra_is_11bit := ra_is_11bit;
@@ -507,53 +525,57 @@
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 {
+runs on MS_BTS_IFACE_CT {
var octetstring data;
- var integer padding_len;
var CodingScheme cs_mcs;
var uint32_t cs_mcs_len;
/* Encode the payload of DATA.ind */
data := enc_RlcmacUlBlock(valueof(ul_data));
- if (ispresent(force_cs_mcs)) {
- cs_mcs := valueof(force_cs_mcs);
- } else if (ischosen(ul_data.ctrl)) {
- cs_mcs := CS_1; /* CTRL is always CS1 */
- } else {
- /* Add padding to encode payload to minimum required CS/MCS: */
- cs_mcs := f_rlcmac_block_len_required_cs_mcs(lengthof(data), ischosen(ul_data.data_egprs));
+ if (ischosen(ul_data.ctrl)) {
+ /* Ctrl blocks are right now encoded by RAW encoder, which was
+ * found to have some issue with final padding, so we add it
+ * here manually. This is actually still incorrect because the
+ * remaining bits of last octet with data are not filled with
+ * the padding sequence, but it's good enough since anyway PCU
+ * don't check these. */
+ data := f_pad_oct(data, f_rlcmac_cs_mcs2block_len(CS_1), '2b'O);
}
-
- cs_mcs_len := f_rlcmac_cs_mcs2block_len(cs_mcs);
- padding_len := cs_mcs_len - lengthof(data);
- if (padding_len < 0) {
- setverdict(fail, "Unable to encode UL block of size ", lengthof(data), " with ", cs_mcs);
- f_shutdown(__BFILE__, __LINE__);
- }
- 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, 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,
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
-runs on MS_BTS_IFACE_CT return integer {
+runs on MS_BTS_IFACE_CT {
var template (value) RlcmacUlBlock ul_data;
- ul_data := t_RLCMAC_UL_DATA(tfi := ms.ul_tbf.tfi,
- cv := cv,
- bsn := ms.ul_tbf.bsn,
- blocks := {t_RLCMAC_LLCBLOCK(payload)});
- if (with_tlli) {
- ul_data.data.mac_hdr.tlli_ind := true;
- ul_data.data.tlli := ms.tlli;
+
+ if (f_rlcmac_cs_mcs_is_mcs(ms.ul_tbf.tx_cs_mcs)) {
+ ul_data := t_RLCMAC_UL_EGPRS_DATA(mcs := ms.ul_tbf.tx_cs_mcs,
+ tfi := ms.ul_tbf.tfi,
+ cv := cv,
+ bsn1 := ms.ul_tbf.bsn,
+ bsn2_offset := 0,
+ blocks := {t_RLCMAC_LLCBLOCK_EGPRS(payload)})
+ if (with_tlli) {
+ ul_data.data_egprs.tlli_ind := true;
+ ul_data.data_egprs.tlli := ms.tlli;
+ }
+ } else {
+ ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
+ tfi := ms.ul_tbf.tfi,
+ cv := cv,
+ bsn := ms.ul_tbf.bsn,
+ blocks := {t_RLCMAC_LLCBLOCK(payload)});
+ if (with_tlli) {
+ ul_data.data.mac_hdr.tlli_ind := true;
+ ul_data.data.tlli := ms.tlli;
+ }
}
f_ultbf_inc_bsn(ms.ul_tbf);
- return f_ms_tx_ul_block(ms, ul_data, fn, nr := nr);
+ 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). */
@@ -561,17 +583,17 @@
template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return octetstring {
var octetstring total_payload := ''O;
+ var uint32_t payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf, with_tlli, 0);
for (var integer i := 0; i < num_blocks; i := i + 1) {
- var integer padding_len;
- var octetstring payload := f_rnd_octstring(10);
+ var octetstring payload := f_rnd_octstring(payload_fill_len);
/* Prepare a new UL block (CV, random payload) */
var integer cv := num_blocks - i - 1;
if (cv > g_bs_cv_max) {
cv := 15;
}
- 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);
+ f_ms_tx_ul_data_block(ms, payload, cv := cv, with_tlli := with_tlli, nr := nr);
+ total_payload := total_payload & payload;
}
return total_payload;
}
diff --git a/pcu/GPRS_TBF.ttcn b/pcu/GPRS_TBF.ttcn
index fb42097..f946f29 100644
--- a/pcu/GPRS_TBF.ttcn
+++ b/pcu/GPRS_TBF.ttcn
@@ -326,10 +326,10 @@
/* include TLLI when needed */
if (tlli_needed) {
- blk := valueof(t_RLCMAC_UL_DATA_TLLI(us.tfi, cv, us.et.v_s,
+ blk := valueof(t_RLCMAC_UL_DATA_TLLI(CS_1, us.tfi, cv, us.et.v_s,
llc_blocks, false, mmctx.tlli));
} else {
- blk := valueof(t_RLCMAC_UL_DATA(us.tfi, cv, us.et.v_s, llc_blocks, false));
+ blk := valueof(t_RLCMAC_UL_DATA(CS_1, us.tfi, cv, us.et.v_s, llc_blocks, false));
}
/* Increment Block Sequence Number */
diff --git a/pcu/PCU_Tests.ttcn b/pcu/PCU_Tests.ttcn
index 8f424ab..f183e4c 100644
--- a/pcu/PCU_Tests.ttcn
+++ b/pcu/PCU_Tests.ttcn
@@ -97,7 +97,7 @@
dl_tbf_ext := 250 * 10, /* ms */
ul_tbf_ext := 250 * 10, /* ms */
initial_cs := 2,
- initial_mcs := 6,
+ initial_mcs := 1,
nsvci := { mp_nsconfig.nsvc[0].nsvci, 0 },
local_port := { mp_nsconfig.nsvc[0].provider.ip.remote_udp_port, 0 },
remote_port := { mp_nsconfig.nsvc[0].provider.ip.local_udp_port, 0 },
@@ -1085,7 +1085,7 @@
/* Send one UL block (with TLLI since we are in One-Phase Access
contention resoultion) and make sure it is ACKED fine. */
- total_payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
+ total_payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
/* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
f_ms_tx_ul_data_block(ms, total_payload, cv := 15, with_tlli := true)
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
@@ -1114,6 +1114,8 @@
var template (value) RlcmacUlBlock ul_data;
var template (value) LlcBlockHdr blk_hdr;
var template (value) LlcBlocks blocks;
+ var integer blk_len;
+ var CodingScheme tx_cs;
var GprsMS ms;
/* Initialize NS/BSSGP side */
@@ -1139,7 +1141,8 @@
more := false, e := true);
blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
/* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
- ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
+ ul_data := t_RLCMAC_UL_DATA_TLLI(cs := ms.ul_tbf.tx_cs_mcs,
+ tfi := ms.ul_tbf.tfi,
cv := 15,
bsn := ms.ul_tbf.bsn,
blocks := blocks,
@@ -1166,12 +1169,15 @@
cv := max_size - i;
}
+ blk_len := 3 + 1 + i; /* 3 Header bytes + LI byte + payload length */
+ tx_cs := f_rlcmac_block_len_required_cs_mcs(blk_len, false);
payload := f_rnd_octstring(i);
blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
more := false, e := true);
blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
/* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
- ul_data := t_RLCMAC_UL_DATA(tfi := ms.ul_tbf.tfi,
+ ul_data := t_RLCMAC_UL_DATA(cs := tx_cs,
+ tfi := ms.ul_tbf.tfi,
cv := cv,
bsn := ms.ul_tbf.bsn,
blocks := blocks);
@@ -1218,7 +1224,8 @@
blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
more := false, e := true);
blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
- ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
+ ul_data := t_RLCMAC_UL_DATA_TLLI(cs := cs,
+ tfi := ms.ul_tbf.tfi,
cv := cv,
bsn := ms.ul_tbf.bsn,
blocks := blocks,
@@ -1368,7 +1375,7 @@
/* Send one UL block (without TLLI since we are in Second-Phase Access)
and make sure it is ACKED fine */
- f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true); /* TODO: send using cs_mcs */
+ f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
@@ -1524,6 +1531,7 @@
var octetstring lost_payload;
var uint5_t tfi;
var GprsMS ms;
+ var uint32_t payload_fill_len;
/* Initialize NS/BSSGP side */
f_init_bssgp();
@@ -1544,7 +1552,7 @@
/* Send one UL block (with TLLI since we are in One-Phase Access
contention resoultion) and make sure it is ACKED fine. */
- payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
+ payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true)); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
f_ms_tx_ul_data_block(ms, payload, cv := 15, with_tlli := true);
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
@@ -1552,20 +1560,22 @@
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
total_payload := payload;
+ payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf);
+
/* Send 2 packets, skip 1 (inc bsn) and send another one */
- payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
+ payload := f_rnd_octstring(payload_fill_len);
f_ms_tx_ul_data_block(ms, payload, cv := 15);
total_payload := total_payload & payload;
- payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
+ payload := f_rnd_octstring(payload_fill_len);
f_ms_tx_ul_data_block(ms, payload, cv := 15);
total_payload := total_payload & payload;
- lost_payload := f_rnd_octstring(20);
+ lost_payload := f_rnd_octstring(payload_fill_len);
ms.ul_tbf.bsn := ms.ul_tbf.bsn + 1; /* LOST PAYLOAD bsn=3, will be retransmitted, next bsn is increased +2 */
total_payload := total_payload & lost_payload;
- payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
+ payload := f_rnd_octstring(payload_fill_len)
f_ms_tx_ul_data_block(ms, payload, cv := 15);
total_payload := total_payload & payload;
@@ -1575,7 +1585,11 @@
/* On CV=0, we'll receive a UL ACK asking about missing block */
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
/* TODO: check ack ack bitmap (URBB) */
- ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 3, blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
+ ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
+ tfi := tfi,
+ cv := 15,
+ bsn := 3,
+ blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
f_ms_tx_ul_block(ms, ul_data);
/* Now final ack is recieved */
@@ -1760,7 +1774,8 @@
*/
/* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
- ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
+ ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
+ tfi := ms.ul_tbf.tfi,
cv := 3,
bsn := ms.ul_tbf.bsn,
blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
@@ -1772,7 +1787,8 @@
f_ms_tx_ul_block(ms, ul_data);
/* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
- ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
+ ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
+ tfi := ms.ul_tbf.tfi,
cv := 2,
bsn := ms.ul_tbf.bsn,
blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
@@ -1787,7 +1803,8 @@
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataA));
/* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
- ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
+ ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
+ tfi := ms.ul_tbf.tfi,
cv := 1,
bsn := ms.ul_tbf.bsn,
blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
@@ -1805,7 +1822,9 @@
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataC));
/* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
- ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
+ ul_data := t_RLCMAC_UL_DATA_TLLI(
+ cs := CS_1,
+ tfi := ms.ul_tbf.tfi,
cv := 0,
bsn := ms.ul_tbf.bsn,
blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),