[PATCH] osmo-ttcn3-hacks[master]: pcu: First DL TBF hack

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Mon Mar 12 14:07:38 UTC 2018


Review at  https://gerrit.osmocom.org/7229

pcu: First DL TBF hack

Change-Id: Ib3f09e125a7a4492d9072f8e9f5896eaac7ed03b
---
M library/GSM_RR_Types.ttcn
M library/L1CTL_PortType.ttcn
M library/LAPDm_RAW_PT.ttcn
M library/RLCMAC_CSN1_Types.ttcn
M library/RLCMAC_Types.ttcn
M pcu/PCU_Tests.ttcn
6 files changed, 279 insertions(+), 20 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/29/7229/1

diff --git a/library/GSM_RR_Types.ttcn b/library/GSM_RR_Types.ttcn
index 75be6f8..b1e6809 100644
--- a/library/GSM_RR_Types.ttcn
+++ b/library/GSM_RR_Types.ttcn
@@ -706,6 +706,57 @@
 		}
 	};
 
+	template ImmediateAssignment t_IMM_ASS_TBF_DL(template GprsTlli tlli) := {
+		ded_or_tbf := {
+			spare := ?,
+			tma := ?,
+			downlink := ?,
+			tbf := true
+		},
+		page_mode := ?,
+		chan_desc := omit,
+		pkt_chan_desc := {
+			channel_Type_spare := ?,
+			tn := ?,
+			tsc := ?,
+			presence := ?,
+			zero := *,
+			one := omit
+		},
+		req_ref := ?,
+		timing_advance := ?,
+		mobile_allocation := ?,
+		rest_octets := {
+			presence := '11'B,
+			ll := omit,
+			lh := omit,
+			hl := omit,
+			hh := {
+				presence := '01'B,
+				ul := omit,
+				dl := {
+					tlli := tlli,
+					group1_present := ?,
+					group1 := *,
+					ta_index_present := ?,
+					ta_index := *,
+					tbf_starting_time_present := ?,
+					tbf_starting_time := *,
+					p0_present := ?,
+					p0 := *,
+					pr_mode := *
+				}
+			}
+		}
+	};
+
+	template GsmRrMessage t_RR_IMM_ASS_TBF_DL(template GprsTlli tlli) := {
+		header := t_RrHeader(IMMEDIATE_ASSIGNMENT, ?),
+		payload := {
+			imm_ass := t_IMM_ASS_TBF_DL(tlli)
+		}
+	};
+
 
 
 } with { encode "RAW" ; variant "FIELDORDER(msb)" }
diff --git a/library/L1CTL_PortType.ttcn b/library/L1CTL_PortType.ttcn
index 4dcacb8..30f4f70 100644
--- a/library/L1CTL_PortType.ttcn
+++ b/library/L1CTL_PortType.ttcn
@@ -83,6 +83,28 @@
 		return rr.payload.imm_ass;
 	}
 
