tbf: Move gprs_rlcmac_poll_timeout into the tbf

Move the gprs_rlcmac_poll_timeout method into the tbf class and
gprs_rlcmac_downlink_assignment into the BTS.
diff --git a/src/bts.cpp b/src/bts.cpp
index 0e45188..8bb0f26 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -24,6 +24,7 @@
 #include <encoding.h>
 #include <decoding.h>
 #include <rlc.h>
+#include <pcu_l1_if.h>
 
 #include <gprs_rlcmac.h>
 #include <gprs_debug.h>
@@ -330,6 +331,24 @@
 	return 0;
 }
 
+void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi)
+{
+	int plen;
+
+	debug_diagram(this, tbf->diag, "IMM.ASS (PCH)");
+	LOGP(DRLCMAC, LOGL_INFO, "TX: START TFI: %u TLLI: 0x%08x Immediate Assignment Downlink (PCH)\n", tbf->tfi, tbf->tlli);
+	bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */
+	bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
+	/* use request reference that has maximum distance to current time,
+	 * so the assignment will not conflict with possible RACH requests. */
+	plen = Encoding::write_immediate_assignment(&m_bts, immediate_assignment, 1, 125,
+		(tbf->pdch[tbf->first_ts]->last_rts_fn + 21216) % 2715648, tbf->ta,
+		tbf->arfcn, tbf->first_ts, tbf->tsc, tbf->tfi, 0, tbf->tlli, poll,
+		tbf->poll_fn, 0, m_bts.alpha, m_bts.gamma, -1);
+	pcu_l1if_tx_pch(immediate_assignment, plen, imsi);
+	bitvec_free(immediate_assignment);
+}
+
 
 /*
  * PDCH code below. TODO: move to a separate file
diff --git a/src/bts.h b/src/bts.h
index 25c6473..608f215 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -170,6 +170,8 @@
 
 	int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn);
 
+	void snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi);
+
 private:
 	int m_cur_fn;
 	struct gprs_rlcmac_bts m_bts;
diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h
index f5a0ee6..6184a51 100644
--- a/src/gprs_rlcmac.h
+++ b/src/gprs_rlcmac.h
@@ -94,8 +94,6 @@
 
 int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf);
 
-int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf);
-
 int gprs_rlcmac_rcv_rach(struct gprs_rlcmac_bts *bts, uint8_t ra, uint32_t Fn, int16_t qta);
 
 struct msgb *gprs_rlcmac_send_packet_uplink_assignment(
diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp
index 00afa86..b016c76 100644
--- a/src/gprs_rlcmac_data.cpp
+++ b/src/gprs_rlcmac_data.cpp
@@ -46,114 +46,6 @@
 #define POLLING_ASSIGNMENT_UL 1
 
 
-static void gprs_rlcmac_downlink_assignment(
-	gprs_rlcmac_tbf *tbf, uint8_t poll,
-	const char *imsi);
-
-int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf)
-{
-	LOGP(DRLCMAC, LOGL_NOTICE, "Poll timeout for %s TBF=%d\n",
-		(tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi);
-
-	tbf->poll_state = GPRS_RLCMAC_POLL_NONE;
-
-	if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) {
-		if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
-				"PACKET CONTROL ACK for PACKET UPLINK ACK\n");
-			tbf->rlcmac_diag();
-			tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK);
-		}
-		tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE;
-		debug_diagram(bts->bts, tbf->diag, "timeout UL-ACK");
-		if (tbf->state_is(GPRS_RLCMAC_FINISHED)) {
-			tbf->dir.ul.n3103++;
-			if (tbf->dir.ul.n3103 == bts->n3103) {
-				LOGP(DRLCMAC, LOGL_NOTICE,
-					"- N3103 exceeded\n");
-				debug_diagram(bts->bts, tbf->diag, "N3103 exceeded");
-				tbf_new_state(tbf, GPRS_RLCMAC_RELEASING);
-				tbf_timer_start(tbf, 3169, bts->t3169, 0);
-				return 0;
-			}
-			/* reschedule UL ack */
-			tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_SEND_ACK;
-		}
-	} else
-	if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) {
-		if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
-				"PACKET CONTROL ACK for PACKET UPLINK "
-				"ASSIGNMENT.\n");
-			tbf->rlcmac_diag();
-			tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);
-		}
-		tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
-		debug_diagram(tbf->bts, tbf->diag, "timeout UL-ASS");
-		tbf->n3105++;
-		if (tbf->n3105 == bts->n3105) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
-			debug_diagram(bts->bts, tbf->diag, "N3105 exceeded");
-			tbf_new_state(tbf, GPRS_RLCMAC_RELEASING);
-			tbf_timer_start(tbf, 3195, bts->t3195, 0);
-			return 0;
-		}
-		/* reschedule UL assignment */
-		tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
-	} else
-	if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) {
-		if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
-				"PACKET CONTROL ACK for PACKET DOWNLINK "
-				"ASSIGNMENT.\n");
-			tbf->rlcmac_diag();
-			tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);
-		}
-		tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
-		debug_diagram(bts->bts, tbf->diag, "timeout DL-ASS");
-		tbf->n3105++;
-		if (tbf->n3105 == bts->n3105) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
-			debug_diagram(bts->bts, tbf->diag, "N3105 exceeded");
-			tbf_new_state(tbf, GPRS_RLCMAC_RELEASING);
-			tbf_timer_start(tbf, 3195, bts->t3195, 0);
-			return 0;
-		}
-		/* reschedule DL assignment */
-		tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
-	} else
-	if (tbf->direction == GPRS_RLCMAC_DL_TBF) {
-		if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
-				"PACKET DOWNLINK ACK.\n");
-			tbf->rlcmac_diag();
-			tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
-		}
-		debug_diagram(bts->bts, tbf->diag, "timeout DL-ACK");
-		tbf->n3105++;
-		if (tbf->n3105 == bts->n3105) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
-			debug_diagram(bts->bts, tbf->diag, "N3105 exceeded");
-			tbf_new_state(tbf, GPRS_RLCMAC_RELEASING);
-			tbf_timer_start(tbf, 3195, bts->t3195, 0);
-			return 0;
-		}
-		/* resend IMM.ASS on CCCH on timeout */
-		if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))
-		 && !(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) {
-			LOGP(DRLCMAC, LOGL_DEBUG, "Re-send dowlink assignment "
-				"for TBF=%d on PCH (IMSI=%s)\n", tbf->tfi,
-				tbf->dir.dl.imsi);
-			/* send immediate assignment */
-			gprs_rlcmac_downlink_assignment(tbf, 0, tbf->dir.dl.imsi);
-			tbf->dir.dl.wait_confirm = 1;
-		}
-	} else
-		LOGP(DRLCMAC, LOGL_ERROR, "- Poll Timeout, but no event!\n");
-
-	return 0;
-}
-
 #ifdef DEBUG_DL_ASS_IDLE
 	char debug_imsi[16];
 #endif
