[PATCH] osmo-pcu[master]: Split TS allocation into digestable pieces

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Max gerrit-no-reply at lists.osmocom.org
Fri Sep 1 12:29:05 UTC 2017


Review at  https://gerrit.osmocom.org/3760

Split TS allocation into digestable pieces

Algorithm B implementation is way too big and complex to maintain or
even to follow the code. Split it into set of smaller functions with
documented interfaces to make it easier to read and modify. Also,
clarify types in function signatures, document them and drop those which
are unused.

This opens up the road for reusing those functions in implementation of
additional allocation algorithms. The test results are intentionally
left unchanged to avoid potential regressions.

Change-Id: I02da2b8ba8c9c8815dae0e39e1fed277ca0df171
Related: OS#2400
---
M src/bts.cpp
M src/bts.h
M src/gprs_rlcmac.h
M src/gprs_rlcmac_ts_alloc.cpp
M src/tbf.cpp
M src/tbf.h
M src/tbf_dl.cpp
M tests/alloc/AllocTest.cpp
M tests/tbf/TbfTest.cpp
9 files changed, 332 insertions(+), 240 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/60/3760/1

diff --git a/src/bts.cpp b/src/bts.cpp
index add6ab3..51d1c31 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -652,12 +652,11 @@
 		#warning "Copy and paste with other routines.."
 
 		if (is_11bit) {
-			tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0,
-				ms_class, 1);
+			tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, ms_class, true);
 		} else {
 			/* set class to 0, since we don't know the multislot
 			 * class yet */
-			tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1);
+			tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, true);
 		}
 
 		if (!tbf) {
diff --git a/src/bts.h b/src/bts.h
index b1fb8cc..1493f6e 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -203,11 +203,9 @@
 	struct gsmtap_inst *gsmtap;
 	uint32_t gsmtap_categ_mask;
 	struct gprs_rlcmac_trx trx[8];
-	int (*alloc_algorithm)(struct gprs_rlcmac_bts *bts,
-		struct GprsMs *ms,
-		struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single,
-		int use_tbf);
-	uint32_t alloc_algorithm_curst; /* options to customize algorithm */
+	int (*alloc_algorithm)(struct gprs_rlcmac_bts *bts, struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf,
+			       bool single, int8_t use_tbf);
+
 	uint8_t force_two_phase;
 	uint8_t alpha, gamma;
 	uint8_t egprs_enabled;
diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h
index be1e686..c16a954 100644
--- a/src/gprs_rlcmac.h
+++ b/src/gprs_rlcmac.h
@@ -21,6 +21,8 @@
 #ifndef GPRS_RLCMAC_H
 #define GPRS_RLCMAC_H
 
+#include <stdbool.h>
+
 #ifdef __cplusplus
 #include <gsm_rlcmac.h>
 #include <gsm_timer.h>
@@ -98,20 +100,14 @@
 
 extern "C" {
 #endif
-int alloc_algorithm_a(struct gprs_rlcmac_bts *bts,
-	struct GprsMs *ms,
-	struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single,
-	int use_trx);
+int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf, bool single,
+		      int8_t use_trx);
 
-int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
-	struct GprsMs *ms,
-	struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single,
-	int use_trx);
+int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf, bool single,
+		      int8_t use_trx);
 
-int alloc_algorithm_dynamic(struct gprs_rlcmac_bts *bts,
-	struct GprsMs *ms,
-	struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single,
-	int use_trx);
+int alloc_algorithm_dynamic(struct gprs_rlcmac_bts *bts, struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf, bool single,
+			    int8_t use_trx);
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp
index 57197b2..ad6f66f 100644
--- a/src/gprs_rlcmac_ts_alloc.cpp
+++ b/src/gprs_rlcmac_ts_alloc.cpp
@@ -300,26 +300,20 @@
 	pdch->attach_tbf(tbf);
 }
 
-static void assign_uplink_tbf_usf(
-				struct gprs_rlcmac_pdch *pdch,
-				struct gprs_rlcmac_ul_tbf *tbf,
-				int tfi, int8_t usf)
+static void assign_uplink_tbf_usf(struct gprs_rlcmac_pdch *pdch, struct gprs_rlcmac_ul_tbf *tbf, uint8_t tfi, int8_t usf)
 {
 	tbf->m_tfi = tfi;
 	tbf->m_usf[pdch->ts_no] = usf;
 	attach_tbf_to_pdch(pdch, tbf);
 }
 
-static void assign_dlink_tbf(
-				struct gprs_rlcmac_pdch *pdch,
-				struct gprs_rlcmac_dl_tbf *tbf,
-				int tfi)
+static void assign_dlink_tbf(struct gprs_rlcmac_pdch *pdch, struct gprs_rlcmac_dl_tbf *tbf, uint8_t tfi)
 {
 	tbf->m_tfi = tfi;
 	attach_tbf_to_pdch(pdch, tbf);
 }
 
-static int find_trx(BTS *bts, const GprsMs *ms, int use_trx)
+static int find_trx(BTS *bts, const GprsMs *ms, int8_t use_trx)
 {
 	unsigned trx_no;
 	unsigned ts;
@@ -377,11 +371,30 @@
 	return NULL;
 }
 
