/* GSM Mobile Radio Interface Layer 3 Call Control */

/* (C) 2008-2016 by Harald Welte <laforge@gnumonks.org>
 * (C) 2008-2012 by Holger Hans Peter Freyther <zecke@selfish.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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <time.h>
#include <netinet/in.h>
#include <regex.h>
#include <sys/types.h>

#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>

#include <osmocom/msc/db.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/gsm_subscriber.h>
#include <osmocom/msc/gsm_04_11.h>
#include <osmocom/msc/gsm_04_08.h>
#include <osmocom/msc/gsm_04_80.h>
#include <osmocom/msc/gsm_04_14.h>
#include <osmocom/msc/gsm_09_11.h>
#include <osmocom/msc/signal.h>
#include <osmocom/msc/transaction.h>
#include <osmocom/msc/transaction_cc.h>
#include <osmocom/msc/silent_call.h>
#include <osmocom/msc/mncc_int.h>
#include <osmocom/abis/e1_input.h>
#include <osmocom/core/bitvec.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/msc_a.h>
#include <osmocom/msc/paging.h>
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/rtp_stream.h>
#include <osmocom/msc/mncc_call.h>
#include <osmocom/msc/msc_t.h>
#include <osmocom/msc/sdp_msg.h>
#include <osmocom/msc/codec_mapping.h>

#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/gsm0480.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/byteswap.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/crypt/auth.h>

#include <assert.h>

static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg);
static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg);
static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg);

static int trans_tx_gsm48(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msg->data;
	gh->proto_discr = GSM48_PDISC_CC | (trans->transaction_id << 4);
	OMSC_LINKID_CB(msg) = trans->dlci;

	return msc_a_tx_dtap_to_i(trans->msc_a, msg);
}

uint32_t msc_cc_next_outgoing_callref() {
	static uint32_t last_callref = 0x80000000;
	last_callref++;
	if (last_callref < 0x80000001)
		last_callref = 0x80000001;
	return last_callref;
}

static void gsm48_cc_guard_timeout(void *arg)
{
	struct gsm_trans *trans = arg;
	LOG_TRANS(trans, LOGL_DEBUG, "guard timeout expired\n");
	trans_free(trans);
	return;
}

static void gsm48_stop_guard_timer(struct gsm_trans *trans)
{
	if (osmo_timer_pending(&trans->cc.timer_guard)) {
		LOG_TRANS(trans, LOGL_DEBUG, "stopping pending guard timer\n");
		osmo_timer_del(&trans->cc.timer_guard);
	}
}

static void gsm48_start_guard_timer(struct gsm_trans *trans)
{
	/* NOTE: The purpose of this timer is to prevent the cc state machine
	 * from hanging in cases where mncc, gsm48 or both become unresponsive
	 * for some reason. The timer is started initially with the setup from
	 * the gsm48 side and then re-started with every incoming mncc message.
	 * Once the mncc state reaches its active state the timer is stopped.
	 * So if the cc state machine does not show any activity for an
	 * extended amount of time during call setup or teardown the guard
	 * timer will time out and hard-clear the connection. */
	if (osmo_timer_pending(&trans->cc.timer_guard))
		gsm48_stop_guard_timer(trans);
	LOG_TRANS(trans, LOGL_DEBUG, "starting guard timer with %d seconds\n", trans->net->mncc_guard_timeout);
	osmo_timer_setup(&trans->cc.timer_guard, gsm48_cc_guard_timeout, trans);
	osmo_timer_schedule(&trans->cc.timer_guard,
			    trans->net->mncc_guard_timeout, 0);
}

/* Call Control */

void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg)
{
	net->mncc_recv(net, msg);
}

int gsm48_cc_tx_notify_ss(struct gsm_trans *trans, const char *message)
{
	struct gsm48_hdr *gh;
	struct msgb *ss_notify;

	ss_notify = gsm0480_create_notifySS(message);
	if (!ss_notify)
		return -1;

	gsm0480_wrap_invoke(ss_notify, GSM0480_OP_CODE_NOTIFY_SS, 0);
	uint8_t *data = msgb_push(ss_notify, 1);
	data[0] = ss_notify->len - 1;
	gh = (struct gsm48_hdr *) msgb_push(ss_notify, sizeof(*gh));
	gh->msg_type = GSM48_MT_CC_FACILITY;
	return trans_tx_gsm48(trans, ss_notify);
}

/* FIXME: this count_statistics is a state machine behaviour. we should convert
 * the complete call control into a state machine. Afterwards we can move this
 * code into state transitions.
 */
static void count_statistics(struct gsm_trans *trans, int new_state)
{
	int old_state = trans->cc.state;
	struct rate_ctr_group *msc = trans->net->msc_ctrs;

	if (old_state == new_state)
		return;

	/* state incoming */
	switch (new_state) {
	case GSM_CSTATE_ACTIVE:
		osmo_stat_item_inc(osmo_stat_item_group_get_item(trans->net->statg, MSC_STAT_ACTIVE_CALLS),
				   1);
		rate_ctr_inc(rate_ctr_group_get_ctr(msc, MSC_CTR_CALL_ACTIVE));
		break;
	}

	/* state outgoing */
	switch (old_state) {
	case GSM_CSTATE_ACTIVE:
		osmo_stat_item_dec(osmo_stat_item_group_get_item(trans->net->statg, MSC_STAT_ACTIVE_CALLS),
				   1);
		if (new_state == GSM_CSTATE_DISCONNECT_REQ ||
				new_state == GSM_CSTATE_DISCONNECT_IND)
			rate_ctr_inc(rate_ctr_group_get_ctr(msc, MSC_CTR_CALL_COMPLETE));
		else
			rate_ctr_inc(rate_ctr_group_get_ctr(msc, MSC_CTR_CALL_INCOMPLETE));
		break;
	}
}

static void new_cc_state(struct gsm_trans *trans, int state)
{
	if (state > 31 || state < 0)
		return;

	LOG_TRANS(trans, LOGL_DEBUG, "new state %s -> %s\n",
		  gsm48_cc_state_name(trans->cc.state),
		  gsm48_cc_state_name(state));

	count_statistics(trans, state);
	trans->cc.state = state;

	/* Stop the guard timer when a call reaches the active state */
	if (state == GSM_CSTATE_ACTIVE)
		gsm48_stop_guard_timer(trans);
}

static int gsm48_cc_tx_status(struct gsm_trans *trans, void *arg)
{
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC STATUS");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
	uint8_t *cause, *call_state;

	gh->msg_type = GSM48_MT_CC_STATUS;

	cause = msgb_put(msg, 3);
	cause[0] = 2;
	cause[1] = GSM48_CAUSE_CS_GSM | GSM48_CAUSE_LOC_USER;
	cause[2] = 0x80 | 30;	/* response to status inquiry */

	call_state = msgb_put(msg, 1);
	call_state[0] = 0xc0 | 0x00;

	return trans_tx_gsm48(trans, msg);
}

static void gsm48_stop_cc_timer(struct gsm_trans *trans)
{
	if (osmo_timer_pending(&trans->cc.timer)) {
		LOG_TRANS(trans, LOGL_DEBUG, "stopping pending timer T%x\n", trans->cc.Tcurrent);
		osmo_timer_del(&trans->cc.timer);
		trans->cc.Tcurrent = 0;
	}
}

/* Log the MNCC tx and rx events.
 * Depending on msg_type, also log whether RTP information is passed on.
 * (This is particularly interesting for the doc/sequence_charts/msc_log_to_ladder.py)
 */
#define log_mncc_rx_tx(ARGS...) _log_mncc_rx_tx(__FILE__, __LINE__, ##ARGS)
static void _log_mncc_rx_tx(const char *file, int line,
			    struct gsm_trans *trans, const char *rx_tx, const union mncc_msg *mncc)
{
	const char *sdp = NULL;
	struct sdp_msg sdp_msg = {};
	struct osmo_sockaddr addr = {};

	if (!log_check_level(DMNCC, LOGL_DEBUG))
		return;

	switch (mncc->msg_type) {
	case MNCC_RTP_CREATE:
	case MNCC_RTP_CONNECT:
		addr = (struct osmo_sockaddr){ .u.sas = mncc->rtp.addr };
		sdp = mncc->rtp.sdp;
		break;

	case MNCC_SETUP_IND:
	case MNCC_SETUP_REQ:
	case MNCC_SETUP_COMPL_IND:
	case MNCC_SETUP_COMPL_REQ:
	case MNCC_SETUP_RSP:
	case MNCC_SETUP_CNF:
	case MNCC_CALL_CONF_IND:
	case MNCC_CALL_PROC_REQ:
	case MNCC_ALERT_IND:
	case MNCC_ALERT_REQ:
		sdp = mncc->signal.sdp;
		break;

	default:
		break;
	}

	if (sdp && sdp[0] && (sdp_msg_from_sdp_str(&sdp_msg, sdp) == 0)) {
		LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_DEBUG, file, line, "%s %s (RTP=%s)\n",
				  rx_tx,
				  get_mncc_name(mncc->msg_type),
				  sdp_msg_to_str(&sdp_msg));
		return;
	}

	if (osmo_sockaddr_is_any(&addr) == 0) {
		LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_DEBUG, file, line, "%s %s (RTP=%s)\n",
				  rx_tx,
				  get_mncc_name(mncc->msg_type),
				  osmo_sockaddr_to_str_c(OTC_SELECT, &addr));
		return;
	}

	LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_DEBUG, file, line, "%s %s\n", rx_tx, get_mncc_name(mncc->msg_type));
}

#define mncc_recvmsg(ARGS...) _mncc_recvmsg(__FILE__, __LINE__, ##ARGS)
static int _mncc_recvmsg(const char *file, int line,
			 struct gsm_network *net, struct gsm_trans *trans, int msg_type, struct gsm_mncc *mncc)
{
	struct msgb *msg;
	unsigned char *data;

	mncc->msg_type = msg_type;
	log_mncc_rx_tx(trans, "tx", (union mncc_msg *)mncc);

	msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC");
	if (!msg)
		return -ENOMEM;

	data = msgb_put(msg, sizeof(struct gsm_mncc));
	memcpy(data, mncc, sizeof(struct gsm_mncc));

	cc_tx_to_mncc(net, msg);
	/* trans may be NULL when sending an MNCC error reply upon an invalid MNCC request */
	if (trans)
		trans->cc.mncc_initiated = true;

	return 0;
}

int mncc_release_ind(struct gsm_network *net, struct gsm_trans *trans,
		     uint32_t callref, int location, int value)
{
	struct gsm_mncc rel;

	memset(&rel, 0, sizeof(rel));
	rel.callref = callref;
	mncc_set_cause(&rel, location, value);
	if (trans && trans->cc.state == GSM_CSTATE_RELEASE_REQ)
		return mncc_recvmsg(net, trans, MNCC_REL_CNF, &rel);
	return mncc_recvmsg(net, trans, MNCC_REL_IND, &rel);
}

/* Call Control Specific transaction release.
 * gets called by trans_free, DO NOT CALL YOURSELF! */
