diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2021-04-23 21:08:22 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2021-04-27 10:28:06 +0200 |
commit | dee557059b9c334f9f18b5d66b1df9930ec0e78a (patch) | |
tree | d46c4aa183b42540fb21c0c73d5edd082ac94447 | |
parent | 95e3d9906c4c1077dd37382c5bffdbfe3aaffb09 (diff) |
pcu: Take into account TbfStartingTime
New versions of osmo-pcu will validate the Pkt Resource Request is sent
on the correct FN, so we must send first UL block exactly when
requested.
Change-Id: I6dad0f3167ace8d4a763fed971db94f32faf6ced
-rw-r--r-- | pcu/GPRS_Components.ttcn | 30 | ||||
-rw-r--r-- | pcu/PCU_Tests.ttcn | 42 |
2 files changed, 49 insertions, 23 deletions
diff --git a/pcu/GPRS_Components.ttcn b/pcu/GPRS_Components.ttcn index 57cd8376..d3ace4d4 100644 --- a/pcu/GPRS_Components.ttcn +++ b/pcu/GPRS_Components.ttcn @@ -96,7 +96,8 @@ type record UlTbf { uint3_t usf[8], boolean is_egprs, uint14_t bsn, - CodingScheme tx_cs_mcs + CodingScheme tx_cs_mcs, + GsmFrameNumber start_time_fn }; type record GprsMS { @@ -160,7 +161,8 @@ template (value) UlTbf t_UlTbf_def := { usf := { USF_UNUSED, USF_UNUSED, USF_UNUSED, USF_UNUSED, USF_UNUSED, USF_UNUSED, USF_UNUSED, USF_UNUSED }, is_egprs := false, bsn := 0, - tx_cs_mcs := CS_1 + tx_cs_mcs := CS_1, + start_time_fn := 0 }; type component MS_BTS_IFACE_CT { @@ -233,6 +235,12 @@ function f_trxnr2arfcn(uint3_t trx_nr) return GsmArfcn { return mp_base_arfcn + trx_nr; } +/* 3GPP TS 44.018 10.5.2.38 Starting Time */ +function f_tbf_starting_time_2_fn_mod_42432(TbfStartingTime st) +runs on MS_BTS_IFACE_CT return GsmFrameNumber { + return 51 * ((st.t3 - st.t2) mod 26) + st.t3 + 51 * 26 * st.t1; +} + function f_ultbf_new_from_rr_imm_ass(in GsmRrMessage rr_imm_ass) runs on MS_BTS_IFACE_CT return UlTbf { var UlTbf ul_tbf := valueof(t_UlTbf_def); @@ -254,8 +262,11 @@ runs on MS_BTS_IFACE_CT return UlTbf { ul_tbf.tfi := ul_tbf.ass.ccch.dynamic.tfi_assignment; ul_tbf.tx_cs_mcs := f_rlcmac_block_ChCodingCommand2cs_mcs(ul_tbf.ass.ccch.dynamic.ch_coding_cmd); ul_tbf.usf[tn_allocated] := ul_tbf.ass.ccch.dynamic.usf; + if (ul_tbf.ass.ccch.dynamic.tbf_starting_time_present == '1'B) { + ul_tbf.start_time_fn := f_tbf_starting_time_2_fn_mod_42432(ul_tbf.ass.ccch.dynamic.tbf_starting_time); + } } else if (match(ul_tbf.ass.ccch, tr_PacketUlSglAssign)) { - /* Nothing to do here yet */ + ul_tbf.start_time_fn := f_tbf_starting_time_2_fn_mod_42432(ul_tbf.ass.ccch.single.tbf_starting_time); } } else if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_EGPRSULAss(?)))) { ul_tbf.ass.ccch_egprs := rr_imm_ass.payload.imm_ass.rest_octets.lh.egprs_ul; @@ -265,7 +276,11 @@ runs on MS_BTS_IFACE_CT return UlTbf { ul_tbf.tfi := ul_tbf.ass.ccch_egprs.dynamic.tfi_assignment; ul_tbf.tx_cs_mcs := f_rlcmac_block_EgprsChCodingCommand2cs_mcs(ul_tbf.ass.ccch_egprs.dynamic.egprs_ch_coding_cmd); ul_tbf.usf[tn_allocated] := ul_tbf.ass.ccch_egprs.dynamic.usf; + if (ul_tbf.ass.ccch_egprs.dynamic.tbf_starting_time_present == '1'B) { + ul_tbf.start_time_fn := f_tbf_starting_time_2_fn_mod_42432(ul_tbf.ass.ccch_egprs.dynamic.tbf_starting_time); + } } else if (match(ul_tbf.ass.ccch_egprs, tr_EgprsUlAssMultiblock)) { + ul_tbf.start_time_fn := f_tbf_starting_time_2_fn_mod_42432(ul_tbf.ass.ccch_egprs.multiblock.tbf_starting_time); /* Nothing to do here yet */ } } else { @@ -661,7 +676,7 @@ runs on MS_BTS_IFACE_CT { /* 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, - template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum) + uint32_t fn := 0, 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); @@ -673,7 +688,12 @@ runs on MS_BTS_IFACE_CT return octetstring { if (cv > g_bs_cv_max) { cv := 15; } - f_ms_tx_ul_data_block(ms, payload, cv := cv, with_tlli := with_tlli, nr := nr); + if (i == 1) { + /* We use FN on i=0 to jump to wanted FN time, then simply submit on next + * available frame (fn=0) */ + fn := 0; + } + f_ms_tx_ul_data_block(ms, payload, cv := cv, with_tlli := with_tlli, fn := fn, nr := nr); total_payload := total_payload & payload; } return total_payload; diff --git a/pcu/PCU_Tests.ttcn b/pcu/PCU_Tests.ttcn index a466732e..52d62713 100644 --- a/pcu/PCU_Tests.ttcn +++ b/pcu/PCU_Tests.ttcn @@ -316,7 +316,7 @@ runs on RAW_PCU_Test_CT { var RlcmacDlBlock dl_block; var uint32_t poll_fn; - f_ms_tx_ul_data_block(g_ms[i], dummy, with_tlli := true, nr := nr); + f_ms_tx_ul_data_block(g_ms[i], dummy, with_tlli := true, fn := g_ms[i].ul_tbf.start_time_fn, nr := nr); f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := nr); } } @@ -354,7 +354,7 @@ runs on RAW_PCU_Test_CT return PollFnCtx { pkt_res_req := ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit); } - f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(valueof(pkt_res_req)), 0, nr := f_ms_tx_TsTrxBtsNum(ms)); + f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(valueof(pkt_res_req)), ms.ul_tbf.start_time_fn, nr := f_ms_tx_TsTrxBtsNum(ms)); /* Store 1st UlTBF context before receiving next one, will * overwrite the TS allocation on MS with info from new UL TBF: */ @@ -420,7 +420,7 @@ testcase TC_pcuif_suspend_active_tbf() runs on RAW_PCU_Test_CT { /* Send one UL block (with TLLI since we are in One-Phase Access contention resoultion) and make sure it is ACKED fine */ - f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true); + f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn); 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); @@ -765,7 +765,7 @@ testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT { contention resoultion) and make sure it is ACKED fine. */ /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */ /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */ - f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true) + f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn) 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); @@ -849,7 +849,7 @@ testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT { contention resoultion) and make sure it is ACKED fine. */ /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */ /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */ - f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true) + f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn) 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); @@ -921,7 +921,7 @@ testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT { contention resoultion) and make sure it is ACKED fine. */ /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */ /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */ - f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true) + f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn) 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); @@ -1299,7 +1299,7 @@ testcase TC_t3169() runs on RAW_PCU_Test_CT { /* Send one UL block (with TLLI since we are in One-Phase Access contention resoultion) and make sure it is ACKED fine */ - f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 1, with_tlli := true) + f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn) f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn); /* UL block should NOT be received in SGSN, since we didn't get CV=0 */ @@ -1905,7 +1905,7 @@ testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT { contention resoultion) and make sure it is ACKED fine. */ 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_ms_tx_ul_data_block(ms, total_payload, cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn) 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); @@ -1966,7 +1966,7 @@ testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT { blocks := blocks, tlli := ms.tlli); f_ultbf_inc_bsn(ms.ul_tbf); - f_ms_tx_ul_block(ms, ul_data); + f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn); /* ACK and check it was received fine */ f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn); @@ -2122,7 +2122,7 @@ private function f_TC_mo_ping_pong_1phase_access(template (present) CodingScheme /* Send one UL block (with TLLI since we are in One-Phase Access contention resoultion) and make sure it is ACKED fine */ - f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true); + f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn); 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); @@ -2349,7 +2349,7 @@ testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT { /* 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(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_ms_tx_ul_data_block(ms, payload, cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn); f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn); /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */ @@ -2580,7 +2580,7 @@ testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT { * 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); + f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn); /* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */ ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1, @@ -2765,7 +2765,8 @@ testcase TC_dl_multislot_tbf_ms_class_from_sgsn() runs on RAW_PCU_Test_CT { /* Send one UL block (with TLLI since we are in One-Phase Access contention resoultion) and make sure it is ACKED fine */ - f_ms_tx_ul_data_block(ms, data, with_tlli := true, nr := f_ms_tx_TsTrxBtsNum(ms)); + f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := ms.ul_tbf.start_time_fn, + nr := f_ms_tx_TsTrxBtsNum(ms)); /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */ f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := f_ms_tx_TsTrxBtsNum(ms)); @@ -2908,7 +2909,7 @@ testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT { /* Send one UL block (with TLLI since we are in One-Phase Access contention resoultion) and make sure it is ACKED fine */ - f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true); + f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn); /* UL block should be received in SGSN */ BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id)); @@ -3128,7 +3129,7 @@ testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT { f_ms_establish_ul_tbf(ms); /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */ - f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true); + f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn); 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); @@ -3187,7 +3188,7 @@ testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT { f_ms_establish_ul_tbf(ms); /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */ - f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true); + f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn); 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); @@ -3676,11 +3677,16 @@ testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT { /* Initialize the PCU interface abstraction */ f_init_raw(testcasename(), info_ind); + /* Single block (two phase) packet access */ + var uint16_t ra := bit2int(chan_req_sb); + f_ms_use_ra(ms, ra, ra_is_11bit := 0); + /* Establish an Uplink TBF */ f_ms_establish_ul_tbf(ms); /* Send Packet Resource Request, so the network will allocate an Uplink resource */ - f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit))); + f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)), + fn := ms.ul_tbf.start_time_fn); /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */ f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS); @@ -3729,7 +3735,7 @@ testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT { f_ms_establish_ul_tbf(ms); /* Send an Uplink block, so this TBF becomes "active" */ - f_ms_tx_ul_data_block(ms, data, with_tlli := true); + f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := ms.ul_tbf.start_time_fn); /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */ f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn); |