@@ -931,27 +823,6 @@
 	return msg;
 }
 
-static void gprs_rlcmac_downlink_assignment(
-	gprs_rlcmac_tbf *tbf, uint8_t poll,
-	const char *imsi)
-{
-	gprs_rlcmac_bts *bts = tbf->bts->bts_data();
-	int plen;
-
-	debug_diagram(bts->bts, tbf->diag, "IMM.ASS (PCH)");
-	LOGP(DRLCMAC, LOGL_INFO, "TX: START TFI: %u TLLI: 0x%08x Immediate Assignment Downlink (PCH)\n", tbf->tfi, tbf->tlli);
-	bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */
-	bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
-	/* use request reference that has maximum distance to current time,
-	 * so the assignment will not conflict with possible RACH requests. */
-	plen = Encoding::write_immediate_assignment(bts, immediate_assignment, 1, 125,
-		(tbf->pdch[tbf->first_ts]->last_rts_fn + 21216) % 2715648, tbf->ta,
-		tbf->arfcn, tbf->first_ts, tbf->tsc, tbf->tfi, 0, tbf->tlli, poll,
-		tbf->poll_fn, 0, bts->alpha, bts->gamma, -1);
-	pcu_l1if_tx_pch(immediate_assignment, plen, imsi);
-	bitvec_free(immediate_assignment);
-}
-
 /* depending on the current TBF, we assign on PACCH or AGCH */
 void gprs_rlcmac_trigger_downlink_assignment(
 	struct gprs_rlcmac_tbf *tbf,
@@ -997,7 +868,7 @@
 		tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH);
 		strncpy(tbf->dir.dl.imsi, imsi, sizeof(tbf->dir.dl.imsi));
 		/* send immediate assignment */
-		gprs_rlcmac_downlink_assignment(tbf, 0, imsi);
+		tbf->bts->snd_dl_ass(tbf, 0, imsi);
 		tbf->dir.dl.wait_confirm = 1;
 	}
 }
diff --git a/src/poll_controller.cpp b/src/poll_controller.cpp
index 115a68f..0f46472 100644
--- a/src/poll_controller.cpp
+++ b/src/poll_controller.cpp
@@ -41,7 +41,7 @@
 			elapsed = (frame_number + 2715648 - tbf->poll_fn)
 								% 2715648;
 			if (elapsed >= 20 && elapsed < 2715400)
-				gprs_rlcmac_poll_timeout(bts, tbf);
+				tbf->poll_timeout();
 		}
 	}
 	llist_for_each_entry(tbf, &bts->dl_tbfs, list) {
@@ -49,7 +49,7 @@
 			elapsed = (frame_number + 2715648 - tbf->poll_fn)
 								% 2715648;
 			if (elapsed >= 20 && elapsed < 2715400)
-				gprs_rlcmac_poll_timeout(bts, tbf);
+				tbf->poll_timeout();
 		}
 	}
 	llist_for_each_entry_safe(sba, sba2, &m_bts.sba()->m_sbas, list) {
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 4225b3b..0321c40 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -42,6 +42,11 @@
 
 static void tbf_timer_cb(void *_tbf);
 
+inline gprs_rlcmac_bts *gprs_rlcmac_tbf::bts_data() const
+{
+	return bts->bts_data();
+}
+
 static inline void tbf_update_ms_class(struct gprs_rlcmac_tbf *tbf,
 					const uint8_t ms_class)
 {
@@ -407,6 +412,105 @@
 	}
 }
 
