/* gprs_ms.cpp
 *
 * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
 *
 * 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_ms.h"
#include <gprs_coding_scheme.h>
#include "bts.h"
#include "tbf.h"
#include "tbf_ul.h"
#include "gprs_debug.h"
#include "gprs_codel.h"
#include "pcu_utils.h"

#include <time.h>

extern "C" {
	#include <osmocom/core/talloc.h>
	#include <osmocom/core/utils.h>
	#include <osmocom/core/timer.h>
	#include <osmocom/gsm/protocol/gsm_04_08.h>
	#include <osmocom/core/logging.h>
	#include "coding_scheme.h"
}

#define GPRS_CODEL_SLOW_INTERVAL_MS 4000

extern void *tall_pcu_ctx;

static int64_t now_msec()
{
	struct timespec ts;
	osmo_clock_gettime(CLOCK_MONOTONIC, &ts);

	return int64_t(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000;
}

struct GprsMsDefaultCallback: public GprsMs::Callback {
	virtual void ms_idle(class GprsMs *ms) {
		delete ms;
	}
	virtual void ms_active(class GprsMs *) {}
};

static GprsMsDefaultCallback gprs_default_cb;

GprsMs::Guard::Guard(GprsMs *ms) :
	m_ms(ms ? ms->ref() : NULL)
{
}

GprsMs::Guard::~Guard()
{
	if (m_ms)
		m_ms->unref();
}

bool GprsMs::Guard::is_idle() const
{
	if (!m_ms)
		return true;

	return !m_ms->m_ul_tbf && !m_ms->m_dl_tbf && m_ms->m_ref == 1;
}

void GprsMs::timeout(void *priv_)
{
	GprsMs *ms = static_cast<GprsMs *>(priv_);

	LOGP(DRLCMAC, LOGL_INFO, "Timeout for MS object, TLLI = 0x%08x\n",
		ms->tlli());

	if (ms->m_timer.data) {
		ms->m_timer.data = NULL;
		ms->unref();
	}
}

GprsMs::GprsMs(BTS *bts, uint32_t tlli) :
	m_bts(bts),
	m_cb(&gprs_default_cb),
	m_ul_tbf(NULL),
	m_dl_tbf(NULL),
	m_tlli(tlli),
	m_new_ul_tlli(0),
	m_new_dl_tlli(0),
	m_ta(GSM48_TA_INVALID),
	m_ms_class(0),
	m_egprs_ms_class(0),
	m_is_idle(true),
	m_ref(0),
	m_list(this),
	m_delay(0),
	m_nack_rate_dl(0),
	m_reserved_dl_slots(0),
	m_reserved_ul_slots(0),
	m_current_trx(NULL),
	m_codel_state(NULL),
	m_mode(GPRS),
	m_dl_ctrl_msg(0)
{
	int codel_interval = LLC_CODEL_USE_DEFAULT;

	LOGP(DRLCMAC, LOGL_INFO, "Creating MS object, TLLI = 0x%08x\n", tlli);

	m_imsi[0] = 0;
	memset(&m_timer, 0, sizeof(m_timer));
	m_timer.cb = GprsMs::timeout;
	m_llc_queue.init();

	set_mode(m_mode);

	if (m_bts)
		codel_interval = m_bts->bts_data()->llc_codel_interval_msec;

	if (codel_interval) {
		if (codel_interval == LLC_CODEL_USE_DEFAULT)
			codel_interval = GPRS_CODEL_SLOW_INTERVAL_MS;
		m_codel_state = talloc(this, struct gprs_codel);
		gprs_codel_init(m_codel_state);
		gprs_codel_set_interval(m_codel_state, codel_interval);
	}
	m_last_cs_not_low = now_msec();
	app_info_pending = false;
}

GprsMs::~GprsMs()
{
	LListHead<gprs_rlcmac_tbf> *pos, *tmp;

	LOGP(DRLCMAC, LOGL_INFO, "Destroying MS object, TLLI = 0x%08x\n", tlli());

	set_reserved_slots(NULL, 0, 0);

	if (osmo_timer_pending(&m_timer))
		osmo_timer_del(&m_timer);

	if (m_ul_tbf) {
		m_ul_tbf->set_ms(NULL);
		m_ul_tbf = NULL;
	}

	if (m_dl_tbf) {
		m_dl_tbf->set_ms(NULL);
		m_dl_tbf = NULL;
	}

	llist_for_each_safe(pos, tmp, &m_old_tbfs)
		pos->entry()->set_ms(NULL);

	m_llc_queue.clear(m_bts);
}

void* GprsMs::operator new(size_t size)
{
	static void *tall_ms_ctx = NULL;
	if (!tall_ms_ctx)
		tall_ms_ctx = talloc_named_const(tall_pcu_ctx, 0, __PRETTY_FUNCTION__);

	return talloc_size(tall_ms_ctx, size);
}

void GprsMs::operator delete(void* p)
{
	talloc_free(p);
}

GprsMs *GprsMs::ref()
{
	m_ref += 1;
	return this;
}

void GprsMs::unref()
{
	OSMO_ASSERT(m_ref >= 0);
	m_ref -= 1;
	if (m_ref == 0)
		update_status();
}

void GprsMs::start_timer()
{
	if (m_delay == 0)
		return;

	if (!m_timer.data)
		m_timer.data = ref();

	osmo_timer_schedule(&m_timer, m_delay, 0);
}

void GprsMs::stop_timer()
{
	if (!m_timer.data)
		return;

	osmo_timer_del(&m_timer);
	m_timer.data = NULL;
	unref();
}

void GprsMs::set_mode(enum mcs_kind mode)
{
	m_mode = mode;

	if (!m_bts)
		return;

	switch (m_mode) {
	case GPRS:
		if (!mcs_is_gprs(m_current_cs_ul)) {
			m_current_cs_ul = GprsCodingScheme::getGprsByNum(
				m_bts->bts_data()->initial_cs_ul);
			if (!m_current_cs_ul.isValid())
				m_current_cs_ul = CS1;
		}
		if (!mcs_is_gprs(m_current_cs_dl)) {
			m_current_cs_dl = GprsCodingScheme::getGprsByNum(
				m_bts->bts_data()->initial_cs_dl);
			if (!m_current_cs_dl.isValid())
				m_current_cs_dl = CS1;
		}
		break;

	case EGPRS_GMSK:
	case EGPRS:
		if (!mcs_is_edge(m_current_cs_ul)) {
			m_current_cs_ul = GprsCodingScheme::getEgprsByNum(
				m_bts->bts_data()->initial_mcs_ul);
			if (!m_current_cs_ul.isValid())
				m_current_cs_ul = MCS1;
		}
		if (!mcs_is_edge(m_current_cs_dl)) {
			m_current_cs_dl = GprsCodingScheme::getEgprsByNum(
				m_bts->bts_data()->initial_mcs_dl);
			if (!m_current_cs_dl.isValid())
				m_current_cs_dl = MCS1;
		}
		break;
	}
}

void GprsMs::attach_tbf(struct gprs_rlcmac_tbf *tbf)
{
	if (tbf->direction == GPRS_RLCMAC_DL_TBF)
		attach_dl_tbf(as_dl_tbf(tbf));
	else
		attach_ul_tbf(as_ul_tbf(tbf));
}

void GprsMs::attach_ul_tbf(struct gprs_rlcmac_ul_tbf *tbf)
{
	if (m_ul_tbf == tbf)
		return;

	LOGP(DRLCMAC, LOGL_INFO, "Attaching TBF to MS object, TLLI = 0x%08x, TBF = %s\n",
		tlli(), tbf->name());

	Guard guard(this);

	if (m_ul_tbf)
		llist_add_tail(&m_ul_tbf->ms_list(), &m_old_tbfs);

	m_ul_tbf = tbf;

	if (tbf)
		stop_timer();
}

void GprsMs::attach_dl_tbf(struct gprs_rlcmac_dl_tbf *tbf)
{
	if (m_dl_tbf == tbf)
		return;

	LOGP(DRLCMAC, LOGL_INFO, "Attaching TBF to MS object, TLLI = 0x%08x, TBF = %s\n",
		tlli(), tbf->name());

	Guard guard(this);

	if (m_dl_tbf)
		llist_add_tail(&m_dl_tbf->ms_list(), &m_old_tbfs);

	m_dl_tbf = tbf;

	if (tbf)
		stop_timer();
}

void GprsMs::detach_tbf(gprs_rlcmac_tbf *tbf)
{
	if (tbf == static_cast<gprs_rlcmac_tbf *>(m_ul_tbf)) {
		m_ul_tbf = NULL;
	} else if (tbf == static_cast<gprs_rlcmac_tbf *>(m_dl_tbf)) {
		m_dl_tbf = NULL;
	} else {
		bool found = false;

		LListHead<gprs_rlcmac_tbf> *pos, *tmp;
		llist_for_each_safe(pos, tmp, &m_old_tbfs) {
			if (pos->entry() == tbf) {
				llist_del(pos);
				found = true;
				break;
			}
		}

		/* Protect against recursive calls via set_ms() */
		if (!found)
			return;
	}

	LOGP(DRLCMAC, LOGL_INFO, "Detaching TBF from MS object, TLLI = 0x%08x, TBF = %s\n",
		tlli(), tbf->name());

	if (tbf->ms() == this)
		tbf->set_ms(NULL);

	if (!m_dl_tbf && !m_ul_tbf) {
		set_reserved_slots(NULL, 0, 0);

		if (tlli() != 0)
			start_timer();
	}

	update_status();
}

