/* gprs_ms.c
 *
 * Copyright (C) 2015-2020 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.
 */


#include "gprs_ms.h"
#include "bts.h"
#include "tbf.h"
#include "tbf_ul.h"
#include "gprs_debug.h"
#include "gprs_codel.h"
#include "pcu_utils.h"
#include "nacc_fsm.h"
#include "tbf_ul_ack_fsm.h"
#include "alloc_algo.h"

#include <time.h>

#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/gsm/gsm48.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/stats.h>
#include "coding_scheme.h"

#define GPRS_CODEL_SLOW_INTERVAL_MS 4000

extern void *tall_pcu_ctx;
static unsigned int next_ms_ctr_group_id;

static const struct rate_ctr_desc ms_ctr_description[] = {
	[MS_CTR_DL_CTRL_MSG_SCHED] = { "ms:dl_ctrl_msg_sched", "Amount of DL CTRL messages scheduled" },
};

static const struct rate_ctr_group_desc ms_ctrg_desc = {
	.group_name_prefix = "pcu:ms",
	.group_description = "MS Statistics",
	.class_id = OSMO_STATS_CLASS_SUBSCRIBER,
	.num_ctr = ARRAY_SIZE(ms_ctr_description),
	.ctr_desc = ms_ctr_description,
};

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;
}

static void ms_becomes_idle(struct GprsMs *ms);

static int ms_use_cb(struct osmo_use_count_entry *e, int32_t old_use_count, const char *file, int line)
{
	struct GprsMs *ms = e->use_count->talloc_object;
	int32_t total;
	int level;
	char buf[1024];

	if (!e->use)
		return -EINVAL;

	total = osmo_use_count_total(&ms->use_count);

	if (total == 0
	    || (total == 1 && old_use_count == 0 && e->count == 1))
		level = LOGL_INFO;
	else
		level = LOGL_DEBUG;


	LOGPSRC(DMS, level, file, line, "%s: %s %s: now used by %s\n",
		ms_name(ms),
		(e->count - old_use_count) > 0 ? "+" : "-", e->use,
		(osmo_use_count_to_str_buf(buf, sizeof(buf), &ms->use_count), buf));

	if (e->count < 0)
		return -ERANGE;

	if (total == 0) {
		OSMO_ASSERT(ms_is_idle(ms));
		ms_becomes_idle(ms);
	}
	return 0;
}

static void ms_release_timer_cb(void *data)
{
	struct GprsMs *ms = (struct GprsMs *) data;
	LOGPMS(ms, DMS, LOGL_INFO, "Release timer expired\n");

	/* Finally free the MS after being idle for a while according to config */
	talloc_free(ms);
}

static void ms_llc_timer_cb(void *_ms)
{
	struct GprsMs *ms = _ms;
	struct gprs_rlcmac_dl_tbf *dl_tbf = ms_dl_tbf(ms);

	if (!dl_tbf)
		return;
	if (tbf_state(dl_tbf_as_tbf_const(dl_tbf)) != TBF_ST_FLOW)
		return;

	LOGPTBFDL(dl_tbf, LOGL_DEBUG, "LLC receive timeout, requesting DL ACK\n");

	dl_tbf_request_dl_ack(dl_tbf);
}

static int ms_talloc_destructor(struct GprsMs *ms);
struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts, const char *use_ref)
{
	struct GprsMs *ms = talloc_zero(tall_pcu_ctx, struct GprsMs);
	OSMO_ASSERT(bts);

	talloc_set_destructor(ms, ms_talloc_destructor);

	llist_add(&ms->list, &bts->ms_list);
	bts_stat_item_inc(bts, STAT_MS_PRESENT);

	ms->bts = bts;
	ms->tlli = GSM_RESERVED_TMSI;
	ms->new_ul_tlli = GSM_RESERVED_TMSI;
	ms->new_dl_tlli = GSM_RESERVED_TMSI;
	ms->ta = GSM48_TA_INVALID;
	ms->current_cs_ul = UNKNOWN;
	ms->current_cs_dl = UNKNOWN;
	INIT_LLIST_HEAD(&ms->old_tbfs);

	ms->use_count = (struct osmo_use_count){
		.talloc_object = ms,
		.use_cb = ms_use_cb,
	};

	int codel_interval = LLC_CODEL_USE_DEFAULT;

	LOGP(DMS, LOGL_INFO, "Creating MS object\n");

	ms->imsi[0] = '\0';
	osmo_timer_setup(&ms->release_timer, ms_release_timer_cb, ms);
	llc_queue_init(&ms->llc_queue, ms);
	memset(&ms->llc_timer, 0, sizeof(ms->llc_timer));
	osmo_timer_setup(&ms->llc_timer, ms_llc_timer_cb, ms);

	ms_set_mode(ms, GPRS);

	codel_interval = the_pcu->vty.llc_codel_interval_msec;
	if (codel_interval == LLC_CODEL_USE_DEFAULT)
		codel_interval = GPRS_CODEL_SLOW_INTERVAL_MS;
	llc_queue_set_codel_interval(&ms->llc_queue, codel_interval);

	ms->last_cs_not_low = now_msec();
	ms->app_info_pending = false;

	ms->ctrs = rate_ctr_group_alloc(ms, &ms_ctrg_desc, next_ms_ctr_group_id++);
	if (!ms->ctrs)
		goto free_ret;

	if (use_ref)
		ms_ref(ms, use_ref);
	return ms;
free_ret:
	talloc_free(ms);
	return NULL;
}

static int ms_talloc_destructor(struct GprsMs *ms)
{
	struct llist_item *pos, *tmp;

	LOGPMS(ms, DMS, LOGL_INFO, "Destroying MS object\n");

	bts_stat_item_dec(ms->bts, STAT_MS_PRESENT);
	llist_del(&ms->list);

	ms_set_reserved_slots(ms, NULL, 0, 0);

	osmo_timer_del(&ms->release_timer);

	if (ms->ul_tbf) {
		tbf_set_ms(ul_tbf_as_tbf(ms->ul_tbf), NULL);
		ms->ul_tbf = NULL;
	}

	if (ms->dl_tbf) {
		tbf_set_ms(dl_tbf_as_tbf(ms->dl_tbf), NULL);
		ms->dl_tbf = NULL;
	}

	llist_for_each_entry_safe(pos, tmp, &ms->old_tbfs, list) {
		struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)pos->entry;
		tbf_set_ms(tbf, NULL);
	}

	llc_queue_clear(&ms->llc_queue, ms->bts);
	osmo_timer_del(&ms->llc_timer);

	if (ms->ctrs)
		rate_ctr_group_free(ms->ctrs);
	return 0;
}

