/* gprs_rlcmac.cpp
 *
 * Copyright (C) 2012 Ivan Klyuchnikov
 * Copyright (C) 2012 Andreas Eversberg <jolly@eversberg.eu>
 * Copyright (C) 2013 by Holger Hans Peter Freyther
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <gprs_rlcmac.h>
#include <gprs_debug.h>
#include <bts.h>
#include <tbf.h>

#include <errno.h>

/* 3GPP TS 05.02 Annex B.1 */

#define MS_NA	255 /* N/A */
#define MS_A	254 /* 1 with hopping, 0 without */
#define MS_B	253 /* 1 with hopping, 0 without (change Rx to Tx)*/
#define MS_C	252 /* 1 with hopping, 0 without (change Tx to Rx)*/

struct gprs_ms_multislot_class {
	uint8_t rx, tx, sum;	/* Maximum Number of Slots: RX, Tx, Sum Rx+Tx */
	uint8_t ta, tb, ra, rb;	/* Minimum Number of Slots */
	uint8_t type; /* Type of Mobile */
};

static const struct gprs_ms_multislot_class gprs_ms_multislot_class[32] = {
/* M-S Class	  Rx	Tx	Sum	Tta	Ttb	Tra	Trb	Type */
/* N/A */	{ MS_NA,MS_NA,	MS_NA,	MS_NA,	MS_NA,	MS_NA,	MS_NA,	MS_NA },
/* 1 */		{ 1,	1,	2,	3,	2,	4,	2,	1 },
/* 2 */		{ 2,	1,	3,	3,	2,	3,	1,	1 },
/* 3 */		{ 2,	2,	3,	3,	2,	3,	1,	1 },
/* 4 */		{ 3,	1,	4,	3,	1,	3,	1,	1 },
/* 5 */		{ 2,	2,	4,	3,	1,	3,	1,	1 },
/* 6 */		{ 3,	2,	4,	3,	1,	3,	1,	1 },
/* 7 */		{ 3,	3,	4,	3,	1,	3,	1,	1 },
/* 8 */		{ 4,	1,	5,	3,	1,	2,	1,	1 },
/* 9 */		{ 3,	2,	5,	3,	1,	2,	1,	1 },
/* 10 */	{ 4,	2,	5,	3,	1,	2,	1,	1 },
/* 11 */	{ 4,	3,	5,	3,	1,	2,	1,	1 },
/* 12 */	{ 4,	4,	5,	2,	1,	2,	1,	1 },
/* 13 */	{ 3,	3,	MS_NA,	MS_NA,	MS_A,	3,	MS_A,	2 },
/* 14 */	{ 4,	4,	MS_NA,	MS_NA,	MS_A,	3,	MS_A,	2 },
/* 15 */	{ 5,	5,	MS_NA,	MS_NA,	MS_A,	3,	MS_A,	2 },
/* 16 */	{ 6,	6,	MS_NA,	MS_NA,	MS_A,	2,	MS_A,	2 },
/* 17 */	{ 7,	7,	MS_NA,	MS_NA,	MS_A,	1,	0,	2 },
/* 18 */	{ 8,	8,	MS_NA,	MS_NA,	0,	0,	0,	2 },
/* 19 */	{ 6,	2,	MS_NA,	3,	MS_B,	2,	MS_C,	1 },
/* 20 */	{ 6,	3,	MS_NA,	3,	MS_B,	2,	MS_C,	1 },
/* 21 */	{ 6,	4,	MS_NA,	3,	MS_B,	2,	MS_C,	1 },
/* 22 */	{ 6,	4,	MS_NA,	2,	MS_B,	2,	MS_C,	1 },
/* 23 */	{ 6,	6,	MS_NA,	2,	MS_B,	2,	MS_C,	1 },
/* 24 */	{ 8,	2,	MS_NA,	3,	MS_B,	2,	MS_C,	1 },
/* 25 */	{ 8,	3,	MS_NA,	3,	MS_B,	2,	MS_C,	1 },
/* 26 */	{ 8,	4,	MS_NA,	3,	MS_B,	2,	MS_C,	1 },
/* 27 */	{ 8,	4,	MS_NA,	2,	MS_B,	2,	MS_C,	1 },
/* 28 */	{ 8,	6,	MS_NA,	2,	MS_B,	2,	MS_C,	1 },
/* 29 */	{ 8,	8,	MS_NA,	2,	MS_B,	2,	MS_C,	1 },
/* N/A */	{ MS_NA,MS_NA,	MS_NA,	MS_NA,	MS_NA,	MS_NA,	MS_NA,	MS_NA },
/* N/A */	{ MS_NA,MS_NA,	MS_NA,	MS_NA,	MS_NA,	MS_NA,	MS_NA,	MS_NA },
};