void GprsMs::update_status()
{
	if (m_ref > 0)
		return;

	if (is_idle() && !m_is_idle) {
		m_is_idle = true;
		m_cb->ms_idle(this);
		/* this can be deleted by now, do not access it */
		return;
	}

	if (!is_idle() && m_is_idle) {
		m_is_idle = false;
		m_cb->ms_active(this);
	}
}

void GprsMs::reset()
{
	LOGP(DRLCMAC, LOGL_INFO,
		"Clearing MS object, TLLI: 0x%08x, IMSI: '%s'\n",
		tlli(), imsi());

	stop_timer();

	m_tlli = 0;
	m_new_dl_tlli = 0;
	m_new_ul_tlli = 0;
	m_imsi[0] = '\0';
}

void GprsMs::merge_old_ms(GprsMs *old_ms)
{
	if (old_ms == this)
		return;

	if (strlen(imsi()) == 0 && strlen(old_ms->imsi()) != 0)
		set_imsi(old_ms->imsi());

	if (!ms_class() && old_ms->ms_class())
		set_ms_class(old_ms->ms_class());

	m_llc_queue.move_and_merge(&old_ms->m_llc_queue);

	old_ms->reset();
}

void GprsMs::set_tlli(uint32_t tlli)
{
	if (tlli == m_tlli || tlli == m_new_ul_tlli)
		return;

	if (tlli != m_new_dl_tlli) {
		LOGP(DRLCMAC, LOGL_INFO,
			"Modifying MS object, UL TLLI: 0x%08x -> 0x%08x, "
			"not yet confirmed\n",
			this->tlli(), tlli);
		m_new_ul_tlli = tlli;
		return;
	}

	LOGP(DRLCMAC, LOGL_INFO,
		"Modifying MS object, TLLI: 0x%08x -> 0x%08x, "
		"already confirmed partly\n",
		m_tlli, tlli);

	m_tlli = tlli;
	m_new_dl_tlli = 0;
	m_new_ul_tlli = 0;
}

