/* GSM 08.08 like API for OpenBSC. The bridge from MSC to BSC */

/* (C) 2010-2011 by Holger Hans Peter Freyther
 * (C) 2010-2011 by On-Waves
 * (C) 2009 by Harald Welte <laforge@gnumonks.org>
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <openbsc/bsc_api.h>
#include <openbsc/bsc_rll.h>
#include <openbsc/gsm_data.h>
#include <openbsc/gsm_subscriber.h>
#include <openbsc/signal.h>
#include <openbsc/abis_rsl.h>
#include <openbsc/chan_alloc.h>
#include <openbsc/handover.h>
#include <openbsc/debug.h>
#include <openbsc/gsm_04_08.h>
#include <openbsc/trau_mux.h>
#include <openbsc/vlr.h>

#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm48.h>

#include <osmocom/core/talloc.h>

#define GSM0808_T10_VALUE    6, 0


static void rll_ind_cb(struct gsm_lchan *, uint8_t, void *, enum bsc_rllr_ind);
static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id);
static void handle_release(struct gsm_subscriber_connection *conn, struct bsc_api *bsc, struct  gsm_lchan *lchan);
static void handle_chan_ack(struct gsm_subscriber_connection *conn, struct bsc_api *bsc, struct  gsm_lchan *lchan);
static void handle_chan_nack(struct gsm_subscriber_connection *conn, struct bsc_api *bsc, struct  gsm_lchan *lchan);

/* GSM 08.08 3.2.2.33 */
static uint8_t lchan_to_chosen_channel(struct gsm_lchan *lchan)
{
	uint8_t channel_mode = 0, channel = 0;

	switch (lchan->tch_mode) {
	case GSM48_CMODE_SPEECH_V1:
	case GSM48_CMODE_SPEECH_EFR:
	case GSM48_CMODE_SPEECH_AMR:
		channel_mode = 0x9;
		break;
	case GSM48_CMODE_SIGN:
		channel_mode = 0x8;
		break;
	case GSM48_CMODE_DATA_14k5:
		channel_mode = 0xe;
		break;
	case GSM48_CMODE_DATA_12k0:
		channel_mode = 0xb;
		break;
	case GSM48_CMODE_DATA_6k0:
		channel_mode = 0xc;
		break;
	case GSM48_CMODE_DATA_3k6:
		channel_mode = 0xd;
		break;
	}

	switch (lchan->type) {
	case GSM_LCHAN_NONE:
		channel = 0x0;
		break;
	case GSM_LCHAN_SDCCH:
		channel = 0x1;
		break;
	case GSM_LCHAN_TCH_F:
		channel = 0x8;
		break;
	case GSM_LCHAN_TCH_H:
		channel = 0x9;
		break;
	case GSM_LCHAN_UNKNOWN:
	default:
		LOGP(DMSC, LOGL_ERROR, "Unknown lchan type: %p\n", lchan);
		break;
	}

	return channel_mode << 4 | channel;
}