+	function f_L1CTL_WAIT_IMM_ASS_TBF_DL(L1CTL_PT pt, GprsTlli tlli) return ImmediateAssignment {
+		var L1ctlDlMessage dl;
+		var GsmRrMessage rr;
+		timer T := 10.0;
+		T.start;
+		alt {
+			[] pt.receive(t_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl {
+				rr := dec_GsmRrMessage(dl.payload.data_ind.payload);
+				log("PCH/AGCN DL RR: ", rr);
+				if (match(rr, t_RR_IMM_ASS_TBF_DL(tlli))) {
+					log("Received IMM.ASS for our TLLI!");
+				} else {
+					repeat;
+				}
+			};
+			[] pt.receive { repeat };
+			[] T.timeout { setverdict(fail, "Timeout waiting for IMM ASS") };
+		}
+		T.stop;
+		return rr.payload.imm_ass;
+	}
+
 	function f_L1CTL_TBF_CFG(L1CTL_PT pt, boolean is_uplink, TfiUsfArr tfi_usf) {
 		timer T := 2.0;
 		T.start;
diff --git a/library/LAPDm_RAW_PT.ttcn b/library/LAPDm_RAW_PT.ttcn
index ab99538..f5d1926 100644
--- a/library/LAPDm_RAW_PT.ttcn
+++ b/library/LAPDm_RAW_PT.ttcn
@@ -26,7 +26,21 @@
 		charstring err optional
 	}
 
-	type record TBF_establish_res {
+	type record length(8) of uint8_t TfiList;
+	type record TbfPars {
+		GsmArfcn	arfcn optional,
+		/* Temporary Flow Identifier for each TN */
+		TfiList		tfi
+	}
+	type record length(8) of TbfPars TbfParsPerTs;
+
+	template TbfPars t_TbfParsInit := {
+		arfcn := omit,
+		tfi := { 255, 255, 255, 255, 255, 255, 255, 255 }
+	}
+
+	type record TBF_UL_establish_res {
+		TbfPars pars optional,
 		charstring err optional
 	}
 
@@ -40,8 +54,15 @@
 		LapdmFrame lapdm
 	}
 
-	type record TBF_establish_req {
+	type integer TbfNr (0..7);	/* maximum of 8 concurrent TBF per direction */
+	type record TBF_UL_establish_req {
+		TbfNr tbf_nr,
 		uint8_t ra
+	}
+
+	type record TBF_DL_establish_req {
+		TbfNr tbf_nr,
+		TbfPars pars
 	}
 
 	/* PH-DATA.ind / PH-DATA.req */
@@ -74,11 +95,12 @@
 		in	BCCH_tune_req,
 			DCCH_establish_req,
 			DCCH_release_req,
-			TBF_establish_req,
+			TBF_UL_establish_req,
+			TBF_DL_establish_req,
 			RLCMAC_ph_data_req,
 			LAPDm_ph_data;
 		out	DCCH_establish_res,
-			TBF_establish_res,
+			TBF_UL_establish_res,
 			RLCMAC_ph_data_ind,
 			LAPDm_ph_data;
 	} with {extension "internal"};
@@ -86,13 +108,14 @@
 	/* port from user (external) point of view */
 	type port LAPDm_PT message {
 		in	DCCH_establish_res,
-			TBF_establish_res,
+			TBF_UL_establish_res,
 			RLCMAC_ph_data_ind,
 			LAPDm_ph_data;
 		out	BCCH_tune_req,
 			DCCH_establish_req,
 			DCCH_release_req,
-			TBF_establish_req,
+			TBF_UL_establish_req,
+			TBF_DL_establish_req,
 			RLCMAC_ph_data_req,
 			LAPDm_ph_data;
 	} with {extension "internal"};
@@ -124,6 +147,9 @@
 
 		/* channel description of the currently active DCH */
 		var ChannelDescription chan_desc;
+
+		var TbfParsPerTs g_tbf_ul;
+		var TbfParsPerTs g_tbf_dl;
 	};
 
 	/* wrapper function to log state transitions */
@@ -286,6 +312,51 @@
 		set_ph_state(PH_STATE_BCH);
 	}
 
