pdch: Move the giant switch/case of gprs_rlcmac_rcv_control_block

Move the dispatch into the PDCH. This needs to be split up
further into understandable blocks.
diff --git a/src/bts.cpp b/src/bts.cpp
index 9567214..3c7ce40 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -571,6 +571,258 @@
 	return 0;
 }
 
+/* Received Uplink RLC control block. */
+int gprs_rlcmac_pdch::rcv_control_block(struct gprs_rlcmac_bts *bts,
+	bitvec *rlc_block, uint8_t trx, uint8_t ts,
+	uint32_t fn)
+{
+	int8_t tfi = 0; /* must be signed */
+	uint32_t tlli = 0;
+	struct gprs_rlcmac_tbf *tbf;
+	struct gprs_rlcmac_sba *sba;
+	int rc;
+
+	RlcMacUplink_t * ul_control_block = (RlcMacUplink_t *)talloc_zero(tall_pcu_ctx, RlcMacUplink_t);
+	LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++\n");
+	decode_gsm_rlcmac_uplink(rlc_block, ul_control_block);
+	LOGPC(DCSN1, LOGL_NOTICE, "\n");
+	LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- RX : Uplink Control Block -------------------------\n");
+	switch (ul_control_block->u.MESSAGE_TYPE) {
+	case MT_PACKET_CONTROL_ACK:
+		tlli = ul_control_block->u.Packet_Control_Acknowledgement.TLLI;
+		tbf = bts->bts->tbf_by_poll_fn(fn, trx, ts);
+		if (!tbf) {
+			LOGP(DRLCMAC, LOGL_NOTICE, "PACKET CONTROL ACK with "
+				"unknown FN=%u TLL=0x%08x (TRX %d TS %d)\n",
+				fn, tlli, trx, ts);
+			break;
+		}
+		tfi = tbf->tfi;
+		if (tlli != tbf->tlli) {
+			LOGP(DRLCMAC, LOGL_INFO, "Phone changed TLLI to "
+				"0x%08x\n", tlli);
+			tbf->tlli = tlli;
+		}
+		LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u TLLI: 0x%08x Packet Control Ack\n", tbf->tfi, tbf->tlli);
+		tbf->poll_state = GPRS_RLCMAC_POLL_NONE;
+
+		/* check if this control ack belongs to packet uplink ack */
+		if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) {
+			LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] END TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli);
+			tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE;
+			debug_diagram(bts->bts, tbf->diag, "got CTL-ACK (fin)");
+			if ((tbf->state_flags &
+				(1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) {
+				tbf->state_flags &=
+					~(1 << GPRS_RLCMAC_FLAG_TO_UL_ACK);
+				LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink "
+					"ack for UL TBF=%d\n", tbf->tfi);
+			}
+			tbf_free(tbf);
+			break;
+		}
+		if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) {
+			LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] DOWNLINK ASSIGNED TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli);
+			/* reset N3105 */
+			tbf->n3105 = 0;
+			tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
+			debug_diagram(bts->bts, tbf->diag, "got CTL-ACK DL-ASS");
+			if (tbf->direction == GPRS_RLCMAC_UL_TBF)
+				tbf = bts->bts->tbf_by_tlli(tbf->tlli,
+							GPRS_RLCMAC_DL_TBF);
+			if (!tbf) {
+				LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but DL "
+					"TBF is gone\n");
+				break;
+			}
+			tbf_new_state(tbf, GPRS_RLCMAC_FLOW);
+			/* stop pending assignment timer */
+			tbf_timer_stop(tbf);
+			if ((tbf->state_flags &
+				(1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) {
+				tbf->state_flags &=
+					~(1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);
+				LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink "
+					"assignment for DL TBF=%d\n", tbf->tfi);
+			}
+			tbf_assign_control_ts(tbf);
+			break;
+		}
+		if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) {
+			LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [DOWNLINK] UPLINK ASSIGNED TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli);
+			/* reset N3105 */
+			tbf->n3105 = 0;
+			tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
+			debug_diagram(bts->bts, tbf->diag, "got CTL-AC UL-ASS");
+			if (tbf->direction == GPRS_RLCMAC_DL_TBF)
+				tbf = bts->bts->tbf_by_tlli(tbf->tlli,
+							GPRS_RLCMAC_UL_TBF);
+			if (!tbf) {
+				LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but UL "
+					"TBF is gone\n");
+				break;
+			}
+			tbf_new_state(tbf, GPRS_RLCMAC_FLOW);
+			if ((tbf->state_flags &
+				(1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) {
+				tbf->state_flags &=
+					~(1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);
+				LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink "
+					"assignment for UL TBF=%d\n", tbf->tfi);
+			}
+			tbf_assign_control_ts(tbf);
+			break;
+		}
+		LOGP(DRLCMAC, LOGL_ERROR, "Error: received PACET CONTROL ACK "
+			"at no request\n");
+		break;
+	case MT_PACKET_DOWNLINK_ACK_NACK:
+		tfi = ul_control_block->u.Packet_Downlink_Ack_Nack.DOWNLINK_TFI;
+		tbf = bts->bts->tbf_by_poll_fn(fn, trx, ts);
+		if (!tbf) {
+			LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with "
+				"unknown FN=%u TFI=%d (TRX %d TS %d)\n",
+				fn, tfi, trx, ts);
+			break;
+		}
+		if (tbf->tfi != tfi) {
+			LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with "
+				"wrong TFI=%d, ignoring!\n", tfi);
+			break;
+		}
+		tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_DL_ACK);
+		if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {
+			tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
+			LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink ack "
+				"for DL TBF=%d\n", tbf->tfi);
+		}
+		/* reset N3105 */
+		tbf->n3105 = 0;
+		/* stop timer T3191 */
+		tbf_timer_stop(tbf);
+		tlli = tbf->tlli;
+		LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u TLLI: 0x%08x Packet Downlink Ack/Nack\n", tbf->tfi, tbf->tlli);
+		tbf->poll_state = GPRS_RLCMAC_POLL_NONE;
+		debug_diagram(bts->bts, tbf->diag, "got DL-ACK");
+
+		rc = gprs_rlcmac_downlink_ack(tbf,
+			ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.FINAL_ACK_INDICATION,
+			ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.STARTING_SEQUENCE_NUMBER,
+			ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.RECEIVED_BLOCK_BITMAP);
+		if (rc == 1) {
+			tbf_free(tbf);
+			break;
+		}
+		/* check for channel request */
+		if (ul_control_block->u.Packet_Downlink_Ack_Nack.Exist_Channel_Request_Description) {
+			LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack "
+				"message, so we provide one:\n");
+			tbf_alloc_ul(bts, tbf->trx_no, tbf->ms_class, tbf->tlli, tbf->ta, tbf);
+			/* schedule uplink assignment */
+			tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
+		}
+		break;
+	case MT_PACKET_RESOURCE_REQUEST:
+		if (ul_control_block->u.Packet_Resource_Request.ID.UnionType) {
+			tlli = ul_control_block->u.Packet_Resource_Request.ID.u.TLLI;
+			tbf = bts->bts->tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF);
+			if (tbf) {
+				LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
+					"TLLI=0x%08x while UL TBF=%d still "
+					"exists. Killing pending DL TBF\n",
+					tlli, tbf->tfi);
+				tbf_free(tbf);
+				tbf = NULL;
+			}
+			if (!tbf) {
+				uint8_t ms_class = 0;
+				struct gprs_rlcmac_tbf *dl_tbf;
+				uint8_t ta;
+
+				if ((dl_tbf = bts->bts->tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) {
+					LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
+						"TLLI=0x%08x while DL TBF=%d still exists. "
+						"Killing pending DL TBF\n", tlli,
+						dl_tbf->tfi);
+					tbf_free(dl_tbf);
+				}
+				LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF "
+					"in packet ressource request of single "
+					"block, so we provide one:\n");
+				sba = bts->bts->sba()->find(trx, ts, fn);
+				if (!sba) {
+					LOGP(DRLCMAC, LOGL_NOTICE, "MS requests UL TBF "
+						"in packet ressource request of single "
+						"block, but there is no resource request "
+						"scheduled!\n");
+					rc = bts->bts->timing_advance()->recall(tlli);
+					if (rc >= 0)
+						ta = rc;
+					else
+						ta = 0;
+				} else {
+					ta = sba->ta;
+					bts->bts->timing_advance()->remember(tlli, ta);
+					llist_del(&sba->list);
+					talloc_free(sba);
+				}
+				if (ul_control_block->u.Packet_Resource_Request.Exist_MS_Radio_Access_capability)
+					ms_class = Decoding::get_ms_class_by_capability(&ul_control_block->u.Packet_Resource_Request.MS_Radio_Access_capability);
+				if (!ms_class)
+					LOGP(DRLCMAC, LOGL_NOTICE, "MS does not give us a class.\n");
+				tbf = tbf_alloc_ul(bts, trx, ms_class, tlli, ta, NULL);
+				if (!tbf)
+					break;
+				/* set control ts to current MS's TS, until assignment complete */
+				LOGP(DRLCMAC, LOGL_DEBUG, "Change control TS to %d until assinment is complete.\n", ts);
+				tbf->control_ts = ts;
+				/* schedule uplink assignment */
+				tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
+				debug_diagram(bts->bts, tbf->diag, "Res. REQ");
+				break;
+			}
+			tfi = tbf->tfi;
+		} else {
+			if (ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.UnionType) {
+				tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.DOWNLINK_TFI;
+				tbf = tbf_by_tfi(bts, tfi, trx, GPRS_RLCMAC_DL_TBF);
+				if (!tbf) {
+					LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown downlink TBF=%d\n", tlli);
+					break;
+				}
+			} else {
+				tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.UPLINK_TFI;
+				tbf = tbf_by_tfi(bts, tfi, trx, GPRS_RLCMAC_UL_TBF);
+				if (!tbf) {
+					LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown uplink TBF=%d\n", tlli);
+					break;
+				}
+			}
+			tlli = tbf->tlli;
+		}
+		LOGP(DRLCMAC, LOGL_ERROR, "RX: [PCU <- BTS] %s TFI: %u TLLI: 0x%08x FIXME: Packet ressource request\n", (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, tbf->tlli);
+		break;
+	case MT_PACKET_MEASUREMENT_REPORT:
+		sba = bts->bts->sba()->find(trx, ts, fn);
+		if (!sba) {
+			LOGP(DRLCMAC, LOGL_NOTICE, "MS send measurement "
+				"in packet ressource request of single "
+				"block, but there is no resource request "
+				"scheduled!\n");
+		} else {
+			bts->bts->timing_advance()->remember(ul_control_block->u.Packet_Measurement_Report.TLLI, sba->ta);
+			llist_del(&sba->list);
+			talloc_free(sba);
+		}
+		gprs_rlcmac_meas_rep(&ul_control_block->u.Packet_Measurement_Report);
+		break;
+	default:
+		LOGP(DRLCMAC, LOGL_NOTICE, "RX: [PCU <- BTS] unknown control block received\n");
+	}
+	talloc_free(ul_control_block);
+	return 1;
+}
+
 
 /* received RLC/MAC block from L1 */
 int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn, int8_t rssi)