static uint8_t chan_mode_to_speech(struct gsm_lchan *lchan)
{
	int mode = 0;

	switch (lchan->tch_mode) {
	case GSM48_CMODE_SPEECH_V1:
		mode = 1;
		break;
	case GSM48_CMODE_SPEECH_EFR:
		mode = 0x11;
		break;
	case GSM48_CMODE_SPEECH_AMR:
		mode = 0x21;
		break;
	case GSM48_CMODE_SIGN:
	case GSM48_CMODE_DATA_14k5:
	case GSM48_CMODE_DATA_12k0:
	case GSM48_CMODE_DATA_6k0:
	case GSM48_CMODE_DATA_3k6:
	default:
		LOGP(DMSC, LOGL_ERROR, "Using non speech mode: %d\n", mode);
		return 0;
		break;
	}

	/* assume to always do AMR HR on any TCH type */
	if (lchan->type == GSM_LCHAN_TCH_H ||
	    lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
		mode |= 0x4;

        return mode;
}

static void assignment_t10_timeout(void *_conn)
{
	struct bsc_api *api;
	struct gsm_subscriber_connection *conn =
		(struct gsm_subscriber_connection *) _conn;

	LOGP(DMSC, LOGL_ERROR, "Assignment T10 timeout on %p\n", conn);

	/*
	 * normal release on the secondary channel but only if the
	 * secondary_channel has not been released by the handle_chan_nack.
	 */
	if (conn->secondary_lchan)
		lchan_release(conn->secondary_lchan, 0, RSL_REL_LOCAL_END);
	conn->secondary_lchan = NULL;

	/* inform them about the failure */
	api = conn->network->bsc_api;
	api->assign_fail(conn, GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL);
}

/*! \brief Determine and apply AMR multi-rate configuration to lchan
 *  Determine which AMR multi-rate configuration to use and apply it to
 *  the lchan (so it can be communicated to BTS and MS during channel
 *  activation.
 *  \param[in] conn subscriber connection (used to resolve bsc_api)
 *  \param[out] lchan logical channel to which to apply mr config
 *  \param[in] full_rate whether to use full-rate (1) or half-rate (0) config
 */
static void handle_mr_config(struct gsm_subscriber_connection *conn,
			     struct gsm_lchan *lchan, int full_rate)
{
	struct bsc_api *api;
	api = conn->network->bsc_api;
	struct amr_multirate_conf *mr;
	struct gsm48_multi_rate_conf *mr_conf;

	/* BSC api override for this method, used in OsmoBSC mode with
	 * bsc_mr_config() to use MSC-specific/specified configuration */
	if (api->mr_config)
		return api->mr_config(conn, lchan, full_rate);

	/* NITB case: use the BTS-specic multi-rate configuration from
	 * the vty/configuration file */
	if (full_rate)
		mr = &lchan->ts->trx->bts->mr_full;
	else
		mr = &lchan->ts->trx->bts->mr_half;

	mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
	mr_conf->ver = 1;

	/* default, if no AMR codec defined */
	if (!mr->gsm48_ie[1]) {
		mr_conf->icmi = 1;
		mr_conf->m5_90 = 1;
	}
	/* store encoded MR config IE lchan for both MS (uplink) and BTS
	 * (downlink) directions */
	gsm48_multirate_config(lchan->mr_ms_lv, mr, mr->ms_mode);
	gsm48_multirate_config(lchan->mr_bts_lv, mr, mr->bts_mode);
}

/*
 * Start a new assignment and make sure that it is completed within T10 either
 * positively, negatively or by the timeout.
 *
 *  1.) allocate a new lchan
 *  2.) copy the encryption key and other data from the
 *      old to the new channel.
 *  3.) RSL Channel Activate this channel and wait
 *
 * -> Signal handler for the LCHAN
 *  4.) Send GSM 04.08 assignment command to the MS
 *
 * -> Assignment Complete/Assignment Failure
 *  5.) Release the SDCCH, continue signalling on the new link
 */
static int handle_new_assignment(struct gsm_subscriber_connection *conn, int chan_mode, int full_rate)
{
	struct gsm_lchan *new_lchan;
	int chan_type;

	chan_type = full_rate ? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H;

	new_lchan = lchan_alloc(conn->bts, chan_type, 0);

	if (!new_lchan) {
		LOGP(DMSC, LOGL_NOTICE, "No free channel.\n");
		return -1;
	}

	/* copy old data to the new channel */
	memcpy(&new_lchan->encr, &conn->lchan->encr, sizeof(new_lchan->encr));
	new_lchan->ms_power = conn->lchan->ms_power;
	new_lchan->bs_power = conn->lchan->bs_power;
	new_lchan->rqd_ta = conn->lchan->rqd_ta;

	/* copy new data to it */
	new_lchan->tch_mode = chan_mode;
	new_lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;

	/* handle AMR correctly */
	if (chan_mode == GSM48_CMODE_SPEECH_AMR)
		handle_mr_config(conn, new_lchan, full_rate);

	if (rsl_chan_activate_lchan(new_lchan, 0x1, 0) < 0) {
		LOGP(DHO, LOGL_ERROR, "could not activate channel\n");
		lchan_free(new_lchan);
		return -1;
	}

	/* remember that we have the channel */
	conn->secondary_lchan = new_lchan;
	new_lchan->conn = conn;

	rsl_lchan_set_state(new_lchan, LCHAN_S_ACT_REQ);
	return 0;
}

struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_lchan *lchan)
{
	struct gsm_subscriber_connection *conn;
	struct gsm_network *net = lchan->ts->trx->bts->network;

	conn = talloc_zero(net, struct gsm_subscriber_connection);
	if (!conn)
		return NULL;

	conn->network = net;
	conn->lchan = lchan;
	conn->bts = lchan->ts->trx->bts;
	conn->via_ran = RAN_GERAN_A;
	conn->lac = conn->bts->location_area_code;
	lchan->conn = conn;
	llist_add_tail(&conn->entry, &net->subscr_conns);
	return conn;
}

