edge: Add is_received and invalidate_bsn to gprs_rlc_ul_window

These methods will be needed for EGPRS decoding.

The is_received method returns true iff a block with the given BSN
has already been received in the current window. A call to
invalidate_bsn marks the block as not received.

Sponsored-by: On-Waves ehf
diff --git a/src/rlc.cpp b/src/rlc.cpp
index bafc56e..227fa36 100644
--- a/src/rlc.cpp
+++ b/src/rlc.cpp
@@ -224,5 +224,12 @@
 {
 	m_v_n.mark_received(bsn);
 	raise_v_r(bsn);
+}
 
+bool gprs_rlc_ul_window::invalidate_bsn(const uint16_t bsn)
+{
+	bool was_valid = m_v_n.is_received(bsn);
+	m_v_n.mark_missing(bsn);
+
+	return was_valid;
 }
diff --git a/src/rlc.h b/src/rlc.h
index 081ba40..8168994 100644
--- a/src/rlc.h
+++ b/src/rlc.h
@@ -194,6 +194,7 @@
 	const uint16_t ssn() const;
 
 	bool is_in_window(uint8_t bsn) const;
+	bool is_received(uint8_t bsn) const;
 
 	void update_rbb(char *rbb);
 	void raise_v_r_to(int moves);
@@ -203,6 +204,7 @@
 	void raise_v_q(int);
 
 	void receive_bsn(const uint16_t bsn);
+	bool invalidate_bsn(const uint16_t bsn);
 
 	uint16_t m_v_r;	/* receive state */
 	uint16_t m_v_q;	/* receive window state */
@@ -401,6 +403,15 @@
 	return offset_v_q < ws();
 }
 
+inline bool gprs_rlc_ul_window::is_received(uint8_t bsn) const
+{
+	uint16_t offset_v_r;
+
+	/* Offset to the end of the received window */
+	offset_v_r = (m_v_r - 1 - bsn) & mod_sns();
+	return is_in_window(bsn) && m_v_n.is_received(bsn) && offset_v_r < ws();
+}
+
 inline const uint16_t gprs_rlc_ul_window::sns() const
 {
 	return RLC_MAX_SNS;