@@ -590,7 +842,7 @@
 		if (!block)
 			return -ENOMEM;
 		bitvec_unpack(block, data);
-		rc = gprs_rlcmac_rcv_control_block(bts, block, trx_no, ts_no, fn);
+		rc = rcv_control_block(bts, block, trx_no, ts_no, fn);
 		bitvec_free(block);
 		break;
 	case GPRS_RLCMAC_CONTROL_BLOCK_OPT:
diff --git a/src/bts.h b/src/bts.h
index 7eabfbc..541b9b2 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -76,6 +76,9 @@
 	int rcv_data_block_acknowledged(struct gprs_rlcmac_bts *bts,
 				uint8_t trx, uint8_t ts,
 				uint8_t *data, uint8_t len, int8_t rssi);
+	int rcv_control_block(struct gprs_rlcmac_bts *bts,
+				bitvec *rlc_block, uint8_t trx, uint8_t ts,
+				uint32_t fn);
 
 #endif
 };
diff --git a/src/decoding.cpp b/src/decoding.cpp
index 596b66e..e7ec99a 100644
--- a/src/decoding.cpp
+++ b/src/decoding.cpp
@@ -68,3 +68,18 @@
 	return 0;
 }
 
+uint8_t Decoding::get_ms_class_by_capability(MS_Radio_Access_capability_t *cap)
+{
+	int i;
+
+	for (i = 0; i < cap->Count_MS_RA_capability_value; i++) {
+		if (!cap->MS_RA_capability_value[i].u.Content.Exist_Multislot_capability)
+			continue;
+		if (!cap->MS_RA_capability_value[i].u.Content.Multislot_capability.Exist_GPRS_multislot_class)
+			continue;
+		return cap->MS_RA_capability_value[i].u.Content.Multislot_capability.GPRS_multislot_class;
+	}
+
+	return 0;
+}
+
diff --git a/src/decoding.h b/src/decoding.h
index 47983a2..0590eb4 100644
--- a/src/decoding.h
+++ b/src/decoding.h
@@ -19,10 +19,13 @@
  */
 #pragma once
 