bool GprsMs::confirm_tlli(uint32_t tlli)
{
	if (tlli == m_tlli || tlli == m_new_dl_tlli)
		return false;

	if (tlli != m_new_ul_tlli) {
		/* The MS has not sent a message with the new TLLI, which may
		 * happen according to the spec [TODO: add reference]. */

		LOGP(DRLCMAC, LOGL_INFO,
			"The MS object cannot fully confirm an unexpected TLLI: 0x%08x, "
			"partly confirmed\n", tlli);
		/* Use the network's idea of TLLI as candidate, this does not
		 * change the result value of tlli() */
		m_new_dl_tlli = tlli;
		return false;
	}

	LOGP(DRLCMAC, LOGL_INFO,
		"Modifying MS object, TLLI: 0x%08x confirmed\n", tlli);

	m_tlli = tlli;
	m_new_dl_tlli = 0;
	m_new_ul_tlli = 0;

	return true;
}

void GprsMs::set_imsi(const char *imsi)
{
	if (!imsi) {
		LOGP(DRLCMAC, LOGL_ERROR, "Expected IMSI!\n");
		return;
	}

	if (imsi[0] && strlen(imsi) < 3) {
		LOGP(DRLCMAC, LOGL_ERROR, "No valid IMSI '%s'!\n",
			imsi);
		return;
	}

	if (strcmp(imsi, m_imsi) == 0)
		return;

	LOGP(DRLCMAC, LOGL_INFO,
		"Modifying MS object, TLLI = 0x%08x, IMSI '%s' -> '%s'\n",
		tlli(), m_imsi, imsi);

	strncpy(m_imsi, imsi, sizeof(m_imsi));
	m_imsi[sizeof(m_imsi) - 1] = '\0';
}

