[MERGED] osmo-ttcn3-hacks[master]: WIP: Work towards a more real DL TBF receiver implementation

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 17:37:48 UTC 2018


Harald Welte has submitted this change and it was merged.

Change subject: WIP: Work towards a more real DL TBF receiver implementation
......................................................................


WIP: Work towards a more real DL TBF receiver implementation

Change-Id: I300312734d99f2b8a406f39e04b4f738940f7579
---
M library/RLCMAC_Types.ttcn
M pcu/GPRS_TBF.ttcn
2 files changed, 161 insertions(+), 17 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/library/RLCMAC_Types.ttcn b/library/RLCMAC_Types.ttcn
index 3ae1203..c946594 100644
--- a/library/RLCMAC_Types.ttcn
+++ b/library/RLCMAC_Types.ttcn
@@ -113,7 +113,14 @@
 		boolean		e
 	} with {
 		variant (e) "FIELDLENGTH(1)"
+		encode "RAW"
 	};
+
+	external function enc_LlcBlockHdr(in LlcBlockHdr si) return octetstring
+		with { extension "prototype(convert) encode(RAW)" };
+	external function dec_LlcBlockHdr(in octetstring stream) return LlcBlockHdr
+		with { extension "prototype(convert) decode(RAW)" };
+
 	type record LlcBlock {
 		/* Header is only present if LI field was present */
 		LlcBlockHdr	hdr optional,
diff --git a/pcu/GPRS_TBF.ttcn b/pcu/GPRS_TBF.ttcn
index a35c780..3e8658e 100644
--- a/pcu/GPRS_TBF.ttcn
+++ b/pcu/GPRS_TBF.ttcn
@@ -18,8 +18,25 @@
 import from LLC_Types all;
 import from GPRS_Context all;
 
-/* input parameters into TBF (mostly mode/cs + LLC PDUs */
+private const integer RLC_GPRS_SNS := 128;
+private const integer RLC_GPRS_WS := 64;
+private const integer RLC_EGPRS_MIN_WS := 64;
+private const integer RLC_EGPRS_MAX_WS := 1024;
+private const integer RLC_EGPRS_SNS := 2048;
+private const integer RLC_EGPRS_MAX_BSN_DELTA := 512;
+private const integer RLC_MAX_SNS := RLC_EGPRS_SNS;
+private const integer RLC_MAX_WS := RLC_EGPRS_MAX_WS;
+private const integer RLC_MAX_LEN := 74 /* MCS-9 data unit */
 
+private const integer sns_half := (RLC_MAX_SNS / 2);
+private const integer mod_sns_half := (RLC_MAX_SNS / 2) - 1;
+
+
+/***********************************************************************
+ * Uplink TBF handling
+ ***********************************************************************/
+
+/* input parameters into TBF (mostly mode/cs + LLC PDUs */
 type record UlTbfPars {
 	/* Acknowledged mode (true) or unacknowledged (false) */
 	boolean			ack_mode,
@@ -45,22 +62,6 @@
 	ep.v_a := 0;
 	ep.v_b := int2bit(0, 128); /* FIXME: EGPRS 2048 bits length */
 }
-
-type record RlcEndpointRx {
-	/* receive state variable V(R) (9.1.5): BSN one higher than highest BSN yet received (mod SNS) */
-	integer			v_r,
-	/* receive window state variable V(Q) (9.1.6): Lowest BSN not yet received (mod SNS) */
-	integer			v_q,
-	/* receive state array V(N) (9.1.7) */
-	bitstring		v_n
-}
-
-private function f_RlcEndpointRx_init(inout RlcEndpointRx ep) {
-	ep.v_r := 0;
-	ep.v_q := 0;
-	ep.v_n := int2bit(0, 128); /* FIXME: EGPRS 2048 bits length */
-}
-
 
 type record UlTbfState {
 	/* "const" input state with TBF Data */
@@ -360,6 +361,142 @@
 	}
 }
 