-static int tfi_find_free(BTS *bts, const GprsMs *ms,
-	enum gprs_rlcmac_tbf_direction dir, int use_trx, int *trx_no_)
+/*! Return free TFI
+ *
+ *  \param[in,out] bts Pointer to BTS struct
+ *  \param[in] trx Pointer to TRX struct
+ *  \param[in] ms Pointer to MS object
+ *  \param[in] dir DL or UL direction
+ *  \param[in] use_trx which TRX to use or -1 if it should be selected based on what MS uses
+ *  \param[out] trx_no_ TRX number on which TFI was found
+ *  \returns negative error code or 0 on success
+ */
+static int tfi_find_free(BTS *bts, const gprs_rlcmac_trx *trx, const GprsMs *ms,
+			 enum gprs_rlcmac_tbf_direction dir, int8_t use_trx, uint8_t *trx_no_)
 {
 	int tfi;
 	uint8_t trx_no;
+
+	if (trx) {
+		if (use_trx >= 0 && use_trx != trx->trx_no) {
+			LOGP(DRLCMAC, LOGL_ERROR, "- Requested incompatible TRX %d (current is %d)\n",
+			     use_trx, trx->trx_no);
+			return -EINVAL;
+		}
+		use_trx = trx->trx_no;
+	}
 
 	if (use_trx == -1 && ms->current_trx())
 		use_trx = ms->current_trx()->trx_no;
@@ -390,20 +403,24 @@
 	if (tfi < 0)
 		return -EBUSY;
 
-	if (trx_no_)
-		*trx_no_ = trx_no;
+	*trx_no_ = trx_no;
 
 	return tfi;
 }
 
-/* Slot Allocation: Algorithm A
+/*! Slot Allocation: Algorithm A
  *
  * Assign single slot for uplink and downlink
+ *
+ *  \param[in,out] bts Pointer to BTS struct
+ *  \param[in,out] ms_ Pointer to MS object
+ *  \param[in,out] tbf_ Pointer to TBF struct
+ *  \param[in] single flag indicating if we should force single-slot allocation
+ *  \param[in] use_trx which TRX to use or -1 if it should be selected during allocation
+ *  \returns negative error code or 0 on success
  */
-int alloc_algorithm_a(struct gprs_rlcmac_bts *bts,
-	GprsMs *ms_,
-	struct gprs_rlcmac_tbf *tbf_, uint32_t cust, uint8_t single,
-	int use_trx)
+int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, GprsMs *ms_, struct gprs_rlcmac_tbf *tbf_, bool single,
+		      int8_t use_trx)
 {
 	struct gprs_rlcmac_pdch *pdch;
 	int ts = -1;
@@ -488,9 +505,15 @@
 	return 0;
 }
 
-static int find_multi_slots(struct gprs_rlcmac_bts *bts,
-	struct gprs_rlcmac_trx *trx,
-	const GprsMs *ms, uint8_t *ul_slots, uint8_t *dl_slots)
+/*! Find set of slots available for allocation while taking MS class into account
+ *
+ *  \param[in,out] trx Pointer to TRX object
+ *  \param[in] ms Pointer to MS object
+ *  \param[in,out] ul_slots set of UL timeslots
+ *  \param[in,out] dl_slots set of DL timeslots
+ *  \returns negative error code or 0 on success
+ */
+static int find_multi_slots(struct gprs_rlcmac_trx *trx, const GprsMs *ms, uint8_t *ul_slots, uint8_t *dl_slots)
 {
 	const struct gprs_ms_multislot_class *ms_class;
 	uint8_t Tx, Sum;	/* Maximum Number of Slots: RX, Tx, Sum Rx+Tx */
@@ -796,15 +819,218 @@
 	return 0;
 }
 