+void gprs_rlcmac_tbf::poll_timeout()
+{
+	LOGP(DRLCMAC, LOGL_NOTICE, "Poll timeout for %s TBF=%d\n",
+		(direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tfi);
+
+	poll_state = GPRS_RLCMAC_POLL_NONE;
+
+	if (ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) {
+		if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) {
+			LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
+				"PACKET CONTROL ACK for PACKET UPLINK ACK\n");
+			rlcmac_diag();
+			state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK);
+		}
+		ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE;
+		debug_diagram(bts, this->diag, "timeout UL-ACK");
+		if (state_is(GPRS_RLCMAC_FINISHED)) {
+			dir.ul.n3103++;
+			if (dir.ul.n3103 == bts->bts_data()->n3103) {
+				LOGP(DRLCMAC, LOGL_NOTICE,
+					"- N3103 exceeded\n");
+				debug_diagram(bts, diag, "N3103 exceeded");
+				tbf_new_state(this, GPRS_RLCMAC_RELEASING);
+				tbf_timer_start(this, 3169, bts->bts_data()->t3169, 0);
+				return;
+			}
+			/* reschedule UL ack */
+			ul_ack_state = GPRS_RLCMAC_UL_ACK_SEND_ACK;
+		}
+	} else if (ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) {
+		if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) {
+			LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
+				"PACKET CONTROL ACK for PACKET UPLINK "
+				"ASSIGNMENT.\n");
+			rlcmac_diag();
+			state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);
+		}
+		ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
+		debug_diagram(bts, diag, "timeout UL-ASS");
+		n3105++;
+		if (n3105 == bts_data()->n3105) {
+			LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
+			debug_diagram(bts, diag, "N3105 exceeded");
+			tbf_new_state(this, GPRS_RLCMAC_RELEASING);
+			tbf_timer_start(this, 3195, bts_data()->t3195, 0);
+			return;
+		}
+		/* reschedule UL assignment */
+		ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
+	} else if (dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) {
+		if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) {
+			LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
+				"PACKET CONTROL ACK for PACKET DOWNLINK "
+				"ASSIGNMENT.\n");
+			rlcmac_diag();
+			state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);
+		}
+		dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
+		debug_diagram(bts, diag, "timeout DL-ASS");
+		n3105++;
+		if (n3105 == bts->bts_data()->n3105) {
+			LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
+			debug_diagram(bts, diag, "N3105 exceeded");
+			tbf_new_state(this, GPRS_RLCMAC_RELEASING);
+			tbf_timer_start(this, 3195, bts_data()->t3195, 0);
+			return;
+		}
+		/* reschedule DL assignment */
+		dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
+	} else if (direction == GPRS_RLCMAC_DL_TBF) {
+		if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {
+			LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
+				"PACKET DOWNLINK ACK.\n");
+			rlcmac_diag();
+			state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
+		}
+		debug_diagram(bts, diag, "timeout DL-ACK");
+		n3105++;
+		if (n3105 == bts->bts_data()->n3105) {
+			LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
+			debug_diagram(bts, diag, "N3105 exceeded");
+			tbf_new_state(this, GPRS_RLCMAC_RELEASING);
+			tbf_timer_start(this, 3195, bts_data()->t3195, 0);
+			return;
+		}
+		/* resend IMM.ASS on CCCH on timeout */
+		if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))
+		 && !(state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) {
+			LOGP(DRLCMAC, LOGL_DEBUG, "Re-send dowlink assignment "
+				"for TBF=%d on PCH (IMSI=%s)\n", tfi,
+				dir.dl.imsi);
+			/* send immediate assignment */
+			bts->snd_dl_ass(this, 0, dir.dl.imsi);
+			dir.dl.wait_confirm = 1;
+		}
+	} else
+		LOGP(DRLCMAC, LOGL_ERROR, "- Poll Timeout, but no event!\n");
+}
+
 struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts,
 	struct gprs_rlcmac_tbf *old_tbf, enum gprs_rlcmac_tbf_direction dir,
 	uint8_t tfi, uint8_t trx,
diff --git a/src/tbf.h b/src/tbf.h
index 0f8e77d..4afc649 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -106,6 +106,8 @@
 	void stop_timer();
 	void stop_t3191();
 
+	void poll_timeout();
+
 	struct llist_head list;
 	uint32_t state_flags;
 	enum gprs_rlcmac_tbf_direction direction;
@@ -207,6 +209,9 @@
 
 	/* store the BTS this TBF belongs to */
 	BTS *bts;
+
+protected:
+	gprs_rlcmac_bts *bts_data() const;
 };