void bsc_subscr_con_free(struct gsm_subscriber_connection *conn)
{
	if (!conn)
		return;

	if (conn->network->bsc_api->conn_cleanup)
		conn->network->bsc_api->conn_cleanup(conn);

	if (conn->vsub) {
		LOGP(DNM, LOGL_ERROR, "conn->vsub should have been cleared.\n");
		conn->vsub = NULL;
	}

	if (conn->ho_lchan) {
		LOGP(DNM, LOGL_ERROR, "The ho_lchan should have been cleared.\n");
		conn->ho_lchan->conn = NULL;
	}

	if (conn->lchan) {
		LOGP(DNM, LOGL_ERROR, "The lchan should have been cleared.\n");
		conn->lchan->conn = NULL;
	}

	if (conn->secondary_lchan) {
		LOGP(DNM, LOGL_ERROR, "The secondary_lchan should have been cleared.\n");
		conn->secondary_lchan->conn = NULL;
	}

	llist_del(&conn->entry);
	talloc_free(conn);
}

int bsc_api_init(struct gsm_network *network, struct bsc_api *api)
{
	network->bsc_api = api;
	return 0;
}

/*! \brief process incoming 08.08 DTAP from MSC (send via BTS to MS) */
int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn,
			struct msgb *msg, int link_id, int allow_sacch)
{
	uint8_t sapi;


	if (!conn->lchan) {
		LOGP(DMSC, LOGL_ERROR,
		     "Called submit dtap without an lchan.\n");
		msgb_free(msg);
		return -1;
	}

	sapi = link_id & 0x7;
	msg->lchan = conn->lchan;
	msg->dst = msg->lchan->ts->trx->rsl_link;

	/* If we are on a TCH and need to submit a SMS (on SAPI=3) we need to use the SACH */
	if (allow_sacch && sapi != 0) {
		if (conn->lchan->type == GSM_LCHAN_TCH_F || conn->lchan->type == GSM_LCHAN_TCH_H)
			link_id |= 0x40;
	}

	msg->l3h = msg->data;
	/* is requested SAPI already up? */
	if (conn->lchan->sapis[sapi] == LCHAN_SAPI_UNUSED) {
		/* Establish L2 for additional SAPI */
		OBSC_LINKID_CB(msg) = link_id;
		if (rll_establish(msg->lchan, sapi, rll_ind_cb, msg) != 0) {
			msgb_free(msg);
			send_sapi_reject(conn, link_id);
			return -1;
		}
		return 0;
	} else {
		/* Directly forward via RLL/RSL to BTS */
		return rsl_data_request(msg, link_id);
	}
}

/*
 * \brief Check if the given channel is compatible with the mode/fullrate
 */
static int chan_compat_with_mode(struct gsm_lchan *lchan, int chan_mode, int full_rate)
{
	switch (chan_mode) {
	case GSM48_CMODE_SIGN:
		/* signalling is always possible */
		return 1;
	case GSM48_CMODE_SPEECH_V1:
	case GSM48_CMODE_SPEECH_AMR:
	case GSM48_CMODE_DATA_3k6:
	case GSM48_CMODE_DATA_6k0:
		/* these services can all run on TCH/H, but we may have
		 * an explicit override by the 'full_rate' argument */
		switch (lchan->type) {
		case GSM_LCHAN_TCH_F:
			return 1;
		case GSM_LCHAN_TCH_H:
			if (full_rate)
				return 0;
			else
				return 1;
			break;
		default:
			return 0;
		}
		break;
	case GSM48_CMODE_DATA_12k0:
	case GSM48_CMODE_DATA_14k5:
	case GSM48_CMODE_SPEECH_EFR:
		/* these services all explicitly require a TCH/F */
		if (lchan->type == GSM_LCHAN_TCH_F)
			return 1;
		else
			return 0;
		break;
	}

	return 0;
}