+	/* Establish TBF / packet transfer mode */
+	private altstep as_tbf_ul_est() runs on lapdm_CT {
+		var TBF_UL_establish_req tbf_ul_req;
+		[] LAPDM_SP.receive(TBF_UL_establish_req:?) -> value tbf_ul_req {
+			var TbfNr tbf_nr := tbf_ul_req.tbf_nr;
+			var TBF_UL_establish_res res;
+			if (isvalue(g_tbf_ul[tbf_nr].arfcn)) {
+				setverdict(fail, "Cannot establish UL TBF ID ", tbf_nr, ": BUSY");
+				self.stop;
+			}
+			f_establish_tbf(tbf_ul_req.ra);
+			if (ph_state == PH_STATE_TBF) {
+				g_tbf_ul[tbf_nr] := valueof(t_TbfParsInit); /* FIXME: Actual TFI[s] */
+				log("Established UL TBF ", tbf_nr);
+				res := { pars := g_tbf_ul[tbf_nr], err := omit };
+			} else {
+				res := { pars := omit, err := "Unable to establish UL TBF" };
+			}
+			LAPDM_SP.send(res);
+		}
+	}
+
+	private altstep as_tbf_dl_est() runs on lapdm_CT {
+		var TBF_DL_establish_req tbf_dl_req;
+		[] LAPDM_SP.receive(TBF_DL_establish_req:?) -> value tbf_dl_req {
+			var TbfNr tbf_nr := tbf_dl_req.tbf_nr;
+			if (isvalue(g_tbf_dl[tbf_nr].arfcn)) {
+				setverdict(fail, "Cannot establish DL TBF ID ", tbf_nr, ": BUSY");
+				self.stop;
+			}
+			g_tbf_dl[tbf_nr] := tbf_dl_req.pars;
+			f_L1CTL_TBF_CFG(L1CTL, false, tbf_dl_req.pars.tfi);
+			set_ph_state(PH_STATE_TBF);
+			log("Established DL TBF ", tbf_nr, ": ", tbf_dl_req.pars);
+		}
+	}
+
+	private function f_init_tbf() runs on lapdm_CT {
+		var integer i;
+		for (i := 0; i < 8; i := i+1) {
+			g_tbf_ul[i] := valueof(t_TbfParsInit);
+			g_tbf_dl[i] := valueof(t_TbfParsInit);
+		}
+	}
+
 	function ScanEvents() runs on lapdm_CT {
 		var L1ctlDlMessage dl;
 		var BCCH_tune_req bt;
@@ -294,7 +365,8 @@
 		var RLCMAC_ph_data_req rpdr;
 		var DCCH_establish_req est_req;
 		var DCCH_establish_res est_res;
-		var TBF_establish_req tbf_req;
+
+		f_init_tbf();
 
 		while (true) {
 		if (ph_state == PH_STATE_NULL) {
@@ -341,17 +413,8 @@
 				LAPDM_SP.send(res);
 			}
 
-			/* Establish TBF / packet transfer mode */
-			[] LAPDM_SP.receive(TBF_establish_req:?) -> value tbf_req {
-				var TBF_establish_res res;
-				f_establish_tbf(tbf_req.ra);
-				if (ph_state == PH_STATE_TBF) {
-					res := { err := omit };
-				} else {
-					res := { err := "Unable to establish TBF" };
-				}
-				LAPDM_SP.send(res);
-			}
+			[] as_tbf_ul_est();
+			[] as_tbf_dl_est();
 
 			[] LAPDM_SP.receive {}
 			[] L1CTL.receive {}
@@ -404,6 +467,7 @@
 			/* decode + forward any blocks from L1 to L23*/
 			[] L1CTL.receive(t_L1CTL_DATA_IND(t_RslChanNr_PDCH(?))) -> value dl {
 				rpdi.block := dec_RlcmacDlBlock(dl.payload.data_ind.payload);
+				/* FIXME: Filter based on g_tbf_dl */
 				rpdi.fn := dl.dl_info.frame_nr;
 				rpdi.ts_nr := dl.dl_info.chan_nr.tn;
 				rpdi.cs := CS1; /* FIXME */
@@ -427,10 +491,14 @@
 				}
 			}
 
+			[] as_tbf_ul_est();
+			[] as_tbf_dl_est();
+
 			/* FIXME: release TBF mode */
 			[] LAPDM_SP.receive(DCCH_release_req:?) {
 				/* go back to BCCH */
 				f_release_tbf();
+				f_init_tbf();
 			}
 
 			}