void GprsMs::set_ta(uint8_t ta_)
{
	if (ta_ == m_ta)
		return;

	if (gsm48_ta_is_valid(ta_)) {
		LOGP(DRLCMAC, LOGL_INFO,
		     "Modifying MS object, TLLI = 0x%08x, TA %d -> %d\n",
		     tlli(), m_ta, ta_);
		m_ta = ta_;
	} else
		LOGP(DRLCMAC, LOGL_NOTICE,
		     "MS object, TLLI = 0x%08x, invalid TA %d rejected (old "
		     "value %d kept)\n", tlli(), ta_, m_ta);
}

void GprsMs::set_ms_class(uint8_t ms_class_)
{
	if (ms_class_ == m_ms_class)
		return;

	LOGP(DRLCMAC, LOGL_INFO,
		"Modifying MS object, TLLI = 0x%08x, MS class %d -> %d\n",
		tlli(), m_ms_class, ms_class_);

	m_ms_class = ms_class_;
}

void GprsMs::set_egprs_ms_class(uint8_t ms_class_)
{
	if (ms_class_ == m_egprs_ms_class)
		return;

	LOGP(DRLCMAC, LOGL_INFO,
		"Modifying MS object, TLLI = 0x%08x, EGPRS MS class %d -> %d\n",
		tlli(), m_egprs_ms_class, ms_class_);

	m_egprs_ms_class = ms_class_;
}

void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate)
{
	struct gprs_rlcmac_bts *bts_data;
	int64_t now;
	GprsCodingScheme max_cs_dl = this->max_cs_dl();

	OSMO_ASSERT(max_cs_dl);
	bts_data = m_bts->bts_data();

	if (error_rate < 0)
		return;

	now = now_msec();

	/* TODO: Check for TBF direction */
	/* TODO: Support different CS values for UL and DL */

	m_nack_rate_dl = error_rate;

	if (error_rate > bts_data->cs_adj_upper_limit) {
		if (mcs_chan_code(m_current_cs_dl) > 0) {
			m_current_cs_dl.dec(mode());
			LOGP(DRLCMACDL, LOGL_INFO,
				"MS (IMSI %s): High error rate %d%%, "
				"reducing CS level to %s\n",
				imsi(), error_rate, mcs_name(m_current_cs_dl));
			m_last_cs_not_low = now;
		}
	} else if (error_rate < bts_data->cs_adj_lower_limit) {
		if (m_current_cs_dl < max_cs_dl) {
		       if (now - m_last_cs_not_low > 1000) {
			       m_current_cs_dl.inc(mode());

			       LOGP(DRLCMACDL, LOGL_INFO,
				       "MS (IMSI %s): Low error rate %d%%, "
				       "increasing DL CS level to %s\n",
				       imsi(), error_rate,
				       mcs_name(m_current_cs_dl));
			       m_last_cs_not_low = now;
		       } else {
			       LOGP(DRLCMACDL, LOGL_DEBUG,
				       "MS (IMSI %s): Low error rate %d%%, "
				       "ignored (within blocking period)\n",
				       imsi(), error_rate);
		       }
		}
	} else {
		LOGP(DRLCMACDL, LOGL_DEBUG,
			"MS (IMSI %s): Medium error rate %d%%, ignored\n",
			imsi(), error_rate);
		m_last_cs_not_low = now;
	}
}

GprsCodingScheme GprsMs::max_cs_ul() const
{
	struct gprs_rlcmac_bts *bts_data;

	OSMO_ASSERT(m_bts != NULL);
	bts_data = m_bts->bts_data();

	if (mcs_is_gprs(m_current_cs_ul)) {
		if (!bts_data->max_cs_ul)
			return GprsCodingScheme(CS4);

		return GprsCodingScheme::getGprsByNum(bts_data->max_cs_ul);
	}

	if (!mcs_is_edge(m_current_cs_ul))
		return GprsCodingScheme(); /* UNKNOWN */

	if (bts_data->max_mcs_ul)
		return GprsCodingScheme::getEgprsByNum(bts_data->max_mcs_ul);
	else if (bts_data->max_cs_ul)
		return GprsCodingScheme::getEgprsByNum(bts_data->max_cs_ul);

	return GprsCodingScheme(MCS4);
}

void GprsMs::set_current_cs_dl(CodingScheme scheme)
{
	m_current_cs_dl = scheme;
}