/* MS has no attached TBFs anymore. */
static void ms_becomes_idle(struct GprsMs *ms)
{
	unsigned long delay_rel_sec = osmo_tdef_get(ms->bts->pcu->T_defs, -2030, OSMO_TDEF_S, -1);

	osmo_gettimeofday(&ms->tv_idle_start, NULL);

	ms_set_reserved_slots(ms, NULL, 0, 0);
	ms->first_common_ts = NULL;

	/* Immediate free():
	 * Skip delaying free() through release timer if delay is configured to be 0.
	 * This is useful for synced freed during unit tests.
	 */
	if (delay_rel_sec == 0) {
		talloc_free(ms);
		return;
	}

	/* Immediate free():
	 * Skip delaying free() through release timer if TMSI is not
	 * known, since those cannot really be reused.
	 */
	if (ms_tlli(ms) == GSM_RESERVED_TMSI) {
		talloc_free(ms);
		return;
	}

	LOGPMS(ms, DMS, LOGL_INFO, "Schedule MS release in %lu secs\n", delay_rel_sec);
	osmo_timer_schedule(&ms->release_timer, delay_rel_sec, 0);
}

static void ms_becomes_active(struct GprsMs *ms)
{
	if (!osmo_timer_pending(&ms->release_timer))
		return;

	LOGPMS(ms, DMS, LOGL_DEBUG, "Cancel scheduled MS release\n");

	timerclear(&ms->tv_idle_start);
	osmo_timer_del(&ms->release_timer);
}

void ms_set_mode(struct GprsMs *ms, enum mcs_kind mode)
{
	ms->mode = mode;

	switch (ms->mode) {
	case GPRS:
		if (!mcs_is_gprs(ms->current_cs_ul)) {
			ms->current_cs_ul = mcs_get_gprs_by_num(
				ms->bts->initial_cs_ul);
			if (!mcs_is_valid(ms->current_cs_ul))
				ms->current_cs_ul = CS1;
		}
		if (!mcs_is_gprs(ms->current_cs_dl)) {
			ms->current_cs_dl = mcs_get_gprs_by_num(
				ms->bts->initial_cs_dl);
			if (!mcs_is_valid(ms->current_cs_dl))
				ms->current_cs_dl = CS1;
		}
		break;

	case EGPRS_GMSK:
		if (!mcs_is_edge_gmsk(ms->current_cs_ul)) {
			ms->current_cs_ul = mcs_get_egprs_by_num(
				ms->bts->initial_mcs_ul);
			if (!mcs_is_valid(ms->current_cs_ul))
				ms->current_cs_ul = MCS1;
		}
		if (!mcs_is_edge_gmsk(ms->current_cs_dl)) {
			ms->current_cs_dl = mcs_get_egprs_by_num(
				ms->bts->initial_mcs_dl);
			if (!mcs_is_valid(ms->current_cs_dl))
				ms->current_cs_dl = MCS1;
		}
		break;
	case EGPRS:
		if (!mcs_is_edge(ms->current_cs_ul)) {
			ms->current_cs_ul = mcs_get_egprs_by_num(
				ms->bts->initial_mcs_ul);
			if (!mcs_is_valid(ms->current_cs_ul))
				ms->current_cs_ul = MCS1;
		}
		if (!mcs_is_edge(ms->current_cs_dl)) {
			ms->current_cs_dl = mcs_get_egprs_by_num(
				ms->bts->initial_mcs_dl);
			if (!mcs_is_valid(ms->current_cs_dl))
				ms->current_cs_dl = MCS1;
		}
		break;
	}
}

/* If a TBF is attached to an MS, it is either in ms->{dl,ul}_tbf or in ms->old_tbfs list */
static bool ms_tbf_is_attached(const struct GprsMs *ms, const struct gprs_rlcmac_tbf *tbf)
{
	const struct llist_item *pos;
	OSMO_ASSERT(ms);
	OSMO_ASSERT(tbf);
	OSMO_ASSERT(tbf_ms(tbf) == ms);

	if (tbf == ul_tbf_as_tbf_const(ms->ul_tbf))
		return true;

	if (tbf == dl_tbf_as_tbf_const(ms->dl_tbf))
		return true;

	llist_for_each_entry(pos, &ms->old_tbfs, list) {
		const struct gprs_rlcmac_tbf *tmp_tbf = (struct gprs_rlcmac_tbf *)pos->entry;
		if (tmp_tbf == tbf)
			return true;
	}
	return false;
}

static void ms_attach_ul_tbf(struct GprsMs *ms, struct gprs_rlcmac_ul_tbf *tbf)
{
	LOGPMS(ms, DMS, LOGL_INFO, "Attaching UL TBF: %s\n", tbf_name((struct gprs_rlcmac_tbf *)tbf));

	if (ms->ul_tbf)
		llist_add_tail(tbf_ms_list(ul_tbf_as_tbf(ms->ul_tbf)), &ms->old_tbfs);

	ms->ul_tbf = tbf;

	ms_ref(ms, MS_USE_TBF);
}

static void ms_attach_dl_tbf(struct GprsMs *ms, struct gprs_rlcmac_dl_tbf *tbf)
{
	LOGPMS(ms, DMS, LOGL_INFO, "Attaching DL TBF: %s\n", tbf_name((struct gprs_rlcmac_tbf *)tbf));

	if (ms->dl_tbf)
		llist_add_tail(tbf_ms_list(dl_tbf_as_tbf(ms->dl_tbf)), &ms->old_tbfs);

	ms->dl_tbf = tbf;

	ms_ref(ms, MS_USE_TBF);
}