diff --git a/library/RLCMAC_CSN1_Types.ttcn b/library/RLCMAC_CSN1_Types.ttcn
index 95b5838..fbd01d4 100644
--- a/library/RLCMAC_CSN1_Types.ttcn
+++ b/library/RLCMAC_CSN1_Types.ttcn
@@ -524,5 +524,31 @@
 		}
 	}
 
+	private const ILevel iNone := {
+		presence := '0'B,
+		i_level := omit
+	}
+	private const ChannelQualityReport c_ChQualRep_default := {
+		c_value := 0,
+		rxqual := 0,
+		sign_var := 0,
+		i_levels := { iNone, iNone, iNone, iNone, iNone, iNone, iNone, iNone }
+	}
+	template (value) RlcmacUlCtrlMsg ts_RlcMacUlCtrl_PKT_DL_ACK(uint5_t dl_tfi,
+								    AckNackDescription andesc,
+					ChannelQualityReport qual_rep := c_ChQualRep_default) := {
+		msg_type := PACKET_DL_ACK_NACK,
+		u := {
+			dl_ack_nack := {
+				dl_tfi := dl_tfi,
+				ack_nack_desc := andesc,
+				chreq_desc_presence := '0'B,
+				chreq_desc := omit,
+				ch_qual_rep := qual_rep
+			}
+		}
+	}
+
+
 
 } with { encode "RAW"; variant "FIELDORDER(msb)" variant "BYTEORDER(last)" };
diff --git a/library/RLCMAC_Types.ttcn b/library/RLCMAC_Types.ttcn
index 78861ff..3ae1203 100644
--- a/library/RLCMAC_Types.ttcn
+++ b/library/RLCMAC_Types.ttcn
@@ -323,6 +323,21 @@
 		}
 	}
 