void _gsm48_cc_trans_free(struct gsm_trans *trans)
{
	gsm48_stop_cc_timer(trans);

	/* send release to L4, if callref still exists */
	if (trans->callref) {
		/* Send MNCC REL.ind (cause='Resource unavailable') */
		if (trans->cc.mncc_initiated) {
			mncc_release_ind(trans->net, trans, trans->callref,
					 GSM48_CAUSE_LOC_PRN_S_LU,
					 (trans->cc.state == GSM_CSTATE_CALL_RECEIVED) ?
					 GSM48_CC_CAUSE_USER_NOTRESPOND :
					 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
		}

		/* FIXME: currently, a CC trans that would not yet be in state GSM_CSTATE_RELEASE_REQ fails to send a
		 * CC Release to the MS if it gets freed here. Hack it to do so. */
		if (trans->cc.state != GSM_CSTATE_RELEASE_REQ) {
			struct gsm_mncc rel = {};
			rel.callref = trans->callref;
			mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
			gsm48_cc_tx_release(trans, &rel);
		}
		/* This is a final freeing of the transaction. The MNCC release may have triggered the
		 * T308 release timer, but we don't have the luxury of graceful CC Release here. */
		gsm48_stop_cc_timer(trans);
	}
	if (trans->cc.state != GSM_CSTATE_NULL)
		new_cc_state(trans, GSM_CSTATE_NULL);

	gsm48_stop_guard_timer(trans);

	if (trans->msc_a && trans->msc_a->cc.active_trans == trans)
		trans->msc_a->cc.active_trans = NULL;
}

/* call-back from paging the B-end of the connection */
static void cc_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans)
{
	if (trans->msc_a) {
		LOG_MSC_A_CAT(msc_a, DPAG, LOGL_ERROR,
			      "Handle paging error: transaction already associated with subscriber,"
			      " apparently it was already handled. Skip.\n");
		return;
	}

	if (msc_a) {
		LOG_TRANS(trans, LOGL_DEBUG, "Paging succeeded\n");
		/* Assign conn */
		msc_a_get(msc_a, MSC_A_USE_CC);
		trans->msc_a = msc_a;
		trans->paging_request = NULL;

		/* Get the GCR from the MO call leg (if any). */
		if (!trans->cc.lcls)
			trans->cc.lcls = trans_lcls_compose(trans, true);
		if (trans->cc.lcls && trans->cc.msg.fields & MNCC_F_GCR) {
			int rc = osmo_dec_gcr(&trans->cc.lcls->gcr,
					      &trans->cc.msg.gcr[0],
					      sizeof(trans->cc.msg.gcr));
			if (rc < 0)
				LOG_TRANS(trans, LOGL_ERROR, "Failed to parse GCR\n");
			else
				trans->cc.lcls->gcr_available = true;
		}

		osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_TRANSACTION_ACCEPTED, trans);
		/* send SETUP request to called party */
		gsm48_cc_tx_setup(trans, &trans->cc.msg);
	} else {
		LOG_TRANS(trans, LOGL_DEBUG, "Paging expired\n");
		/* Temporarily out of order */
		mncc_release_ind(trans->net, trans,
				 trans->callref,
				 GSM48_CAUSE_LOC_PRN_S_LU,
				 GSM48_CC_CAUSE_DEST_OOO);
		trans->callref = 0;
		trans->paging_request = NULL;
		trans_free(trans);
	}
}

/* bridge channels of two transactions */
static int tch_bridge(struct gsm_network *net, const struct gsm_mncc_bridge *bridge)
{
	struct gsm_trans *trans1 = trans_find_by_callref(net, bridge->callref[0]);
	struct gsm_trans *trans2 = trans_find_by_callref(net, bridge->callref[1]);
	struct call_leg *cl1;
	struct call_leg *cl2;

	if (!trans1 || !trans2) {
		LOG_TRANS(trans1 ? : trans2, LOGL_ERROR, "Cannot MNCC_BRIDGE, one or both call legs are unset\n");
		return -EIO;
	}

	if (!trans1->msc_a || !trans2->msc_a) {
		LOG_TRANS(trans1, LOGL_ERROR, "Cannot MNCC_BRIDGE, one or both call legs lack an active connection\n");
		LOG_TRANS(trans2, LOGL_ERROR, "Cannot MNCC_BRIDGE, one or both call legs lack an active connection\n");
		return -EIO;
	}

	LOG_TRANS(trans1, LOGL_DEBUG, "MNCC_BRIDGE: Local bridge to callref 0x%x\n", trans2->callref);
	LOG_TRANS(trans2, LOGL_DEBUG, "MNCC_BRIDGE: Local bridge to callref 0x%x\n", trans1->callref);

	/* This call bridging mechanism is only used with the internal MNCC (with external MNCC briding would be done by
	 * the PBX). For inter-MSC Handover scenarios, an external MNCC is mandatory. The conclusion is that in this
	 * code path, there is only one MSC, and the MSC-I role is local, and hence we can directly access the ran_conn.
	 * If we can't, then we must give up. */
	cl1 = trans1->msc_a->cc.call_leg;
	cl2 = trans2->msc_a->cc.call_leg;

	return call_leg_local_bridge(cl1, trans1->callref, trans1, cl2, trans2->callref, trans2);
}

static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg)
{
	LOG_TRANS(trans, LOGL_DEBUG, "-> STATUS ENQ\n");
	return gsm48_cc_tx_status(trans, msg);
}

static void gsm48_cc_timeout(void *arg)
{
	struct gsm_trans *trans = arg;
	int disconnect = 0, release = 0;
	int mo_cause = GSM48_CC_CAUSE_RECOVERY_TIMER;
	int mo_location = GSM48_CAUSE_LOC_USER;
	int l4_cause = GSM48_CC_CAUSE_NORMAL_UNSPEC;
	int l4_location = GSM48_CAUSE_LOC_PRN_S_LU;
	struct gsm_mncc mo_rel, l4_rel;

	LOG_TRANS(trans, LOGL_INFO, "Timeout of T%x\n", trans->cc.Tcurrent);

	memset(&mo_rel, 0, sizeof(struct gsm_mncc));
	mo_rel.callref = trans->callref;
	memset(&l4_rel, 0, sizeof(struct gsm_mncc));
	l4_rel.callref = trans->callref;

	switch(trans->cc.Tcurrent) {
	case 0x303:
		release = 1;
		l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
		break;
	case 0x310:
		disconnect = 1;
		l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
		break;
	case 0x313:
		disconnect = 1;
		/* unknown, did not find it in the specs */
		break;
	case 0x301:
		disconnect = 1;
		l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
		break;
	case 0x308:
		if (!trans->cc.T308_second) {
			/* restart T308 a second time */
			gsm48_cc_tx_release(trans, &trans->cc.msg);
			trans->cc.T308_second = 1;
			break; /* stay in release state */
		}
		trans_free(trans);
		return;
	case 0x306:
		release = 1;
		mo_cause = trans->cc.msg.cause.value;
		mo_location = trans->cc.msg.cause.location;
		break;
	case 0x323:
		disconnect = 1;
		break;
	default:
		release = 1;
	}

	if (release && trans->callref) {
		/* process release towards layer 4 */
		mncc_release_ind(trans->net, trans, trans->callref,
				 l4_location, l4_cause);
		trans->callref = 0;
	}

	if (disconnect && trans->callref) {
		/* process disconnect towards layer 4 */
		mncc_set_cause(&l4_rel, l4_location, l4_cause);
		mncc_recvmsg(trans->net, trans, MNCC_DISC_IND, &l4_rel);
	}

	/* process disconnect towards mobile station */
	if (disconnect || release) {
		mncc_set_cause(&mo_rel, mo_location, mo_cause);
		mo_rel.cause.diag[0] = ((trans->cc.Tcurrent & 0xf00) >> 8) + '0';
		mo_rel.cause.diag[1] = ((trans->cc.Tcurrent & 0x0f0) >> 4) + '0';
		mo_rel.cause.diag[2] = (trans->cc.Tcurrent & 0x00f) + '0';
		mo_rel.cause.diag_len = 3;

		if (disconnect)
			gsm48_cc_tx_disconnect(trans, &mo_rel);
		if (release)
			gsm48_cc_tx_release(trans, &mo_rel);
	}

}

/* disconnect both calls from the bridge */
static inline void disconnect_bridge(struct gsm_network *net,
				     const struct gsm_mncc_bridge *bridge, int err)
{
	struct gsm_trans *trans0 = trans_find_by_callref(net, bridge->callref[0]);
	struct gsm_trans *trans1 = trans_find_by_callref(net, bridge->callref[1]);
	struct gsm_mncc mx_rel;
	if (!trans0 || !trans1)
		return;

	LOG_TRANS(trans0, LOGL_ERROR, "Failed to bridge TCH for calls %x <-> %x :: %s \n",
	       trans0->callref, trans1->callref, strerror(err));
	LOG_TRANS(trans1, LOGL_ERROR, "Failed to bridge TCH for calls %x <-> %x :: %s \n",
	       trans0->callref, trans1->callref, strerror(err));

	memset(&mx_rel, 0, sizeof(struct gsm_mncc));
	mncc_set_cause(&mx_rel, GSM48_CAUSE_LOC_INN_NET,
		       GSM48_CC_CAUSE_CHAN_UNACCEPT);

	mx_rel.callref = trans0->callref;
	gsm48_cc_tx_disconnect(trans0, &mx_rel);

	mx_rel.callref = trans1->callref;
	gsm48_cc_tx_disconnect(trans1, &mx_rel);
}

static void gsm48_start_cc_timer(struct gsm_trans *trans, int current,
				 int sec, int micro)
{
	LOG_TRANS(trans, LOGL_DEBUG, "starting timer T%x with %d seconds\n", current, sec);
	osmo_timer_setup(&trans->cc.timer, gsm48_cc_timeout, trans);
	osmo_timer_schedule(&trans->cc.timer, sec, micro);
	trans->cc.Tcurrent = current;
}