-/* Slot Allocation: Algorithm B
+/*! Update MS' reserved timeslots
+ *
+ *  \param[in,out] trx Pointer to TRX struct
+ *  \param[in,out] ms_ Pointer to MS object
+ *  \param[in] tbf_ Pointer to TBF struct
+ *  \param[in] res_ul_slots Newly reserved UL slots
+ *  \param[in] res_dl_slots Newly reserved DL slots
+ *  \param[in] ul_slots available UL slots (for logging only)
+ *  \param[in] dl_slots available DL slots (for logging only)
+ */
+static void update_ms_reserved_slots(gprs_rlcmac_trx *trx, GprsMs *ms, uint8_t res_ul_slots, uint8_t res_dl_slots,
+				     uint8_t ul_slots, uint8_t dl_slots)
+{
+	char slot_info[9] = { 0 };
+
+	if (res_ul_slots == ms->reserved_ul_slots() && res_dl_slots == ms->reserved_dl_slots())
+		return;
+
+	/* The reserved slots have changed, update the MS */
+	ms->set_reserved_slots(trx, res_ul_slots, res_dl_slots);
+
+	LOGP(DRLCMAC, LOGL_DEBUG, "- Reserved DL/UL slots: (TS=0)\"%s\"(TS=7)\n",
+	     set_flag_chars(set_flag_chars(set_flag_chars(slot_info, dl_slots, 'D', '.'), ul_slots, 'U'),
+			    ul_slots & dl_slots, 'C'));
+}
+
+/*! Assign fiven UL timeslots to UL TBF
+ *
+ *  \param[in,out] ul_tbf Pointer to UL TBF struct
+ *  \param[in,out] trx Pointer to TRX object
+ *  \param[in] ul_slots Set of slots to be assigned
+ *  \param[in] tfi selected TFI
+ *  \param[in] usf selected USF
+ */
+static void assign_ul_tbf_slots(struct gprs_rlcmac_ul_tbf *ul_tbf, gprs_rlcmac_trx *trx, uint8_t ul_slots, int tfi,
+				int *usf)
+{
+	uint8_t ts;
+
+	for (ts = 0; ts < 8; ts++) {
+		if (!(ul_slots & (1 << ts)))
+			continue;
+
+		OSMO_ASSERT(usf[ts] >= 0);
+
+		LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning UL TS %u\n", ts);
+		assign_uplink_tbf_usf(&trx->pdch[ts], ul_tbf, tfi, usf[ts]);
+	}
+}
+
+/*! Assign fiven DL timeslots to DL TBF
+ *
+ *  \param[in,out] dl_tbf Pointer to DL TBF struct
+ *  \param[in,out] trx Pointer to TRX object
+ *  \param[in] ul_slots Set of slots to be assigned
+ *  \param[in] tfi selected TFI
+ */
+static void assign_dl_tbf_slots(struct gprs_rlcmac_dl_tbf *dl_tbf, gprs_rlcmac_trx *trx, uint8_t dl_slots, int tfi)
+{
+	uint8_t ts;
+
+	for (ts = 0; ts < 8; ts++) {
+		if (!(dl_slots & (1 << ts)))
+			continue;
+
+		LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning DL TS %u\n", ts);
+		assign_dlink_tbf(&trx->pdch[ts], dl_tbf, tfi);
+	}
+}
+
+/*! Update timeslot counters
+ *
+ *  \param[in] slots Timeslots in use
+ *  \param[in] reserved_slots Reserved timeslots
+ *  \param[out] slotcount Number of TS in use
+ *  \param[out] avail_count Number of reserved TS
+ */
+static void update_slot_counters(uint8_t slots, uint8_t reserved_slots, uint8_t *slotcount, uint8_t *avail_count)
+{
+	(*slotcount) = pcu_bitcount(slots);
+	(*avail_count) = pcu_bitcount(reserved_slots);
+}
+
+/*! Return single TS from a given UL/DL set according to TBF's direction
+ *
+ *  \param[in,out] trx Pointer to TRX object
+ *  \param[in] tbf Pointer to TBF object
+ *  \param[in] dl_slots set of DL timeslots
+ *  \param[in] ul_slots set of UL timeslots
+ *  \param[in,out] ts corresponding TS or -1 for autoselection
+ *  \returns UL or DL timeslot number
+ */
+static uint8_t get_slots_single(gprs_rlcmac_trx *trx, const gprs_rlcmac_tbf *tbf, uint8_t dl_slots, uint8_t ul_slots,
+				int *ts)
+{
+	uint8_t ret = dl_slots & ul_slots; /* Make sure to consider the first common slot only */
+
+	if (*ts < 0)
+		*ts = find_least_busy_pdch(trx, tbf->direction, ret, compute_usage_by_num_tbfs, NULL, NULL);
+
+	if (*ts < 0)
+		return pcu_lsb(ret);
+
+	return ret & (1 << (*ts));
+}
+
+/*! Find set of UL timeslots available for allocation
+ *
+ *  \param[in,out] trx Pointer to TRX object
+ *  \param[in] tbf Pointer to TBF object
+ *  \param[in] single Flag to force the single TS allocation
+ *  \param[in] dl_slots set of DL timeslots
+ *  \param[in] reserved_ul_slots set of reserved UL timeslots
+ *  \param[in] first_common_ts First TS common for both UL and DL or -1 if unknown
+ *  \param[in,out] usf USF array
+ *  \param[in,out] ul_slots set of UL timeslots
+ *  \param[out] slotcount Number of selected UL timeslots
+ *  \param[out] avail_count Number of available UL timeslots
+ *  \returns negative error code or first selected TS on success
+ */
+static int get_ul_slot_set(gprs_rlcmac_trx *trx, const gprs_rlcmac_tbf *tbf, bool single, uint8_t dl_slots,
+			   uint8_t reserved_ul_slots, int8_t first_common_ts,
+			   int *usf, uint8_t *ul_slots, uint8_t *slotcount, uint8_t *avail_count)
+{
+	int ts = first_common_ts;
+	char slot_info[9] = { 0 };
+	int free_usf = -1;
+
+	if (single)
+		(*ul_slots) = get_slots_single(trx, tbf, dl_slots, *ul_slots, &ts);
+
+	if ((*ul_slots) == 0) {
+		LOGP(DRLCMAC, LOGL_NOTICE, "No uplink slots available\n");
+		return -EINVAL;
+	}
+
+	if (first_common_ts >= 0)
+		(*ul_slots) = 1 << first_common_ts;
+	else
+		(*ul_slots) = (*ul_slots) & dl_slots;
+
+	ts = find_least_busy_pdch(trx, GPRS_RLCMAC_UL_TBF, *ul_slots, compute_usage_by_num_tbfs, NULL, &free_usf);
+
+	if (free_usf < 0) {
+		LOGP(DRLCMAC, LOGL_NOTICE, "No USF available\n");
+		return -EBUSY;
+	}
+	OSMO_ASSERT(ts >= 0 && ts <= 8);
+
+	(*ul_slots) = 1 << ts;
+	usf[ts] = free_usf;
+
+	LOGP(DRLCMAC, LOGL_DEBUG, "- Selected UL slots: (TS=0)\"%s\"(TS=7)%s\n",
+	     set_flag_chars(set_flag_chars(slot_info, reserved_ul_slots, 'u', '.'), *ul_slots, 'U'),
+	     single ? ", single" : "");
+
+	update_slot_counters(*ul_slots, reserved_ul_slots, slotcount, avail_count);
+
+	return ts;
+}
+
+/*! Find set of DL timeslots available for allocation
+ *
+ *  \param[in,out] trx Pointer to TRX object
+ *  \param[in] tbf Pointer to TBF object
+ *  \param[in] single Flag to force the single TS allocation
+ *  \param[in] ul_slots set of UL timeslots
+ *  \param[in] reserved_dl_slots set of reserved DL timeslots
+ *  \param[in] first_common_ts First TS common for both UL and DL or -1 if unknown
+ *  \param[in,out] dl_slots set of DL timeslots
+ *  \param[out] slotcount Number of selected UL timeslots
+ *  \param[out] avail_count Number of available UL timeslots
+ *  \returns negative error code or first selected TS on success
+ */
+static int get_dl_slot_set(gprs_rlcmac_trx *trx, const gprs_rlcmac_tbf *tbf, bool single, uint8_t ul_slots,
+			   uint8_t reserved_dl_slots, int8_t first_common_ts,
+			   uint8_t *dl_slots, uint8_t *slotcount, uint8_t *avail_count)
+{
+	int ts = first_common_ts;
+	char slot_info[9] = { 0 };
+
+	if (single)
+		(*dl_slots) = get_slots_single(trx, tbf, *dl_slots, ul_slots, &ts);
+
+	if ((*dl_slots) == 0) {
+		LOGP(DRLCMAC, LOGL_NOTICE, "No downlink slots available\n");
+		return -EINVAL;
+	}
+
+	LOGP(DRLCMAC, LOGL_DEBUG, "- Selected DL slots: (TS=0)\"%s\"(TS=7)%s\n",
+	     set_flag_chars(set_flag_chars(slot_info, reserved_dl_slots, 'd', '.'), (*dl_slots), 'D'),
+	     single ? ", single" : "");
+
+	update_slot_counters(*dl_slots, reserved_dl_slots, slotcount, avail_count);
+
+	return ffs(*dl_slots) - 1;
+}
+
+/*! Slot Allocation: Algorithm B
  *
  * Assign as many downlink slots as possible.
  * Assign one uplink slot. (With free USF)
  *
+ *  \param[in,out] bts Pointer to BTS struct
+ *  \param[in,out] ms_ Pointer to MS object
+ *  \param[in,out] tbf_ Pointer to TBF struct
+ *  \param[in] single flag indicating if we should force single-slot allocation
+ *  \param[in] use_trx which TRX to use or -1 if it should be selected during allocation
+ *  \returns negative error code or 0 on success
  */