/**
 * Send a GSM08.08 Assignment Request. Right now this does not contain the
 * audio codec type or the allowed rates for the config. It is assumed that
 * this is for audio handling only. In case the current channel does not allow
 * the selected mode a new one will be allocated.
 *
 * TODO: Add multirate configuration, make it work for more than audio.
 */
int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_mode, int full_rate)
{
	struct bsc_api *api;
	api = conn->network->bsc_api;

	if (!chan_compat_with_mode(conn->lchan, chan_mode, full_rate)) {
		if (handle_new_assignment(conn, chan_mode, full_rate) != 0)
			goto error;
	} else {
		if (chan_mode == GSM48_CMODE_SPEECH_AMR)
			handle_mr_config(conn, conn->lchan, full_rate);

		LOGP(DMSC, LOGL_NOTICE,
		     "Sending %s ChanModify for speech: %s on channel %s\n",
		     gsm_lchan_name(conn->lchan),
		     get_value_string(gsm48_chan_mode_names, chan_mode),
		     get_value_string(gsm_chan_t_names, conn->lchan->type));
		gsm48_lchan_modify(conn->lchan, chan_mode);
	}

	/* we will now start the timer to complete the assignment */
	osmo_timer_setup(&conn->T10, assignment_t10_timeout, conn);
	osmo_timer_schedule(&conn->T10, GSM0808_T10_VALUE);
	return 0;

error:
	api->assign_fail(conn, 0, NULL);
	return -1;
}

int gsm0808_page(struct gsm_bts *bts, unsigned int page_group, unsigned int mi_len,
		 uint8_t *mi, int chan_type)
{
	return rsl_paging_cmd(bts, page_group, mi_len, mi, chan_type, false);
}

static void handle_ass_compl(struct gsm_subscriber_connection *conn,
			     struct msgb *msg)
{
	struct gsm48_hdr *gh;
	struct bsc_api *api = conn->network->bsc_api;

	if (conn->secondary_lchan != msg->lchan) {
		LOGP(DMSC, LOGL_ERROR, "Assignment Compl should occur on second lchan.\n");
		return;
	}

	gh = msgb_l3(msg);
	if (msgb_l3len(msg) - sizeof(*gh) != 1) {
		LOGP(DMSC, LOGL_ERROR, "Assignment Compl invalid: %zu\n",
		     msgb_l3len(msg) - sizeof(*gh));
		return;
	}

	/* switch TRAU muxer for E1 based BTS from one channel to another */
	if (is_e1_bts(conn->bts))
		switch_trau_mux(conn->lchan, conn->secondary_lchan);

	/* swap channels */
	osmo_timer_del(&conn->T10);

	lchan_release(conn->lchan, 0, RSL_REL_LOCAL_END);
	conn->lchan = conn->secondary_lchan;
	conn->secondary_lchan = NULL;

	if (is_ipaccess_bts(conn->bts) && conn->lchan->tch_mode != GSM48_CMODE_SIGN)
		rsl_ipacc_crcx(conn->lchan);

	api->assign_compl(conn, gh->data[0],
			  lchan_to_chosen_channel(conn->lchan),
			  conn->lchan->encr.alg_id,
			  chan_mode_to_speech(conn->lchan));
}

static void handle_ass_fail(struct gsm_subscriber_connection *conn,
			    struct msgb *msg)
{
	struct bsc_api *api = conn->network->bsc_api;
	uint8_t *rr_failure;
	struct gsm48_hdr *gh;


	if (conn->lchan != msg->lchan) {
		LOGP(DMSC, LOGL_ERROR, "Assignment failure should occur on primary lchan.\n");
		return;
	}

	/* stop the timer and release it */
	osmo_timer_del(&conn->T10);
	lchan_release(conn->secondary_lchan, 0, RSL_REL_LOCAL_END);
	conn->secondary_lchan = NULL;

	gh = msgb_l3(msg);
	if (msgb_l3len(msg) - sizeof(*gh) != 1) {
		LOGP(DMSC, LOGL_ERROR, "assignment failure unhandled: %zu\n",
		     msgb_l3len(msg) - sizeof(*gh));
		rr_failure = NULL;
	} else {
		rr_failure = &gh->data[0];
	}

	api->assign_fail(conn,
			 GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE,
			 rr_failure);
}

static void handle_classmark_chg(struct gsm_subscriber_connection *conn,
				 struct msgb *msg)
{
	struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	uint8_t cm2_len, cm3_len = 0;
	uint8_t *cm2, *cm3 = NULL;