static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	uint8_t msg_type = gsm48_hdr_msg_type(gh);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc setup;

	gsm48_start_guard_timer(trans);

	memset(&setup, 0, sizeof(struct gsm_mncc));
	setup.callref = trans->callref;

	/* New Global Call Reference */
	if (!trans->cc.lcls)
		trans->cc.lcls = trans_lcls_compose(trans, true);

	/* Pass the LCLS GCR on to the MT call leg via MNCC */
	if (trans->cc.lcls) {
		struct msgb *gcr_msg = msgb_alloc(sizeof(setup.gcr), "MNCC GCR");
		const struct osmo_gcr_parsed *gcr = &trans->cc.lcls->gcr;
		int rc;

		if (gcr_msg != NULL && (rc = osmo_enc_gcr(gcr_msg, gcr)) > 0) {
			memcpy(&setup.gcr[0], gcr_msg->data, rc);
			setup.fields |= MNCC_F_GCR;
		} else
			LOG_TRANS(trans, LOGL_ERROR, "Failed to encode GCR\n");
		msgb_free(gcr_msg);
	}

	OSMO_ASSERT(trans->msc_a);

	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
	/* emergency setup is identified by msg_type */
	if (msg_type == GSM48_MT_CC_EMERG_SETUP) {
		setup.fields |= MNCC_F_EMERGENCY;
		setup.emergency = 1;
		/* use destination number as configured by user (if any) */
		if (trans->net->emergency.route_to_msisdn) {
			setup.fields |= MNCC_F_CALLED;
			setup.called.type = 0; /* unknown */
			setup.called.plan = 0; /* unknown */
			OSMO_STRLCPY_ARRAY(setup.called.number,
					   trans->net->emergency.route_to_msisdn);
		}
	}

	/* use subscriber as calling party number */
	setup.fields |= MNCC_F_CALLING;
	OSMO_STRLCPY_ARRAY(setup.calling.number, trans->vsub->msisdn);
	OSMO_STRLCPY_ARRAY(setup.imsi, trans->vsub->imsi);

	/* bearer capability */
	if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
		setup.fields |= MNCC_F_BEARER_CAP;
		gsm48_decode_bearer_cap(&setup.bearer_cap,
				  TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);

		/* Create a copy of the bearer capability
		 * in the transaction struct, so we can use
		 * this information later */
		memcpy(&trans->bearer_cap, &setup.bearer_cap,
		       sizeof(trans->bearer_cap));
	}
	/* facility */
	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
		setup.fields |= MNCC_F_FACILITY;
		gsm48_decode_facility(&setup.facility,
				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
	}
	/* called party bcd number */
	if (TLVP_PRESENT(&tp, GSM48_IE_CALLED_BCD)) {
		setup.fields |= MNCC_F_CALLED;
		gsm48_decode_called(&setup.called,
			      TLVP_VAL(&tp, GSM48_IE_CALLED_BCD)-1);
	}
	/* user-user */
	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
		setup.fields |= MNCC_F_USERUSER;
		gsm48_decode_useruser(&setup.useruser,
				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
	}
	/* ss-version */
	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
		setup.fields |= MNCC_F_SSVERSION;
		gsm48_decode_ssversion(&setup.ssversion,
				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
	}
	/* CLIR suppression */
	if (TLVP_PRESENT(&tp, GSM48_IE_CLIR_SUPP))
		setup.clir.sup = 1;
	/* CLIR invocation */
	if (TLVP_PRESENT(&tp, GSM48_IE_CLIR_INVOC))
		setup.clir.inv = 1;
	/* cc cap */
	if (TLVP_PRESENT(&tp, GSM48_IE_CC_CAP)) {
		setup.fields |= MNCC_F_CCCAP;
		gsm48_decode_cccap(&setup.cccap,
			     TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1);
	}

	/* MO call leg starting, gather all codec information so far known: */
	trans_cc_filter_init(trans);
	trans_cc_filter_set_ran(trans, trans->msc_a->c.ran->type);
	trans_cc_filter_set_bss(trans, trans->msc_a);
	if (setup.fields & MNCC_F_BEARER_CAP)
		trans_cc_filter_set_ms_from_bc(trans, &trans->bearer_cap);
	trans_cc_filter_run(trans);

	LOG_TRANS(trans, setup.emergency ? LOGL_NOTICE : LOGL_INFO, "%sSETUP to %s\n",
		  setup.emergency ? "EMERGENCY_" : "", setup.called.number);

	rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MO_SETUP));

	new_cc_state(trans, GSM_CSTATE_INITIATED);

	/* To complete the MNCC_SETUP_IND, we need to provide an RTP address and port. First instruct the MGW to create
	 * a CN-side RTP conn, and continue with MNCC_SETUP_IND once that is done. Leave trans.cc in GSM_CSTATE_NULL and
	 * note down the msg_type to indicate that we indeed composed an MNCC_SETUP_IND for later. */
	setup.msg_type = MNCC_SETUP_IND;
	trans->cc.msg = setup;
	return msc_a_try_call_assignment(trans);
	/* continue in gsm48_cc_rx_setup_cn_local_rtp_port_known() */
}

/* Callback for MNCC_SETUP_IND waiting for the core network RTP port to be established by the MGW (via msc_a) */
void gsm48_cc_rx_setup_cn_local_rtp_port_known(struct gsm_trans *trans)
{
	struct msc_a *msc_a = trans->msc_a;
	struct gsm_mncc setup = trans->cc.msg;
	struct osmo_sockaddr_str *rtp_cn_local;
	struct sdp_msg *sdp;
	int rc;

	if (trans->cc.state != GSM_CSTATE_INITIATED
	    || setup.msg_type != MNCC_SETUP_IND) {
		LOG_TRANS(trans, LOGL_ERROR,
			  "Unexpected CC state. Expected GSM_CSTATE_INITIATED and a buffered MNCC_SETUP_IND message,"
			  " found CC state %d and msg_type %s\n",
			  trans->cc.state, get_mncc_name(setup.msg_type));
		trans->callref = 0;
		trans_free(trans);
		return;
	}

	if (!msc_a) {
		LOG_TRANS(trans, LOGL_ERROR, "No connection for CC trans\n");
		trans->callref = 0;
		trans_free(trans);
		return;
	}

	/* 'setup' above has taken the value of trans->cc.msg, we can now clear that. */
	trans->cc.msg = (struct gsm_mncc){};

	/* Insert the CN side RTP port now available into SDP and compose SDP string */
	rtp_cn_local = call_leg_local_ip(msc_a->cc.call_leg, RTP_TO_CN);
	if (!osmo_sockaddr_str_is_nonzero(rtp_cn_local)) {
		LOG_TRANS(trans, LOGL_ERROR, "Cannot compose SDP for MNCC_SETUP_IND: no RTP set up for the CN side\n");
		trans_free(trans);
		return;
	}
	trans->cc.local.rtp = *rtp_cn_local;

	sdp = trans->cc.local.audio_codecs.count ? &trans->cc.local : NULL;
	rc = sdp_msg_to_sdp_str_buf(setup.sdp, sizeof(setup.sdp), sdp);
	if (rc >= sizeof(setup.sdp)) {
		LOG_TRANS(trans, LOGL_ERROR, "MNCC_SETUP_IND: SDP too long (%d > %zu bytes)\n", rc, sizeof(setup.sdp));
		trans_free(trans);
		return;
	}

	/* indicate setup to MNCC */
	mncc_recvmsg(trans->net, trans, MNCC_SETUP_IND, &setup);
}

static void rx_mncc_sdp(struct gsm_trans *trans, uint32_t mncc_msg_type, const char *sdp)
{
	int rc;
	if (!sdp[0])
		return;
	rc = sdp_msg_from_sdp_str(&trans->cc.remote, sdp);
	if (rc)
		LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "rx %s: Failed to parse SDP: %d\n",
			      get_mncc_name(mncc_msg_type), rc);
}

static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
{
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC SETUP");
	struct gsm48_hdr *gh;
	struct gsm_mncc *setup = arg;
	int rc, trans_id;
	struct gsm_mncc_bearer_cap bearer_cap;

	gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	/* transaction id must not be assigned */
	if (trans->transaction_id != TRANS_ID_UNASSIGNED) {
		LOG_TRANS(trans, LOGL_DEBUG, "TX Setup with assigned transaction. "
			"This is not allowed!\n");
		/* Temporarily out of order */
		rc = mncc_release_ind(trans->net, trans, trans->callref,
				      GSM48_CAUSE_LOC_PRN_S_LU,
				      GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
		trans->callref = 0;
		trans_free(trans);
		msgb_free(msg);
		return rc;
	}

	/* Get free transaction_id */
	trans_id = trans_assign_trans_id(trans->net, trans->vsub, TRANS_CC);
	if (trans_id < 0) {
		/* no free transaction ID */
		rc = mncc_release_ind(trans->net, trans, trans->callref,
				      GSM48_CAUSE_LOC_PRN_S_LU,
				      GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
		trans->callref = 0;
		trans_free(trans);
		msgb_free(msg);
		return rc;
	}
	trans->transaction_id = trans_id;

	gh->msg_type = GSM48_MT_CC_SETUP;

	gsm48_start_cc_timer(trans, 0x303, GSM48_T303);

	/* MT call leg is starting. Gather all codecs information so far known.
	 * (Usually) paging has succeeded, and now we're processing the MNCC Setup from the remote MO call leg.
	 * Initialize the codecs filter with this side's BSS' codec list, received at Complete Layer 3.
	 * We haven't received the MT MS's Bearer Capabilities yet; the Bearer Capabilities handled here are
	 * actually the remote call leg's Bearer Capabilities. */
	trans_cc_filter_init(trans);
	trans_cc_filter_set_ran(trans, trans->msc_a->c.ran->type);
	trans_cc_filter_set_bss(trans, trans->msc_a);
	if (setup->fields & MNCC_F_BEARER_CAP)
		trans->bearer_cap.transfer = setup->bearer_cap.transfer;

	switch (trans->bearer_cap.transfer) {
	case GSM48_BCAP_ITCAP_SPEECH:
		/* sdp.remote: if SDP is included in the MNCC, take that as definitive list of remote audio codecs. */
		rx_mncc_sdp(trans, setup->msg_type, setup->sdp);
		/* sdp.remote: if there is no SDP information or we failed to parse it, try using the Bearer Capability from
		 * MNCC, if any. */
		if (!trans->cc.remote.audio_codecs.count && (setup->fields & MNCC_F_BEARER_CAP)) {
			trans->cc.remote = (struct sdp_msg){};
			trans_cc_set_remote_from_bc(trans, &setup->bearer_cap);
			LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s Bearer Cap: remote=%s\n",
				      get_mncc_name(setup->msg_type), sdp_msg_to_str(&trans->cc.remote));
		}
		if (!trans->cc.remote.audio_codecs.count)
			LOG_TRANS(trans, LOGL_INFO,
				  "Got no information of remote audio codecs: neither SDP nor Bearer Capability. Trying anyway.\n");
		break;
	case GSM48_BCAP_ITCAP_UNR_DIG_INF:
		sdp_audio_codecs_set_csd(&trans->cc.codecs.ms);
		break;
	default:
		LOG_TRANS(trans, LOGL_ERROR, "Handling of information transfer capability %d not implemented\n",
			  trans->bearer_cap.transfer);
	}

	trans_cc_filter_run(trans);

	/* Compose Bearer Capability information that reflects only the codecs (Speech Versions) / CSD bearer services
	 * remaining after intersecting MS, BSS and remote call leg restrictions. To store in trans for later use, and
	 * to include in the outgoing CC Setup message. */
	switch (trans->bearer_cap.transfer) {
	case GSM48_BCAP_ITCAP_SPEECH:
		bearer_cap = (struct gsm_mncc_bearer_cap){
			.speech_ver = { -1 },
		};
		sdp_audio_codecs_to_bearer_cap(&bearer_cap, &trans->cc.local.audio_codecs);
		rc = bearer_cap_set_radio(&bearer_cap);
		if (rc) {
			LOG_TRANS(trans, LOGL_ERROR, "Error composing Bearer Capability for CC Setup\n");
			trans_free(trans);
			msgb_free(msg);
			return rc;
		}
		/* If no resulting codecs remain, error out. We cannot find a codec that matches both call legs. If the MGW were
		 * able to transcode, we could use non-identical codecs on each conn of the MGW endpoint, but we are aiming for
		 * finding a matching codec. */
		if (bearer_cap.speech_ver[0] == -1) {
			LOG_TRANS(trans, LOGL_ERROR, "%s: no codec match possible: %s\n",
				  get_mncc_name(setup->msg_type),
				  codec_filter_to_str(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote));

			/* incompatible codecs */
			rc = mncc_release_ind(trans->net, trans, trans->callref,
					      GSM48_CAUSE_LOC_PRN_S_LU,
					      GSM48_CC_CAUSE_INCOMPAT_DEST /* TODO: correct cause code? */);
			trans->callref = 0;
			trans_free(trans);
			msgb_free(msg);
			return rc;
		}
		break;
	case GSM48_BCAP_ITCAP_UNR_DIG_INF:
		if (csd_bs_list_to_bearer_cap(&bearer_cap, &trans->cc.local.bearer_services) == 0) {
			LOG_TRANS(trans, LOGL_ERROR, "Error composing Bearer Capability for CC Setup\n");

			/* incompatible codecs */
			rc = mncc_release_ind(trans->net, trans, trans->callref,
					      GSM48_CAUSE_LOC_PRN_S_LU,
					      GSM48_CC_CAUSE_INCOMPAT_DEST /* TODO: correct cause code? */);
			trans->callref = 0;
			trans_free(trans);
			msgb_free(msg);
			return rc;
		}
		break;
	}

	/* Create a copy of the bearer capability in the transaction struct, so we can use this information later */
	trans->bearer_cap = bearer_cap;

	gsm48_encode_bearer_cap(msg, 0, &bearer_cap);

	/* facility */
	if (setup->fields & MNCC_F_FACILITY)
		gsm48_encode_facility(msg, 0, &setup->facility);
	/* progress */
	if (setup->fields & MNCC_F_PROGRESS)
		gsm48_encode_progress(msg, 0, &setup->progress);
	/* calling party BCD number */
	if (setup->fields & MNCC_F_CALLING)
		gsm48_encode_calling(msg, &setup->calling);
	/* called party BCD number */
	if (setup->fields & MNCC_F_CALLED)
		gsm48_encode_called(msg, &setup->called);
	/* user-user */
	if (setup->fields & MNCC_F_USERUSER)
		gsm48_encode_useruser(msg, 0, &setup->useruser);
	/* redirecting party BCD number */
	if (setup->fields & MNCC_F_REDIRECTING)
		gsm48_encode_redirecting(msg, &setup->redirecting);
	/* signal */
	if (setup->fields & MNCC_F_SIGNAL)
		gsm48_encode_signal(msg, setup->signal);

	new_cc_state(trans, GSM_CSTATE_CALL_PRESENT);

	rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MT_SETUP));

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc call_conf;
	int rc;

	gsm48_stop_cc_timer(trans);
	gsm48_start_cc_timer(trans, 0x310, GSM48_T310);

	memset(&call_conf, 0, sizeof(struct gsm_mncc));
	call_conf.callref = trans->callref;

	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