+	template RlcmacDlBlock tr_RLCMAC_DATA_RRBP := {
+		data := {
+			mac_hdr := {
+				mac_hdr := {
+					payload_type := MAC_PT_RLC_DATA,
+					rrbp := ?,
+					rrbp_valid := true,
+					usf := ?
+				},
+				hdr_ext := ?
+			},
+			blocks := ?
+		}
+	}
+
 	/* Template for Uplink MAC Control Header */
 	template UlMacCtrlHeader t_RLCMAC_UlMacCtrlH(template MacPayloadType pt, template boolean retry := false) := {
 		payload_type := pt,
diff --git a/pcu/PCU_Tests.ttcn b/pcu/PCU_Tests.ttcn
index ef46831..12b63d6 100644
--- a/pcu/PCU_Tests.ttcn
+++ b/pcu/PCU_Tests.ttcn
@@ -16,6 +16,7 @@
 	import from LAPDm_RAW_PT all;
 	import from GPRS_Context all;
 	import from GPRS_TBF all;
+	import from L1CTL_PortType all;
 
 	modulepar {
 		BssgpConfig mp_gb_cfg := {
@@ -221,12 +222,12 @@
 		L1.send(tune_req);
 		/* FIXME: wait for confirm */
 
-		var TBF_establish_req est_req := { ra := hex2int('7B'H) };
+		var TBF_UL_establish_req est_req := { tbf_nr := 0, ra := hex2int('7B'H) };
 		L1.send(est_req);
 		T.start;
 		/* FIXME: wait for confirm */
 		alt {
-			[] L1.receive(TBF_establish_res:?) {}
+			[] L1.receive(TBF_UL_establish_res:?) {}
 			[] L1.receive { repeat; }
 			[] T.timeout {
 				setverdict(fail, "Timeout establishing UL TBF");
@@ -526,6 +527,82 @@
 		f_exit();
 	}
 
+	testcase TC_dl_tbf() runs on dummy_CT {
+		g_mmctx.imsi := '262420123456789'H;
+		g_mmctx.tlli := f_random_tlli();
+		f_init();
+
+		f_establish_dl_tbf();
+
+		f_exit();
+	}
+
+	function f_wait_tbf_dl(TbfNr tbf_nr, GprsTlli tlli) runs on dummy_CT return ImmediateAssignment {
+		var LAPDm_ph_data ph_data;
+		var GsmRrMessage rr;
+		timer T := 10.0;
+		T.start;
+		alt {
+		[] L1.receive(LAPDm_ph_data:{sacch:=?,sapi:=0,lapdm:={bbis:=?}}) -> value ph_data {
+			rr := dec_GsmRrMessage(ph_data.lapdm.bbis.payload);
+			log("PCH/AGCH DL RR: ", rr);
+			if (match(rr, t_RR_IMM_ASS_TBF_DL(tlli))) {
+				var TbfPars tbf_pars := valueof(t_TbfParsInit);
+				log("Received IMM.ASS for our TLLI!");
+				tbf_pars.tfi[rr.payload.imm_ass.pkt_chan_desc.tn] :=
+					rr.payload.imm_ass.rest_octets.hh.dl.group1.tfi_assignment;
+				L1.send(TBF_DL_establish_req:{tbf_nr, tbf_pars});
+			} else {
+				repeat;
+			}
+		}
+		[] L1.receive { repeat };
+		[] T.timeout {
+			setverdict(fail, "Timeout waiting for IMM ASS")
+			self.stop;
+			}
+		}
+		T.stop;
+		return rr.payload.imm_ass;
+	}
+
+	/* Establish an UL TBF: Tune to ARFCN, send RACH, receive AGCH, enable TBF Rx */
+	function f_establish_dl_tbf() runs on dummy_CT {
+		timer T := 5.0;
+		var BCCH_tune_req tune_req := { { false, 871 }, true };
+		L1.send(tune_req);
+		/* FIXME: wait for confirm */
+
+		/* sending a GMM PDU as DL-UNITDATA should trigger Paging + DL TBF Assignment */
+		tx_gmm('1'B, '01020304'O, c_LLC_SAPI_LLGMM);
+
+		/* Expect an IMM.ASS for PDCH on the AGCH */
+		f_wait_tbf_dl(0, g_mmctx.tlli);
+
+		var RLCMAC_ph_data_ind dl;
+		alt {
+		[] L1.receive(RLCMAC_ph_data_ind:{cs:=?, ts_nr:=?, fn:=?, block:=tr_RLCMAC_DATA_RRBP}) ->
+value dl {
+			var uint6_t tfi := dl.block.data.mac_hdr.hdr_ext.tfi;
+			var GsmFrameNumber ul_fn := f_rrbp_fn(dl.fn, dl.block.data.mac_hdr.mac_hdr.rrbp);
+			var AckNackDescription an_desc := { /* FIXME: compute this based on state */
+				final_ack := '1'B,
+				starting_seq_nr := 0,
+				receive_block_bitmap := '0000000000000000000000000000000000000000000000000000000000000001'B
+			}
+			var RlcmacUlCtrlMsg ctrl_ack;
+			ctrl_ack := valueof(ts_RlcMacUlCtrl_PKT_DL_ACK(tfi, an_desc));
+			var RlcmacUlBlock ul_block := valueof(ts_RLC_UL_CTRL_ACK(ctrl_ack));
+			L1.send(ts_PH_DATA_ABS(0, CS1, dl.ts_nr, ul_fn, {false, 871}, ul_block));
+			log("Sent DL ACK: ", ul_block);
+			}
+		[] L1.receive { repeat; }
+		}
+
+		f_sleep(10.0);
+	}
+
+
 	control {
 		execute(TC_selftest_bssgp());
 		execute(TC_selftest_ns());

-- 
To view, visit https://gerrit.osmocom.org/7229
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib3f09e125a7a4492d9072f8e9f5896eaac7ed03b
Gerrit-PatchSet: 1
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>



More information about the gerrit-log mailing list