	DEBUGP(DRR, "CLASSMARK CHANGE ");

	/* classmark 2 */
	cm2_len = gh->data[0];
	cm2 = &gh->data[1];
	DEBUGPC(DRR, "CM2(len=%u) ", cm2_len);

	if (payload_len > cm2_len + 1) {
		/* we must have a classmark3 */
		if (gh->data[cm2_len+1] != 0x20) {
			DEBUGPC(DRR, "ERR CM3 TAG\n");
			return;
		}
		if (cm2_len > 3) {
			DEBUGPC(DRR, "CM2 too long!\n");
			return;
		}

		cm3_len = gh->data[cm2_len+2];
		cm3 = &gh->data[cm2_len+3];
		if (cm3_len > 14) {
			DEBUGPC(DRR, "CM3 len %u too long!\n", cm3_len);
			return;
		}
		DEBUGPC(DRR, "CM3(len=%u)\n", cm3_len);
	}
	api->classmark_chg(conn, cm2, cm2_len, cm3, cm3_len);
}

/* Chapter 9.1.16 Handover complete */
static void handle_rr_ho_compl(struct msgb *msg)
{
	struct lchan_signal_data sig;
	struct gsm48_hdr *gh = msgb_l3(msg);

	DEBUGP(DRR, "HANDOVER COMPLETE cause = %s\n",
		rr_cause_name(gh->data[0]));

	sig.lchan = msg->lchan;
	sig.mr = NULL;
	osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_COMPL, &sig);
	/* FIXME: release old channel */
}

/* Chapter 9.1.17 Handover Failure */
static void handle_rr_ho_fail(struct msgb *msg)
{
	struct lchan_signal_data sig;
	struct gsm48_hdr *gh = msgb_l3(msg);

	DEBUGP(DRR, "HANDOVER FAILED cause = %s\n",
		rr_cause_name(gh->data[0]));

	sig.lchan = msg->lchan;
	sig.mr = NULL;
	osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_FAIL, &sig);
	/* FIXME: release allocated new channel */
}


static void dispatch_dtap(struct gsm_subscriber_connection *conn,
			  uint8_t link_id, struct msgb *msg)
{
	struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
	struct gsm48_hdr *gh;
	uint8_t pdisc;
	uint8_t msg_type;
	int rc;

	if (msgb_l3len(msg) < sizeof(*gh)) {
		LOGP(DMSC, LOGL_ERROR, "Message too short for a GSM48 header.\n");
		return;
	}

	gh = msgb_l3(msg);
	pdisc = gsm48_hdr_pdisc(gh);
	msg_type = gsm48_hdr_msg_type(gh);

	/* the idea is to handle all RR messages here, and only hand
	 * MM/CC/SMS-CP/LCS up to the MSC.  Some messages like PAGING
	 * RESPONSE or CM SERVICE REQUEST will not be covered here, as
	 * they are only possible in the first L3 message of each L2
	 * channel, i.e. 'conn' will not exist and gsm0408_rcvmsg()
	 * will call api->compl_l3() for it */
	switch (pdisc) {
	case GSM48_PDISC_RR:
		switch (msg_type) {
		case GSM48_MT_RR_GPRS_SUSP_REQ:
			DEBUGP(DRR, "%s\n",
			       gsm48_rr_msg_name(GSM48_MT_RR_GPRS_SUSP_REQ));
			break;
		case GSM48_MT_RR_STATUS:
			LOGP(DRR, LOGL_NOTICE, "%s (cause: %s)\n",
			     gsm48_rr_msg_name(GSM48_MT_RR_STATUS),
			     rr_cause_name(gh->data[0]));
			break;
		case GSM48_MT_RR_MEAS_REP:
			/* This shouldn't actually end up here, as RSL treats
			* L3 Info of 08.58 MEASUREMENT REPORT different by calling
			* directly into gsm48_parse_meas_rep */
			LOGP(DMEAS, LOGL_ERROR, "DIRECT GSM48 MEASUREMENT REPORT ?!? ");
			break;
		case GSM48_MT_RR_HANDO_COMPL:
			handle_rr_ho_compl(msg);
			break;
		case GSM48_MT_RR_HANDO_FAIL:
			handle_rr_ho_fail(msg);
			break;
		case GSM48_MT_RR_CIPH_M_COMPL:
			if (api->cipher_mode_compl)
				api->cipher_mode_compl(conn, msg,
						conn->lchan->encr.alg_id);
			break;
		case GSM48_MT_RR_ASS_COMPL:
			handle_ass_compl(conn, msg);
			break;
		case GSM48_MT_RR_ASS_FAIL:
			handle_ass_fail(conn, msg);
			break;
		case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
			osmo_timer_del(&conn->T10);
			rc = gsm48_rx_rr_modif_ack(msg);
			if (rc < 0) {
				api->assign_fail(conn,
						 GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE,
						 NULL);
			} else if (rc >= 0) {
				api->assign_compl(conn, 0,
						  lchan_to_chosen_channel(conn->lchan),
						  conn->lchan->encr.alg_id,
						  chan_mode_to_speech(conn->lchan));
			}
			break;
		case GSM48_MT_RR_CLSM_CHG:
			handle_classmark_chg(conn, msg);
			break;
		case GSM48_MT_RR_APP_INFO:
			/* Passing RR APP INFO to MSC, not quite
			 * according to spec */
			if (api->dtap)
				api->dtap(conn, link_id, msg);
			break;
		default:
			/* Normally, a MSC should never receive RR
			 * messages, but we'd rather forward what we
			 * don't know than drop it... */
			LOGP(DRR, LOGL_NOTICE,
			     "BSC: Passing %s 04.08 RR message to MSC\n",
			     gsm48_rr_msg_name(msg_type));
			if (api->dtap)
				api->dtap(conn, link_id, msg);
		}
		break;
	default:
		if (api->dtap)
			api->dtap(conn, link_id, msg);
		break;
	}
}