static inline int8_t find_free_usf(struct gprs_rlcmac_pdch *pdch)
{
	struct gprs_rlcmac_ul_tbf *tbf;
	uint8_t usf_map = 0;
	uint8_t tfi, usf;

	/* make map of used USF */
	for (tfi = 0; tfi < 32; tfi++) {
		tbf = pdch->ul_tbf_by_tfi(tfi);
		if (!tbf)
			continue;
		usf_map |= (1 << tbf->m_usf[pdch->ts_no]);
	}

	/* look for USF, don't use USF=7 */
	for (usf = 0; usf < 7; usf++) {
		if (!(usf_map & (1 << usf)))
			return usf;
	}

	return -1;
}

static int find_enabled_pdch(struct gprs_rlcmac_trx *trx, const uint8_t start_ts)
{
	int ts;
	for (ts = start_ts; ts < 8; ts++) {
		struct gprs_rlcmac_pdch *pdch;

		pdch = &trx->pdch[ts];
		if (!pdch->is_enabled()) {
			LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because "
				"not enabled\n", ts);
			continue;
		}
		return ts;
	}

	return 8;
}

static void assign_uplink_tbf_usf(
				struct gprs_rlcmac_pdch *pdch,
				struct gprs_rlcmac_ul_tbf *tbf, int8_t usf)
{
	tbf->trx->ul_tbf[tbf->tfi()] = tbf;
	tbf->pdch[pdch->ts_no] = pdch;
	tbf->m_usf[pdch->ts_no] = usf;
}

static void assign_dlink_tbf(
				struct gprs_rlcmac_pdch *pdch,
				struct gprs_rlcmac_dl_tbf *tbf)
{
	tbf->trx->dl_tbf[tbf->tfi()] = tbf;
	tbf->pdch[pdch->ts_no] = pdch;
}


/* Slot Allocation: Algorithm A
 *
 * Assign single slot for uplink and downlink
 */
int alloc_algorithm_a(struct gprs_rlcmac_bts *bts,
	struct gprs_rlcmac_tbf *old_tbf,
	struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single)
{
	struct gprs_rlcmac_pdch *pdch;
	uint8_t ts;

	LOGP(DRLCMAC, LOGL_DEBUG, "Slot Allocation (Algorithm A) for class "
		"%d\n", tbf->ms_class);

	ts = find_enabled_pdch(tbf->trx, 0);
	if (ts == 8)
		return -EINVAL;

	pdch = &tbf->trx->pdch[ts];
	if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
		int8_t usf; /* must be signed */
		struct gprs_rlcmac_ul_tbf *ul_tbf = static_cast<gprs_rlcmac_ul_tbf *>(tbf);

		/* if USF available */
		usf = find_free_usf(pdch);
		if (usf < 0) {
			LOGP(DRLCMAC, LOGL_NOTICE, "- Failed "
				"allocating TS=%d, no USF available\n", ts);
			return -EBUSY;
		}
		LOGP(DRLCMAC, LOGL_DEBUG, "- Assign uplink "
			"TS=%d USF=%d\n", ts, usf);
		assign_uplink_tbf_usf(pdch, ul_tbf, usf);
	} else {
		struct gprs_rlcmac_dl_tbf *dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(tbf);
		LOGP(DRLCMAC, LOGL_DEBUG, "- Assign downlink TS=%d\n", ts);
		assign_dlink_tbf(pdch, dl_tbf);
	}
	/* the only one TS is the common TS */
	tbf->first_ts = tbf->first_common_ts = ts;

	tbf->upgrade_to_multislot = 0;

	return 0;
}