GprsCodingScheme GprsMs::max_cs_dl() const
{
	struct gprs_rlcmac_bts *bts_data;

	OSMO_ASSERT(m_bts != NULL);
	bts_data = m_bts->bts_data();

	if (mcs_is_gprs(m_current_cs_dl)) {
		if (!bts_data->max_cs_dl)
			return GprsCodingScheme(CS4);

		return GprsCodingScheme::getGprsByNum(bts_data->max_cs_dl);
	}

	if (!mcs_is_edge(m_current_cs_dl))
		return GprsCodingScheme(); /* UNKNOWN */

	if (bts_data->max_mcs_dl)
		return GprsCodingScheme::getEgprsByNum(bts_data->max_mcs_dl);
	else if (bts_data->max_cs_dl)
		return GprsCodingScheme::getEgprsByNum(bts_data->max_cs_dl);

	return GprsCodingScheme(MCS4);
}

void GprsMs::update_cs_ul(const pcu_l1_meas *meas)
{
	struct gprs_rlcmac_bts *bts_data;
	GprsCodingScheme max_cs_ul = this->max_cs_ul();

	int old_link_qual;
	int low;
	int high;
	GprsCodingScheme new_cs_ul = m_current_cs_ul;
	uint8_t current_cs = mcs_chan_code(m_current_cs_ul);

	bts_data = m_bts->bts_data();

	if (!max_cs_ul) {
		LOGP(DRLCMACMEAS, LOGL_ERROR,
			"max_cs_ul cannot be derived (current UL CS: %s)\n",
			mcs_name(m_current_cs_ul));
		return;
	}

	if (!m_current_cs_ul) {
		LOGP(DRLCMACMEAS, LOGL_ERROR,
		     "Unable to update UL (M)CS because it's not set: %s\n",
		     mcs_name(m_current_cs_ul));
		return;
	}

	if (!meas->have_link_qual) {
		LOGP(DRLCMACMEAS, LOGL_ERROR,
		     "Unable to update UL (M)CS %s because we don't have link quality measurements.\n",
		     mcs_name(m_current_cs_ul));
		return;
	}

	if (mcs_is_gprs(m_current_cs_ul)) {
		if (current_cs >= MAX_GPRS_CS)
			current_cs = MAX_GPRS_CS - 1;
		low  = bts_data->cs_lqual_ranges[current_cs].low;
		high = bts_data->cs_lqual_ranges[current_cs].high;
	} else if (mcs_is_edge(m_current_cs_ul)) {
		if (current_cs >= MAX_EDGE_MCS)
			current_cs = MAX_EDGE_MCS - 1;
		low  = bts_data->mcs_lqual_ranges[current_cs].low;
		high = bts_data->mcs_lqual_ranges[current_cs].high;
	} else {
		LOGP(DRLCMACMEAS, LOGL_ERROR,
		     "Unable to update UL (M)CS because it's neither GPRS nor EDGE: %s\n",
		     mcs_name(m_current_cs_ul));
		return;
	}

	/* To avoid rapid changes of the coding scheme, we also take
	 * the old link quality value into account (if present). */
	if (m_l1_meas.have_link_qual)
		old_link_qual = m_l1_meas.link_qual;
	else
		old_link_qual = meas->link_qual;

	if (meas->link_qual < low &&  old_link_qual < low)
		new_cs_ul.dec(mode());
	else if (meas->link_qual > high &&  old_link_qual > high &&
		m_current_cs_ul < max_cs_ul)
		new_cs_ul.inc(mode());

	if (m_current_cs_ul != new_cs_ul) {
		LOGP(DRLCMACMEAS, LOGL_INFO,
			"MS (IMSI %s): "
			"Link quality %ddB (old %ddB) left window [%d, %d], "
			"modifying uplink CS level: %s -> %s\n",
			imsi(), meas->link_qual, old_link_qual,
			low, high,
			mcs_name(m_current_cs_ul), mcs_name(new_cs_ul));

		m_current_cs_ul = new_cs_ul;
	}
}

void GprsMs::update_l1_meas(const pcu_l1_meas *meas)
{
	unsigned i;

	update_cs_ul(meas);

	if (meas->have_rssi)
		m_l1_meas.set_rssi(meas->rssi);
	if (meas->have_bto)
		m_l1_meas.set_bto(meas->bto);
	if (meas->have_ber)
		m_l1_meas.set_ber(meas->ber);
	if (meas->have_link_qual)
		m_l1_meas.set_link_qual(meas->link_qual);

	if (meas->have_ms_rx_qual)
		m_l1_meas.set_ms_rx_qual(meas->ms_rx_qual);
	if (meas->have_ms_c_value)
		m_l1_meas.set_ms_c_value(meas->ms_c_value);
	if (meas->have_ms_sign_var)
		m_l1_meas.set_ms_sign_var(meas->ms_sign_var);

	if (meas->have_ms_i_level) {
		for (i = 0; i < ARRAY_SIZE(meas->ts); ++i) {
			if (meas->ts[i].have_ms_i_level)
				m_l1_meas.set_ms_i_level(i, meas->ts[i].ms_i_level);
			else
				m_l1_meas.ts[i].have_ms_i_level = 0;
		}
	}
}

