pcu: Introduce test TC_ul_flow_multiple_llc_blocks
Related: OS#4559
Change-Id: I62f42981d31bc5c2e4c61e92bea329bd74cb2d19
diff --git a/pcu/PCU_Tests.ttcn b/pcu/PCU_Tests.ttcn
index bdcf7c1..ef689e2 100644
--- a/pcu/PCU_Tests.ttcn
+++ b/pcu/PCU_Tests.ttcn
@@ -1333,6 +1333,110 @@
f_shutdown(__BFILE__, __LINE__, final := true);
}
+/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
+ * Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
+ * Check "3GPP TS 44.060" Annex B. */
+testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
+ var RlcmacDlBlock dl_block;
+ var octetstring dataA := f_rnd_octstring(20);
+ var octetstring dataB := f_rnd_octstring(13);
+ var octetstring dataC := f_rnd_octstring(3);
+ var octetstring dataD := f_rnd_octstring(12);
+ var uint32_t sched_fn;
+ var GprsMS ms;
+ var template (value) RlcmacUlBlock ul_data;
+
+ /* Initialize NS/BSSGP side */
+ f_init_bssgp();
+ /* Initialize GPRS MS side */
+ f_init_gprs_ms();
+ ms := g_ms[0]; /* We only use first MS in this test */
+
+ /* Initialize the PCU interface abstraction */
+ f_init_raw(testcasename());
+
+ /* Establish BSSGP connection to the PCU */
+ f_bssgp_establish();
+ f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
+
+ /* Establish an Uplink TBF */
+ f_ms_establish_ul_tbf(ms);
+
+ /* Summary of what's transmitted:
+ * 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
+ * 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
+ * 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
+ * 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
+ * And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
+ * We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
+ */
+
+ /* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
+ ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
+ cv := 3,
+ bsn := ms.ul_tbf.bsn,
+ blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
+ tlli := ms.tlli);
+ /* Indicate no llc header, meaning first LLC block doesn't finish in current
+ * RLCMAC block being sent. */
+ ul_data.data.mac_hdr.e := true;
+ f_ultbf_inc_bsn(ms.ul_tbf);
+ 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,
+ cv := 2,
+ bsn := ms.ul_tbf.bsn,
+ blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
+ t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
+ t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
+ },
+ tlli := ms.tlli);
+ f_ultbf_inc_bsn(ms.ul_tbf);
+ f_ms_tx_ul_block(ms, ul_data);
+
+ /* UL block dataA should be received in SGSN */
+ BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.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,
+ cv := 1,
+ bsn := ms.ul_tbf.bsn,
+ blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
+ t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
+ t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
+ t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
+ t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
+ },
+ tlli := ms.tlli);
+ f_ultbf_inc_bsn(ms.ul_tbf);
+ f_ms_tx_ul_block(ms, ul_data);
+
+ /* UL block dataB and dataC should be received in SGSN */
+ BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, dataB));
+ BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, dataC));
+
+ /* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
+ ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
+ cv := 0,
+ bsn := ms.ul_tbf.bsn,
+ blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
+ t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
+ },
+ tlli := ms.tlli);
+ f_ultbf_inc_bsn(ms.ul_tbf);
+ f_ms_tx_ul_block(ms, ul_data);
+
+ /* UL block dataB and dataD should be received in SGSN */
+ BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, dataD));
+
+ f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
+ /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
+ f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
+
+ f_shutdown(__BFILE__, __LINE__, final := true);
+}
+
private function f_pkt_paging_match_imsi(in PacketPagingReq req, hexstring imsi)
runs on RAW_PCU_Test_CT {
var MobileIdentityLV_Paging mi_lv := req.repeated_pageinfo.cs.mobile_identity;
@@ -1766,6 +1870,7 @@
execute (TC_ul_intermediate_retrans() );
execute( TC_imm_ass_dl_block_retrans() );
execute( TC_dl_flow_more_blocks() );
+ execute (TC_ul_flow_multiple_llc_blocks() );
execute( TC_paging_cs_from_bts() );
execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
execute( TC_paging_cs_from_sgsn_sign() );