-int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
-	GprsMs *ms_, struct gprs_rlcmac_tbf *tbf_,
-	uint32_t cust, uint8_t single, int use_trx)
+int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, GprsMs *ms_, struct gprs_rlcmac_tbf *tbf_, bool single,
+		      int8_t use_trx)
 {
 	uint8_t dl_slots;
 	uint8_t ul_slots;
@@ -812,14 +1038,11 @@
 	uint8_t reserved_ul_slots;
 	int8_t first_common_ts;
 	uint8_t slotcount = 0;
-	uint8_t avail_count = 0;
-	char slot_info[9] = {0};
-	int ts;
+	uint8_t avail_count = 0, trx_no;
 	int first_ts = -1;
 	int usf[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
 	int rc;
 	int tfi;
-	int trx_no;
 	const GprsMs *ms = ms_;
 	const gprs_rlcmac_tbf *tbf = tbf_;
 	gprs_rlcmac_trx *trx;
@@ -836,18 +1059,8 @@
 	first_common_ts = ms->first_common_ts();
 	trx = ms->current_trx();
 
-	if (trx) {
-		if (use_trx >= 0 && use_trx != trx->trx_no) {
-			LOGP(DRLCMAC, LOGL_ERROR,
-				"- Requested incompatible TRX %d (current is %d)\n",
-				use_trx, trx->trx_no);
-			return -EINVAL;
-		}
-		use_trx = trx->trx_no;
-	}
-
 	/* Step 2a: Find usable TRX and TFI */
-	tfi = tfi_find_free(bts->bts, ms, tbf->direction, use_trx, &trx_no);
+	tfi = tfi_find_free(bts->bts, trx, ms, tbf->direction, use_trx, &trx_no);
 	if (tfi < 0) {
 		LOGP(DRLCMAC, LOGL_NOTICE, "- Failed to allocate a TFI\n");
 		return tfi;
@@ -858,7 +1071,7 @@
 		trx = &bts->trx[trx_no];
 
 	if (!dl_slots || !ul_slots) {
-		rc = find_multi_slots(bts, trx, ms, &ul_slots, &dl_slots);
+		rc = find_multi_slots(trx, ms, &ul_slots, &dl_slots);
 		if (rc < 0)
 			return rc;
 
@@ -867,95 +1080,25 @@
 	}
 
 	/* Step 3: Derive the slot set for the current TBF */
-	if (single) {
-		/* Make sure to consider the first common slot only */
-		ul_slots = dl_slots = dl_slots & ul_slots;
-
-		ts = first_common_ts;
-
-		if (ts < 0)
-			ts = find_least_busy_pdch(trx, tbf->direction,
-				dl_slots & ul_slots, compute_usage_by_num_tbfs,
-				NULL, NULL);
-		if (ts < 0)
-			ul_slots = dl_slots = pcu_lsb(dl_slots & ul_slots);
-		else
-			ul_slots = dl_slots = (dl_slots & ul_slots) & (1<<ts);
-	}
-
-	if (dl_slots == 0) {
-		LOGP(DRLCMAC, LOGL_NOTICE, "No downlink slots available\n");
-		return -EINVAL;
-	}
-
-	if (ul_slots == 0) {
-		LOGP(DRLCMAC, LOGL_NOTICE, "No uplink slots available\n");
-		return -EINVAL;
-	}
-
 	if (tbf->direction == GPRS_RLCMAC_DL_TBF) {
-		LOGP(DRLCMAC, LOGL_DEBUG,
-			"- Selected DL slots: (TS=0)\"%s\"(TS=7)%s\n",
-			set_flag_chars(set_flag_chars(slot_info,
-					reserved_dl_slots, 'd', '.'),
-					dl_slots, 'D'),
-			single ? ", single" : "");
-
-		/* assign downlink */
-		if (dl_slots == 0) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "No downlink slots "
-				"available\n");
-			return -EINVAL;
-		}
-		slotcount = pcu_bitcount(dl_slots);
-		first_ts = ffs(dl_slots) - 1;
-		avail_count = pcu_bitcount(reserved_dl_slots);
-
+		first_ts = get_dl_slot_set(trx, tbf, single, ul_slots, reserved_dl_slots, first_common_ts,
+					   &dl_slots, &slotcount, &avail_count);
 	} else {
-		int free_usf = -1;
-
-		if (first_common_ts >= 0)
-			ul_slots = 1 << first_common_ts;
-		else
-			ul_slots = ul_slots & dl_slots;
-
-		ts = find_least_busy_pdch(trx, GPRS_RLCMAC_UL_TBF,
-			ul_slots, compute_usage_by_num_tbfs,
-			NULL, &free_usf);
-
-		if (free_usf < 0) {
-			LOGP(DRLCMAC, LOGL_NOTICE, "No USF available\n");
-			return -EBUSY;
-		}
-		OSMO_ASSERT(ts >= 0 && ts <= 8);
-
-		ul_slots = 1 << ts;
-		usf[ts] = free_usf;
-
-		LOGP(DRLCMAC, LOGL_DEBUG,
-			"- Selected UL slots: (TS=0)\"%s\"(TS=7)%s\n",
-			set_flag_chars(set_flag_chars(slot_info,
-					reserved_ul_slots, 'u', '.'),
-					ul_slots, 'U'),
-			single ? ", single" : "");
-
-		slotcount++;
-		first_ts = ts;
+		first_ts = get_ul_slot_set(trx, tbf, single, dl_slots, reserved_ul_slots, first_common_ts, usf,
+					   &ul_slots, &slotcount, &avail_count);
 
 		/* We will stick to that single UL slot, unreserve the others */
+		slotcount = 1;
 		reserved_ul_slots = ul_slots;
-
-		avail_count = pcu_bitcount(reserved_ul_slots);
 	}
+
+	if (first_ts < 0)
+		return -EINVAL;
 
 	first_common_ts = ffs(dl_slots & ul_slots) - 1;
 
 	if (first_common_ts < 0) {
 		LOGP(DRLCMAC, LOGL_NOTICE, "No first common slots available\n");
-		return -EINVAL;
-	}
-	if (first_ts < 0) {
-		LOGP(DRLCMAC, LOGL_NOTICE, "No first slot available\n");
 		return -EINVAL;
 	}
 
@@ -974,58 +1117,23 @@
 	 * may be modified from now on. */
 
 	/* Step 4: Update MS and TBF and really allocate the resources */
-
-	/* The reserved slots have changed, update the MS */
-	if (reserved_ul_slots != ms->reserved_ul_slots() ||
-		reserved_dl_slots != ms->reserved_dl_slots())
-	{
-		ms_->set_reserved_slots(trx,
-			reserved_ul_slots, reserved_dl_slots);
-
-		LOGP(DRLCMAC, LOGL_DEBUG,
-			"- Reserved DL/UL slots: (TS=0)\"%s\"(TS=7)\n",
-			set_flag_chars(set_flag_chars(set_flag_chars(slot_info,
-				dl_slots, 'D', '.'),
-				ul_slots, 'U'),
-				ul_slots & dl_slots, 'C'));
-	}
+	update_ms_reserved_slots(trx, ms_, reserved_ul_slots, reserved_dl_slots, ul_slots, dl_slots);
 
 	tbf_->trx = trx;
 	tbf_->first_common_ts = first_common_ts;
 	tbf_->first_ts = first_ts;
 
-	if (tbf->direction == GPRS_RLCMAC_DL_TBF) {
-		struct gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf_);
-		for (ts = 0; ts < 8; ts++) {
-			if (!(dl_slots & (1 << ts)))
-				continue;
-
-			LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning DL TS "
-				"%d\n", ts);
-			assign_dlink_tbf(&trx->pdch[ts], dl_tbf, tfi);
-		}
-	} else {
-		struct gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf_);
-
-		for (ts = 0; ts < 8; ts++) {
-			if (!(ul_slots & (1 << ts)))
-				continue;
-
-			OSMO_ASSERT(usf[ts] >= 0);
-
-			LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning UL TS "
-				"%d\n", ts);
-			assign_uplink_tbf_usf(&trx->pdch[ts], ul_tbf,
-				tfi, usf[ts]);
-		}
-	}
+	if (tbf->direction == GPRS_RLCMAC_DL_TBF)
+		assign_dl_tbf_slots(as_dl_tbf(tbf_), trx, dl_slots, tfi);
+	else
+		assign_ul_tbf_slots(as_ul_tbf(tbf_), trx, ul_slots, tfi, usf);
 
 	bts->bts->tbf_alloc_algo_b();
 
 	return 0;
 }
 