GprsCodingScheme GprsMs::current_cs_dl() const
{
	GprsCodingScheme cs = m_current_cs_dl;
	size_t unencoded_octets;

	if (!m_bts)
		return cs;

	unencoded_octets = m_llc_queue.octets();

	/* If the DL TBF is active, add number of unencoded chunk octets */
	if (m_dl_tbf)
		unencoded_octets += m_dl_tbf->m_llc.chunk_size();

	/* There are many unencoded octets, don't reduce */
	if (unencoded_octets >= m_bts->bts_data()->cs_downgrade_threshold)
		return cs;

	/* RF conditions are good, don't reduce */
	if (m_nack_rate_dl < m_bts->bts_data()->cs_adj_lower_limit)
		return cs;

	/* The throughput would probably be better if the CS level was reduced */
	cs.dec(mode());

	/* CS-2 doesn't gain throughput with small packets, further reduce to CS-1 */
	if (cs == GprsCodingScheme(CS2))
		cs.dec(mode());

	return cs;
}

int GprsMs::first_common_ts() const
{
	if (m_dl_tbf)
		return m_dl_tbf->first_common_ts;

	if (m_ul_tbf)
		return m_ul_tbf->first_common_ts;

	return -1;
}

uint8_t GprsMs::dl_slots() const
{
	uint8_t slots = 0;

	if (m_dl_tbf)
		slots |= m_dl_tbf->dl_slots();

	if (m_ul_tbf)
		slots |= m_ul_tbf->dl_slots();

	return slots;
}

uint8_t GprsMs::ul_slots() const
{
	uint8_t slots = 0;

	if (m_dl_tbf)
		slots |= m_dl_tbf->ul_slots();

	if (m_ul_tbf)
		slots |= m_ul_tbf->ul_slots();

	return slots;
}

uint8_t GprsMs::current_pacch_slots() const
{
	uint8_t slots = 0;

	bool is_dl_active = m_dl_tbf && m_dl_tbf->is_tfi_assigned();
	bool is_ul_active = m_ul_tbf && m_ul_tbf->is_tfi_assigned();

	if (!is_dl_active && !is_ul_active)
		return 0;

	/* see TS 44.060, 8.1.1.2.2 */
	if (is_dl_active && !is_ul_active)
		slots =  m_dl_tbf->dl_slots();
	else if (!is_dl_active && is_ul_active)
		slots =  m_ul_tbf->ul_slots();
	else
		slots =  m_ul_tbf->ul_slots() & m_dl_tbf->dl_slots();

	/* Assume a multislot class 1 device */
	/* TODO: For class 2 devices, this could be removed */
	slots = pcu_lsb(slots);

	return slots;
}

void GprsMs::set_reserved_slots(gprs_rlcmac_trx *trx,
	uint8_t ul_slots, uint8_t dl_slots)
{
	if (m_current_trx) {
		m_current_trx->unreserve_slots(GPRS_RLCMAC_DL_TBF,
			m_reserved_dl_slots);
		m_current_trx->unreserve_slots(GPRS_RLCMAC_UL_TBF,
			m_reserved_ul_slots);
		m_reserved_dl_slots = 0;
		m_reserved_ul_slots = 0;
	}
	m_current_trx = trx;
	if (trx) {
		m_reserved_dl_slots = dl_slots;
		m_reserved_ul_slots = ul_slots;
		m_current_trx->reserve_slots(GPRS_RLCMAC_DL_TBF,
			m_reserved_dl_slots);
		m_current_trx->reserve_slots(GPRS_RLCMAC_UL_TBF,
			m_reserved_ul_slots);
	}
}

gprs_rlcmac_tbf *GprsMs::tbf(enum gprs_rlcmac_tbf_direction dir) const
{
	switch (dir) {
	case GPRS_RLCMAC_DL_TBF: return m_dl_tbf;
	case GPRS_RLCMAC_UL_TBF: return m_ul_tbf;
	}

	return NULL;
}