#if 0
	/* repeat */
	if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_CIR))
		call_conf.repeat = 1;
	if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_SEQ))
		call_conf.repeat = 2;
#endif
	/* bearer capability */
	if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
		call_conf.fields |= MNCC_F_BEARER_CAP;
		gsm48_decode_bearer_cap(&call_conf.bearer_cap,
				  TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);

		/* Create a copy of the bearer capability
		 * in the transaction struct, so we can use
		 * this information later */
		memcpy(&trans->bearer_cap, &call_conf.bearer_cap,
		       sizeof(trans->bearer_cap));

		/* This is the MT call leg's Call Conf, containing the MS Bearer Capabilities of the MT MS.
		 * Store in codecs filter. */
		trans_cc_filter_set_ms_from_bc(trans, &call_conf.bearer_cap);
	}

	/* cause */
	if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
		call_conf.fields |= MNCC_F_CAUSE;
		gsm48_decode_cause(&call_conf.cause,
			     TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
	}
	/* cc cap */
	if (TLVP_PRESENT(&tp, GSM48_IE_CC_CAP)) {
		call_conf.fields |= MNCC_F_CCCAP;
		gsm48_decode_cccap(&call_conf.cccap,
			     TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1);
	}

	/* IMSI of called subscriber */
	OSMO_STRLCPY_ARRAY(call_conf.imsi, trans->vsub->imsi);

	/* Assign call (if not done yet) */
	rc = msc_a_try_call_assignment(trans);

	/* don't continue, if there were problems with
	 * the call assignment. */
	if (rc)
		return rc;

	/* Directly ack with MNCC_CALL_CONF_IND, not yet containing SDP or RTP IP:port information. */
	new_cc_state(trans, GSM_CSTATE_MO_TERM_CALL_CONF);
	return mncc_recvmsg(trans->net, trans, MNCC_CALL_CONF_IND, &call_conf);
}

static int mncc_recv_rtp(struct gsm_network *net, struct gsm_trans *trans, uint32_t callref,
			 int cmd, struct osmo_sockaddr_str *rtp_addr, uint32_t payload_type,
			 uint32_t payload_msg_type, const struct sdp_msg *sdp);

static int gsm48_cc_mt_rtp_port_and_codec_known(struct gsm_trans *trans)
{
	struct msc_a *msc_a = trans->msc_a;
	struct osmo_sockaddr_str *rtp_cn_local;
	struct gsm_mncc_rtp;

	if (!msc_a) {
		LOG_TRANS(trans, LOGL_ERROR, "No connection for CC trans\n");
		trans->callref = 0;
		trans_free(trans);
		return -EINVAL;
	}

	/* Insert the CN side RTP port now available into SDP */
	rtp_cn_local = call_leg_local_ip(msc_a->cc.call_leg, RTP_TO_CN);
	if (!rtp_cn_local) {
		LOG_TRANS(trans, LOGL_ERROR, "Cannot compose SDP for MNCC_RTP_CREATE: no RTP set up for the CN side\n");
		trans_free(trans);
		return -EINVAL;
	}
	trans->cc.local.rtp = *rtp_cn_local;

	trans_cc_filter_run(trans);

	/* If we haven't completed Assignment yet, don't sent MNCC_RTP_CREATE */
	if (!sdp_audio_codec_is_set(&trans->cc.codecs.assignment)) {
		LOG_TRANS(trans, LOGL_DEBUG, "no codec confirmed by Assignment yet\n");
		return 0;
	}

	return mncc_recv_rtp(msc_a_net(msc_a), trans, trans->callref, MNCC_RTP_CREATE, rtp_cn_local, 0, 0,
			     &trans->cc.local);
}

static int gsm48_cc_tx_call_proc_and_assign(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *proceeding = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC PROC");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
	int rc;

	gh->msg_type = GSM48_MT_CC_CALL_PROC;

	new_cc_state(trans, GSM_CSTATE_MO_CALL_PROC);

	/* bearer capability */
	if (proceeding->fields & MNCC_F_BEARER_CAP) {
		gsm48_encode_bearer_cap(msg, 0, &proceeding->bearer_cap);
		memcpy(&trans->bearer_cap, &proceeding->bearer_cap, sizeof(trans->bearer_cap));
	}
	/* facility */
	if (proceeding->fields & MNCC_F_FACILITY)
		gsm48_encode_facility(msg, 0, &proceeding->facility);
	/* progress */
	if (proceeding->fields & MNCC_F_PROGRESS)
		gsm48_encode_progress(msg, 0, &proceeding->progress);

	rc = trans_tx_gsm48(trans, msg);
	if (rc)
		return rc;

	/* Assign call (if not done yet) */
	return msc_a_try_call_assignment(trans);
}

static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc alerting;
	int rc;

	gsm48_stop_cc_timer(trans);
	gsm48_start_cc_timer(trans, 0x301, GSM48_T301);

	memset(&alerting, 0, sizeof(struct gsm_mncc));
	alerting.callref = trans->callref;
	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
	/* facility */
	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
		alerting.fields |= MNCC_F_FACILITY;
		gsm48_decode_facility(&alerting.facility,
				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
	}

	/* progress */
	if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
		alerting.fields |= MNCC_F_PROGRESS;
		gsm48_decode_progress(&alerting.progress,
				TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
	}
	/* ss-version */
	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
		alerting.fields |= MNCC_F_SSVERSION;
		gsm48_decode_ssversion(&alerting.ssversion,
				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
	}

	new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED);

	trans_cc_filter_run(trans);
	rc = sdp_msg_to_sdp_str_buf(alerting.sdp, sizeof(alerting.sdp), &trans->cc.local);
	if (rc >= sizeof(alerting.sdp)) {
		LOG_TRANS(trans, LOGL_ERROR, "MNCC_ALERT_IND: SDP too long (%d > %zu bytes)\n",
			  rc, sizeof(alerting.sdp));
		trans_free(trans);
		return -EINVAL;
	}

	return mncc_recvmsg(trans->net, trans, MNCC_ALERT_IND,
			    &alerting);
}

static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *alerting = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC ALERT");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_ALERTING;

	/* facility */
	if (alerting->fields & MNCC_F_FACILITY)
		gsm48_encode_facility(msg, 0, &alerting->facility);
	/* progress */
	if (alerting->fields & MNCC_F_PROGRESS)
		gsm48_encode_progress(msg, 0, &alerting->progress);
	/* user-user */
	if (alerting->fields & MNCC_F_USERUSER)
		gsm48_encode_useruser(msg, 0, &alerting->useruser);

	new_cc_state(trans, GSM_CSTATE_CALL_DELIVERED);

	if (alerting->sdp[0]) {
		struct call_leg *cl = trans->msc_a->cc.call_leg;
		struct rtp_stream *rtp_cn = cl ? cl->rtp[RTP_TO_CN] : NULL;
		sdp_msg_from_sdp_str(&trans->cc.remote, alerting->sdp);
		trans_cc_filter_run(trans);
		LOG_TRANS(trans, LOGL_DEBUG, "msg_type=%s\n", get_mncc_name(alerting->msg_type));
		if (rtp_cn) {
			rtp_stream_set_remote_addr_and_codecs(rtp_cn, &trans->cc.remote);
			rtp_stream_commit(rtp_cn);
		}
	}

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *progress = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC PROGRESS");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_PROGRESS;

	/* progress */
	gsm48_encode_progress(msg, 1, &progress->progress);
	/* user-user */
	if (progress->fields & MNCC_F_USERUSER)
		gsm48_encode_useruser(msg, 0, &progress->useruser);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *connect = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSN 04.08 CC CON");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_CONNECT;

	gsm48_stop_cc_timer(trans);
	gsm48_start_cc_timer(trans, 0x313, GSM48_T313);

	/* facility */
	if (connect->fields & MNCC_F_FACILITY)
		gsm48_encode_facility(msg, 0, &connect->facility);
	/* progress */
	if (connect->fields & MNCC_F_PROGRESS)
		gsm48_encode_progress(msg, 0, &connect->progress);
	/* connected number */
	if (connect->fields & MNCC_F_CONNECTED)
		gsm48_encode_connected(msg, &connect->connected);
	/* user-user */
	if (connect->fields & MNCC_F_USERUSER)
		gsm48_encode_useruser(msg, 0, &connect->useruser);

	new_cc_state(trans, GSM_CSTATE_CONNECT_IND);

	/* Received an MNCC_SETUP_RSP with the remote leg's SDP information. Apply codec choice. */
	if (connect->sdp[0]) {
		struct call_leg *cl = trans->msc_a->cc.call_leg;
		struct rtp_stream *rtp_cn = cl ? cl->rtp[RTP_TO_CN] : NULL;
		rx_mncc_sdp(trans, connect->msg_type, connect->sdp);
		trans_cc_filter_run(trans);
		LOG_TRANS(trans, LOGL_DEBUG, "msg_type=%s\n", get_mncc_name(connect->msg_type));
		if (rtp_cn) {
			rtp_stream_set_remote_addr_and_codecs(rtp_cn, &trans->cc.remote);
			rtp_stream_commit(rtp_cn);
		}
	}

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc connect;

	gsm48_stop_cc_timer(trans);

	memset(&connect, 0, sizeof(struct gsm_mncc));
	connect.callref = trans->callref;
	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
	/* use subscriber as connected party number */
	connect.fields |= MNCC_F_CONNECTED;
	OSMO_STRLCPY_ARRAY(connect.connected.number, trans->vsub->msisdn);
	OSMO_STRLCPY_ARRAY(connect.imsi, trans->vsub->imsi);

	/* facility */
	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
		connect.fields |= MNCC_F_FACILITY;
		gsm48_decode_facility(&connect.facility,
				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
	}
	/* user-user */
	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
		connect.fields |= MNCC_F_USERUSER;
		gsm48_decode_useruser(&connect.useruser,
				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
	}
	/* ss-version */
	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
		connect.fields |= MNCC_F_SSVERSION;
		gsm48_decode_ssversion(&connect.ssversion,
				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
	}

	new_cc_state(trans, GSM_CSTATE_CONNECT_REQUEST);
	rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MT_CONNECT));

	trans_cc_filter_run(trans);
	sdp_msg_to_sdp_str_buf(connect.sdp, sizeof(connect.sdp), &trans->cc.local);
	return mncc_recvmsg(trans->net, trans, MNCC_SETUP_CNF, &connect);
}