/*! \brief RSL has received a DATA INDICATION with L3 from MS */
int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id)
{
	int rc;
	struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
	struct gsm_lchan *lchan;

	lchan = msg->lchan;
	if (lchan->state != LCHAN_S_ACTIVE) {
		LOGP(DRSL, LOGL_INFO, "Got data in non active state(%s), "
		     "discarding.\n", gsm_lchans_name(lchan->state));
		return -1;
	}


	if (lchan->conn) {
		/* if we already have a connection, forward via DTAP to
		 * MSC */
		dispatch_dtap(lchan->conn, link_id, msg);
	} else {
		/* allocate a new connection */
		rc = BSC_API_CONN_POL_REJECT;
		lchan->conn = bsc_subscr_con_allocate(msg->lchan);
		if (!lchan->conn) {
			lchan_release(lchan, 1, RSL_REL_NORMAL);
			return -1;
		}

		/* fwd via bsc_api to send COMPLETE L3 INFO to MSC */
		rc = api->compl_l3(lchan->conn, msg, 0);

		if (rc != BSC_API_CONN_POL_ACCEPT) {
			lchan->conn->lchan = NULL;
			bsc_subscr_con_free(lchan->conn);
			lchan_release(lchan, 1, RSL_REL_NORMAL);
		}
	}

	return 0;
}

/*! \brief We received a GSM 08.08 CIPHER MODE from the MSC */
int gsm0808_cipher_mode(struct gsm_subscriber_connection *conn, int cipher,
			const uint8_t *key, int len, int include_imeisv)
{
	if (cipher > 0 && key == NULL) {
		LOGP(DRSL, LOGL_ERROR, "Need to have an encrytpion key.\n");
		return -1;
	}

	if (len > MAX_A5_KEY_LEN) {
		LOGP(DRSL, LOGL_ERROR, "The key is too long: %d\n", len);
		return -1;
	}

	conn->lchan->encr.alg_id = RSL_ENC_ALG_A5(cipher);
	if (key) {
		conn->lchan->encr.key_len = len;
		memcpy(conn->lchan->encr.key, key, len);
	}

	return gsm48_send_rr_ciph_mode(conn->lchan, include_imeisv);
}

/*
 * Release all occupied RF Channels but stay around for more.
 */
int gsm0808_clear(struct gsm_subscriber_connection *conn)
{
	if (conn->ho_lchan)
		bsc_clear_handover(conn, 1);

	if (conn->secondary_lchan)
		lchan_release(conn->secondary_lchan, 0, RSL_REL_LOCAL_END);

	if (conn->lchan)
		lchan_release(conn->lchan, 1, RSL_REL_NORMAL);

	conn->lchan = NULL;
	conn->secondary_lchan = NULL;
	conn->ho_lchan = NULL;
	conn->bts = NULL;

	osmo_timer_del(&conn->T10);

	return 0;
}