+/***********************************************************************
+ * Downlink TBF handling
+ ***********************************************************************/
+
+type record RlcEndpointRx {
+	/* receive state variable V(R) (9.1.5): BSN one higher than highest BSN yet received (mod SNS) */
+	integer			v_r,
+	/* receive window state variable V(Q) (9.1.6): Lowest BSN not yet received (mod SNS) */
+	integer			v_q,
+	/* receive state array V(N) (9.1.7) */
+	bitstring		v_n
+}
+
+private function f_RlcEndpointRx_init(inout RlcEndpointRx ep) {
+	ep.v_r := 0;
+	ep.v_q := 0;
+	ep.v_n := int2bit(0, 128); /* FIXME: EGPRS 2048 bits length */
+}
+
+type record DlTbfPars {
+	/* Acknowledged mode (true) or unacknowledged (false) */
+	boolean			ack_mode,
+	/* Coding Scheme for transmission, determines block size */
+	GprsCodingScheme	initial_cs,
+	/* Sequence Number Space */
+	integer			sns,
+	/* Window Size */
+	integer			ws
+}
+
+type record DlTbfState {
+	/* "const" input state with TBF Data */
+	DlTbfPars		tbf,
+	uint8_t			num_ts,
+
+	RlcEndpointRx		er,
+
+	integer			tfi,
+
+	/* list of abstract/decoded RLC PDUs */
+	record of RlcmacDlBlock	rlc_received
+}
+
+function f_dl_tbf_mod_sns(DlTbfState ds, integer val) return integer
+{
+	return (val mod ds.tbf.sns);
+}
+
+function f_dl_tbf_is_in_window(integer bsn) return boolean {
+	setverdict(fail, "pleaes implement me");
+	self.stop;
+}
+
+function f_dl_tbf_is_received(inout DlTbfState ds, integer bsn) return boolean {
+	var integer offset_v_r;
+
+	if (not f_dl_tbf_is_in_window(bsn)) {
+		return false;
+	}
+
+	/* offset to the end of the received window */
+	offset_v_r := f_dl_tbf_mod_sns(ds, ds.er.v_r - 1 - bsn);
+	if (not (offset_v_r < ds.tbf.ws)) {
+		return false;
+	}
+
+	if (ds.er.v_n[bsn mod sns_half] == '1'B) {
+		return true;
+	}
+
+	return false;
+}
+
+function f_dl_tbf_mark_received(inout DlTbfState ds, integer bsn) {
+	ds.er.v_n[bsn mod sns_half] := '1'B;
+	f_dl_tbf_raise_v_r(ds, bsn);
+}
+
+/* Raise V(Q) if possible */
+function f_dl_tbf_raise_v_q(inout DlTbfState ds, integer bsn) return integer {
+	var integer count := 0;
+	while (ds.er.v_q != ds.er.v_r) {
+		var integer v_q_old := ds.er.v_q;
+		if (not f_dl_tbf_is_received(ds, v_q_old)) {
+			break;
+		}
+		ds.er.v_q := f_dl_tbf_mod_sns(ds, ds.er.v_q + 1)
+		log("RLCMAC: Taking block ", v_q_old, " out, raising V(Q) to ", ds.er.v_q);
+		count := count+1;
+	}
+	return count;
+}
+
+function f_dl_tbf_raise_v_r(inout DlTbfState ds, integer bsn) {
+	var integer offset_v_r := f_dl_tbf_mod_sns(ds, bsn + 1 - ds.er.v_r);
+	if (offset_v_r < (ds.tbf.sns / 2)) {
+		for (var integer i := offset_v_r; i > 0; i := i-1) {
+			/* mark as missing */
+			ds.er.v_n[bsn mod sns_half] := '0'B;
+			//raise_v_r_to(1);
+		}
+		log("RLCMAC: Raising V(R) to ", ds.er.v_r);
+	}
+}
+
+/* process the actual data and update TbfState */
+function f_dl_tbf_process_dl_data(inout DlTbfState ds, RlcmacDlDataBlock db) {
+	var integer bsn := db.mac_hdr.hdr_ext.bsn;
+	if (db.mac_hdr.hdr_ext.tfi != ds.tfi) {
+		setverdict(fail, "Unexpected TFI of DL Data Block ", db);
+		self.stop;
+	}
+	f_dl_tbf_mark_received(ds, bsn);
+	if (ds.tbf.ack_mode) {
+		/* In RLC acknowledged mode, the receive window is defined by the receive window
+		 * state variable V(Q) in the following inequality[ V(Q) ≤ BSN < V(Q)+ WS ] modulo
+		 * SNS */
+		if (bsn < ds.er.v_q or bsn > ds.er.v_q + ds.tbf.ws) {
+			setverdict(fail, "Unexpected BSN outside of window ", bsn);
+			self.stop;
+		}
+
+		/* In RLC acknowledged mode, the value of V(Q) shall be updated when the RLC
+		 * receiver receives the RLC data block whose BSN is equal to V(Q). The value of
+		 * V(Q) shall then be set to the BSN value of the next RLC data block in the receive
+		 * window (modulo SNS) that has not yet been received, or it shall be set to V(R) if
+		 * all RLC data blocks in the receive window have been received */
+		f_dl_tbf_mark_received(ds, bsn);
+	} else {
+		/* In RLC unacknowledged mode, if [V(R) - V(Q)] modulo SNS > WS after updating V(R),
+		 * then V(Q) is set to [V(R) - WS] modulo SNS. */
+		/* FIXME */
+	}
+
+}
+
 
 
 }

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I300312734d99f2b8a406f39e04b4f738940f7579
Gerrit-PatchSet: 3
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list