/*
 * Select a window of Rx slots if available.
 * The maximum allowed slots depend on RX or the window of available
 * slots. This must be done for uplink TBF also, because it is the basis
 * for calculating control slot and uplink slot(s).
 */
static uint8_t select_dl_slots(struct gprs_rlcmac_trx *trx,
			const int ms_type, const int ms_max_rxslots,
			uint8_t *out_rx_win_min, uint8_t *out_rx_win_max)

{
	uint8_t rx_window = 0;
	int rx_window_size = 0;
	int8_t last_tsc = -1; /* must be signed */
	uint8_t rx_win_min = 0, rx_win_max = 0;

	for (int ts_no = 0; ts_no < 8; ts_no++) {
		struct gprs_rlcmac_pdch *pdch;
		pdch = &trx->pdch[ts_no];

		/* check if enabled */
		if (!pdch->is_enabled()) {
			LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because "
				"not enabled\n", ts_no);
			if (ms_type == 1 && rx_window)
				goto inc_window;
			continue;
		}
		/* check if TSC changes */
		if (last_tsc < 0)
			last_tsc = pdch->tsc;
		else if (last_tsc != pdch->tsc) {
			LOGP(DRLCMAC, LOGL_ERROR, "Skipping TS %d of TRX=%d, "
				"because it has different TSC than lower TS "
				"of TRX. In order to allow multislot, all "
				"slots must be configured with the same "
				"TSC!\n", ts_no, trx->trx_no);
			if (ms_type == 1 && rx_window)
				goto inc_window;
			continue;
		}

		if (!rx_window)
			rx_win_min = ts_no;

		rx_window |= (1 << ts_no);
		LOGP(DRLCMAC, LOGL_DEBUG, "- Selected DL TS %d\n", ts_no);

		/* range of window (required for Type 1) */
		rx_win_max = ts_no;

inc_window:
		if (++rx_window_size == ms_max_rxslots) {
			LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because slots / "
				"window reached maximum alowed Rx size\n");
			break;
		}
		if (ms_type == 1 && rx_window_size == 5) {
			LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because slots / "
				"window reached maximum supported Rx size of "
				"this algorithm\n");
			break;
		}
	}

	LOGP(DRLCMAC, LOGL_DEBUG, "- Selected slots for RX: "
		"(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n",
		((rx_window & 0x01)) ? 'D' : '.',
		((rx_window & 0x02)) ? 'D' : '.',
		((rx_window & 0x04)) ? 'D' : '.',
		((rx_window & 0x08)) ? 'D' : '.',
		((rx_window & 0x10)) ? 'D' : '.',
		((rx_window & 0x20)) ? 'D' : '.',
		((rx_window & 0x40)) ? 'D' : '.',
		((rx_window & 0x80)) ? 'D' : '.');

	*out_rx_win_min = rx_win_min;
	*out_rx_win_max = rx_win_max;
	return rx_window;
}