static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id)
{
	struct bsc_api *api;

	if (!conn)
		return;

	api = conn->network->bsc_api;
	if (!api || !api->sapi_n_reject)
		return;

	api->sapi_n_reject(conn, link_id);
}

static void rll_ind_cb(struct gsm_lchan *lchan, uint8_t link_id, void *_data, enum bsc_rllr_ind rllr_ind)
{
	struct msgb *msg = _data;

	/*
	 * There seems to be a small window that the RLL timer can
	 * fire after a lchan_release call and before the S_CHALLOC_FREED
	 * is called. Check if a conn is set before proceeding.
	 */
	if (!lchan->conn)
		return;

	switch (rllr_ind) {
	case BSC_RLLR_IND_EST_CONF:
		rsl_data_request(msg, OBSC_LINKID_CB(msg));
		break;
	case BSC_RLLR_IND_REL_IND:
	case BSC_RLLR_IND_ERR_IND:
	case BSC_RLLR_IND_TIMEOUT:
		send_sapi_reject(lchan->conn, OBSC_LINKID_CB(msg));
		msgb_free(msg);
		break;
	}
}

static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal,
				   void *handler_data, void *signal_data)
{
	struct bsc_api *bsc;
	struct gsm_lchan *lchan;
	struct lchan_signal_data *lchan_data;

	if (subsys != SS_LCHAN)
		return 0;


	lchan_data = signal_data;
	if (!lchan_data->lchan || !lchan_data->lchan->conn)
		return 0;

	lchan = lchan_data->lchan;
	bsc = lchan->ts->trx->bts->network->bsc_api;
	if (!bsc)
		return 0;

	switch (signal) {
	case S_LCHAN_UNEXPECTED_RELEASE:
		handle_release(lchan->conn, bsc, lchan);
		break;
	case S_LCHAN_ACTIVATE_ACK:
		handle_chan_ack(lchan->conn, bsc, lchan);
		break;
	case S_LCHAN_ACTIVATE_NACK:
		handle_chan_nack(lchan->conn, bsc, lchan);
		break;
	}

	return 0;
}

static void handle_release(struct gsm_subscriber_connection *conn,
			   struct bsc_api *bsc, struct gsm_lchan *lchan)
{
	int destruct = 1;

	if (conn->secondary_lchan == lchan) {
		osmo_timer_del(&conn->T10);
		conn->secondary_lchan = NULL;

		bsc->assign_fail(conn,
				 GSM0808_CAUSE_RADIO_INTERFACE_FAILURE,
				 NULL);
	}

	/* clear the connection now */
	if (bsc->clear_request)
		destruct = bsc->clear_request(conn, 0);

	/* now give up all channels */
	if (conn->lchan == lchan)
		conn->lchan = NULL;
	if (conn->ho_lchan == lchan) {
		bsc_clear_handover(conn, 0);
		conn->ho_lchan = NULL;
	}
	lchan->conn = NULL;

	gsm0808_clear(conn);

	if (destruct)
		bsc_subscr_con_free(conn);
}

static void handle_chan_ack(struct gsm_subscriber_connection *conn,
			    struct bsc_api *api, struct gsm_lchan *lchan)
{
	if (conn->secondary_lchan != lchan)
		return;

	LOGP(DMSC, LOGL_NOTICE, "Sending assignment on chan: %p\n", lchan);
	gsm48_send_rr_ass_cmd(conn->lchan, lchan, lchan->ms_power);
}

static void handle_chan_nack(struct gsm_subscriber_connection *conn,
			     struct bsc_api *api, struct gsm_lchan *lchan)
{
	if (conn->secondary_lchan != lchan)
		return;

	LOGP(DMSC, LOGL_ERROR, "Channel activation failed. Waiting for timeout now\n");
	conn->secondary_lchan->conn = NULL;
	conn->secondary_lchan = NULL;
}

static __attribute__((constructor)) void on_dso_load_bsc(void)
{
	osmo_signal_register_handler(SS_LCHAN, bsc_handle_lchan_signal, NULL);
}