void ms_attach_tbf(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
{
	OSMO_ASSERT(ms);
	OSMO_ASSERT(tbf);
	OSMO_ASSERT(!ms_tbf_is_attached(ms, tbf));

	if (tbf_direction(tbf) == GPRS_RLCMAC_DL_TBF)
		ms_attach_dl_tbf(ms, tbf_as_dl_tbf(tbf));
	else
		ms_attach_ul_tbf(ms, tbf_as_ul_tbf(tbf));

	ms_becomes_active(ms);
}

void ms_detach_tbf(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
{
	OSMO_ASSERT(tbf_ms(tbf) == ms);

	/* In general this should not happen, but it can happen if during TBF
	 * allocation something fails before tbf->setup() called ms_attach_tbf(). */
	if (!ms_tbf_is_attached(ms, tbf))
		return;

	LOGPMS(ms, DMS, LOGL_INFO, "Detaching TBF: %s\n",
	       tbf_name(tbf));

	if (tbf == ul_tbf_as_tbf(ms->ul_tbf)) {
		ms->ul_tbf = NULL;
	} else if (tbf == dl_tbf_as_tbf(ms->dl_tbf)) {
		ms->dl_tbf = NULL;
	} else {
		/* We know from ms_tbf_is_attached()==true check above that tbf
		 * is in ms->old_tbfs, no need to look it up again. */
		llist_del(tbf_ms_list(tbf));
	}

	ms_unref(ms, MS_USE_TBF);
}

/* Cleans up old MS being merged into a new one. Should be called with a
ms_ref() taken to avoid use-after-free. */
static void ms_reset(struct GprsMs *ms)
{
	LOGPMS(ms, DMS, LOGL_INFO, "Clearing MS object\n");
	struct llist_item *pos;
	struct gprs_rlcmac_tbf *tbf;

	tbf = ul_tbf_as_tbf(ms_ul_tbf(ms));
	if (tbf && !tbf_timers_pending(tbf, T_MAX))
		tbf_free(tbf);
	tbf = dl_tbf_as_tbf(ms_dl_tbf(ms));
	if (tbf && !tbf_timers_pending(tbf, T_MAX))
		tbf_free(tbf);

	llist_for_each_entry(pos, &ms->old_tbfs, list) {
		tbf = (struct gprs_rlcmac_tbf *)pos->entry;
		if (!tbf_timers_pending(tbf, T_MAX))
			tbf_free(tbf);
	}

	/* Flag it with invalid data so that it cannot be looked up anymore and
	* shows up specially if listed in VTY. Furthermore, it will also trigger
	* immediate free() when it becomes idle: */
	ms->tlli = GSM_RESERVED_TMSI;
	ms->new_dl_tlli = ms->tlli;
	ms->new_ul_tlli = ms->tlli;
	ms->imsi[0] = '\0';
}

/* This function should be called on the MS object of a TBF each time an RLCMAC
 * block is received for it with TLLI information.
 * Besides updating the TLLI field on the MS object, it also seeks for other MS
 * objects in the store and merges them into the current MS object. The MS
 * duplication happened because we don't learn the TLLI of the created TBF until
 * a later point. */
void ms_update_announced_tlli(struct GprsMs *ms, uint32_t tlli)
{
	struct GprsMs *old_ms = NULL;

	if (tlli == GSM_RESERVED_TMSI)
		return;

	/* When the TLLI does not match the ms, check if there is another
	 * MS object that belongs to that TLLI and if yes make sure one of them
	 * gets deleted. */
	if (!ms_check_tlli(ms, tlli))
		old_ms = bts_get_ms_by_tlli(ms->bts, tlli, GSM_RESERVED_TMSI);

	ms_set_tlli(ms, tlli);

	if (old_ms)
		ms_merge_and_clear_ms(ms, old_ms);
	/* old_ms may no longer be available here */
}

/* Merge 'old_ms' object into 'ms' object.
 * 'old_ms' may be freed during the call to this function, don't use the pointer to it afterwards */
void ms_merge_and_clear_ms(struct GprsMs *ms, struct GprsMs *old_ms)
{
	char old_ms_name[128];
	OSMO_ASSERT(old_ms != ms);
	ms_ref(old_ms, __func__);

	ms_name_buf(old_ms, old_ms_name, sizeof(old_ms_name));

	LOGPMS(ms, DMS, LOGL_INFO, "Merge MS: %s\n", old_ms_name);

	if (strlen(ms_imsi(ms)) == 0 && strlen(ms_imsi(old_ms)) != 0)
		osmo_strlcpy(ms->imsi, ms_imsi(old_ms), sizeof(ms->imsi));

	if (!ms_ms_class(ms) && ms_ms_class(old_ms))
		ms_set_ms_class(ms, ms_ms_class(old_ms));

	if (!ms_egprs_ms_class(ms) && ms_egprs_ms_class(old_ms))
		ms_set_egprs_ms_class(ms, ms_egprs_ms_class(old_ms));

	llc_queue_move_and_merge(&ms->llc_queue, &old_ms->llc_queue);

	/* Clean up the old MS object */
	ms_reset(old_ms);

	ms_unref(old_ms, __func__);
}

/* Apply changes to the TLLI directly, used interally by functions below: */
static void ms_apply_tlli_change(struct GprsMs *ms, uint32_t tlli)
{
	ms->tlli = tlli;
	ms->new_dl_tlli = GSM_RESERVED_TMSI;
	ms->new_ul_tlli = GSM_RESERVED_TMSI;

	/* Update TBF FSM names: */
	if (ms->ul_tbf)
		tbf_update_state_fsm_name(ul_tbf_as_tbf(ms->ul_tbf));
	if (ms->dl_tbf)
		tbf_update_state_fsm_name(dl_tbf_as_tbf(ms->dl_tbf));
}

/* Set/update the MS object TLLI based on knowledge gained from the MS side (Uplink direction) */
void ms_set_tlli(struct GprsMs *ms, uint32_t tlli)
{
	if (tlli == ms->tlli || tlli == ms->new_ul_tlli)
		return;

	if (tlli != ms->new_dl_tlli) {
		LOGP(DMS, LOGL_INFO,
			"Modifying MS object, UL TLLI: 0x%08x -> 0x%08x, "
			"not yet confirmed\n",
			ms_tlli(ms), tlli);
		ms->new_ul_tlli = tlli;
		return;
	}

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

	ms_apply_tlli_change(ms, tlli);
}

/* Set/update the MS object TLLI based on knowledge gained from the SGSN side (Downlink direction) */
bool ms_confirm_tlli(struct GprsMs *ms, uint32_t tlli)
{
	if (tlli == ms->tlli || tlli == ms->new_dl_tlli)
		return false;

	if (tlli != ms->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(DMS, 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() */
		ms->new_dl_tlli = tlli;
		return false;
	}

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

	ms_apply_tlli_change(ms, tlli);

	return true;
}

void ms_set_imsi(struct GprsMs *ms, const char *imsi)
{
	if (!imsi) {
		LOGP(DMS, LOGL_ERROR, "Expected IMSI!\n");
		return;
	}

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

	if (strcmp(imsi, ms->imsi) == 0)
		return;

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

	struct GprsMs *old_ms = bts_get_ms_by_imsi(ms->bts, imsi);
	/* Check if we are going to store a different MS object with already
	   existing IMSI. This is probably a bug in code calling this function,
	   since it should take care of this explicitly */
	if (old_ms) {
		/* We cannot find ms->ms by IMSI since we know that it has a
		* different IMSI */
		OSMO_ASSERT(old_ms != ms);

		LOGPMS(ms, DMS, LOGL_NOTICE,
		       "IMSI '%s' was already assigned to another "
		       "MS object: TLLI = 0x%08x, that IMSI will be removed\n",
		       imsi, ms_tlli(old_ms));

		ms_merge_and_clear_ms(ms, old_ms);
		/* old_ms may no longer be available here */
	}

	/* Store the new IMSI: */
	osmo_strlcpy(ms->imsi, imsi, sizeof(ms->imsi));

	/* Update TBF FSM names: */
	if (ms->ul_tbf)
		tbf_update_state_fsm_name(ul_tbf_as_tbf(ms->ul_tbf));
	if (ms->dl_tbf)
		tbf_update_state_fsm_name(dl_tbf_as_tbf(ms->dl_tbf));
}

void ms_set_ta(struct GprsMs *ms, uint8_t ta_)
{
	if (ta_ == ms->ta)
		return;

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

void ms_set_ms_class(struct GprsMs *ms, uint8_t ms_class_)
{
	if (ms_class_ == ms->ms_class)
		return;

	LOGP(DMS, LOGL_INFO,
		"Modifying MS object, TLLI = 0x%08x, MS class %d -> %d\n",
		ms_tlli(ms), ms->ms_class, ms_class_);

	ms->ms_class = ms_class_;
}

void ms_set_egprs_ms_class(struct GprsMs *ms, uint8_t ms_class_)
{
	if (ms_class_ == ms->egprs_ms_class)
		return;

	LOGP(DMS, LOGL_INFO,
		"Modifying MS object, TLLI = 0x%08x, EGPRS MS class %d -> %d\n",
		ms_tlli(ms), ms->egprs_ms_class, ms_class_);

	ms->egprs_ms_class = ms_class_;

	if (!bts_max_mcs_ul(ms->bts) || !bts_max_mcs_dl(ms->bts)) {
		LOGPMS(ms, DMS, LOGL_DEBUG,
		       "Avoid enabling EGPRS because use of MCS is disabled: ul=%u dl=%u\n",
			bts_max_mcs_ul(ms->bts), bts_max_mcs_dl(ms->bts));
		return;
	}

	if (mcs_is_edge_gmsk(mcs_get_egprs_by_num(bts_max_mcs_ul(ms->bts))) &&
		mcs_is_edge_gmsk(mcs_get_egprs_by_num(bts_max_mcs_dl(ms->bts))) &&
		ms_mode(ms) != EGPRS)
	{
		ms_set_mode(ms, EGPRS_GMSK);
	} else {
		ms_set_mode(ms, EGPRS);
	}
	LOGPMS(ms, DMS, LOGL_INFO, "Enabled EGPRS, mode %s\n", mode_name(ms_mode(ms)));
}

void ms_update_error_rate(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf, int error_rate)
{
	int64_t now;
	enum CodingScheme max_cs_dl = ms_max_cs_dl(ms);
	OSMO_ASSERT(max_cs_dl);

	if (error_rate < 0)
		return;

	now = now_msec();

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

	ms->nack_rate_dl = error_rate;

	if (error_rate > the_pcu->vty.cs_adj_upper_limit) {
		if (mcs_chan_code(ms->current_cs_dl) > 0) {
			mcs_dec_kind(&ms->current_cs_dl, ms_mode(ms));
			LOGP(DRLCMACDL, LOGL_INFO,
				"MS (IMSI %s): High error rate %d%%, "
				"reducing CS level to %s\n",
				ms_imsi(ms), error_rate, mcs_name(ms->current_cs_dl));
			ms->last_cs_not_low = now;
		}
	} else if (error_rate < the_pcu->vty.cs_adj_lower_limit) {
		if (ms->current_cs_dl < max_cs_dl) {
		       if (now - ms->last_cs_not_low > 1000) {
			       mcs_inc_kind(&ms->current_cs_dl, ms_mode(ms));

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

enum CodingScheme ms_max_cs_ul(const struct GprsMs *ms)
{
	enum CodingScheme cs;
	OSMO_ASSERT(ms->bts != NULL);

	if (mcs_is_gprs(ms->current_cs_ul)) {
		if (!bts_max_cs_ul(ms->bts)) {
			return CS4;
		}

		return mcs_get_gprs_by_num(bts_max_cs_ul(ms->bts));
	}

	cs = mcs_get_egprs_by_num(bts_max_mcs_ul(ms->bts));
	if (ms_mode(ms) == EGPRS_GMSK && cs > MCS4)
		cs = MCS4;
	return cs;
}

void ms_set_current_cs_dl(struct GprsMs *ms, enum CodingScheme scheme)
{
	ms->current_cs_dl = scheme;
}

enum CodingScheme ms_max_cs_dl(const struct GprsMs *ms)
{
	enum CodingScheme cs;
	OSMO_ASSERT(ms->bts != NULL);

	if (mcs_is_gprs(ms->current_cs_dl)) {
		if (!bts_max_cs_dl(ms->bts)) {
			return CS4;
		}

		return mcs_get_gprs_by_num(bts_max_cs_dl(ms->bts));
	}

	cs = mcs_get_egprs_by_num(bts_max_mcs_dl(ms->bts));
	if (ms_mode(ms) == EGPRS_GMSK && cs > MCS4)
		cs = MCS4;
	return cs;
}

void ms_update_cs_ul(struct GprsMs *ms, const struct pcu_l1_meas *meas)
{
	enum CodingScheme max_cs_ul = ms_max_cs_ul(ms);

	int old_link_qual;
	int low;
	int high;
	enum CodingScheme new_cs_ul = ms->current_cs_ul;
	uint8_t current_cs = mcs_chan_code(ms->current_cs_ul);

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

	if (!ms->current_cs_ul) {
		LOGP(DRLCMACMEAS, LOGL_ERROR,
		     "Unable to update UL (M)CS because it's not set: %s\n",
		     mcs_name(ms->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(ms->current_cs_ul));
		return;
	}

	if (mcs_is_gprs(ms->current_cs_ul)) {
		if (current_cs >= MAX_GPRS_CS)
			current_cs = MAX_GPRS_CS - 1;
		low  = the_pcu->vty.cs_lqual_ranges[current_cs].low;
		high = the_pcu->vty.cs_lqual_ranges[current_cs].high;
	} else if (mcs_is_edge(ms->current_cs_ul)) {
		if (current_cs >= MAX_EDGE_MCS)
			current_cs = MAX_EDGE_MCS - 1;
		low  = the_pcu->vty.mcs_lqual_ranges[current_cs].low;
		high = the_pcu->vty.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(ms->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 (ms->l1_meas.have_link_qual)
		old_link_qual = ms->l1_meas.link_qual;
	else
		old_link_qual = meas->link_qual;

	if (meas->link_qual < low &&  old_link_qual < low)
		mcs_dec_kind(&new_cs_ul, ms_mode(ms));
	else if (meas->link_qual > high &&  old_link_qual > high &&
		ms->current_cs_ul < max_cs_ul)
		mcs_inc_kind(&new_cs_ul, ms_mode(ms));

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

		ms->current_cs_ul = new_cs_ul;
	}
}

void ms_update_l1_meas(struct GprsMs *ms, const struct pcu_l1_meas *meas)
{
	unsigned i;

	ms_update_cs_ul(ms, meas);

	if (meas->have_rssi)
		pcu_l1_meas_set_rssi(&ms->l1_meas, meas->rssi);
	if (meas->have_bto)
		pcu_l1_meas_set_bto(&ms->l1_meas, meas->bto);
	if (meas->have_ber)
		pcu_l1_meas_set_ber(&ms->l1_meas, meas->ber);
	if (meas->have_link_qual)
		pcu_l1_meas_set_link_qual(&ms->l1_meas, meas->link_qual);

	if (meas->have_ms_rx_qual)
		pcu_l1_meas_set_ms_rx_qual(&ms->l1_meas, meas->ms_rx_qual);
	if (meas->have_ms_c_value)
		pcu_l1_meas_set_ms_c_value(&ms->l1_meas, meas->ms_c_value);
	if (meas->have_ms_sign_var)
		pcu_l1_meas_set_ms_sign_var(&ms->l1_meas, 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)
				pcu_l1_meas_set_ms_i_level(&ms->l1_meas, i, meas->ts[i].ms_i_level);
			else
				ms->l1_meas.ts[i].have_ms_i_level = 0;
		}
	}
}

/* req_mcs_kind acts as a set filter, where EGPRS means any and GPRS is the most restrictive */
enum CodingScheme ms_current_cs_dl(const struct GprsMs *ms, enum mcs_kind req_mcs_kind)
{
	enum CodingScheme orig_cs = ms->current_cs_dl;
	struct gprs_rlcmac_bts *bts = ms->bts;
	size_t unencoded_octets;
	enum CodingScheme cs;

	/* It could be that a TBF requests a GPRS CS despite the MS currently
	   being upgraded to EGPRS (hence reporting MCS). That could happen
	   because the TBF was created early in the process where we didn't have
	   yet enough information about the MS, and only AFTER it was created we
	   upgraded the MS to be EGPRS capable.
	   As a result, when  the MS is queried for the target CS here, we could be
	   returning an MCS despite the current TBF being established as GPRS,
	   but we rather stick to the TBF type we assigned to the MS rather than
	   magically sending EGPRS data blocks to a GPRS TBF.
	   It could also be that the caller requests specific MCS kind
	   explicitly too due to scheduling restrictions (GPRS+EGPRS multiplexing). */
	if (req_mcs_kind == EGPRS_GMSK && mcs_is_edge(orig_cs) && orig_cs > MCS4) {
		cs = bts_cs_dl_is_supported(bts, MCS4) ? MCS4 :
		     bts_cs_dl_is_supported(bts, MCS3) ? MCS3 :
		     bts_cs_dl_is_supported(bts, MCS2) ? MCS2 :
		     MCS1;
	} else if (req_mcs_kind == GPRS && mcs_is_edge(orig_cs)) { /* GPRS */
			int i;
			cs = orig_cs > MCS4 ? MCS4 : orig_cs;
			cs -= (MCS1 - CS1); /* MCSx -> CSx */
			/* Find suitable CS starting from equivalent MCS which is supported by BTS: */
			for (i = mcs_chan_code(cs); !bts_cs_dl_is_supported(bts, CS1 + i); i--);
			OSMO_ASSERT(i >= 0 && i <= 3); /* CS1 is always supported */
			cs = CS1 + i;
	} else {
		cs = orig_cs;
	}

	if (orig_cs != cs)
		LOGPMS(ms, DMS, LOGL_INFO, "MS (mode=%s) suggests transmitting "
			"DL %s, downgrade to %s in order to match TBF & scheduler requirements\n",
			mode_name(ms_mode(ms)), mcs_name(orig_cs), mcs_name(cs));

	unencoded_octets = llc_queue_octets(&ms->llc_queue);

	/* If the DL TBF is active, add number of unencoded chunk octets */
	if (ms->dl_tbf)
		unencoded_octets += llc_chunk_size(tbf_llc(dl_tbf_as_tbf(ms->dl_tbf)));

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

	/* RF conditions are good, don't reduce */
	if (ms->nack_rate_dl < the_pcu->vty.cs_adj_lower_limit)
		return cs;

	/* The throughput would probably be better if the CS level was reduced */
	mcs_dec_kind(&cs, ms_mode(ms));

	/* CS-2 doesn't gain throughput with small packets, further reduce to CS-1 */
	if (cs == CS2)
		mcs_dec_kind(&cs, ms_mode(ms));

	return cs;
}

struct gprs_rlcmac_pdch *ms_first_common_ts(const struct GprsMs *ms)
{
	return ms->first_common_ts;
}

void ms_set_first_common_ts(struct GprsMs *ms, struct gprs_rlcmac_pdch *pdch)
{
	OSMO_ASSERT(pdch);
	ms->first_common_ts = pdch;
}

uint8_t ms_dl_slots(const struct GprsMs *ms)
{
	uint8_t slots = 0;

	if (ms->dl_tbf)
		slots |= tbf_dl_slots(dl_tbf_as_tbf(ms->dl_tbf));

	if (ms->ul_tbf)
		slots |= tbf_dl_slots(ul_tbf_as_tbf(ms->ul_tbf));

	return slots;
}

uint8_t ms_ul_slots(const struct GprsMs *ms)
{
	uint8_t slots = 0;

	if (ms->dl_tbf)
		slots |= tbf_ul_slots(dl_tbf_as_tbf(ms->dl_tbf));

	if (ms->ul_tbf)
		slots |= tbf_ul_slots(ul_tbf_as_tbf(ms->ul_tbf));

	return slots;
}

uint8_t ms_current_pacch_slots(const struct GprsMs *ms)
{
	uint8_t slots = 0;

	bool is_dl_active = ms->dl_tbf && tbf_is_tfi_assigned(dl_tbf_as_tbf(ms->dl_tbf));
	bool is_ul_active = ms->ul_tbf && tbf_is_tfi_assigned(ul_tbf_as_tbf(ms->ul_tbf));

	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 =  tbf_dl_slots(dl_tbf_as_tbf(ms->dl_tbf));
	else if (!is_dl_active && is_ul_active)
		slots =  tbf_ul_slots(ul_tbf_as_tbf(ms->ul_tbf));
	else
		slots =  tbf_ul_slots(ul_tbf_as_tbf(ms->ul_tbf)) &
			 tbf_dl_slots(dl_tbf_as_tbf(ms->dl_tbf));

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

	return slots;
}

void ms_set_reserved_slots(struct GprsMs *ms, struct gprs_rlcmac_trx *trx,
	uint8_t ul_slots, uint8_t dl_slots)
{
	if (ms->current_trx) {
		bts_trx_unreserve_slots(ms->current_trx, GPRS_RLCMAC_DL_TBF,
			ms->reserved_dl_slots);
		bts_trx_unreserve_slots(ms->current_trx, GPRS_RLCMAC_UL_TBF,
			ms->reserved_ul_slots);
		ms->reserved_dl_slots = 0;
		ms->reserved_ul_slots = 0;
	}
	ms->current_trx = trx;
	if (trx) {
		ms->reserved_dl_slots = dl_slots;
		ms->reserved_ul_slots = ul_slots;
		bts_trx_reserve_slots(ms->current_trx, GPRS_RLCMAC_DL_TBF,
			ms->reserved_dl_slots);
		bts_trx_reserve_slots(ms->current_trx, GPRS_RLCMAC_UL_TBF,
			ms->reserved_ul_slots);
	}
}

struct gprs_rlcmac_tbf *ms_tbf(const struct GprsMs *ms, enum gprs_rlcmac_tbf_direction dir)
{
	switch (dir) {
	case GPRS_RLCMAC_DL_TBF: return dl_tbf_as_tbf(ms->dl_tbf);
	case GPRS_RLCMAC_UL_TBF: return ul_tbf_as_tbf(ms->ul_tbf);
	}

	return NULL;
}

const char *ms_name(const struct GprsMs *ms)
{
	static char _ms_name_buf[128];
	return ms_name_buf(ms, _ms_name_buf, sizeof(_ms_name_buf));
}

char *ms_name_buf(const struct GprsMs *ms, char *buf, unsigned int buf_size)
{
	struct osmo_strbuf sb = { .buf = buf, .len = buf_size };
	uint32_t tlli = ms_tlli(ms);

	OSMO_STRBUF_PRINTF(sb, "MS(");
	if (ms_imsi_is_valid(ms))
		OSMO_STRBUF_PRINTF(sb, "IMSI-%s:", ms_imsi(ms));
	if (tlli != GSM_RESERVED_TMSI)
		OSMO_STRBUF_PRINTF(sb, "TLLI-0x%08x:", tlli);
	OSMO_STRBUF_PRINTF(sb, "TA-%" PRIu8 ":MSCLS-%" PRIu8 "-%" PRIu8,
			   ms_ta(ms), ms_ms_class(ms), ms_egprs_ms_class(ms));
	if (ms->ul_tbf)
		OSMO_STRBUF_PRINTF(sb, ":UL");
	if (ms->dl_tbf)
		OSMO_STRBUF_PRINTF(sb, ":DL");

	OSMO_STRBUF_PRINTF(sb, ")");
	return buf;
}

int ms_nacc_start(struct GprsMs *ms, Packet_Cell_Change_Notification_t *notif)
{
	if (!ms->nacc)
		ms->nacc = nacc_fsm_alloc(ms);
	if (!ms->nacc)
		return -EINVAL;
	return osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_RX_CELL_CHG_NOTIFICATION, notif);
}

bool ms_nacc_rts(const struct GprsMs *ms)
{
	if (!ms->nacc)
		return false;
	if (ms->nacc->fi->state == NACC_ST_TX_NEIGHBOUR_DATA ||
	    ms->nacc->fi->state == NACC_ST_TX_CELL_CHG_CONTINUE)
		return true;
	return false;
}

struct msgb *ms_nacc_create_rlcmac_msg(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf,
				       const struct gprs_rlcmac_pdch *pdch, uint32_t fn)
{
	int rc;
	struct nacc_ev_create_rlcmac_msg_ctx data_ctx;

	data_ctx = (struct nacc_ev_create_rlcmac_msg_ctx) {
			.tbf = tbf,
			.pdch = pdch,
			.fn = fn,
			.msg = NULL,
	};

	rc = osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_CREATE_RLCMAC_MSG, &data_ctx);
	if (rc != 0 || !data_ctx.msg)
		return NULL;
	return data_ctx.msg;
}

static void ms_start_llc_timer(struct GprsMs *ms)
{
	if (the_pcu->vty.llc_idle_ack_csec > 0) {
		struct timespec tv;
		csecs_to_timespec(the_pcu->vty.llc_idle_ack_csec, &tv);
		osmo_timer_schedule(&ms->llc_timer, tv.tv_sec, tv.tv_nsec / 1000);
	}
}

/* Can we get to send a DL TBF ass to the MS? */
static bool ms_is_reachable_for_dl_ass(const struct GprsMs *ms)
{
	struct gprs_rlcmac_ul_tbf *ul_tbf = ms_ul_tbf(ms);

	/* This function assumes it is called when no DL TBF is present */
	OSMO_ASSERT(!ms_dl_tbf(ms));

	/* 3GPP TS 44.060 sec 7.1.3.1 Initiation of the Packet resource request procedure:
	* "Furthermore, the mobile station shall not respond to PACKET DOWNLINK ASSIGNMENT
	* or MULTIPLE TBF DOWNLINK ASSIGNMENT messages before contention resolution is
	* completed on the mobile station side." */
	/* The possible uplink TBF is used to trigger downlink assignment:
	* - If there is no uplink TBF the MS is potentially in packet idle mode
	* and hence assignment will be done over CCCH (PCH)
	* - If there's an uplink TBF but it is finished (waiting for last PKT
	* CTRL ACK after sending last Pkt UL ACK/NACK with FINAL_ACK=1, then we
	* have no ways to contact the MS right now. Assignment will be delayed
	* until PKT CTRL ACK is received and the TBF is released at the MS side
	* (then assignment goes through PCH).
	*/
	if (!ul_tbf)
		return true;
	if (ul_tbf_contention_resolution_done(ul_tbf) &&
	    !tbf_ul_ack_waiting_cnf_final_ack(ul_tbf))
		return true;

	return false;

}

/* Alloc a UL TBF to be assigned over PACCH. Called when an MS requests to
 * create a new UL TBF during the end of life of a previous UL TBF (or an SBA).
 * In summary, this TBF is allocated as a consequence of receiving a "Pkt
 * Resource Req" or "Pkt Ctrl Ack" from the MS.
 * See TS 44.060 9.3.2.4.2 "Non-extended uplink TBF mode".
 */
struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_assigned_pacch(struct GprsMs *ms, int8_t use_trx)
{
	struct gprs_rlcmac_ul_tbf *ul_tbf;
	const struct alloc_resources_req req = {
		.bts = ms->bts,
		.ms = ms,
		.direction = GPRS_RLCMAC_UL_TBF,
		.single = false,
		.use_trx = use_trx,
	};
	struct alloc_resources_res res = {};
	int rc;

	rc = the_pcu->alloc_algorithm(&req, &res);
	if (rc < 0) {
		LOGPMS(ms, DTBF, LOGL_NOTICE,
			"Timeslot Allocation failed: trx = %d, single_slot = %d\n",
			req.use_trx, req.single);
		bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
		return NULL;
	}

	ul_tbf = ul_tbf_alloc(ms->bts, ms);
	if (!ul_tbf) {
		LOGPMS(ms, DTBF, LOGL_NOTICE, "ul_tbf_alloc() failed\n");
		/* Caller will most probably send a Imm Ass Reject after return */
		return NULL;
	}

	/* Update MS, really allocate the resources */
	if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
	    res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
		/* The reserved slots have changed, update the MS */
		ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
	}
	ms_set_first_common_ts(ms, res.first_common_ts);

	/* Apply allocated resources to TBF: */
	ul_tbf_apply_allocated_resources(ul_tbf, &res);

	ms_attach_tbf(ms, ul_tbf_as_tbf(ul_tbf));

	osmo_fsm_inst_dispatch(tbf_state_fi(ul_tbf_as_tbf(ul_tbf)), TBF_EV_ASSIGN_ADD_PACCH, NULL);
	/* Contention resolution is considered to be done since TLLI is known in MS */
	return ul_tbf;
}

/* Alloc a UL TBF to be assigned over AGCH. Used by request of a "One phase
 * packet access", where MS requested only 1 PDCH TS (TS 44.018 Table 9.1.8.1). */
struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_assigned_agch(struct GprsMs *ms)
{
	struct gprs_rlcmac_ul_tbf *ul_tbf;
	const struct alloc_resources_req req = {
		.bts = ms->bts,
		.ms = ms,
		.direction = GPRS_RLCMAC_UL_TBF,
		.single = true,
		.use_trx = -1,
	};
	struct alloc_resources_res res = {};
	int rc;

	rc = the_pcu->alloc_algorithm(&req, &res);
	if (rc < 0) {
		LOGPMS(ms, DTBF, LOGL_NOTICE,
			"Timeslot Allocation failed: trx = %d, single_slot = %d\n",
			req.use_trx, req.single);
		bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
		return NULL;
	}

	ul_tbf = ul_tbf_alloc(ms->bts, ms);
	if (!ul_tbf) {
		LOGPMS(ms, DTBF, LOGL_NOTICE, "ul_tbf_alloc() failed\n");
		/* Caller will most probably send a Imm Ass Reject after return */
		return NULL;
	}

	/* Update MS, really allocate the resources */
	if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
	    res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
		/* The reserved slots have changed, update the MS */
		ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
	}
	ms_set_first_common_ts(ms, res.first_common_ts);

	/* Apply allocated resources to TBF: */
	ul_tbf_apply_allocated_resources(ul_tbf, &res);

	ms_attach_tbf(ms, ul_tbf_as_tbf(ul_tbf));

	osmo_fsm_inst_dispatch(tbf_state_fi(ul_tbf_as_tbf(ul_tbf)), TBF_EV_ASSIGN_ADD_CCCH, NULL);
	return ul_tbf;
}

/* Create a temporary dummy TBF to Tx a ImmAssReject if allocating a new one during
 * packet resource Request failed. This is similar as ul_tbf_alloc() but without
 * calling alloc_algo (in charge of TFI/USF allocation), and reusing resources
 * from Packet Resource Request we received. See TS 44.060 sec 7.1.3.2.1  */
struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_rejected_pacch(struct GprsMs *ms, struct gprs_rlcmac_pdch *pdch)
{
	struct gprs_rlcmac_ul_tbf *ul_tbf;
	struct alloc_resources_res fake_res = {
		.trx = pdch->trx,
		.first_common_ts = pdch,
		.reserved_ul_slots = 0,
		.reserved_dl_slots = 0,
		.ass_slots_mask = 0,
		.upgrade_to_multislot = false,
		.tfi = TBF_TFI_UNSET,
		.usf = {0},
	};
	ul_tbf = ul_tbf_alloc(ms->bts, ms);
	if (!ul_tbf)
		return NULL;

	/* The only one TS is the common, control TS */
	ms_set_first_common_ts(ms, pdch);

	/* Apply fake resources to TBF, to attach it to the proper TRX/PDCH: */
	ul_tbf_apply_allocated_resources(ul_tbf, &fake_res);

	ms_attach_tbf(ms, ul_tbf_as_tbf(ul_tbf));

	osmo_fsm_inst_dispatch(tbf_state_fi(ul_tbf_as_tbf(ul_tbf)), TBF_EV_ASSIGN_ADD_PACCH, NULL);
	osmo_fsm_inst_dispatch(tbf_ul_ass_fi(ul_tbf_as_tbf(ul_tbf)), TBF_UL_ASS_EV_SCHED_ASS_REJ, NULL);

	return ul_tbf;
}

/* A new DL-TBF is allocated and assigned through PACCH using "tbf".
 * "tbf" may be either a UL-TBF or a DL-TBF.
 * Note: This should be called only when MS is reachable, see ms_is_reachable_for_dl_ass().
 */
int ms_new_dl_tbf_assigned_on_pacch(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
{
	OSMO_ASSERT(tbf);
	struct gprs_rlcmac_dl_tbf *dl_tbf;
	const struct alloc_resources_req req = {
		.bts = ms->bts,
		.ms = ms,
		.direction = GPRS_RLCMAC_DL_TBF,
		.single = false,
		.use_trx = tbf_get_trx(tbf)->trx_no,
	};
	struct alloc_resources_res res = {};
	int rc;

	rc = the_pcu->alloc_algorithm(&req, &res);
	if (rc < 0) {
		LOGPMS(ms, DTBF, LOGL_NOTICE,
			"Timeslot Allocation failed: trx = %d, single_slot = %d\n",
			req.use_trx, req.single);
		bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
		return -EBUSY;
	}

	dl_tbf = dl_tbf_alloc(ms->bts, ms);
	if (!dl_tbf) {
		LOGPMS(ms, DTBF, LOGL_NOTICE, "dl_tbf_alloc() failed\n");
		return -1;
	}

	/* Update MS, really allocate the resources */
	if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
	    res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
		/* The reserved slots have changed, update the MS */
		ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
	}
	ms_set_first_common_ts(ms, res.first_common_ts);

	/* Apply allocated resources to TBF: */
	dl_tbf_apply_allocated_resources(dl_tbf, &res);

	ms_attach_tbf(ms, dl_tbf_as_tbf(dl_tbf));

	LOGPTBFDL(dl_tbf, LOGL_DEBUG, "[DOWNLINK] START (PACCH)\n");
	dl_tbf_trigger_ass_on_pacch(dl_tbf, tbf);
	return 0;
}

/* A new DL-TBF is allocated and assigned through PCH.
 * Note: This should be called only when MS is reachable, see ms_is_reachable_for_dl_ass().
 */
int ms_new_dl_tbf_assigned_on_pch(struct GprsMs *ms)
{
	struct gprs_rlcmac_dl_tbf *dl_tbf;
	const struct alloc_resources_req req = {
		.bts = ms->bts,
		.ms = ms,
		.direction = GPRS_RLCMAC_DL_TBF,
		.single = true,
		.use_trx = -1,
	};
	struct alloc_resources_res res = {};
	int rc;

	rc = the_pcu->alloc_algorithm(&req, &res);
	if (rc < 0) {
		LOGPMS(ms, DTBF, LOGL_NOTICE,
			"Timeslot Allocation failed: trx = %d, single_slot = %d\n",
			req.use_trx, req.single);
		bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
		return -EBUSY;
	}

	dl_tbf = dl_tbf_alloc(ms->bts, ms);
	if (!dl_tbf) {
		LOGPMS(ms, DTBF, LOGL_NOTICE, "dl_tbf_alloc() failed\n");
		return -1;
	}

	/* Update MS, really allocate the resources */
	if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
	    res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
		/* The reserved slots have changed, update the MS */
		ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
	}
	ms_set_first_common_ts(ms, res.first_common_ts);

	/* Apply allocated resources to TBF: */
	dl_tbf_apply_allocated_resources(dl_tbf, &res);

	ms_attach_tbf(ms, dl_tbf_as_tbf(dl_tbf));

	LOGPTBFDL(dl_tbf, LOGL_DEBUG, "[DOWNLINK] START (PCH)\n");
	dl_tbf_trigger_ass_on_pch(dl_tbf);
	return 0;
}

int ms_append_llc_dl_data(struct GprsMs *ms, uint16_t pdu_delay_csec, const uint8_t *data, uint16_t len)
{
	struct timespec expire_time;
	struct gprs_rlcmac_dl_tbf *dl_tbf;
	int rc = 0;

	LOGPMS(ms, DTBFDL, LOGL_DEBUG, "appending %u bytes to DL LLC queue\n", len);

	struct msgb *llc_msg = msgb_alloc(len, "llc_pdu_queue");
	if (!llc_msg)
		return -ENOMEM;

	llc_queue_calc_pdu_lifetime(ms->bts, pdu_delay_csec, &expire_time);
	memcpy(msgb_put(llc_msg, len), data, len);
	llc_queue_enqueue(ms_llc_queue(ms), llc_msg, &expire_time);
	ms_start_llc_timer(ms);

	dl_tbf = ms_dl_tbf(ms);
	if (dl_tbf) {
		if (tbf_state(dl_tbf_as_tbf_const(dl_tbf)) == TBF_ST_WAIT_RELEASE) {
			LOGPTBFDL(dl_tbf, LOGL_DEBUG, "in WAIT RELEASE state (T3193), so reuse TBF\n");
			rc = ms_new_dl_tbf_assigned_on_pacch(ms, dl_tbf_as_tbf(dl_tbf));
		}
	} else {
		/* Check if we can create a DL TBF to start sending the enqueued
		 * data. Otherwise it will be triggered later when it is reachable
		 * again. */
		if (ms_is_reachable_for_dl_ass(ms)) {
			if (ms_ul_tbf(ms))
				rc = ms_new_dl_tbf_assigned_on_pacch(ms, ul_tbf_as_tbf(ms_ul_tbf(ms)));
			else
				rc = ms_new_dl_tbf_assigned_on_pch(ms);
		}
	}
	return rc;
}