static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm_mncc connect_ack;

	gsm48_stop_cc_timer(trans);

	new_cc_state(trans, GSM_CSTATE_ACTIVE);
	rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MO_CONNECT_ACK));

	memset(&connect_ack, 0, sizeof(struct gsm_mncc));
	connect_ack.callref = trans->callref;

	return mncc_recvmsg(trans->net, trans, MNCC_SETUP_COMPL_IND,
			    &connect_ack);
}

static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg)
{
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC CON ACK");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_CONNECT_ACK;

	new_cc_state(trans, GSM_CSTATE_ACTIVE);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc disc;

	gsm48_stop_cc_timer(trans);

	new_cc_state(trans, GSM_CSTATE_DISCONNECT_REQ);

	memset(&disc, 0, sizeof(struct gsm_mncc));
	disc.callref = trans->callref;
	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_CAUSE, 0);
	/* cause */
	if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
		disc.fields |= MNCC_F_CAUSE;
		gsm48_decode_cause(&disc.cause,
			     TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
	}
	/* facility */
	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
		disc.fields |= MNCC_F_FACILITY;
		gsm48_decode_facility(&disc.facility,
				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
	}
	/* user-user */
	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
		disc.fields |= MNCC_F_USERUSER;
		gsm48_decode_useruser(&disc.useruser,
				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
	}
	/* ss-version */
	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
		disc.fields |= MNCC_F_SSVERSION;
		gsm48_decode_ssversion(&disc.ssversion,
				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
	}

	return mncc_recvmsg(trans->net, trans, MNCC_DISC_IND, &disc);
}

static struct gsm_mncc_cause default_cause = {
	.location	= GSM48_CAUSE_LOC_PRN_S_LU,
	.coding		= 0,
	.rec		= 0,
	.rec_val	= 0,
	.value		= GSM48_CC_CAUSE_NORMAL_UNSPEC,
	.diag_len	= 0,
	.diag		= { 0 },
};

static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *disc = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC DISC");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_DISCONNECT;

	gsm48_stop_cc_timer(trans);
	gsm48_start_cc_timer(trans, 0x306, GSM48_T306);

	/* cause */
	if (disc->fields & MNCC_F_CAUSE)
		gsm48_encode_cause(msg, 1, &disc->cause);
	else
		gsm48_encode_cause(msg, 1, &default_cause);

	/* facility */
	if (disc->fields & MNCC_F_FACILITY)
		gsm48_encode_facility(msg, 0, &disc->facility);
	/* progress */
	if (disc->fields & MNCC_F_PROGRESS)
		gsm48_encode_progress(msg, 0, &disc->progress);
	/* user-user */
	if (disc->fields & MNCC_F_USERUSER)
		gsm48_encode_useruser(msg, 0, &disc->useruser);

	/* store disconnect cause for T306 expiry */
	memcpy(&trans->cc.msg, disc, sizeof(struct gsm_mncc));

	new_cc_state(trans, GSM_CSTATE_DISCONNECT_IND);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc rel;
	int rc;

	gsm48_stop_cc_timer(trans);

	memset(&rel, 0, sizeof(struct gsm_mncc));
	rel.callref = trans->callref;
	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
	/* cause */
	if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
		rel.fields |= MNCC_F_CAUSE;
		gsm48_decode_cause(&rel.cause,
			     TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
	}
	/* facility */
	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
		rel.fields |= MNCC_F_FACILITY;
		gsm48_decode_facility(&rel.facility,
				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
	}
	/* user-user */
	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
		rel.fields |= MNCC_F_USERUSER;
		gsm48_decode_useruser(&rel.useruser,
				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
	}
	/* ss-version */
	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
		rel.fields |= MNCC_F_SSVERSION;
		gsm48_decode_ssversion(&rel.ssversion,
				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
	}

	if (trans->cc.state == GSM_CSTATE_RELEASE_REQ) {
		/* release collision 5.4.5 */
		rc = mncc_recvmsg(trans->net, trans, MNCC_REL_CNF, &rel);
	} else {
		rc = gsm48_tx_simple(trans->msc_a,
				     GSM48_PDISC_CC | (trans->transaction_id << 4),
				     GSM48_MT_CC_RELEASE_COMPL);
		rc = mncc_recvmsg(trans->net, trans, MNCC_REL_IND, &rel);
	}

	new_cc_state(trans, GSM_CSTATE_NULL);

	trans->callref = 0;
	trans_free(trans);

	return rc;
}

static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *rel = arg;
	struct msgb *msg;
	struct gsm48_hdr *gh;

	if (!trans->msc_a) {
		LOG_TRANS(trans, LOGL_DEBUG, "Cannot send CC REL, there is no MSC-A connection\n");
		return -EINVAL;
	}

	msg = gsm48_msgb_alloc_name("GSM 04.08 CC REL");
	gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_RELEASE;

	gsm48_stop_cc_timer(trans);
	gsm48_start_cc_timer(trans, 0x308, GSM48_T308);

	/* cause */
	if (rel->fields & MNCC_F_CAUSE)
		gsm48_encode_cause(msg, 0, &rel->cause);
	/* facility */
	if (rel->fields & MNCC_F_FACILITY)
		gsm48_encode_facility(msg, 0, &rel->facility);
	/* user-user */
	if (rel->fields & MNCC_F_USERUSER)
		gsm48_encode_useruser(msg, 0, &rel->useruser);

	trans->cc.T308_second = 0;
	memcpy(&trans->cc.msg, rel, sizeof(struct gsm_mncc));

	if (trans->cc.state != GSM_CSTATE_RELEASE_REQ)
		new_cc_state(trans, GSM_CSTATE_RELEASE_REQ);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc rel;
	int rc = 0;

	gsm48_stop_cc_timer(trans);

	memset(&rel, 0, sizeof(struct gsm_mncc));
	rel.callref = trans->callref;
	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
	/* cause */
	if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
		rel.fields |= MNCC_F_CAUSE;
		gsm48_decode_cause(&rel.cause,
			     TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
	}
	/* facility */
	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
		rel.fields |= MNCC_F_FACILITY;
		gsm48_decode_facility(&rel.facility,
				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
	}
	/* user-user */
	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
		rel.fields |= MNCC_F_USERUSER;
		gsm48_decode_useruser(&rel.useruser,
				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
	}
	/* ss-version */
	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
		rel.fields |= MNCC_F_SSVERSION;
		gsm48_decode_ssversion(&rel.ssversion,
				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
	}

	if (trans->callref) {
		switch (trans->cc.state) {
		case GSM_CSTATE_CALL_PRESENT:
			rc = mncc_recvmsg(trans->net, trans,
					  MNCC_REJ_IND, &rel);
			break;
		case GSM_CSTATE_RELEASE_REQ:
			rc = mncc_recvmsg(trans->net, trans,
					  MNCC_REL_CNF, &rel);
			break;
		default:
			rc = mncc_recvmsg(trans->net, trans,
					  MNCC_REL_IND, &rel);
		}
	}

	trans->callref = 0;
	trans_free(trans);

	return rc;
}

static int gsm48_cc_tx_release_compl(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *rel = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC REL COMPL");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
	int ret;

	gh->msg_type = GSM48_MT_CC_RELEASE_COMPL;

	trans->callref = 0;

	gsm48_stop_cc_timer(trans);

	/* cause */
	if (rel->fields & MNCC_F_CAUSE)
		gsm48_encode_cause(msg, 0, &rel->cause);
	/* facility */
	if (rel->fields & MNCC_F_FACILITY)
		gsm48_encode_facility(msg, 0, &rel->facility);
	/* user-user */
	if (rel->fields & MNCC_F_USERUSER)
		gsm48_encode_useruser(msg, 0, &rel->useruser);

	ret =  trans_tx_gsm48(trans, msg);

	trans_free(trans);

	return ret;
}

static int gsm48_cc_rx_facility(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc fac;

	memset(&fac, 0, sizeof(struct gsm_mncc));
	fac.callref = trans->callref;
	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_FACILITY, 0);
	/* facility */
	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
		fac.fields |= MNCC_F_FACILITY;
		gsm48_decode_facility(&fac.facility,
				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
	}
	/* ss-version */
	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
		fac.fields |= MNCC_F_SSVERSION;
		gsm48_decode_ssversion(&fac.ssversion,
				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
	}

	return mncc_recvmsg(trans->net, trans, MNCC_FACILITY_IND, &fac);
}