+#include <gsm_rlcmac.h>
+
 #include <stdint.h>
 
 class Decoding {
 public:
 	static int tlli_from_ul_data(const uint8_t *data, uint8_t len,
 					uint32_t *tlli);
+	static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap);
 };
diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h
index af15e77..4fe5067 100644
--- a/src/gprs_rlcmac.h
+++ b/src/gprs_rlcmac.h
@@ -98,10 +98,6 @@
 
 int gprs_rlcmac_rcv_rach(struct gprs_rlcmac_bts *bts, uint8_t ra, uint32_t Fn, int16_t qta);
 
-int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts,
-	bitvec *rlc_block, uint8_t trx, uint8_t ts,
-	uint32_t fn);
-
 struct msgb *gprs_rlcmac_send_packet_uplink_assignment(
         struct gprs_rlcmac_tbf *tbf, uint32_t fn);
 
diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp
index f2887b2..1f81201 100644
--- a/src/gprs_rlcmac_data.cpp
+++ b/src/gprs_rlcmac_data.cpp
@@ -159,273 +159,6 @@
 	return 0;
 }
 
-static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap)
-{
-	int i;
-
-	for (i = 0; i < cap->Count_MS_RA_capability_value; i++) {
-		if (!cap->MS_RA_capability_value[i].u.Content.Exist_Multislot_capability)
-			continue;
-		if (!cap->MS_RA_capability_value[i].u.Content.Multislot_capability.Exist_GPRS_multislot_class)
-			continue;
-		return cap->MS_RA_capability_value[i].u.Content.Multislot_capability.GPRS_multislot_class;
-	}
-
-	return 0;
-}
-
-/* Received Uplink RLC control block. */
-int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts,
-	bitvec *rlc_block, uint8_t trx, uint8_t ts,
-	uint32_t fn)
-{
-	int8_t tfi = 0; /* must be signed */
-	uint32_t tlli = 0;
-	struct gprs_rlcmac_tbf *tbf;
-	struct gprs_rlcmac_sba *sba;
-	int rc;
-
-	RlcMacUplink_t * ul_control_block = (RlcMacUplink_t *)talloc_zero(tall_pcu_ctx, RlcMacUplink_t);
-	LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++\n");
-	decode_gsm_rlcmac_uplink(rlc_block, ul_control_block);
-	LOGPC(DCSN1, LOGL_NOTICE, "\n");
-	LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- RX : Uplink Control Block -------------------------\n");
-	switch (ul_control_block->u.MESSAGE_TYPE) {
-	case MT_PACKET_CONTROL_ACK:
-		tlli = ul_control_block->u.Packet_Control_Acknowledgement.TLLI;
-		tbf = bts->bts->tbf_by_poll_fn(fn, trx, ts);
-		if (!tbf) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "PACKET CONTROL ACK with "
-				"unknown FN=%u TLL=0x%08x (TRX %d TS %d)\n",
-				fn, tlli, trx, ts);
-			break;
-		}
-		tfi = tbf->tfi;
-		if (tlli != tbf->tlli) {
-			LOGP(DRLCMAC, LOGL_INFO, "Phone changed TLLI to "
-				"0x%08x\n", tlli);
-			tbf->tlli = tlli;
-		}
-		LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u TLLI: 0x%08x Packet Control Ack\n", tbf->tfi, tbf->tlli);
-		tbf->poll_state = GPRS_RLCMAC_POLL_NONE;
-
-		/* check if this control ack belongs to packet uplink ack */
-		if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) {
-			LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] END TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli);
-			tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE;
-			debug_diagram(bts->bts, tbf->diag, "got CTL-ACK (fin)");
-			if ((tbf->state_flags &
-				(1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) {
-				tbf->state_flags &=
-					~(1 << GPRS_RLCMAC_FLAG_TO_UL_ACK);
-				LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink "
-					"ack for UL TBF=%d\n", tbf->tfi);
-			}
-			tbf_free(tbf);
-			break;
-		}
-		if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) {
-			LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] DOWNLINK ASSIGNED TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli);
-			/* reset N3105 */
-			tbf->n3105 = 0;
-			tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
-			debug_diagram(bts->bts, tbf->diag, "got CTL-ACK DL-ASS");
-			if (tbf->direction == GPRS_RLCMAC_UL_TBF)
-				tbf = bts->bts->tbf_by_tlli(tbf->tlli,
-							GPRS_RLCMAC_DL_TBF);
-			if (!tbf) {
-				LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but DL "
-					"TBF is gone\n");
-				break;
-			}
-			tbf_new_state(tbf, GPRS_RLCMAC_FLOW);
-			/* stop pending assignment timer */
-			tbf_timer_stop(tbf);
-			if ((tbf->state_flags &
-				(1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) {
-				tbf->state_flags &=
-					~(1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);
-				LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink "
-					"assignment for DL TBF=%d\n", tbf->tfi);
-			}
-			tbf_assign_control_ts(tbf);
-			break;
-		}
-		if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) {
-			LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [DOWNLINK] UPLINK ASSIGNED TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli);
-			/* reset N3105 */
-			tbf->n3105 = 0;
-			tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
-			debug_diagram(bts->bts, tbf->diag, "got CTL-AC UL-ASS");
-			if (tbf->direction == GPRS_RLCMAC_DL_TBF)
-				tbf = bts->bts->tbf_by_tlli(tbf->tlli,
-							GPRS_RLCMAC_UL_TBF);
-			if (!tbf) {
-				LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but UL "
-					"TBF is gone\n");
-				break;
-			}
-			tbf_new_state(tbf, GPRS_RLCMAC_FLOW);
-			if ((tbf->state_flags &
-				(1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) {
-				tbf->state_flags &=
-					~(1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);
-				LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink "
-					"assignment for UL TBF=%d\n", tbf->tfi);
-			}
-			tbf_assign_control_ts(tbf);
-			break;
-		}
-		LOGP(DRLCMAC, LOGL_ERROR, "Error: received PACET CONTROL ACK "
-			"at no request\n");
-		break;
-	case MT_PACKET_DOWNLINK_ACK_NACK:
-		tfi = ul_control_block->u.Packet_Downlink_Ack_Nack.DOWNLINK_TFI;
-		tbf = bts->bts->tbf_by_poll_fn(fn, trx, ts);
-		if (!tbf) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with "
-				"unknown FN=%u TFI=%d (TRX %d TS %d)\n",
-				fn, tfi, trx, ts);
-			break;
-		}
-		if (tbf->tfi != tfi) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with "
-				"wrong TFI=%d, ignoring!\n", tfi);
-			break;
-		}
-		tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_DL_ACK);
-		if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {
-			tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
-			LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink ack "
-				"for DL TBF=%d\n", tbf->tfi);
-		}
-		/* reset N3105 */
-		tbf->n3105 = 0;
-		/* stop timer T3191 */
-		tbf_timer_stop(tbf);
-		tlli = tbf->tlli;
-		LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u TLLI: 0x%08x Packet Downlink Ack/Nack\n", tbf->tfi, tbf->tlli);
-		tbf->poll_state = GPRS_RLCMAC_POLL_NONE;
-		debug_diagram(bts->bts, tbf->diag, "got DL-ACK");
-
-		rc = gprs_rlcmac_downlink_ack(tbf,
-			ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.FINAL_ACK_INDICATION,
-			ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.STARTING_SEQUENCE_NUMBER,
-			ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.RECEIVED_BLOCK_BITMAP);
-		if (rc == 1) {
-			tbf_free(tbf);
-			break;
-		}
-		/* check for channel request */
-		if (ul_control_block->u.Packet_Downlink_Ack_Nack.Exist_Channel_Request_Description) {
-			LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack "
-				"message, so we provide one:\n");
-			tbf_alloc_ul(bts, tbf->trx_no, tbf->ms_class, tbf->tlli, tbf->ta, tbf);
-			/* schedule uplink assignment */
-			tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
-		}
-		break;
-	case MT_PACKET_RESOURCE_REQUEST:
-		if (ul_control_block->u.Packet_Resource_Request.ID.UnionType) {
-			tlli = ul_control_block->u.Packet_Resource_Request.ID.u.TLLI;
-			tbf = bts->bts->tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF);
-			if (tbf) {
-				LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
-					"TLLI=0x%08x while UL TBF=%d still "
-					"exists. Killing pending DL TBF\n",
-					tlli, tbf->tfi);
-				tbf_free(tbf);
-				tbf = NULL;
-			}
-			if (!tbf) {
-				uint8_t ms_class = 0;
-				struct gprs_rlcmac_tbf *dl_tbf;
-				uint8_t ta;
-
-				if ((dl_tbf = bts->bts->tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) {
-					LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
-						"TLLI=0x%08x while DL TBF=%d still exists. "
-						"Killing pending DL TBF\n", tlli,
-						dl_tbf->tfi);
-					tbf_free(dl_tbf);
-				}
-				LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF "
-					"in packet ressource request of single "
-					"block, so we provide one:\n");
-				sba = bts->bts->sba()->find(trx, ts, fn);
-				if (!sba) {
-					LOGP(DRLCMAC, LOGL_NOTICE, "MS requests UL TBF "
-						"in packet ressource request of single "
-						"block, but there is no resource request "
-						"scheduled!\n");
-					rc = bts->bts->timing_advance()->recall(tlli);
-					if (rc >= 0)
-						ta = rc;
-					else
-						ta = 0;
-				} else {
-					ta = sba->ta;
-					bts->bts->timing_advance()->remember(tlli, ta);
-					llist_del(&sba->list);
-					talloc_free(sba);
-				}
-				if (ul_control_block->u.Packet_Resource_Request.Exist_MS_Radio_Access_capability)
-					ms_class = get_ms_class_by_capability(&ul_control_block->u.Packet_Resource_Request.MS_Radio_Access_capability);
-				if (!ms_class)
-					LOGP(DRLCMAC, LOGL_NOTICE, "MS does not give us a class.\n");
-				tbf = tbf_alloc_ul(bts, trx, ms_class, tlli, ta, NULL);
-				if (!tbf)
-					break;
-				/* set control ts to current MS's TS, until assignment complete */
-				LOGP(DRLCMAC, LOGL_DEBUG, "Change control TS to %d until assinment is complete.\n", ts);
-				tbf->control_ts = ts;
-				/* schedule uplink assignment */
-				tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
-				debug_diagram(bts->bts, tbf->diag, "Res. REQ");
-				break;
-			}
-			tfi = tbf->tfi;
-		} else {
-			if (ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.UnionType) {
-				tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.DOWNLINK_TFI;
-				tbf = tbf_by_tfi(bts, tfi, trx, GPRS_RLCMAC_DL_TBF);
-				if (!tbf) {
-					LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown downlink TBF=%d\n", tlli);
-					break;
-				}
-			} else {
-				tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.UPLINK_TFI;
-				tbf = tbf_by_tfi(bts, tfi, trx, GPRS_RLCMAC_UL_TBF);
-				if (!tbf) {
-					LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown uplink TBF=%d\n", tlli);
-					break;
-				}
-			}
-			tlli = tbf->tlli;
-		}
-		LOGP(DRLCMAC, LOGL_ERROR, "RX: [PCU <- BTS] %s TFI: %u TLLI: 0x%08x FIXME: Packet ressource request\n", (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, tbf->tlli);
-		break;
-	case MT_PACKET_MEASUREMENT_REPORT:
-		sba = bts->bts->sba()->find(trx, ts, fn);
-		if (!sba) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "MS send measurement "
-				"in packet ressource request of single "
-				"block, but there is no resource request "
-				"scheduled!\n");
-		} else {
-			bts->bts->timing_advance()->remember(ul_control_block->u.Packet_Measurement_Report.TLLI, sba->ta);
-			llist_del(&sba->list);
-			talloc_free(sba);
-		}
-		gprs_rlcmac_meas_rep(&ul_control_block->u.Packet_Measurement_Report);
-		break;
-	default:
-		LOGP(DRLCMAC, LOGL_NOTICE, "RX: [PCU <- BTS] unknown control block received\n");
-	}
-	talloc_free(ul_control_block);
-	return 1;
-}
-
 #ifdef DEBUG_DL_ASS_IDLE
 	char debug_imsi[16];
 #endif