-/* Slot Allocation: Algorithm dynamic
+/*! Slot Allocation: Algorithm dynamic
  *
  * This meta algorithm automatically selects on of the other algorithms based
  * on the current system state.
@@ -1033,10 +1141,15 @@
  * The goal is to support as many MS and TBF as possible. On low usage, the
  * goal is to provide the highest possible bandwidth per MS.
  *
+ *  \param[in,out] bts Pointer to BTS struct
+ *  \param[in,out] ms_ Pointer to MS object
+ *  \param[in,out] tbf_ Pointer to TBF struct
+ *  \param[in] single flag indicating if we should force single-slot allocation
+ *  \param[in] use_trx which TRX to use or -1 if it should be selected during allocation
+ *  \returns negative error code or 0 on success
  */
-int alloc_algorithm_dynamic(struct gprs_rlcmac_bts *bts,
-	GprsMs *ms_, struct gprs_rlcmac_tbf *tbf_,
-	uint32_t cust, uint8_t single, int use_trx)
+int alloc_algorithm_dynamic(struct gprs_rlcmac_bts *bts, GprsMs *ms_, struct gprs_rlcmac_tbf *tbf_, bool single,
+			    int8_t use_trx)
 {
 	int rc;
 
@@ -1048,7 +1161,7 @@
 	}
 
 	if (!bts->multislot_disabled) {
-		rc = alloc_algorithm_b(bts, ms_, tbf_, cust, single, use_trx);
+		rc = alloc_algorithm_b(bts, ms_, tbf_, single, use_trx);
 		if (rc >= 0)
 			return rc;
 
@@ -1057,7 +1170,7 @@
 		bts->multislot_disabled = 1;
 	}
 