static int gsm48_cc_tx_facility(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *fac = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC FAC");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_FACILITY;

	/* facility */
	gsm48_encode_facility(msg, 1, &fac->facility);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_hold(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm_mncc hold;

	memset(&hold, 0, sizeof(struct gsm_mncc));
	hold.callref = trans->callref;
	return mncc_recvmsg(trans->net, trans, MNCC_HOLD_IND, &hold);
}

static int gsm48_cc_tx_hold_ack(struct gsm_trans *trans, void *arg)
{
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC HLD ACK");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_HOLD_ACK;

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_tx_hold_rej(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *hold_rej = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC HLD REJ");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_HOLD_REJ;

	/* cause */
	if (hold_rej->fields & MNCC_F_CAUSE)
		gsm48_encode_cause(msg, 1, &hold_rej->cause);
	else
		gsm48_encode_cause(msg, 1, &default_cause);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_retrieve(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm_mncc retrieve;

	memset(&retrieve, 0, sizeof(struct gsm_mncc));
	retrieve.callref = trans->callref;
	return mncc_recvmsg(trans->net, trans, MNCC_RETRIEVE_IND,
			    &retrieve);
}

static int gsm48_cc_tx_retrieve_ack(struct gsm_trans *trans, void *arg)
{
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC RETR ACK");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_RETR_ACK;

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_tx_retrieve_rej(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *retrieve_rej = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC RETR REJ");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_RETR_REJ;

	/* cause */
	if (retrieve_rej->fields & MNCC_F_CAUSE)
		gsm48_encode_cause(msg, 1, &retrieve_rej->cause);
	else
		gsm48_encode_cause(msg, 1, &default_cause);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_start_dtmf(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc dtmf;

	memset(&dtmf, 0, sizeof(struct gsm_mncc));
	dtmf.callref = trans->callref;
	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
	/* keypad facility */
	if (TLVP_PRESENT(&tp, GSM48_IE_KPD_FACILITY)) {
		dtmf.fields |= MNCC_F_KEYPAD;
		gsm48_decode_keypad(&dtmf.keypad,
			      TLVP_VAL(&tp, GSM48_IE_KPD_FACILITY)-1);
	}

	return mncc_recvmsg(trans->net, trans, MNCC_START_DTMF_IND, &dtmf);
}

static int gsm48_cc_tx_start_dtmf_ack(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *dtmf = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF ACK");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_START_DTMF_ACK;

	/* keypad */
	if (dtmf->fields & MNCC_F_KEYPAD)
		gsm48_encode_keypad(msg, dtmf->keypad);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_tx_start_dtmf_rej(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *dtmf = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF REJ");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_START_DTMF_REJ;

	/* cause */
	if (dtmf->fields & MNCC_F_CAUSE)
		gsm48_encode_cause(msg, 1, &dtmf->cause);
	else
		gsm48_encode_cause(msg, 1, &default_cause);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_tx_stop_dtmf_ack(struct gsm_trans *trans, void *arg)
{
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF STP ACK");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_STOP_DTMF_ACK;

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_stop_dtmf(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm_mncc dtmf;

	memset(&dtmf, 0, sizeof(struct gsm_mncc));
	dtmf.callref = trans->callref;

	return mncc_recvmsg(trans->net, trans, MNCC_STOP_DTMF_IND, &dtmf);
}

static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc modify;

	memset(&modify, 0, sizeof(struct gsm_mncc));
	modify.callref = trans->callref;
	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, 0);
	/* bearer capability */
	if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
		modify.fields |= MNCC_F_BEARER_CAP;
		gsm48_decode_bearer_cap(&modify.bearer_cap,
				  TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);

		/* Create a copy of the bearer capability
		 * in the transaction struct, so we can use
		 * this information later */
		memcpy(&trans->bearer_cap,&modify.bearer_cap,
		       sizeof(trans->bearer_cap));
	}

	new_cc_state(trans, GSM_CSTATE_MO_ORIG_MODIFY);

	return mncc_recvmsg(trans->net, trans, MNCC_MODIFY_IND, &modify);
}

static int gsm48_cc_tx_modify(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *modify = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_MODIFY;

	gsm48_start_cc_timer(trans, 0x323, GSM48_T323);

	/* bearer capability */
	gsm48_encode_bearer_cap(msg, 1, &modify->bearer_cap);
	memcpy(&trans->bearer_cap, &modify->bearer_cap, sizeof(trans->bearer_cap));

	new_cc_state(trans, GSM_CSTATE_MO_TERM_MODIFY);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc modify;

	gsm48_stop_cc_timer(trans);

	memset(&modify, 0, sizeof(struct gsm_mncc));
	modify.callref = trans->callref;
	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, 0);
	/* bearer capability */
	if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
		modify.fields |= MNCC_F_BEARER_CAP;
		gsm48_decode_bearer_cap(&modify.bearer_cap,
				  TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);

		/* Create a copy of the bearer capability
		 * in the transaction struct, so we can use
		 * this information later */
		memcpy(&trans->bearer_cap,&modify.bearer_cap,
		       sizeof(trans->bearer_cap));
	}

	new_cc_state(trans, GSM_CSTATE_ACTIVE);

	return mncc_recvmsg(trans->net, trans, MNCC_MODIFY_CNF, &modify);
}

static int gsm48_cc_tx_modify_complete(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *modify = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD COMPL");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_MODIFY_COMPL;

	/* bearer capability */
	gsm48_encode_bearer_cap(msg, 1, &modify->bearer_cap);
	memcpy(&trans->bearer_cap, &modify->bearer_cap, sizeof(trans->bearer_cap));

	new_cc_state(trans, GSM_CSTATE_ACTIVE);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc modify;

	gsm48_stop_cc_timer(trans);

	memset(&modify, 0, sizeof(struct gsm_mncc));
	modify.callref = trans->callref;
	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, GSM48_IE_CAUSE);
	/* bearer capability */
	if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
		modify.fields |= GSM48_IE_BEARER_CAP;
		gsm48_decode_bearer_cap(&modify.bearer_cap,
				  TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);

		/* Create a copy of the bearer capability
		 * in the transaction struct, so we can use
		 * this information later */
		memcpy(&trans->bearer_cap,&modify.bearer_cap,
		       sizeof(trans->bearer_cap));
	}
	/* cause */
	if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
		modify.fields |= MNCC_F_CAUSE;
		gsm48_decode_cause(&modify.cause,
			     TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
	}

	new_cc_state(trans, GSM_CSTATE_ACTIVE);

	return mncc_recvmsg(trans->net, trans, MNCC_MODIFY_REJ, &modify);
}

static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *modify = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD REJ");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_MODIFY_REJECT;

	/* bearer capability */
	gsm48_encode_bearer_cap(msg, 1, &modify->bearer_cap);
	memcpy(&trans->bearer_cap, &modify->bearer_cap, sizeof(trans->bearer_cap));
	/* cause */
	gsm48_encode_cause(msg, 1, &modify->cause);

	new_cc_state(trans, GSM_CSTATE_ACTIVE);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_tx_notify(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *notify = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC NOT");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_NOTIFY;

	/* notify */
	gsm48_encode_notify(msg, notify->notify);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_notify(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
//	struct tlv_parsed tp;
	struct gsm_mncc notify;

	memset(&notify, 0, sizeof(struct gsm_mncc));
	notify.callref = trans->callref;
//	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len);
	if (payload_len >= 1)
		gsm48_decode_notify(&notify.notify, gh->data);

	return mncc_recvmsg(trans->net, trans, MNCC_NOTIFY_IND, &notify);
}

static int gsm48_cc_tx_userinfo(struct gsm_trans *trans, void *arg)
{
	struct gsm_mncc *user = arg;
	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USR INFO");
	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));

	gh->msg_type = GSM48_MT_CC_USER_INFO;

	/* user-user */
	if (user->fields & MNCC_F_USERUSER)
		gsm48_encode_useruser(msg, 1, &user->useruser);
	/* more data */
	if (user->more)
		gsm48_encode_more(msg);

	return trans_tx_gsm48(trans, msg);
}

static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
	struct tlv_parsed tp;
	struct gsm_mncc user;

	memset(&user, 0, sizeof(struct gsm_mncc));
	user.callref = trans->callref;
	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_USER_USER, 0);
	/* user-user */
	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
		user.fields |= MNCC_F_USERUSER;
		gsm48_decode_useruser(&user.useruser,
				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
	}
	/* more data */
	if (TLVP_PRESENT(&tp, GSM48_IE_MORE_DATA))
		user.more = 1;

	return mncc_recvmsg(trans->net, trans, MNCC_USERINFO_IND, &user);
}

static int mncc_recv_rtp(struct gsm_network *net, struct gsm_trans *trans, uint32_t callref,
			 int cmd, struct osmo_sockaddr_str *rtp_addr, uint32_t payload_type,
			 uint32_t payload_msg_type, const struct sdp_msg *sdp)
{
	uint8_t data[sizeof(struct gsm_mncc)];
	struct gsm_mncc_rtp *rtp;

	memset(&data, 0, sizeof(data));
	rtp = (struct gsm_mncc_rtp *) &data[0];

	rtp->callref = callref;
	rtp->msg_type = cmd;
	if (rtp_addr) {
		if (osmo_sockaddr_str_to_sockaddr(rtp_addr, &rtp->addr) < 0)
			return -EINVAL;
	}
	rtp->payload_type = payload_type;
	rtp->payload_msg_type = payload_msg_type;
	if (sdp)
		sdp_msg_to_sdp_str_buf(rtp->sdp, sizeof(rtp->sdp), sdp);
	return mncc_recvmsg(net, trans, cmd, (struct gsm_mncc *)data);
}

static void mncc_recv_rtp_err(struct gsm_network *net, struct gsm_trans *trans, uint32_t callref, int cmd)
{
	mncc_recv_rtp(net, trans, callref, cmd, NULL, 0, 0, NULL);
}

static int tch_rtp_create(struct gsm_network *net, const struct gsm_mncc_rtp *rtp)
{
	struct gsm_trans *trans;

	/* Find callref */
	trans = trans_find_by_callref(net, rtp->callref);
	if (!trans) {
		LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP create for non-existing trans\n");
		mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CREATE);
		return -EIO;
	}
	log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
	if (!trans->msc_a) {
		LOG_TRANS_CAT(trans, DMNCC, LOGL_NOTICE, "RTP create for trans without conn\n");
		mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CREATE);
		return 0;
	}
	log_mncc_rx_tx(trans, "rx", (const union mncc_msg *)rtp);

	/* Assign call (if not done yet) */
	return msc_a_try_call_assignment(trans);
}

int cc_on_cn_local_rtp_port_known(struct gsm_trans *cc_trans)
{
	/* Depending on MO or MT call, dispatch the event differently */
	switch (cc_trans->cc.state) {
	case GSM_CSTATE_INITIATED:
		if (cc_trans->cc.msg.msg_type != MNCC_SETUP_IND) {
			LOG_TRANS(cc_trans, LOGL_ERROR, "Assuming MO call, expected MNCC_SETUP_IND to be prepared\n");
			return -EINVAL;
		}
		/* This is the MO call leg, waiting for a CN RTP be able to send initial MNCC_SETUP_IND. */
		gsm48_cc_rx_setup_cn_local_rtp_port_known(cc_trans);
		return 0;

	case GSM_CSTATE_MO_TERM_CALL_CONF:
		/* This is the MT call leg, waiting for a CN RTP to be able to send MNCC_CALL_CONF_IND. */
		return gsm48_cc_mt_rtp_port_and_codec_known(cc_trans);

	default:
		LOG_TRANS(cc_trans, LOGL_ERROR, "CN RTP address available, but in unexpected state %d\n",
			  cc_trans->cc.state);
		return -EINVAL;
	}
}

int cc_on_assignment_done(struct gsm_trans *trans)
{
	struct msc_a *msc_a = trans->msc_a;

	switch (trans->cc.state) {
	case GSM_CSTATE_INITIATED:
	case GSM_CSTATE_MO_CALL_PROC:
		/* MO call */
		break;

	case GSM_CSTATE_CALL_RECEIVED:
	case GSM_CSTATE_MO_TERM_CALL_CONF:
		/* MT call */
		break;

	case GSM_CSTATE_ACTIVE:
		/* already active. MNCC finished before Abis completed the Assignment. */
		break;

	default:
		LOG_TRANS(trans, LOGL_ERROR, "Assignment done in unexpected CC state: %d\n", trans->cc.state);
		return -EINVAL;
	}

	if (!call_leg_local_ip(msc_a->cc.call_leg, RTP_TO_CN)) {
		LOG_TRANS(trans, LOGL_DEBUG,
			  "Assignment complete, but still waiting for the CRCX OK on the CN side RTP\n");
		return 0;
	}
	return gsm48_tch_rtp_create(trans);
}