static int reduce_rx_window(const int ms_type, const struct gprs_rlcmac_tbf *old_tbf,
				const int Tt, const int Tr,
				int *rx_window,
				uint8_t *rx_win_min, uint8_t *rx_win_max)
{
	if (ms_type != 1)
		return 0;
	if (!old_tbf)
		return 0;
	if (old_tbf->direction != GPRS_RLCMAC_UL_TBF)
		return 0;

	uint8_t collide = 0, ul_usage = 0;

	/* calculate mask of colliding slots */
	for (uint8_t ts_no = 0; ts_no < 8; ts_no++) {
		int j;
		if (!old_tbf->pdch[ts_no])
			continue;

		ul_usage |= (1 << ts_no);
		/* mark bits from TS-t .. TS+r */
		for (j = (ts_no - Tt) & 7; j != ((ts_no + Tr + 1) & 7); j = (j + 1) & 7)
			collide |= (1 << j);
	}

	LOGP(DRLCMAC, LOGL_DEBUG, "- Not allowed slots due to existing "
		"UL allocation: (TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7) "
		" D=downlink  x=not usable\n",
		((ul_usage & 0x01)) ? 'D' : ((collide & 0x01))?'x':'.',
		((ul_usage & 0x02)) ? 'D' : ((collide & 0x02))?'x':'.',
		((ul_usage & 0x04)) ? 'D' : ((collide & 0x04))?'x':'.',
		((ul_usage & 0x08)) ? 'D' : ((collide & 0x08))?'x':'.',
		((ul_usage & 0x10)) ? 'D' : ((collide & 0x10))?'x':'.',
		((ul_usage & 0x20)) ? 'D' : ((collide & 0x20))?'x':'.',
		((ul_usage & 0x40)) ? 'D' : ((collide & 0x40))?'x':'.',
		((ul_usage & 0x80)) ? 'D' : ((collide & 0x80))?'x':'.');

	/*
	 * Uplink/Downlink in GSM is shifted by three timeslots. Make
	 * sure they don't collide.
	 */
	*rx_window &= ~(collide << 3);
	*rx_window &= ~(collide >> 5);
	LOGP(DRLCMAC, LOGL_DEBUG, "- Remaining slots for RX: "
		"(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n",
		((*rx_window & 0x01)) ? 'D' : '.',
		((*rx_window & 0x02)) ? 'D' : '.',
		((*rx_window & 0x04)) ? 'D' : '.',
		((*rx_window & 0x08)) ? 'D' : '.',
		((*rx_window & 0x10)) ? 'D' : '.',
		((*rx_window & 0x20)) ? 'D' : '.',
		((*rx_window & 0x40)) ? 'D' : '.',
		((*rx_window & 0x80)) ? 'D' : '.');

	if (!*rx_window) {
		LOGP(DRLCMAC, LOGL_NOTICE, "No suitable downlink slots "
			"available with current uplink assignment\n");
		return -EBUSY;
	}

	return 0;
}

/* shrink range of rx_win_min and rx_win_max */
static void shrink_rx_window(uint8_t *rx_win_min, uint8_t *rx_win_max, int rx_window)
{
	/* calculate new min/max */
	for (uint8_t ts_no = *rx_win_min; ts_no <= *rx_win_max; ts_no++) {
		if ((rx_window & (1 << ts_no)))
			break;
		*rx_win_min = ts_no + 1;
		LOGP(DRLCMAC, LOGL_DEBUG, "- TS is unused, so "
			"raising start of DL window to %d\n",
			*rx_win_min);
	}
	for (uint8_t ts_no = *rx_win_max; ts_no >= *rx_win_min; ts_no--) {
		if ((rx_window & (1 << ts_no)))
			break;
		*rx_win_max = ts_no - 1;
		LOGP(DRLCMAC, LOGL_DEBUG, "- TS is unused, so "
			"lowering end of DL window to %d\n",
			*rx_win_max);
	}
}

/*
 * reduce window, to allow at least one uplink TX slot
 * this is only required for Type 1
 */
static uint8_t update_rx_win_max(const int ms_type, const int Tt,
			const int Tr, uint8_t rx_win_min, uint8_t rx_win_max)
{
	if (ms_type != 1)
		return rx_win_max;

	if (rx_win_max - rx_win_min + 1 + Tt + 1 + Tr > 8) {
		rx_win_max = rx_win_min + 7 - Tt - 1 - Tr;
		LOGP(DRLCMAC, LOGL_DEBUG, "- Reduce RX window due to time "
			"contraints to %d slots\n", rx_win_max - rx_win_min + 1);
	}

	return rx_win_max;
}

