[PATCH 8/8] tbf: Prepare to make thing things private in the tbf, start with the state

Holger Hans Peter Freyther hfreyther at sysmocom.de
Sat Oct 19 14:26:38 UTC 2013


From: Holger Hans Peter Freyther <holger at moiji-mobile.com>

There really shouldn't be too many callers of state. Instead the
tbf should dispatch depending on the internal state. For now
introduce state_is and state_is_not accessor functions so we can
start to see who is using the internal state.
---
 src/gprs_rlcmac_data.cpp  | 18 +++++++++---------
 src/gprs_rlcmac_sched.cpp |  6 +++---
 src/tbf.cpp               | 18 +++++++++---------
 src/tbf.h                 | 24 +++++++++++++++++++++++-
 4 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp
index b5ea7c9..17c4b1b 100644
--- a/src/gprs_rlcmac_data.cpp
+++ b/src/gprs_rlcmac_data.cpp
@@ -98,7 +98,7 @@ int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf)
 		}
 		tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE;
 		debug_diagram(tbf->diag, "timeout UL-ACK");
-		if (tbf->state == GPRS_RLCMAC_FINISHED) {
+		if (tbf->state_is(GPRS_RLCMAC_FINISHED)) {
 			struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
 
 			tbf->dir.ul.n3103++;
@@ -687,7 +687,7 @@ static int gprs_rlcmac_assemble_llc(struct gprs_rlcmac_tbf *tbf, uint8_t *data,
 struct msgb *gprs_rlcmac_send_uplink_ack(struct gprs_rlcmac_tbf *tbf,
 	uint32_t fn)
 {
-	int final = (tbf->state == GPRS_RLCMAC_FINISHED);
+	int final = (tbf->state_is(GPRS_RLCMAC_FINISHED));
 	struct msgb *msg;
 
 	if (final) {
@@ -899,7 +899,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts,
 	}
 
 	/* Check CV of last frame in buffer */
-	if (tbf->state == GPRS_RLCMAC_FLOW /* still in flow state */
+	if (tbf->state_is(GPRS_RLCMAC_FLOW) /* still in flow state */
 	 && tbf->dir.ul.v_q == tbf->dir.ul.v_r) { /* if complete */
 		struct rlc_ul_header *last_rh = (struct rlc_ul_header *)
 			tbf->rlc_block[(tbf->dir.ul.v_r - 1) & mod_sns_half];
@@ -917,7 +917,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts,
 
 	/* If TLLI is included or if we received half of the window, we send
 	 * an ack/nack */
-	if (rh->si || rh->ti || tbf->state == GPRS_RLCMAC_FINISHED
+	if (rh->si || rh->ti || tbf->state_is(GPRS_RLCMAC_FINISHED)
 	 || (tbf->dir.ul.rx_counter % SEND_ACK_AFTER_FRAMES) == 0) {
 		if (rh->si) {
 			LOGP(DRLCMACUL, LOGL_NOTICE, "- Scheduling Ack/Nack, "
@@ -927,7 +927,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts,
 			LOGP(DRLCMACUL, LOGL_DEBUG, "- Scheduling Ack/Nack, "
 				"because TLLI is included.\n");
 		}
-		if (tbf->state == GPRS_RLCMAC_FINISHED) {
+		if (tbf->state_is(GPRS_RLCMAC_FINISHED)) {
 			LOGP(DRLCMACUL, LOGL_DEBUG, "- Scheduling Ack/Nack, "
 				"because last block has CV==0.\n");
 		}
@@ -942,7 +942,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts,
 				debug_diagram(tbf->diag, "sched UL-ACK stall");
 			if (rh->ti)
 				debug_diagram(tbf->diag, "sched UL-ACK TLLI");
-			if (tbf->state == GPRS_RLCMAC_FINISHED)
+			if (tbf->state_is(GPRS_RLCMAC_FINISHED))
 				debug_diagram(tbf->diag, "sched UL-ACK CV==0");
 			if ((tbf->dir.ul.rx_counter % SEND_ACK_AFTER_FRAMES) == 0)
 				debug_diagram(tbf->diag, "sched UL-ACK n=%d",
@@ -1200,11 +1200,11 @@ do_resend:
 
 	/* if the window has stalled, or transfer is complete,
 	 * send an unacknowledged block */
-	if (tbf->state == GPRS_RLCMAC_FINISHED
+	if (tbf->state_is(GPRS_RLCMAC_FINISHED)
 	 || ((tbf->dir.dl.v_s - tbf->dir.dl.v_a) & mod_sns) == tbf->ws) {
 	 	int resend = 0;
 
-		if (tbf->state == GPRS_RLCMAC_FINISHED)
+		if (tbf->state_is(GPRS_RLCMAC_FINISHED))
 			LOGP(DRLCMACDL, LOGL_DEBUG, "- Restarting at BSN %d, "
 				"because all blocks have been transmitted.\n",
 					tbf->dir.dl.v_a);
@@ -1568,7 +1568,7 @@ int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_tbf *tbf, uint8_t final,
 			"X=Resend-Unacked\n", tbf->dir.dl.v_a, show_v_b,
 			(tbf->dir.dl.v_s - 1) & mod_sns);
 
-		if (tbf->state == GPRS_RLCMAC_FINISHED
+		if (tbf->state_is(GPRS_RLCMAC_FINISHED)
 		 && tbf->dir.dl.v_s == tbf->dir.dl.v_a) {
 			LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of "
 				"all blocks, but without final ack "
diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp
index f3edaac..476d781 100644
--- a/src/gprs_rlcmac_sched.cpp
+++ b/src/gprs_rlcmac_sched.cpp
@@ -103,7 +103,7 @@ uint8_t sched_select_uplink(uint8_t trx, uint8_t ts, uint32_t fn,
 		/* we don't need to give resources in FINISHED state,
 		 * because we have received all blocks and only poll
 		 * for packet control ack. */
-		if (tbf->state != GPRS_RLCMAC_FLOW)
+		if (tbf->state_is_not(GPRS_RLCMAC_FLOW))
 			continue;
 
 		/* use this USF */
@@ -182,8 +182,8 @@ struct msgb *sched_select_downlink(uint8_t trx, uint8_t ts, uint32_t fn,
 		if (tbf->direction != GPRS_RLCMAC_DL_TBF)
 			continue;
 		/* no DL resources needed, go next */
-		if (tbf->state != GPRS_RLCMAC_FLOW
-		 && tbf->state != GPRS_RLCMAC_FINISHED)
+		if (tbf->state_is_not(GPRS_RLCMAC_FLOW)
+		 && tbf->state_is_not(GPRS_RLCMAC_FINISHED))
 			continue;
 
 		/* waiting for CCCH IMM.ASS confirm */
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 918520c..547612f 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -59,7 +59,7 @@ static int tbf_append_data(struct gprs_rlcmac_tbf *tbf,
 				const uint8_t *data, const uint16_t len)
 {
 	LOGP(DRLCMAC, LOGL_INFO, "TBF: APPEND TFI: %u TLLI: 0x%08x\n", tbf->tfi, tbf->tlli);
-	if (tbf->state == GPRS_RLCMAC_WAIT_RELEASE) {
+	if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE)) {
 		LOGP(DRLCMAC, LOGL_DEBUG, "TBF in WAIT RELEASE state "
 			"(T3193), so reuse TBF\n");
 		memcpy(tbf->llc_frame, data, len);
@@ -357,7 +357,7 @@ void tbf_new_state(struct gprs_rlcmac_tbf *tbf,
 	LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d changes state from %s to %s\n",
 		(tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi,
 		tbf_state_name[tbf->state], tbf_state_name[state]);
-	tbf->state = state;
+	tbf->set_state(state);
 }
 
 void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T,
@@ -409,7 +409,7 @@ struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts,
 	if (!tbf)
 		return NULL;
 
-	if (tbf->state != GPRS_RLCMAC_RELEASING)
+	if (tbf->state_is_not(GPRS_RLCMAC_RELEASING))
 		return tbf;
 
 	return NULL;
@@ -422,13 +422,13 @@ struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli,
 	struct gprs_rlcmac_tbf *tbf;
 	if (dir == GPRS_RLCMAC_UL_TBF) {
 		llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) {
-			if (tbf->state != GPRS_RLCMAC_RELEASING
+			if (tbf->state_is_not(GPRS_RLCMAC_RELEASING)
 			 && tbf->tlli == tlli && tbf->tlli_valid)
 				return tbf;
 		}
 	} else {
 		llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) {
-			if (tbf->state != GPRS_RLCMAC_RELEASING
+			if (tbf->state_is_not(GPRS_RLCMAC_RELEASING)
 			 && tbf->tlli == tlli)
 				return tbf;
 		}
@@ -443,14 +443,14 @@ struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts)
 	/* only one TBF can poll on specific TS/FN, because scheduler can only
 	 * schedule one downlink control block (with polling) at a FN per TS */
 	llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) {
-		if (tbf->state != GPRS_RLCMAC_RELEASING
+		if (tbf->state_is_not(GPRS_RLCMAC_RELEASING)
 		 && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED
 		 && tbf->poll_fn == fn && tbf->trx == trx
 		 && tbf->control_ts == ts)
 			return tbf;
 	}
 	llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) {
-		if (tbf->state != GPRS_RLCMAC_RELEASING
+		if (tbf->state_is_not(GPRS_RLCMAC_RELEASING)
 		 && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED
 		 && tbf->poll_fn == fn && tbf->trx == trx
 		 && tbf->control_ts == ts)
@@ -561,7 +561,7 @@ void tbf_timer_cb(void *_tbf)
 #endif
 	case 0: /* assignment */
 		if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) {
-			if (tbf->state == GPRS_RLCMAC_ASSIGN) {
+			if (tbf->state_is(GPRS_RLCMAC_ASSIGN)) {
 				LOGP(DRLCMAC, LOGL_NOTICE, "Releasing due to "
 					"PACCH assignment timeout.\n");
 				tbf_free(tbf);
@@ -572,7 +572,7 @@ void tbf_timer_cb(void *_tbf)
 		if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) {
 			/* change state to FLOW, so scheduler will start transmission */
 			tbf->dir.dl.wait_confirm = 0;
-			if (tbf->state == GPRS_RLCMAC_ASSIGN) {
+			if (tbf->state_is(GPRS_RLCMAC_ASSIGN)) {
 				tbf_new_state(tbf, GPRS_RLCMAC_FLOW);
 				tbf_assign_control_ts(tbf);
 			} else
diff --git a/src/tbf.h b/src/tbf.h
index d2aead2..84d558e 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -91,10 +91,13 @@ struct gprs_rlcmac_tbf {
 	static void free_all(struct gprs_rlcmac_trx *trx);
 	static void free_all(struct gprs_rlcmac_pdch *pdch);
 
+	bool state_is(enum gprs_rlcmac_tbf_state rhs) const;
+	bool state_is_not(enum gprs_rlcmac_tbf_state rhs) const;
+	void set_state(enum gprs_rlcmac_tbf_state new_state);
+
 	int rlcmac_diag();
 
 	struct llist_head list;
-	enum gprs_rlcmac_tbf_state state;
 	uint32_t state_flags;
 	enum gprs_rlcmac_tbf_direction direction;
 	uint8_t tfi;
@@ -187,6 +190,10 @@ struct gprs_rlcmac_tbf {
 	int diag; /* number where TBF is presented in diagram */
 	int diag_new; /* used to format output of new TBF */
 #endif
+
+	/* these should become protected but only after gprs_rlcmac_data.c
+	 * stops to iterate over all tbf in its current form */
+	enum gprs_rlcmac_tbf_state state;
 };
 
 
@@ -232,3 +239,18 @@ void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf);
 
 void tbf_timer_cb(void *_tbf);
 
+
+inline bool gprs_rlcmac_tbf::state_is(enum gprs_rlcmac_tbf_state rhs) const
+{
+	return state == rhs;
+}
+
+inline bool gprs_rlcmac_tbf::state_is_not(enum gprs_rlcmac_tbf_state rhs) const
+{
+	return state != rhs;
+}
+
+inline void gprs_rlcmac_tbf::set_state(enum gprs_rlcmac_tbf_state new_state)
+{
+	state = new_state;
+}
-- 
1.8.4.rc3





More information about the osmocom-net-gprs mailing list