/* Trigger TCH_RTP_CREATE acknowledgement */
int gsm48_tch_rtp_create(struct gsm_trans *trans)
{
	/* This function is called as soon as the port, on which the
	 * mgcp-gw expects the incoming RTP stream from the remote
	 * end (e.g. Asterisk) is known. */
	struct msc_a *msc_a = trans->msc_a;
	struct gsm_network *net = msc_a_net(msc_a);
	struct call_leg *cl = msc_a->cc.call_leg;
	struct osmo_sockaddr_str *rtp_cn_local;
	struct rtp_stream *rtp_cn = cl ? cl->rtp[RTP_TO_CN] : NULL;
	int mncc_payload_msg_type;
	struct sdp_audio_codec *codec;
	const struct codec_mapping *m;
	struct sdp_audio_codecs *codecs;

	if (!rtp_cn) {
		LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "Cannot RTP CREATE to MNCC, no RTP set up for the CN side\n");
		return -EINVAL;
	}

	trans_cc_filter_run(trans);
	codecs = &trans->cc.local.audio_codecs;
	if (!codecs->count) {
		LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR,
			      "Cannot RTP CREATE to MNCC, there is no codec available\n");
		return -EINVAL;
	}

	/* Populate the legacy MNCC codec elements: payload_type and payload_msg_type */
	codec = &codecs->codec[0];
	m = codec_mapping_by_subtype_name(codec->subtype_name);
	mncc_payload_msg_type = m ? m->mncc_payload_msg_type : 0;

	rtp_cn_local = call_leg_local_ip(cl, RTP_TO_CN);
	if (!rtp_cn_local) {
		LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "Cannot RTP CREATE to MNCC, no local RTP IP:port to CN set up\n");
		return -EINVAL;
	}

	return mncc_recv_rtp(net, trans, trans->callref, MNCC_RTP_CREATE, rtp_cn_local,
			     codec->payload_type, mncc_payload_msg_type, &trans->cc.local);
}

static int tch_rtp_connect(struct gsm_network *net, const struct gsm_mncc_rtp *rtp)
{
	struct gsm_trans *trans;
	struct call_leg *cl;
	struct rtp_stream *rtps;

	/* Find callref */
	trans = trans_find_by_callref(net, rtp->callref);
	if (!trans) {
		LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP connect for non-existing trans\n");
		mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CONNECT);
		return -EIO;
	}
	log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
	if (!trans->msc_a) {
		LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP connect for trans without conn\n");
		mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CONNECT);
		return -EIO;
	}

	log_mncc_rx_tx(trans, "rx", (const union mncc_msg *)rtp);

	cl = trans->msc_a->cc.call_leg;
	rtps = cl ? cl->rtp[RTP_TO_CN] : NULL;

	if (!rtps) {
		LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP connect for trans without ongoing call\n");
		mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CONNECT);
		return -EINVAL;
	}

	rx_mncc_sdp(trans, rtp->msg_type, rtp->sdp);
	rtp_stream_set_remote_addr_and_codecs(rtps, &trans->cc.remote);

	if (!osmo_sockaddr_str_is_nonzero(&rtps->remote)) {
		/* Didn't get an IP address from SDP. Try legacy MNCC IP address */
		struct osmo_sockaddr_str rtp_addr;
		if (osmo_sockaddr_str_from_sockaddr(&rtp_addr, &rtp->addr) < 0) {
			LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP connect with invalid IP addr\n");
			mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CONNECT);
			return -EINVAL;
		}
		rtp_stream_set_remote_addr(rtps, &rtp_addr);
	}

	rtp_stream_commit(rtps);
	return 0;
}

static struct downstate {
	uint32_t	states;
	int		type;
	int		(*rout) (struct gsm_trans *trans, void *arg);
} downstatelist[] = {
	/* mobile originating call establishment */
	{SBIT(GSM_CSTATE_INITIATED), /* 5.2.1.2 */
	 MNCC_CALL_PROC_REQ, gsm48_cc_tx_call_proc_and_assign},
	{SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.2 | 5.2.1.5 */
	 MNCC_ALERT_REQ, gsm48_cc_tx_alerting},
	{SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC) | SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.2 | 5.2.1.6 | 5.2.1.6 */
	 MNCC_SETUP_RSP, gsm48_cc_tx_connect},
	{SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.4.2 */
	 MNCC_PROGRESS_REQ, gsm48_cc_tx_progress},
	/* mobile terminating call establishment */
	{SBIT(GSM_CSTATE_NULL), /* 5.2.2.1 */
	 MNCC_SETUP_REQ, gsm48_cc_tx_setup},
	{SBIT(GSM_CSTATE_CONNECT_REQUEST),
	 MNCC_SETUP_COMPL_REQ, gsm48_cc_tx_connect_ack},
	 /* signalling during call */
	{SBIT(GSM_CSTATE_ACTIVE),
	 MNCC_NOTIFY_REQ, gsm48_cc_tx_notify},
	{ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ),
	 MNCC_FACILITY_REQ, gsm48_cc_tx_facility},
	{ALL_STATES,
	 MNCC_START_DTMF_RSP, gsm48_cc_tx_start_dtmf_ack},
	{ALL_STATES,
	 MNCC_START_DTMF_REJ, gsm48_cc_tx_start_dtmf_rej},
	{ALL_STATES,
	 MNCC_STOP_DTMF_RSP, gsm48_cc_tx_stop_dtmf_ack},
	{SBIT(GSM_CSTATE_ACTIVE),
	 MNCC_HOLD_CNF, gsm48_cc_tx_hold_ack},
	{SBIT(GSM_CSTATE_ACTIVE),
	 MNCC_HOLD_REJ, gsm48_cc_tx_hold_rej},
	{SBIT(GSM_CSTATE_ACTIVE),
	 MNCC_RETRIEVE_CNF, gsm48_cc_tx_retrieve_ack},
	{SBIT(GSM_CSTATE_ACTIVE),
	 MNCC_RETRIEVE_REJ, gsm48_cc_tx_retrieve_rej},
	{SBIT(GSM_CSTATE_ACTIVE),
	 MNCC_MODIFY_REQ, gsm48_cc_tx_modify},
	{SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
	 MNCC_MODIFY_RSP, gsm48_cc_tx_modify_complete},
	{SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
	 MNCC_MODIFY_REJ, gsm48_cc_tx_modify_reject},
	{SBIT(GSM_CSTATE_ACTIVE),
	 MNCC_USERINFO_REQ, gsm48_cc_tx_userinfo},
	/* clearing */
	{SBIT(GSM_CSTATE_INITIATED),
	 MNCC_REJ_REQ, gsm48_cc_tx_release_compl},
	{ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_DISCONNECT_IND) - SBIT(GSM_CSTATE_RELEASE_REQ) - SBIT(GSM_CSTATE_DISCONNECT_REQ), /* 5.4.4 */
	 MNCC_DISC_REQ, gsm48_cc_tx_disconnect},
	{ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), /* 5.4.3.2 */
	 MNCC_REL_REQ, gsm48_cc_tx_release},
};

#define DOWNSLLEN \
	(sizeof(downstatelist) / sizeof(struct downstate))


static int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
{
	int i, rc = 0;
	struct msc_a *msc_a = NULL;
	struct gsm_trans *trans = NULL;
	const struct gsm_mncc *data;

	/* handle special messages */
	switch(msg->msg_type) {
	case MNCC_BRIDGE:
		rc = tch_bridge(net, &msg->bridge);
		if (rc < 0)
			disconnect_bridge(net, &msg->bridge, -rc);
		return rc;
	case MNCC_RTP_CREATE:
		return tch_rtp_create(net, &msg->rtp);
	case MNCC_RTP_CONNECT:
		return tch_rtp_connect(net, &msg->rtp);
	case MNCC_RTP_FREE:
		/* unused right now */
		return -EIO;

	case MNCC_FRAME_DROP:
	case MNCC_FRAME_RECV:
	case GSM_TCHF_FRAME:
	case GSM_TCHF_FRAME_EFR:
	case GSM_TCHH_FRAME:
	case GSM_TCH_FRAME_AMR:
		LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP streams must be handled externally; %s not supported.\n",
		     get_mncc_name(msg->msg_type));
		return -ENOTSUP;
	}

	data = &msg->signal;

	/* Find callref */
	trans = trans_find_by_callref(net, data->callref);

	/* Callref unknown */
	if (!trans) {
		struct vlr_subscr *vsub;

		if (msg->msg_type != MNCC_SETUP_REQ) {
			LOG_TRANS_CAT(trans, DCC, LOGL_ERROR, "Unknown call reference for %s\n",
				      get_mncc_name(msg->msg_type));
			/* Invalid call reference */
			return mncc_release_ind(net, NULL, data->callref,
						GSM48_CAUSE_LOC_PRN_S_LU,
						GSM48_CC_CAUSE_INVAL_TRANS_ID);
		}
		if (!data->called.number[0] && !data->imsi[0]) {
			LOG_TRANS_CAT(trans, DCC, LOGL_ERROR, "Neither number nor IMSI in %s\n",
				      get_mncc_name(msg->msg_type));
			/* Invalid number */
			return mncc_release_ind(net, NULL, data->callref,
						GSM48_CAUSE_LOC_PRN_S_LU,
						GSM48_CC_CAUSE_INV_NR_FORMAT);
		}
		/* New transaction due to setup, find subscriber */
		if (data->called.number[0]) {
			vsub = vlr_subscr_find_by_msisdn(net->vlr, data->called.number, __func__);
			if (!vsub)
				LOG_TRANS_CAT(trans, DCC, LOGL_ERROR, "rx %s for unknown subscriber number '%s'\n",
					      get_mncc_name(msg->msg_type), data->called.number);
		} else {
			vsub = vlr_subscr_find_by_imsi(net->vlr, data->imsi, __func__);
			if (!vsub)
				LOG_TRANS_CAT(trans, DCC, LOGL_ERROR, "rx %s for unknown subscriber IMSI '%s'\n",
					      get_mncc_name(msg->msg_type), data->imsi);
		}
		if (!vsub)
			return mncc_release_ind(net, NULL, data->callref, GSM48_CAUSE_LOC_PRN_S_LU,
						GSM48_CC_CAUSE_USER_NOTRESPOND);
		/* update the subscriber we deal with */
		log_set_context(LOG_CTX_VLR_SUBSCR, vsub);

		/* If subscriber is not "attached" */
		if (!vsub->lu_complete) {
			LOG_TRANS_CAT(trans, DCC, LOGL_ERROR, "rx %s for subscriber that is not attached: %s\n",
				      get_mncc_name(msg->msg_type), vlr_subscr_name(vsub));
			vlr_subscr_put(vsub, __func__);
			/* Temporarily out of order */
			return mncc_release_ind(net, NULL, data->callref,
						GSM48_CAUSE_LOC_PRN_S_LU,
						GSM48_CC_CAUSE_DEST_OOO);
		}

		/* Find valid conn */
		msc_a = msc_a_for_vsub(vsub, true);

		/* If subscriber is BUSY and we do not DO call in call aka "call-waiting" */
		if (!net->call_waiting && msc_a) {
			struct gsm_trans *existing_cc_trans = trans_find_by_type(msc_a, TRANS_CC);
			if (existing_cc_trans && existing_cc_trans->cc.state != GSM_CSTATE_NULL) {
				LOG_TRANS_CAT(existing_cc_trans, DCC, LOGL_NOTICE,
					      "rx '%s' for subscriber %s with trans state (%s)"
					      " rejecting with USER_BUSY\n",
					get_mncc_name(msg->msg_type), data->called.number,
					gsm48_cc_state_name(existing_cc_trans->cc.state));
				return mncc_release_ind(net, NULL, data->callref,
							GSM48_CAUSE_LOC_PRN_S_LU,
							GSM48_CC_CAUSE_USER_BUSY);
			}
		}

		/* Create transaction */
		trans = trans_alloc(net, vsub, TRANS_CC,
				    TRANS_ID_UNASSIGNED, data->callref);
		if (!trans) {
			LOG_TRANS(trans, LOGL_ERROR, "No memory for trans.\n");
			vlr_subscr_put(vsub, __func__);
			/* Resource unavailable */
			mncc_release_ind(net, NULL, data->callref,
					 GSM48_CAUSE_LOC_PRN_S_LU,
					 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
			return -ENOMEM;
		}

		/* Remember remote SDP, if any */
		rx_mncc_sdp(trans, data->msg_type, data->sdp);

		/* If subscriber has no conn */
		if (!msc_a) {
			/* This condition will return before the common logging of the received MNCC message below, so
			 * log it now. */
			log_mncc_rx_tx(trans, "rx", msg);

			/* store setup information until paging succeeds */
			memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc));

			/* Request a channel. If Paging already started, paging_request_start() will append the new
			 * trans to the already ongoing Paging. */
			trans->paging_request = paging_request_start(vsub, PAGING_CAUSE_CALL_CONVERSATIONAL,
								     cc_paging_cb, trans, "MNCC: establish call");
			if (!trans->paging_request) {
				LOG_TRANS(trans, LOGL_ERROR, "Failed to allocate paging token.\n");
				trans_free(trans);
			}
			vlr_subscr_put(vsub, __func__);
			return 0;
		}

		/* Assign conn */
		trans->msc_a = msc_a;
		msc_a_get(msc_a, MSC_A_USE_CC);
		trans->dlci = 0x00; /* SAPI=0, not SACCH */
		vlr_subscr_put(vsub, __func__);
	} else {
		/* update the subscriber we deal with */
		log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
	}

	log_mncc_rx_tx(trans, "rx", msg);

	gsm48_start_guard_timer(trans);
	trans->cc.mncc_initiated = true;

	if (trans->msc_a)
		msc_a = trans->msc_a;

	/* if paging did not respond yet */
	if (!msc_a) {
		struct gsm_mncc rel = {
			.callref = data->callref,
		};
		LOG_TRANS(trans, LOGL_DEBUG, "still paging\n");
		mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
				GSM48_CC_CAUSE_NORM_CALL_CLEAR);
		if (msg->msg_type == MNCC_REL_REQ)
			rc = mncc_recvmsg(net, trans, MNCC_REL_CNF, &rel);
		else
			rc = mncc_recvmsg(net, trans, MNCC_REL_IND, &rel);
		trans->callref = 0;
		trans_free(trans);
		return rc;
	}

	/* Find function for current state and message */
	for (i = 0; i < DOWNSLLEN; i++)
		if ((msg->msg_type == downstatelist[i].type)
		 && ((1 << trans->cc.state) & downstatelist[i].states))
			break;
	if (i == DOWNSLLEN) {
		LOG_TRANS(trans, LOGL_DEBUG, "Message '%s' unhandled at state '%s'\n",
			  get_mncc_name(msg->msg_type), gsm48_cc_state_name(trans->cc.state));
		return 0;
	}

	rc = downstatelist[i].rout(trans, (void*)msg);

	return rc;
}