static void tx_win_from_rx(const int ms_type,
				uint8_t rx_win_min, uint8_t rx_win_max,
				int Tt, int Tr,
				uint8_t *tx_win_min, uint8_t *tx_win_max,
				uint8_t *tx_range)
{
	if (ms_type == 1) {
		/* calculate TX window (shifted by 3 timeslots)
		 * it uses the space between tx_win_max and tx_win_min */
		*tx_win_min = (rx_win_max - 2 + Tt) & 7;
		*tx_win_max = (rx_win_min + 4 - Tr) & 7;
	} else {
		/* TX and RX simultaniously */
		*tx_win_min = rx_win_min;
		*tx_win_max = 7;
	}

	*tx_range = (*tx_win_max - *tx_win_min + 1) & 7;
	/* if TX window fills complete range */
	if (*tx_range == 0)
		*tx_range = 8;
	LOGP(DRLCMAC, LOGL_DEBUG, "- TX-Window is: %d..%d\n", *tx_win_min,
		*tx_win_max);
}

/*
 * Select a window of Tx slots if available.
 * The maximum allowed slots depend on TX or the window of available
 * slots.
 */
static int select_ul_slots(gprs_rlcmac_trx *trx,
		const int ms_type, const int ms_max_txslots,
		uint8_t tx_win_min, uint8_t tx_range,
		int8_t *usf, int8_t *first_common_ts, uint8_t rx_window)
{
	int tsc = -1;
	uint8_t tx_window = 0;
	int i;
	uint8_t ts_no;

	for (ts_no = tx_win_min, i = 0; i < tx_range; ts_no = (ts_no + 1) & 7, i++) {
		gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no];

		/* check if enabled */
		if (!pdch->is_enabled()) {
			LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
				"because not enabled\n", ts_no);
			if (ms_type == 1 && tx_window)
				goto inc_window;
			continue;
		}
		/* check if used as downlink */
		if (!(rx_window & (1 << ts_no))) {
			LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
				"because not a downlink slot\n", ts_no);
			if (ms_type == 1 && tx_window)
				goto inc_window;
			continue;
		}
		/* check if TSC changes */
		if (tsc < 0)
			tsc = pdch->tsc;
		else if (tsc != pdch->tsc) {
			LOGP(DRLCMAC, LOGL_ERROR, "Skipping TS %d of "
				"TRX=%d, because it has different TSC "
				"than lower TS of TRX. In order to "
				"allow multislot, all slots must be "
				"configured with the same TSC!\n",
				ts_no, trx->trx_no);
			if (ms_type == 1)
				goto inc_window;
			continue;
		}
		/* check for free usf */
		usf[ts_no] = find_free_usf(pdch);
		if (usf[ts_no] < 0) {
			LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
			"because no USF available\n", ts_no);
			if (ms_type == 1)
				goto inc_window;
			continue;
		}

		if (!tx_window)
			*first_common_ts = ts_no;

		tx_window |= (1 << ts_no);
		LOGP(DRLCMAC, LOGL_DEBUG, "- Selected UL TS %d\n", ts_no);

inc_window:
		if (1 && ms_type == 1) { /* FIXME: multislot UL assignment */
			LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because "
				"1 slot assigned\n");
			break;
		}
		if (i+1 == ms_max_txslots) {
			LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because "
				"slots / window reached maximum "
				"allowed Tx size\n");
			break;
		}
	}

	LOGP(DRLCMAC, LOGL_DEBUG, "- Selected TX window: "
		"(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n",
		((tx_window & 0x01)) ? 'U' : '.',
		((tx_window & 0x02)) ? 'U' : '.',
		((tx_window & 0x04)) ? 'U' : '.',
		((tx_window & 0x08)) ? 'U' : '.',
		((tx_window & 0x10)) ? 'U' : '.',
		((tx_window & 0x20)) ? 'U' : '.',
		((tx_window & 0x40)) ? 'U' : '.',
		((tx_window & 0x80)) ? 'U' : '.');

	if (!tx_window) {
		LOGP(DRLCMAC, LOGL_NOTICE, "No suitable uplink slots "
			"available\n");
		return -EBUSY;
	}

	return tx_window;
}

