EGPRS: fix for EPDAN out of window

Fix alignment of EPDAN outside the RLC transmit window,
according to section 9.1.8.2.4 in 44.060 version 7.27.0 Release 7.
The specification explains that a bit within the uncompressed bitmap
whose corresponding BSN is not within the transmit window shall be
ignored. Without this fix PCU was dropping the EPDAN message and not
updating the status of BSNs which are inside the RLC window. This patch
updates the status of the BSNs which are inside the window and ignores
the remaining bits.

Related: OS#1789

Change-Id: Id07d178970f168f5389016c1eea31eb6b82057b6
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index c89cd03..f6836f8 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -847,6 +847,11 @@
 	unsigned received_packets = 0, lost_packets = 0;
 	unsigned num_blocks = strlen(show_rbb);
 
+	unsigned distance = m_window.distance();
+
+	num_blocks = num_blocks > distance
+				? distance : num_blocks;
+
 	/* SSN - 1 is in range V(A)..V(S)-1 */
 	for (unsigned int bitpos = 0; bitpos < num_blocks; bitpos++) {
 		bool is_received;
@@ -919,13 +924,15 @@
 int gprs_rlcmac_dl_tbf::update_window(unsigned first_bsn,
 	const struct bitvec *rbb)
 {
-	int16_t dist; /* must be signed */
+	unsigned dist;
 	uint16_t lost = 0, received = 0;
 	char show_v_b[RLC_MAX_SNS + 1];
 	char show_rbb[RLC_MAX_SNS + 1];
 	int error_rate;
 	struct ana_result ana_res;
-	unsigned num_blocks = rbb->cur_bit;
+	dist = m_window.distance();
+	unsigned num_blocks = rbb->cur_bit > dist
+				? dist : rbb->cur_bit;
 	unsigned behind_last_bsn = m_window.mod_sns(first_bsn + num_blocks);
 
 	Decoding::extract_rbb(rbb, show_rbb);
@@ -934,25 +941,6 @@
 		"(BSN=%d)  R=ACK I=NACK\n", first_bsn,
 		show_rbb, m_window.mod_sns(behind_last_bsn - 1));
 
-	/* apply received array to receive state (first_bsn..behind_last_bsn-1) */
-	if (num_blocks > 0) {
-		/* calculate distance of ssn from V(S) */
-		dist = m_window.mod_sns(m_window.v_s() - behind_last_bsn);
-		/* check if distance is less than distance V(A)..V(S) */
-		if (dist >= m_window.distance()) {
-			/* this might happpen, if the downlink assignment
-			 * was not received by ms and the ack refers
-			 * to previous TBF
-			 * FIXME: we should implement polling for
-			 * control ack!
-			 * TODO: check whether this FIXME still makes sense
-			 */
-			LOGP(DRLCMACDL, LOGL_NOTICE, "- ack range is out of "
-				"V(A)..V(S) range %s Free TBF!\n", tbf_name(this));
-			return 1; /* indicate to free TBF */
-		}
-	}
-
 	error_rate = analyse_errors(show_rbb, behind_last_bsn, &ana_res);
 
 	if (bts_data()->cs_adj_enabled && ms())