-	rc = alloc_algorithm_a(bts, ms_, tbf_, cust, single, use_trx);
+	rc = alloc_algorithm_a(bts, ms_, tbf_, single, use_trx);
 	return rc;
 }
 
diff --git a/src/tbf.cpp b/src/tbf.cpp
index c5f4348..0e617ab 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -385,7 +385,7 @@
 #warning "Copy and paste with tbf_new_dl_assignment"
 	/* create new TBF, use same TRX as DL TBF */
 	/* use multislot class of downlink TBF */
-	tbf = tbf_alloc_ul_tbf(bts, ms, use_trx, ms_class, egprs_ms_class, 0);
+	tbf = tbf_alloc_ul_tbf(bts, ms, use_trx, ms_class, egprs_ms_class, false);
 	if (!tbf) {
 		LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
 		/* FIXME: send reject */
@@ -489,8 +489,7 @@
 		return -EINVAL;
 
 	tbf_unlink_pdch(this);
-	rc = bts_data->alloc_algorithm(bts_data, ms(), this,
-		bts_data->alloc_algorithm_curst, 0, -1);
+	rc = bts_data->alloc_algorithm(bts_data, ms(), this, 0, -1);
 	/* if no resource */
 	if (rc < 0) {
 		LOGP(DRLCMAC, LOGL_ERROR, "No resource after update???\n");
@@ -752,9 +751,8 @@
 		LOGP(DRLCMAC, LOGL_ERROR, "- Poll Timeout, but no event!\n");
 }
 
-static int setup_tbf(struct gprs_rlcmac_tbf *tbf,
-	GprsMs *ms, int8_t use_trx,
-	uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot)
+static int setup_tbf(struct gprs_rlcmac_tbf *tbf, GprsMs *ms, int8_t use_trx, uint8_t ms_class, uint8_t egprs_ms_class,
+		     bool single_slot)
 {
 	int rc;
 	struct gprs_rlcmac_bts *bts;
@@ -769,8 +767,7 @@
 	tbf->m_created_ts = time(NULL);
 	tbf->set_ms_class(ms_class);
 	/* select algorithm */
-	rc = bts->alloc_algorithm(bts, ms, tbf, bts->alloc_algorithm_curst,
-		single_slot, use_trx);
+	rc = bts->alloc_algorithm(bts, ms, tbf, single_slot, use_trx);
 	/* if no resource */
 	if (rc < 0) {
 		return -1;
@@ -830,9 +827,8 @@
 	}
 }
 
-struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
-	GprsMs *ms, int8_t use_trx,
-	uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot)
+struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx, uint8_t ms_class,
+					    uint8_t egprs_ms_class, bool single_slot)
 {
 	struct gprs_rlcmac_ul_tbf *tbf;
 	int rc;
@@ -921,9 +917,8 @@
 	return 0;
 }
 
-struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
-	GprsMs *ms, int8_t use_trx,
-	uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot)
+struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx, uint8_t ms_class,
+					    uint8_t egprs_ms_class, bool single_slot)
 {
 	struct gprs_rlcmac_dl_tbf *tbf;
 	int rc;
@@ -1314,9 +1309,8 @@
 
 	bts->tbf_reused();
 
-	new_tbf = tbf_alloc_dl_tbf(bts->bts_data(), ms(),
-		this->trx->trx_no, ms_class(),
-		ms() ?  ms()->egprs_ms_class() : 0, 0);
+	new_tbf = tbf_alloc_dl_tbf(bts->bts_data(), ms(), this->trx->trx_no, ms_class(),
+				   ms() ?  ms()->egprs_ms_class() : 0, false);
 
 	if (!new_tbf) {
 		LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
diff --git a/src/tbf.h b/src/tbf.h
index 95e1e89..8f92149 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -314,13 +314,11 @@
 	int8_t use_trx, uint8_t ms_class, uint8_t egprs_ms_class,
 	uint32_t tlli, uint8_t ta, GprsMs *ms);
 
-struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
-	GprsMs *ms, int8_t use_trx,
-	uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot);
+struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx, uint8_t ms_class,
+					    uint8_t egprs_ms_class, bool single_slot);
 
-struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
-	GprsMs *ms, int8_t use_trx,
-	uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot);
+struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx, uint8_t ms_class,
+					    uint8_t egprs_ms_class, bool single_slot);
 
 void tbf_free(struct gprs_rlcmac_tbf *tbf);
 
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index b350720..7fd1131 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -118,7 +118,7 @@
 				const uint8_t egprs_ms_class,
 				struct gprs_rlcmac_dl_tbf **tbf)
 {
-	uint8_t ss;
+	bool ss;
 	int8_t use_trx;
 	uint16_t ta = GSM48_TA_INVALID;
 	struct gprs_rlcmac_ul_tbf *ul_tbf = NULL, *old_ul_tbf;
@@ -136,11 +136,11 @@
 	if (ul_tbf && ul_tbf->m_contention_resolution_done
 	 && !ul_tbf->m_final_ack_sent) {
 		use_trx = ul_tbf->trx->trx_no;
-		ss = 0;
+		ss = false;
 		old_ul_tbf = ul_tbf;
 	} else {
 		use_trx = -1;
-		ss = 1; /* PCH assignment only allows one timeslot */
+		ss = true; /* PCH assignment only allows one timeslot */
 		old_ul_tbf = NULL;
 	}
 
diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp
index e26c432..271f966 100644
--- a/tests/alloc/AllocTest.cpp
+++ b/tests/alloc/AllocTest.cpp
@@ -39,7 +39,7 @@
 static gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts,
 		GprsMs *ms, gprs_rlcmac_tbf_direction dir,
 		uint8_t use_trx,
-		uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot)
+		uint8_t ms_class, uint8_t egprs_ms_class, bool single_slot)
 {
 	if (dir == GPRS_RLCMAC_UL_TBF)
 		return tbf_alloc_ul_tbf(bts, ms, use_trx,
@@ -202,7 +202,7 @@
 		trx->pdch[6].enable();
 		trx->pdch[7].enable();
 
-		ul_tbf = tbf_alloc_ul_tbf(bts, NULL, -1, ms_class, 0, 1);
+		ul_tbf = tbf_alloc_ul_tbf(bts, NULL, -1, ms_class, 0, true);
 		OSMO_ASSERT(ul_tbf);
 		OSMO_ASSERT(ul_tbf->ms());
 		OSMO_ASSERT(ul_tbf->ms()->current_trx());
@@ -210,7 +210,7 @@
 		dump_assignment(ul_tbf, "UL");
 
 		/* assume final ack has not been sent */
-		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf->ms(), trx_no, ms_class, 0, 0);
+		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf->ms(), trx_no, ms_class, 0, false);
 		OSMO_ASSERT(dl_tbf);
 		dump_assignment(dl_tbf, "DL");
 
@@ -244,7 +244,7 @@
 		trx->pdch[6].enable();
 		trx->pdch[7].enable();
 
-		dl_tbf = tbf_alloc_dl_tbf(bts, NULL, -1, ms_class, 0, 1);
+		dl_tbf = tbf_alloc_dl_tbf(bts, NULL, -1, ms_class, 0, true);
 		dl_tbf->update_ms(0x23, GPRS_RLCMAC_DL_TBF);
 		OSMO_ASSERT(dl_tbf);
 		OSMO_ASSERT(dl_tbf->ms());
@@ -252,7 +252,7 @@
 		trx_no = dl_tbf->ms()->current_trx()->trx_no;
 		dump_assignment(dl_tbf, "DL");
 
-		ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf->ms(), trx_no, ms_class, 0, 0);
+		ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf->ms(), trx_no, ms_class, 0, false);
 		ul_tbf->update_ms(0x23, GPRS_RLCMAC_UL_TBF);
 		ul_tbf->m_contention_resolution_done = 1;
 		OSMO_ASSERT(ul_tbf);
@@ -294,7 +294,7 @@
 
 		tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
 		OSMO_ASSERT(tfi >= 0);
-		ul_tbf = tbf_alloc_ul_tbf(bts, NULL, .1, ms_class, 0, 0);
+		ul_tbf = tbf_alloc_ul_tbf(bts, NULL, .1, ms_class, 0, false);
 		OSMO_ASSERT(ul_tbf);
 		OSMO_ASSERT(ul_tbf->ms());
 		OSMO_ASSERT(ul_tbf->ms()->current_trx());
@@ -302,7 +302,7 @@
 		dump_assignment(ul_tbf, "UL");
 
 		/* assume final ack has not been sent */
-		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf->ms(), trx_no, ms_class, 0, 0);
+		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf->ms(), trx_no, ms_class, 0, false);
 		OSMO_ASSERT(dl_tbf);
 		dump_assignment(dl_tbf, "DL");
 
@@ -357,14 +357,14 @@
 		ENABLE_PDCH(6, ts6, trx);
 		ENABLE_PDCH(7, ts7, trx);
 
-		ul_tbf = tbf_alloc_ul_tbf(bts, NULL, -1, ms_class, 0, 1);
+		ul_tbf = tbf_alloc_ul_tbf(bts, NULL, -1, ms_class, 0, true);
 		OSMO_ASSERT(ul_tbf->ms());
 		OSMO_ASSERT(ul_tbf->ms()->current_trx());
 		trx_no = ul_tbf->ms()->current_trx()->trx_no;
 		OSMO_ASSERT(ul_tbf);
 
 		/* assume final ack has not been sent */