/*
 * Assign the first common ts, which is used for control or
 * single slot.
 */
static int select_first_ts(gprs_rlcmac_trx *trx, uint8_t tx_win_min,
	uint8_t tx_range, uint8_t rx_window)
{
	uint8_t ts_no;
	int i;
	for (ts_no = tx_win_min, i = 0; i < tx_range; ts_no = (ts_no + 1) & 7, i++) {
		gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no];
		/* check if enabled */
		if (!pdch->is_enabled()) {
			LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
					"because not enabled\n", ts_no);
			continue;
		}
		/* check if used as downlink */
		if (!(rx_window & (1 << ts_no))) {
			LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
				"because not a downlink slot\n", ts_no);
			continue;
		}
		return ts_no;
	}

	return -1;
}

/* Slot Allocation: Algorithm B
 *
 * Assign as many downlink slots as possible.
 * Assign one uplink slot. (With free USF)
 *
 */
int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
	struct gprs_rlcmac_tbf *old_tbf,
	struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single)
{
	const struct gprs_ms_multislot_class *ms_class;
	uint8_t Tx, Sum;	/* Maximum Number of Slots: RX, Tx, Sum Rx+Tx */
	uint8_t Tta, Ttb, Tra, Trb, Tt, Tr;	/* Minimum Number of Slots */
	uint8_t Type; /* Type of Mobile */
	int rx_window;
	static const char *digit[10] = { "0","1","2","3","4","5","6","7","8","9" };
	int8_t usf[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; /* must be signed */
	int8_t first_common_ts = -1;
	uint8_t ts;
	uint8_t slotcount = 0;


	if (tbf->ms_class >= 32) {
		LOGP(DRLCMAC, LOGL_ERROR, "Multislot class %d out of range.\n",
			tbf->ms_class);
		return -EINVAL;
	}

	if (tbf->ms_class) {
		ms_class = &gprs_ms_multislot_class[tbf->ms_class];
		LOGP(DRLCMAC, LOGL_DEBUG, "Slot Allocation (Algorithm B) for "
			"class %d\n", tbf->ms_class);
	} else {
		ms_class = &gprs_ms_multislot_class[12];
		LOGP(DRLCMAC, LOGL_DEBUG, "Slot Allocation (Algorithm B) for "
			"unknow class (assuming 12)\n");
	}

	if (ms_class->tx == MS_NA) {
		LOGP(DRLCMAC, LOGL_NOTICE, "Multislot class %d not "
			"applicable.\n", tbf->ms_class);
		return -EINVAL;
	}

	Tx = ms_class->tx;
	Sum = ms_class->sum;
	Tta = ms_class->ta;
	Ttb = ms_class->tb;
	Tra = ms_class->ra;
	Trb = ms_class->rb;
	Type = ms_class->type;

	/* Tta and Ttb may depend on hopping or frequency change */
	if (Ttb == MS_A || Ttb == MS_B)
		Ttb = 0;
	if (Trb == MS_A || Trb == MS_C)
		Trb = 0;

	LOGP(DRLCMAC, LOGL_DEBUG, "- Rx=%d Tx=%d Sum Rx+Tx=%s  Tta=%s Ttb=%d "
		" Tra=%d Trb=%d Type=%d\n", ms_class->rx, Tx,
		(Sum == MS_NA) ? "N/A" : digit[Sum],
		(Tta == MS_NA) ? "N/A" : digit[Tta], Ttb, Tra, Trb, Type);

	/* select the values for time contraints */
	/* applicable to type 1 and type 2 */
	Tt = Ttb;
	Tr = Trb;

	uint8_t rx_win_min, rx_win_max;
	rx_window = select_dl_slots(tbf->trx, ms_class->type, ms_class->rx,
				&rx_win_min, &rx_win_max);


	/* reduce window, if existing uplink slots collide RX window */
	int rc = reduce_rx_window(ms_class->type, old_tbf, Tt, Tr,
				&rx_window, &rx_win_min, &rx_win_max);
	if (rc < 0)
		return rc;
	shrink_rx_window(&rx_win_min, &rx_win_max, rx_window);
	rx_win_max = update_rx_win_max(ms_class->type, Tt, Tr,
				rx_win_min, rx_win_max);
	shrink_rx_window(&rx_win_min, &rx_win_max, rx_window);
	LOGP(DRLCMAC, LOGL_DEBUG, "- RX-Window is: %d..%d\n", rx_win_min,
		rx_win_max);

	/* calculate TX window */
	uint8_t tx_win_min, tx_win_max, tx_range;
	tx_win_from_rx(ms_class->type, rx_win_min, rx_win_max, Tt, Tr,
				&tx_win_min, &tx_win_max, &tx_range);

	/* select UL slots but in both cases assign first_common_ts */
	uint8_t tx_window = 0;
	if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
		rc = select_ul_slots(tbf->trx, ms_class->type, ms_class->tx,
					tx_win_min, tx_range, usf,
					&first_common_ts, rx_window);
		if (rc < 0)
			return rc;
		tx_window = rc;
	} else {
		first_common_ts = select_first_ts(tbf->trx, tx_win_min,
					tx_range, rx_window);
	}
	#warning "first_common_ts might be different if there was no free USF for the new uplink assignment"

	if (first_common_ts < 0) {
		LOGP(DRLCMAC, LOGL_NOTICE, "No first common slots available\n");
		return -EINVAL;
	}

	if (tbf->direction == GPRS_RLCMAC_DL_TBF) {
		struct gprs_rlcmac_dl_tbf *dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(tbf);
		/* assign downlink */
		if (rx_window == 0) {
			LOGP(DRLCMAC, LOGL_NOTICE, "No downlink slots "
				"available\n");
			return -EINVAL;
		}
		for (ts = 0; ts < 8; ts++) {
			if ((rx_window & (1 << ts))) {
				/* be sure to select a single downlink slots
				 * that can be used for uplink, if multiple
				 * slots are assigned later. */
				if (single && first_common_ts != ts)
					continue;
				LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning DL TS "
					"%d\n", ts);
				assign_dlink_tbf(&tbf->trx->pdch[ts], dl_tbf);
				slotcount++;
				if (slotcount == 1)
					dl_tbf->first_ts = ts;
				if (single)
					break;
			}
		}
	} else {
		struct gprs_rlcmac_ul_tbf *ul_tbf = static_cast<gprs_rlcmac_ul_tbf *>(tbf);
		for (ts = 0; ts < 8; ts++) {
			if ((tx_window & (1 << ts))) {
				LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning UL TS "
					"%d\n", ts);
				assign_uplink_tbf_usf(&tbf->trx->pdch[ts], ul_tbf, usf[ts]);
				slotcount++;
				if (slotcount == 1)
					ul_tbf->first_ts = ts;
				if (single)
					break;
			}
		}
	}
	if (single && slotcount) {
		uint8_t ts_count = 0;
		for (ts = 0; ts < 8; ts++)
			if ((tx_window & (1 << ts)))
				ts_count++;

		tbf->upgrade_to_multislot = (ts_count > 1);
		LOGP(DRLCMAC, LOGL_INFO, "Using single slot at TS %d for %s\n",
			tbf->first_ts,
			(tbf->direction == GPRS_RLCMAC_DL_TBF) ? "DL" : "UL");
	} else {
		tbf->upgrade_to_multislot = 0;
		LOGP(DRLCMAC, LOGL_INFO, "Using %d slots for %s\n", slotcount,
			(tbf->direction == GPRS_RLCMAC_DL_TBF) ? "DL" : "UL");
	}
	if (slotcount == 0)
		return -EBUSY;

	tbf->first_common_ts = first_common_ts;

	return 0;
}