struct mncc_call *mncc_find_by_callref_from_msg(const union mncc_msg *msg)
{
	uint32_t callref;

	switch (msg->msg_type) {
	case MNCC_BRIDGE:
		callref = msg->bridge.callref[0];
		break;
	case MNCC_RTP_CREATE:
	case MNCC_RTP_CONNECT:
		callref = msg->rtp.callref;
		break;

	case MNCC_RTP_FREE:
	case MNCC_FRAME_DROP:
	case MNCC_FRAME_RECV:
	case GSM_TCHF_FRAME:
	case GSM_TCHF_FRAME_EFR:
	case GSM_TCHH_FRAME:
	case GSM_TCH_FRAME_AMR:
		return NULL;

	default:
		callref = msg->signal.callref;
		break;
	}

	return mncc_call_find_by_callref(callref);
}

/* Demux incoming genuine calls to GSM CC from MNCC forwarding for inter-MSC handover */
int mncc_tx_to_cc(struct gsm_network *net, void *arg)
{
	const union mncc_msg *msg = arg;
	struct mncc_call *mncc_call = NULL;

	if (msg->msg_type == MNCC_SETUP_REQ) {
		/* Incoming call to forward for inter-MSC Handover? */
		mncc_call = msc_t_check_call_to_handover_number(&msg->signal);
		if (mncc_call)
			LOG_MNCC_CALL(mncc_call, LOGL_DEBUG,
				      "Incoming call matches pending inter-MSC Handover Number\n");
	}
	if (!mncc_call) {
		/* Find already active MNCC FSM for this callref.
		 * Currently only for inter-MSC call forwarding, but mncc_fsm could at some point also be used for direct
		 * MNCC<->GSM-CC call handling. */
		mncc_call = mncc_find_by_callref_from_msg(msg);
	}
	if (mncc_call) {
		mncc_call_rx(mncc_call, msg);
		return 0;
	}

	/* None of the above? Then it must be a normal GSM CC call related message. */
	return mncc_tx_to_gsm_cc(net, msg);
}

static struct datastate {
	uint32_t	states;
	int		type;
	int		(*rout) (struct gsm_trans *trans, struct msgb *msg);
} datastatelist[] = {
	/* mobile originating call establishment */
	{SBIT(GSM_CSTATE_NULL), /* 5.2.1.2 */
	 GSM48_MT_CC_SETUP, gsm48_cc_rx_setup},
	{SBIT(GSM_CSTATE_NULL), /* 5.2.1.2 */
	 GSM48_MT_CC_EMERG_SETUP, gsm48_cc_rx_setup},
	{SBIT(GSM_CSTATE_CONNECT_IND), /* 5.2.1.2 */
	 GSM48_MT_CC_CONNECT_ACK, gsm48_cc_rx_connect_ack},
	/* mobile terminating call establishment */
	{SBIT(GSM_CSTATE_CALL_PRESENT), /* 5.2.2.3.2 */
	 GSM48_MT_CC_CALL_CONF, gsm48_cc_rx_call_conf},
	{SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF), /* ???? | 5.2.2.3.2 */
	 GSM48_MT_CC_ALERTING, gsm48_cc_rx_alerting},
	{SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF) | SBIT(GSM_CSTATE_CALL_RECEIVED), /* (5.2.2.6) | 5.2.2.6 | 5.2.2.6 */
	 GSM48_MT_CC_CONNECT, gsm48_cc_rx_connect},
	 /* signalling during call */
	{ALL_STATES - SBIT(GSM_CSTATE_NULL),
	 GSM48_MT_CC_FACILITY, gsm48_cc_rx_facility},
	{SBIT(GSM_CSTATE_ACTIVE),
	 GSM48_MT_CC_NOTIFY, gsm48_cc_rx_notify},
	{ALL_STATES,
	 GSM48_MT_CC_START_DTMF, gsm48_cc_rx_start_dtmf},
	{ALL_STATES,
	 GSM48_MT_CC_STOP_DTMF, gsm48_cc_rx_stop_dtmf},
	{ALL_STATES,
	 GSM48_MT_CC_STATUS_ENQ, gsm48_cc_rx_status_enq},
	{SBIT(GSM_CSTATE_ACTIVE),
	 GSM48_MT_CC_HOLD, gsm48_cc_rx_hold},
	{SBIT(GSM_CSTATE_ACTIVE),
	 GSM48_MT_CC_RETR, gsm48_cc_rx_retrieve},
	{SBIT(GSM_CSTATE_ACTIVE),
	 GSM48_MT_CC_MODIFY, gsm48_cc_rx_modify},
	{SBIT(GSM_CSTATE_MO_TERM_MODIFY),
	 GSM48_MT_CC_MODIFY_COMPL, gsm48_cc_rx_modify_complete},
	{SBIT(GSM_CSTATE_MO_TERM_MODIFY),
	 GSM48_MT_CC_MODIFY_REJECT, gsm48_cc_rx_modify_reject},
	{SBIT(GSM_CSTATE_ACTIVE),
	 GSM48_MT_CC_USER_INFO, gsm48_cc_rx_userinfo},
	/* clearing */
	{ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), /* 5.4.3.2 */
	 GSM48_MT_CC_DISCONNECT, gsm48_cc_rx_disconnect},
	{ALL_STATES - SBIT(GSM_CSTATE_NULL), /* 5.4.4.1.2.2 */
	 GSM48_MT_CC_RELEASE, gsm48_cc_rx_release},
	{ALL_STATES, /* 5.4.3.4 */
	 GSM48_MT_CC_RELEASE_COMPL, gsm48_cc_rx_release_compl},
};

#define DATASLLEN \
	(sizeof(datastatelist) / sizeof(struct datastate))

int gsm0408_rcv_cc(struct msc_a *msc_a, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	uint8_t msg_type = gsm48_hdr_msg_type(gh);
	uint8_t transaction_id = gsm48_hdr_trans_id_flip_ti(gh);
	struct gsm_trans *trans = NULL;
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);
	struct gsm_network *net = msc_a_net(msc_a);
	int i, rc = 0;

	if (msg_type & 0x80) {
		LOG_TRANS(trans, LOGL_DEBUG, "MSG 0x%2x not defined for PD error\n", msg_type);
		return -EINVAL;
	}

	if (!vsub) {
		LOG_TRANS(trans, LOGL_ERROR, "Invalid conn: no subscriber\n");
		return -EINVAL;
	}

	/* Find transaction */
	trans = trans_find_by_id(msc_a, TRANS_CC, transaction_id);

	/* Create transaction */
	if (!trans) {
		/* Create transaction */
		trans = trans_alloc(net, vsub,
				    TRANS_CC,
				    transaction_id, msc_cc_next_outgoing_callref());
		if (!trans) {
			LOG_TRANS(trans, LOGL_ERROR, "No memory for trans.\n");
			rc = gsm48_tx_simple(msc_a,
					     GSM48_PDISC_CC | (transaction_id << 4),
					     GSM48_MT_CC_RELEASE_COMPL);
			return -ENOMEM;
		}
		if (osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_TRANSACTION_ACCEPTED, trans)) {
			LOG_MSC_A(msc_a, LOGL_ERROR, "Not allowed to accept CC transaction\n");
			trans_free(trans);
			return -EINVAL;
		}

		/* Assign transaction */
		msc_a_get(msc_a, MSC_A_USE_CC);
		trans->msc_a = msc_a;
		trans->dlci = OMSC_LINKID_CB(msg); /* DLCI as received from BSC */

		/* An earlier CM Service Request for this CC message now has concluded */
		if (!osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_CC))
			LOG_MSC_A(msc_a, LOGL_ERROR,
				  "Creating new CC transaction without prior CM Service Request\n");
		else
			msc_a_put(msc_a, MSC_A_USE_CM_SERVICE_CC);
	}

	LOG_TRANS(trans, LOGL_DEBUG, "rx %s in state %s\n", gsm48_cc_msg_name(msg_type),
		  gsm48_cc_state_name(trans->cc.state));

	/* find function for current state and message */
	for (i = 0; i < DATASLLEN; i++)
		if ((msg_type == datastatelist[i].type)
		 && ((1 << trans->cc.state) & datastatelist[i].states))
			break;
	if (i == DATASLLEN) {
		LOG_TRANS(trans, LOGL_ERROR, "Message unhandled at this state.\n");

		/* If a transaction was just now created, it was a bogus transaction ID, and we need to clean up the
		 * transaction right away. */
		if (trans->cc.state == GSM_CSTATE_NULL) {
			LOG_TRANS(trans, LOGL_ERROR, "Unknown transaction ID for non-SETUP message is not allowed"
				  " -- disarding new CC transaction right away\n");
			trans_free(trans);
		}
		return 0;
	}

	assert(trans->vsub);

	rc = datastatelist[i].rout(trans, msg);

	return rc;
}