-		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf->ms(), trx_no, ms_class, 0, 0);
+		dl_tbf = tbf_alloc_dl_tbf(bts, ul_tbf->ms(), trx_no, ms_class, 0, false);
 		OSMO_ASSERT(dl_tbf);
 
 		/* verify that both are on the same ts */
@@ -401,14 +401,14 @@
 		ENABLE_PDCH(6, ts6, trx);
 		ENABLE_PDCH(7, ts7, trx);
 
-		dl_tbf = tbf_alloc_dl_tbf(bts, NULL, -1, ms_class, 0, 1);
+		dl_tbf = tbf_alloc_dl_tbf(bts, NULL, -1, ms_class, 0, true);
 		OSMO_ASSERT(dl_tbf);
 		OSMO_ASSERT(dl_tbf->ms());
 		OSMO_ASSERT(dl_tbf->ms()->current_trx());
 		trx_no = dl_tbf->ms()->current_trx()->trx_no;
 		dl_tbf->update_ms(0x23, GPRS_RLCMAC_DL_TBF);
 
-		ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf->ms(), trx_no, ms_class, 0, 0);
+		ul_tbf = tbf_alloc_ul_tbf(bts, dl_tbf->ms(), trx_no, ms_class, 0, false);
 		OSMO_ASSERT(ul_tbf);
 		ul_tbf->update_ms(0x23, GPRS_RLCMAC_UL_TBF);
 		ul_tbf->m_contention_resolution_done = 1;
@@ -452,10 +452,8 @@
 	test_all_alloc_b();
 }
 
-typedef int (*algo_t)(struct gprs_rlcmac_bts *bts,
-		struct GprsMs *ms,
-		struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single,
-		int use_trx);
+typedef int (*algo_t)(struct gprs_rlcmac_bts *bts, struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf, bool single,
+		      int8_t use_trx);
 
 static char get_dir_char(uint8_t mask, uint8_t tx, uint8_t rx, uint8_t busy)
 {
@@ -497,7 +495,7 @@
 	case TEST_MODE_UL_AND_DL:
 		if (ms && ms->ul_tbf())
 			tbf_free(ms->ul_tbf());
-		tbf = tbf_alloc_ul_tbf(bts, ms, trx_no, ms_class, 0, 0);
+		tbf = tbf_alloc_ul_tbf(bts, ms, trx_no, ms_class, 0, false);
 		if (tbf == NULL)
 			return NULL;
 		break;
@@ -506,7 +504,7 @@
 	case TEST_MODE_DL_AND_UL:
 		if (ms && ms->dl_tbf())
 			tbf_free(ms->dl_tbf());
-		tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, ms_class, 0, 0);
+		tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, ms_class, 0, false);
 		if (tbf == NULL)
 			return NULL;
 	}
@@ -813,7 +811,7 @@
 	trx->pdch[6].enable();
 	trx->pdch[7].enable();
 
-	dl_tbf1 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0);
+	dl_tbf1 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, false);
 	OSMO_ASSERT(dl_tbf1);
 
 	for (int i = 0; i < 8; i++) {
@@ -823,7 +821,7 @@
 	OSMO_ASSERT(numTs1 == 4);
 	printf("TBF1: numTs(%d)\n", numTs1);
 
-	dl_tbf2 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, 0);
+	dl_tbf2 = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, egprs_ms_class, false);
 	OSMO_ASSERT(dl_tbf2);
 
 	for (int i = 0; i < 8; i++) {
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index 0db7fde..43a6142 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -81,16 +81,12 @@
 	/*
 	 * Make a uplink and downlink allocation
 	 */
-	gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(the_bts.bts_data(),
-						NULL,
-						0, 0, 0, 0);
+	gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(the_bts.bts_data(), NULL, 0, 0, 0, false);
 	OSMO_ASSERT(dl_tbf != NULL);
 	dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF);
 	dl_tbf->set_ta(4);
 
-	gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts.bts_data(),
-						dl_tbf->ms(),
-						0, 0, 0, 0);
+	gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), dl_tbf->ms(), 0, 0, 0, false);
 	OSMO_ASSERT(ul_tbf != NULL);
 	ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF);
 
@@ -170,7 +166,7 @@
 
 	tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);
 	OSMO_ASSERT(tfi >= 0);
-	dl_tbf = tbf_alloc_dl_tbf(bts, NULL, trx_no, ms_class, egprs_ms_class, 1);
+	dl_tbf = tbf_alloc_dl_tbf(bts, NULL, trx_no, ms_class, egprs_ms_class, true);
 	dl_tbf->set_ta(0);
 	check_tbf(dl_tbf);
 
@@ -2209,7 +2205,7 @@
 		1234, 1234, 1234, 1, 1, 0, 0, 0);
 
 	/* Does no support EGPRS */
-	dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, 0, 0);
+	dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, 0, false);
 	OSMO_ASSERT(dl_tbf != NULL);
 	fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
 		dl_tbf->dl_slots(),
@@ -2223,7 +2219,7 @@
 	bts->egprs_enabled = 1;
 
 	/* Does support EGPRS */
-	dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, 0);
+	dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, false);
 
 	OSMO_ASSERT(dl_tbf != NULL);
 	fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
@@ -2267,7 +2263,7 @@
 	bts->egprs_enabled = 1;
 
 	/* Does support EGPRS */
-	dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, 1);
+	dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, true);
 
 	OSMO_ASSERT(dl_tbf != NULL);
 	fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",

-- 
To view, visit https://gerrit.osmocom.org/3760
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I02da2b8ba8c9c8815dae0e39e1fed277ca0df171
Gerrit-PatchSet: 1
Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>



More information about the gerrit-log mailing list