/* Code to manage a subscriber's MSC-A role */
/*
 * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * SPDX-License-Identifier: AGPL-3.0+
 *
 * Author: Neels Hofmeyr
 *
 * 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 <osmocom/core/utils.h>
#include <osmocom/core/tdef.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/signal.h>

#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/msc_roles.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/msc_a.h>
#include <osmocom/msc/msc_t.h>
#include <osmocom/msc/msc_i.h>
#include <osmocom/msc/paging.h>
#include <osmocom/msc/signal.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/transaction.h>
#include <osmocom/msc/transaction_cc.h>
#include <osmocom/msc/ran_peer.h>
#include <osmocom/msc/ran_msg_a.h>
#include <osmocom/msc/ran_msg_iu.h>
#include <osmocom/msc/sgs_iface.h>
#include <osmocom/msc/gsm_04_08.h>
#include <osmocom/msc/gsm_09_11.h>
#include <osmocom/msc/gsm_04_14.h>
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/rtp_stream.h>
#include <osmocom/msc/msc_ho.h>
#include <osmocom/msc/codec_mapping.h>
#include <osmocom/msc/msc_vgcs.h>

#define MSC_A_USE_WAIT_CLEAR_COMPLETE "wait-Clear-Complete"

static struct osmo_fsm msc_a_fsm;

static const struct osmo_tdef_state_timeout msc_a_fsm_timeouts[32] = {
	[MSC_A_ST_VALIDATE_L3] = { .T = -1 },
	[MSC_A_ST_AUTH_CIPH] = { .keep_timer = true },
	[MSC_A_ST_WAIT_CLASSMARK_UPDATE] = { .keep_timer = true },
	[MSC_A_ST_AUTHENTICATED] = { .keep_timer = true },
	[MSC_A_ST_RELEASING] = { .T = -2 },
	[MSC_A_ST_RELEASED] = { .T = -2 },
};

/* Transition to a state, using the T timer defined in msc_a_fsm_timeouts.
 * The actual timeout value is in turn obtained from network->T_defs.
 * Assumes local variable fi exists. */
#define msc_a_state_chg_always(msc_a, state) \
	osmo_tdef_fsm_inst_state_chg((msc_a)->c.fi, state, msc_a_fsm_timeouts, (msc_a)->c.ran->tdefs, 5)

/* Same as msc_a_state_chg_always() but ignore if the msc_a already is in the target state. */
#define msc_a_state_chg(msc_a, STATE) do { \
		if ((msc_a)->c.fi->state != STATE) \
			msc_a_state_chg_always(msc_a, STATE); \
	} while(0)

struct gsm_network *msc_a_net(const struct msc_a *msc_a)
{
	return msub_net(msc_a->c.msub);
}

struct vlr_subscr *msc_a_vsub(const struct msc_a *msc_a)
{
	if (!msc_a)
		return NULL;
	return msub_vsub(msc_a->c.msub);
}

struct msc_i *msc_a_msc_i(const struct msc_a *msc_a)
{
	if (!msc_a)
		return NULL;
	return msub_msc_i(msc_a->c.msub);
}

struct msc_t *msc_a_msc_t(const struct msc_a *msc_a)
{
	if (!msc_a)
		return NULL;
	return msub_msc_t(msc_a->c.msub);
}

struct msc_a *msc_a_fi_priv(struct osmo_fsm_inst *fi)
{
	OSMO_ASSERT(fi);
	OSMO_ASSERT(fi->fsm == &msc_a_fsm);
	OSMO_ASSERT(fi->priv);
	return fi->priv;
}

bool msc_a_is_ciphering_to_be_attempted(const struct msc_a *msc_a)
{
	struct gsm_network *net = msc_a_net(msc_a);
	bool is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU);
	if (is_utran)
		return net->uea_encryption_mask > (1 << OSMO_UTRAN_UEA0);
	else
		return net->a5_encryption_mask > 0x1;
}

bool msc_a_is_ciphering_required(const struct msc_a *msc_a)
{
	struct gsm_network *net = msc_a_net(msc_a);
	bool is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU);
	if (is_utran)
		return net->uea_encryption_mask
			&& ((net->uea_encryption_mask & (1 << OSMO_UTRAN_UEA0)) == 0);
	else
		return net->a5_encryption_mask
			&& ((net->a5_encryption_mask & 0x1) == 0);
}

static void update_counters(struct osmo_fsm_inst *fi, bool conn_accepted)
{
	struct msc_a *msc_a = fi->priv;
	struct gsm_network *net = msc_a_net(msc_a);
	switch (msc_a->complete_layer3_type) {
	case COMPLETE_LAYER3_LU:
		rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, conn_accepted ? MSC_CTR_LOC_UPDATE_COMPLETED : MSC_CTR_LOC_UPDATE_FAILED));
		break;
	case COMPLETE_LAYER3_CM_SERVICE_REQ:
		rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, conn_accepted ? MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED : MSC_CTR_CM_SERVICE_REQUEST_REJECTED));
		break;
	case COMPLETE_LAYER3_PAGING_RESP:
		rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, conn_accepted ? MSC_CTR_PAGING_RESP_ACCEPTED : MSC_CTR_PAGING_RESP_REJECTED));
		break;
	case COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ:
		rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs,
						    conn_accepted ? MSC_CTR_CM_RE_ESTABLISH_REQ_ACCEPTED
								  : MSC_CTR_CM_RE_ESTABLISH_REQ_REJECTED));
		break;
	default:
		break;
	}
}

static void evaluate_acceptance_outcome(struct osmo_fsm_inst *fi, bool conn_accepted)
{
	struct msc_a *msc_a = fi->priv;
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);

	update_counters(fi, conn_accepted);

	if (conn_accepted) {
		/* Record the Cell ID seen in Complete Layer 3 Information in the VLR, so that it also shows in vty
		 * 'show' output. */
		vsub->cgi = msc_a->via_cell;
	}

	/* Trigger transactions that we paged for */
	if (msc_a->complete_layer3_type == COMPLETE_LAYER3_PAGING_RESP) {
		if (conn_accepted)
			paging_response(msc_a);
		else
			paging_expired(vsub);
	}

	if (conn_accepted)
		osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_ATTACHED, msc_a_vsub(msc_a));

	if (msc_a->complete_layer3_type == COMPLETE_LAYER3_LU)
		msc_a_put(msc_a, MSC_A_USE_LOCATION_UPDATING);

	if (conn_accepted && msc_a->complete_layer3_type == COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ) {
		/* Trigger new Assignment to recommence the voice call. A little dance here because normally we verify
		 * that no CC trans is already active. */
		struct gsm_trans *cc_trans = msc_a->cc.active_trans;
		msc_a->cc.active_trans = NULL;
		osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_TRANSACTION_ACCEPTED, cc_trans);
		msc_a_try_call_assignment(cc_trans);
	}
}

bool msc_a_is_accepted(const struct msc_a *msc_a)
{
	if (!msc_a || !msc_a->c.fi)
		return false;
	return msc_a->c.fi->state == MSC_A_ST_AUTHENTICATED
		|| msc_a->c.fi->state == MSC_A_ST_COMMUNICATING;
}

bool msc_a_in_release(struct msc_a *msc_a)
{
	if (!msc_a)
		return true;
	if (msc_a->c.fi->state == MSC_A_ST_RELEASING)
		return true;
	if (msc_a->c.fi->state == MSC_A_ST_RELEASED)
		return true;
	return false;
}

static int msc_a_ran_dec(struct msc_a *msc_a, const struct an_apdu *an_apdu, enum msc_role from_role)
{
	int rc;
	struct msc_a_ran_dec_data d = {
		.from_role = from_role,
		.an_apdu = an_apdu,
	};
	msc_a_get(msc_a, __func__);
	rc = msc_role_ran_decode(msc_a->c.fi, an_apdu, msc_a_ran_decode_cb, &d);
	msc_a_put(msc_a, __func__);
	return rc;
};

static void msc_a_fsm_validate_l3(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct msc_a *msc_a = fi->priv;
	const struct an_apdu *an_apdu;

	switch (event) {
	case MSC_A_EV_FROM_I_COMPLETE_LAYER_3:
	case MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST:
	case MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST:
		an_apdu = data;
		msc_a_ran_dec(msc_a, an_apdu, MSC_ROLE_I);
		return;

	case MSC_A_EV_COMPLETE_LAYER_3_OK:
		msc_a_state_chg(msc_a, MSC_A_ST_AUTH_CIPH);
		return;

	case MSC_A_EV_MO_CLOSE:
	case MSC_A_EV_CN_CLOSE:
		evaluate_acceptance_outcome(fi, false);
		/* fall through */
	case MSC_A_EV_UNUSED:
		msc_a_state_chg(msc_a, MSC_A_ST_RELEASING);
		return;

	default:
		OSMO_ASSERT(false);
	}
}

/* Figure out whether to first send a Classmark Request to the MS to figure out algorithm support. */
static bool msc_a_need_classmark_for_ciphering(struct msc_a *msc_a)
{
	struct gsm_network *net = msc_a_net(msc_a);
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);
	int i = 0;
	bool request_classmark = false;

	/* Only on GERAN-A do we ever need Classmark Information for Ciphering. */
	if (msc_a->c.ran->type != OSMO_RAT_GERAN_A)
		return false;

	for (i = 0; i < 8; i++) {
		int supported;

		/* A5/n permitted by osmo-msc.cfg? */
		if (!(net->a5_encryption_mask & (1 << i)))
			continue;

		/* A5/n supported by MS? */
		supported = osmo_gsm48_classmark_supports_a5(&vsub->classmark, i);
		if (supported < 0) {
			LOG_MSC_A(msc_a, LOGL_DEBUG, "For A5/%d, we still need Classmark %d\n", i, -supported);
			request_classmark = true;
		}
	}

	return request_classmark;
}

static int msc_a_ran_enc_ciphering(struct msc_a *msc_a, bool umts_aka, bool retrieve_imeisv);

/* VLR callback for ops.set_ciph_mode() */
int msc_a_vlr_set_cipher_mode(void *_msc_a, bool umts_aka, bool retrieve_imeisv)
{
	struct msc_a *msc_a = _msc_a;
	struct vlr_subscr *vsub;

	if (!msc_a) {
		LOGP(DMSC, LOGL_ERROR, "Insufficient info to start ciphering: "
				       "MSC-A role is NULL?!?\n");
		return -EINVAL;
	}

	vsub = msc_a_vsub(msc_a);
	if (!vsub || !vsub->last_tuple) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "Insufficient info to start ciphering: "
					     "vlr_subscr is NULL?!?\n");
		return -EINVAL;
	}

	if (msc_a_need_classmark_for_ciphering(msc_a)) {
		int rc;
		struct ran_msg msg = {
			.msg_type = RAN_MSG_CLASSMARK_REQUEST,
		};
		rc = msc_a_ran_down(msc_a, MSC_ROLE_I, &msg);
		if (rc) {
			LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot send Classmark Request\n");
			return -EIO;
		}

		msc_a->state_before_classmark_update = msc_a->c.fi->state;
		msc_a->action_on_classmark_update = (struct msc_a_action_on_classmark_update){
			.type = MSC_A_CLASSMARK_UPDATE_THEN_CIPHERING,
			.ciphering = {
				.umts_aka = umts_aka,
				.retrieve_imeisv = retrieve_imeisv,
			},
		};
		msc_a_state_chg(msc_a, MSC_A_ST_WAIT_CLASSMARK_UPDATE);
		return 0;
	}

	return msc_a_ran_enc_ciphering(msc_a, umts_aka, retrieve_imeisv);
}

static uint8_t filter_a5(uint8_t a5_mask, bool umts_aka)
{
	/* With GSM AKA: allow A5/0, 1, 3 = 0b00001011 = 0xb.
	 * UMTS aka: allow A5/0, 1, 3, 4 = 0b00011011 = 0x1b.
	 */
	return a5_mask & (umts_aka ? 0x1b : 0x0b);
}

static int msc_a_ran_enc_ciphering(struct msc_a *msc_a, bool umts_aka, bool retrieve_imeisv)
{
	struct gsm_network *net;
	struct vlr_subscr *vsub;
	struct ran_msg msg;

	if (!msc_a) {
		LOGP(DMSC, LOGL_ERROR, "Insufficient info to start ciphering: "
				       "MSC-A role is NULL?!?\n");
		return -EINVAL;
	}

	net = msc_a_net(msc_a);
	vsub = msc_a_vsub(msc_a);

	if (!net || !vsub || !vsub->last_tuple) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "Insufficient info to start ciphering: "
					     "gsm_network and/or vlr_subscr is NULL?!?\n");
		return -EINVAL;
	}

	msg = (struct ran_msg){
		.msg_type = RAN_MSG_CIPHER_MODE_COMMAND,
		.cipher_mode_command = {
			.vec = vsub->last_tuple ? &vsub->last_tuple->vec : NULL,
			.classmark = &vsub->classmark,
			.geran = {
				.umts_aka = umts_aka,
				.retrieve_imeisv = retrieve_imeisv,
				.a5_encryption_mask = filter_a5(net->a5_encryption_mask, umts_aka),

				/* for ran_a.c to store the GERAN key that is actually used */
				.chosen_key = &msc_a->geran_encr,
			},
			.utran = {
				.uea_encryption_mask = net->uea_encryption_mask,
			},
		},
	};

	if (msc_a_ran_down(msc_a, MSC_ROLE_I, &msg)) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "Sending Cipher Mode Command failed\n");
		/* Returning error to the VLR ops.set_ciph_mode() will cancel the attach. Other callers need to take
		 * care of the return value. */
		return -EINVAL;
	}

	if (msc_a->geran_encr.key_len)
		LOG_MSC_A(msc_a, LOGL_DEBUG, "RAN encoding chose ciphering: A5/%d kc %s kc128 %s\n",
			  msc_a->geran_encr.alg_id - 1,
			  osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.key, msc_a->geran_encr.key_len),
			  msc_a->geran_encr.kc128_present ?
			    osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.kc128, sizeof(msc_a->geran_encr.kc128))
			    : "-");
	return 0;
}

static void msc_a_fsm_auth_ciph(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct msc_a *msc_a = fi->priv;

	/* If accepted, transition the state, all other cases mean failure. */
	switch (event) {
	case MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST:
	case MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST:
		msc_a_ran_dec(msc_a, data, MSC_ROLE_I);
		return;

	case MSC_A_EV_AUTHENTICATED:
		msc_a_state_chg(msc_a, MSC_A_ST_AUTHENTICATED);
		return;

	case MSC_A_EV_UNUSED:
		msc_a_state_chg(msc_a, MSC_A_ST_RELEASING);
		return;

	case MSC_A_EV_MO_CLOSE:
	case MSC_A_EV_CN_CLOSE:
		evaluate_acceptance_outcome(fi, false);
		msc_a_state_chg(msc_a, MSC_A_ST_RELEASING);
		return;


	default:
		OSMO_ASSERT(false);
	}
}

static void msc_a_fsm_wait_classmark_update(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct msc_a *msc_a = fi->priv;

	switch (event) {
	case MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST:
	case MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST:
		msc_a_ran_dec(msc_a, data, MSC_ROLE_I);
		return;

	case MSC_A_EV_CLASSMARK_UPDATE:
		switch (msc_a->action_on_classmark_update.type) {
		case MSC_A_CLASSMARK_UPDATE_THEN_CIPHERING:
			msc_a_state_chg(msc_a, MSC_A_ST_AUTH_CIPH);
			if (msc_a_ran_enc_ciphering(msc_a,
						     msc_a->action_on_classmark_update.ciphering.umts_aka,
						     msc_a->action_on_classmark_update.ciphering.retrieve_imeisv)) {
				LOG_MSC_A(msc_a, LOGL_ERROR,
					  "After Classmark Update, still failed to send Cipher Mode Command\n");
				msc_a_state_chg(msc_a, MSC_A_ST_RELEASING);
			}
			return;

		default:
			LOG_MSC_A(msc_a, LOGL_ERROR, "Internal error: After Classmark Update, don't know what to do\n");
			msc_a_state_chg(msc_a, msc_a->state_before_classmark_update);
			return;
		}

	case MSC_A_EV_UNUSED:
		/* Seems something detached / aborted in the middle of auth+ciph. */
		evaluate_acceptance_outcome(fi, false);
		msc_a_state_chg(msc_a, MSC_A_ST_RELEASING);
		return;

	case MSC_A_EV_MO_CLOSE:
	case MSC_A_EV_CN_CLOSE:
		evaluate_acceptance_outcome(fi, false);
		msc_a_state_chg(msc_a, MSC_A_ST_RELEASING);
		return;

	default:
		OSMO_ASSERT(false);
	}
}

static bool msc_a_fsm_has_active_transactions(struct osmo_fsm_inst *fi)
{
	struct msc_a *msc_a = fi->priv;
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);
	struct gsm_trans *trans;

	if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_SILENT_CALL)) {
		LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: silent call still active\n", __func__);
		return true;
	}

	if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_CC)) {
		LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still awaiting MO CC request after a CM Service Request\n",
			 __func__);
		return true;
	}
	if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_GCC)) {
		LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still awaiting MO GCC request after a CM Service Request\n",
			 __func__);
		return true;
	}
	if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_BCC)) {
		LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still awaiting MO BCC request after a CM Service Request\n",
			 __func__);
		return true;
	}
	if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_SMS)) {
		LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still awaiting MO SMS after a CM Service Request\n",
			 __func__);
		return true;
	}
	if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_SS)) {
		LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still awaiting MO SS after a CM Service Request\n",
			 __func__);
		return true;
	}

	if (vsub && !llist_empty(&vsub->cs.requests)) {
		struct paging_request *pr;
		llist_for_each_entry(pr, &vsub->cs.requests, entry) {
			LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still active: %s\n", __func__, pr->label);
		}
		return true;
	}

	if ((trans = trans_has_conn(msc_a))) {
		LOG_MSC_A(msc_a, LOGL_DEBUG, "connection still has active transaction: %s\n",
			  trans_type_name(trans->type));
		return true;
	}

	return false;
}

static void msc_a_fsm_authenticated_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct msc_a *msc_a = fi->priv;
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);

	/* Stop Location Update expiry for this subscriber. While the subscriber
	 * has an open connection the LU expiry timer must remain disabled.
	 * Otherwise we would kick the subscriber off the network when the timer
	 * expires e.g. during a long phone call.
	 * The LU expiry timer will restart once the connection is closed. */
	if (vsub)
		vsub->expire_lu = VLR_SUBSCRIBER_NO_EXPIRATION;

	evaluate_acceptance_outcome(fi, true);
}

static void msc_a_fsm_authenticated(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct msc_a *msc_a = fi->priv;

	switch (event) {
	case MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST:
	case MSC_A_EV_FROM_I_PREPARE_SUBSEQUENT_HANDOVER_REQUEST:
	case MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST:
		msc_a_ran_dec(msc_a, data, MSC_ROLE_I);
		return;

	case MSC_A_EV_COMPLETE_LAYER_3_OK:
		/* When Authentication is off, we may already be in the Accepted state when the code
		 * evaluates the Compl L3. Simply ignore. This just cosmetically mutes the error log
		 * about the useless event. */
		return;

	case MSC_A_EV_TRANSACTION_ACCEPTED:
		msc_a_state_chg(msc_a, MSC_A_ST_COMMUNICATING);
		return;

	case MSC_A_EV_MO_CLOSE:
	case MSC_A_EV_CN_CLOSE:
	case MSC_A_EV_UNUSED:
		msc_a_state_chg(msc_a, MSC_A_ST_RELEASING);
		return;

	default:
		OSMO_ASSERT(false);
	}
}

static struct call_leg *msc_a_ensure_call_leg(struct msc_a *msc_a, struct gsm_trans *for_cc_trans)
{
	struct call_leg *cl = msc_a->cc.call_leg;
	struct gsm_network *net = msc_a_net(msc_a);

	/* Ensure that events about RTP endpoints coming from the msc_a->cc.call_leg know which gsm_trans to abort on
	 * error */
	if (!msc_a->cc.active_trans)
		msc_a->cc.active_trans = for_cc_trans;
	if (msc_a->cc.active_trans != for_cc_trans) {
		LOG_TRANS(for_cc_trans, LOGL_ERROR,
			  "Cannot create call leg, another trans is already active for this conn\n");
		return NULL;
	}

	if (!cl) {
		cl = msc_a->cc.call_leg = call_leg_alloc(msc_a->c.fi,
							 MSC_EV_CALL_LEG_TERM,
							 MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
							 MSC_EV_CALL_LEG_RTP_COMPLETE);
		OSMO_ASSERT(cl);

		if (net->use_osmux != OSMUX_USAGE_OFF) {
			struct msc_i *msc_i = msc_a_msc_i(msc_a);
			if (msc_i->c.remote_to) {
				/* TODO: investigate what to do in this case */
				LOG_MSC_A(msc_a, LOGL_ERROR, "Osmux not yet supported for inter-MSC");
			} else {
				cl->ran_peer_supports_osmux = msc_i->ran_conn->ran_peer->remote_supports_osmux;
			}
		}

	}
	return cl;
}

int msc_a_ensure_cn_local_rtp(struct msc_a *msc_a, struct gsm_trans *cc_trans)
{
	struct call_leg *cl;
	struct rtp_stream *rtp_to_ran;

	cl = msc_a_ensure_call_leg(msc_a, cc_trans);
	if (!cl)
		return -EINVAL;
	rtp_to_ran = cl->rtp[RTP_TO_RAN];

	if (call_leg_local_ip(cl, RTP_TO_CN)) {
		/* Already has an RTP address and port towards the CN, continue right away. */
		return osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, cl->rtp[RTP_TO_CN]);
	}

	/* No CN RTP address available yet, ask the MGW to create one.
	 * Set a codec to be used: if Assignment on the RAN side is already done, take the same codec as the RTP_TO_RAN.
	 * If no RAN side RTP is established, try to guess a preliminary codec from SDP -- before Assignment, picking a
	 * codec from the SDP is more politeness/avoiding confusion than necessity. The actual codec to be used would be
	 * determined later. If no codec could be determined, pass none for the time being. */
	return call_leg_ensure_ci(cl, RTP_TO_CN, cc_trans->call_id, cc_trans,
				  rtp_to_ran->codecs_known ? &rtp_to_ran->codecs : NULL, NULL);
}

/* The MGW has given us a local IP address for the RAN side. Ready to start the Assignment of a voice channel. */
void msc_a_tx_assignment_cmd(struct msc_a *msc_a)
{
	struct ran_msg msg;
	struct gsm_trans *cc_trans = msc_a->cc.active_trans;
	struct gsm0808_channel_type channel_type;

	if (!cc_trans) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "No CC transaction active\n");
		call_leg_release(msc_a->cc.call_leg);
		return;
	}

	trans_cc_filter_run(cc_trans);
	LOG_TRANS(cc_trans, LOGL_DEBUG, "Sending Assignment Command\n");

	switch (cc_trans->bearer_cap.transfer) {
	case GSM48_BCAP_ITCAP_SPEECH:
		if (!cc_trans->cc.local.audio_codecs.count) {
			LOG_TRANS(cc_trans, LOGL_ERROR, "Assignment not possible, no matching codec: %s\n",
				  codec_filter_to_str(&cc_trans->cc.codecs, &cc_trans->cc.local, &cc_trans->cc.remote));
			call_leg_release(msc_a->cc.call_leg);
			return;
		}

		/* Compose 48.008 Channel Type from the current set of codecs
		 * determined from both local and remote codec capabilities. */
		if (sdp_audio_codecs_to_gsm0808_channel_type(&channel_type, &cc_trans->cc.local.audio_codecs)) {
			LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot compose Channel Type (Permitted Speech) from codecs: %s\n",
				  codec_filter_to_str(&cc_trans->cc.codecs, &cc_trans->cc.local, &cc_trans->cc.remote));
			trans_free(cc_trans);
			return;
		}
		break;
	case GSM48_BCAP_ITCAP_3k1_AUDIO:
	case GSM48_BCAP_ITCAP_FAX_G3:
	case GSM48_BCAP_ITCAP_UNR_DIG_INF:
		if (!cc_trans->cc.local.bearer_services.count) {
			LOG_TRANS(cc_trans, LOGL_ERROR, "Assignment not possible, no matching bearer service: %s\n",
				  csd_filter_to_str(&cc_trans->cc.csd, &cc_trans->cc.local, &cc_trans->cc.remote));
			call_leg_release(msc_a->cc.call_leg);
			return;
		}

		/* Compose 48.008 Channel Type from the current set of bearer
		 * services determined from local and remote capabilities. */
		if (csd_bs_list_to_gsm0808_channel_type(&channel_type, &cc_trans->cc.local.bearer_services)) {
			LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot compose channel type from: %s\n",
				  csd_filter_to_str(&cc_trans->cc.csd, &cc_trans->cc.local, &cc_trans->cc.remote));
			return;
		}
		break;
	default:
		LOG_TRANS(cc_trans, LOGL_ERROR, "Assignment not possible for information transfer capability %d\n",
			  cc_trans->bearer_cap.transfer);
		call_leg_release(msc_a->cc.call_leg);
		return;
	}

	/* The RAN side RTP address is known, so the voice/CSD Assignment can commence. */
	msg = (struct ran_msg){
		.msg_type = RAN_MSG_ASSIGNMENT_COMMAND,
		.assignment_command = {
			.cn_rtp = &msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local,
			.channel_type = &channel_type,
			.osmux_present = msc_a->cc.call_leg->rtp[RTP_TO_RAN]->use_osmux,
			.osmux_cid = msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local_osmux_cid,
			.call_id_present = true,
			.call_id = cc_trans->call_id,
			.lcls = cc_trans->cc.lcls,
		},
	};
	if (msc_a_ran_down(msc_a, MSC_ROLE_I, &msg)) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot send Assignment\n");
		trans_free(cc_trans);
		return;
	}
}

static struct gsm_trans *find_waiting_call(struct msc_a *msc_a)
{
	struct gsm_trans *trans;
	struct gsm_network *net = msc_a_net(msc_a);

	llist_for_each_entry(trans, &net->trans_list, entry) {
		if (trans->msc_a != msc_a)
			continue;
		if (trans->type != TRANS_CC)
			continue;
		if (trans->msc_a->cc.active_trans == trans)
			continue;
		return trans;
	}
	return NULL;
}

static void msc_a_cleanup_rtp_streams(struct msc_a *msc_a, uint32_t event, void *data)
{
	switch (event) {

	case MSC_EV_CALL_LEG_TERM:
		msc_a->cc.call_leg = NULL;
		if (msc_a->cc.mncc_forwarding_to_remote_ran)
			msc_a->cc.mncc_forwarding_to_remote_ran->rtps = NULL;

		if (msc_a->ho.new_cell.mncc_forwarding_to_remote_ran)
			msc_a->ho.new_cell.mncc_forwarding_to_remote_ran->rtps = NULL;
		return;

	case MSC_MNCC_EV_CALL_ENDED:
		msc_a->cc.mncc_forwarding_to_remote_ran = NULL;
		return;

	default:
		return;
	}
}

static void msc_a_fsm_communicating(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct msc_a *msc_a = fi->priv;
	struct rtp_stream *rtps;
	struct gsm_trans *waiting_trans;
	struct an_apdu *an_apdu;

	msc_a_cleanup_rtp_streams(msc_a, event, data);

	switch (event) {
	case MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST:
	case MSC_A_EV_FROM_I_PREPARE_SUBSEQUENT_HANDOVER_REQUEST:
	case MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST:
		an_apdu = data;
		msc_a_ran_dec(msc_a, an_apdu, MSC_ROLE_I);
		return;

	case MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE:
	case MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE:
	case MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST:
	case MSC_A_EV_FROM_T_SEND_END_SIGNAL_REQUEST:
		an_apdu = data;
		msc_a_ran_dec(msc_a, an_apdu, MSC_ROLE_T);
		return;

	case MSC_A_EV_TRANSACTION_ACCEPTED:
		/* no-op */
		return;

	case MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE:
		rtps = data;
		if (!rtps) {
			LOG_MSC_A(msc_a, LOGL_ERROR, "Invalid data for %s\n", osmo_fsm_event_name(fi->fsm, event));
			return;
		}
		if (!msc_a->cc.call_leg) {
			LOG_MSC_A(msc_a, LOGL_ERROR, "No call leg active\n");
			return;
		}
		if (!osmo_sockaddr_str_is_nonzero(&rtps->local)) {
			LOG_MSC_A(msc_a, LOGL_ERROR, "Invalid RTP address received from MGW: " OSMO_SOCKADDR_STR_FMT "\n",
				 OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local));
			call_leg_release(msc_a->cc.call_leg);
			return;
		}
		LOG_MSC_A(msc_a, LOGL_DEBUG,
			  "MGW endpoint's RTP address available for the CI %s: " OSMO_SOCKADDR_STR_FMT " (osmux=%s:%d)\n",
			  rtp_direction_name(rtps->dir), OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local),
			  rtps->use_osmux ? "yes" : "no", rtps->local_osmux_cid);
		switch (rtps->dir) {
		case RTP_TO_RAN:
			msc_a_tx_assignment_cmd(msc_a);
			return;
		case RTP_TO_CN:
			cc_on_cn_local_rtp_port_known(rtps->for_trans);
			return;
		default:
			LOG_MSC_A(msc_a, LOGL_ERROR, "Invalid data for %s\n", osmo_fsm_event_name(fi->fsm, event));
			return;
		}

	case MSC_EV_CALL_LEG_RTP_COMPLETE:
		/* Nothing to do. */
		return;

	case MSC_MNCC_EV_CALL_ENDED:
		/* Cleaned up above */
		return;

	case MSC_EV_CALL_LEG_TERM:
		/* RTP streams cleaned up above */

		msc_a_get(msc_a, __func__);
		if (msc_a->cc.active_trans)
			trans_free(msc_a->cc.active_trans);

		/* If there is another call still waiting to be activated, this is the time when the mgcp_ctx is
		 * available again and the other call can start assigning. */
		waiting_trans = find_waiting_call(msc_a);
		if (waiting_trans) {
			LOG_MSC_A(msc_a, LOGL_DEBUG, "(ti %02x) Call waiting: starting Assignment\n",
				  waiting_trans->transaction_id);
			msc_a_try_call_assignment(waiting_trans);
		}
		msc_a_put(msc_a, __func__);
		return;

	case MSC_A_EV_HANDOVER_REQUIRED:
		msc_ho_start(msc_a, (struct ran_handover_required*)data);
		return;

	case MSC_A_EV_HANDOVER_END:
		/* Termination event of the msc_ho_fsm. No action needed, it's all done in the msc_ho_fsm cleanup. This
		 * event only exists because osmo_fsm_inst_alloc_child() requires a parent term event; and maybe
		 * interesting for logging. */
		return;

	case MSC_A_EV_MO_CLOSE:
	case MSC_A_EV_CN_CLOSE:
	case MSC_A_EV_UNUSED:
		msc_a_state_chg(msc_a, MSC_A_ST_RELEASING);
		return;

	default:
		OSMO_ASSERT(false);
	}
}

static int msc_a_fsm_timer_cb(struct osmo_fsm_inst *fi)
{
	struct msc_a *msc_a = fi->priv;
	if (msc_a_in_release(msc_a)) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "Timeout while releasing, discarding right now\n");
		msc_a_put_all(msc_a, MSC_A_USE_WAIT_CLEAR_COMPLETE);
		msc_a_state_chg(msc_a, MSC_A_ST_RELEASED);
	} else {
		enum gsm48_reject_value cause = GSM48_REJECT_CONGESTION;
		osmo_fsm_inst_dispatch(fi, MSC_A_EV_CN_CLOSE, &cause);
	}
	return 0;
}

static void msc_a_fsm_releasing_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct msc_a *msc_a = fi->priv;
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);
	int i;
	char buf[128];
	const char * const use_counts_to_cancel[] = {
		MSC_A_USE_LOCATION_UPDATING,
		MSC_A_USE_CM_SERVICE_CC,
		MSC_A_USE_CM_SERVICE_SMS,
		MSC_A_USE_CM_SERVICE_SS,
		MSC_A_USE_CM_SERVICE_GCC,
		MSC_A_USE_CM_SERVICE_BCC,
		MSC_A_USE_PAGING_RESPONSE,
	};

	LOG_MSC_A(msc_a, LOGL_DEBUG, "Releasing: msc_a use is %s\n",
		  osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count));

	if (vsub) {
		vlr_subscr_get(vsub, __func__);

		/* Cancel all VLR FSMs, if any */
		vlr_subscr_cancel_attach_fsm(vsub, OSMO_FSM_TERM_ERROR, GSM48_REJECT_CONGESTION);

		/* The subscriber has no active connection anymore.
		 * Restart the periodic Location Update expiry timer for this subscriber. */
		vlr_subscr_enable_expire_lu(vsub);
	}

	/* If we're closing in a middle of a trans, we need to clean up */
	trans_conn_closed(msc_a);

	call_leg_release(msc_a->cc.call_leg);

	/* Cancel use counts for pending CM Service / Paging */
	for (i = 0; i < ARRAY_SIZE(use_counts_to_cancel); i++) {
		const char *use = use_counts_to_cancel[i];
		int32_t count = osmo_use_count_by(&msc_a->use_count, use);
		if (!count)
			continue;
		LOG_MSC_A(msc_a, LOGL_DEBUG, "Releasing: canceling still pending use: %s (%d)\n", use, count);
		osmo_use_count_get_put(&msc_a->use_count, use, -count);
	}

	if (msc_a->c.ran->type == OSMO_RAT_EUTRAN_SGS) {
		sgs_iface_tx_release(vsub);
		/* In SGsAP there is no confirmation of a release. */
		msc_a_state_chg(msc_a, MSC_A_ST_RELEASED);
	} else {
		struct ran_msg msg = {
			.msg_type = RAN_MSG_CLEAR_COMMAND,
			.clear_command = {
				/* "Call Control" is the only cause code listed in 3GPP TS 48.008 3.2.1.21 CLEAR COMMAND
				 * that qualifies for a normal release situation. (OS#4664) */
				.gsm0808_cause = GSM0808_CAUSE_CALL_CONTROL,
				.csfb_ind = (vsub && vsub->sgs_fsm->state == SGS_UE_ST_ASSOCIATED),
			},
		};
		msc_a_get(msc_a, MSC_A_USE_WAIT_CLEAR_COMPLETE);
		msc_a_ran_down(msc_a, MSC_ROLE_I, &msg);

		/* The connection is cleared. The MS will now go back to 4G,
		   Switch the RAN type back to SGS. */
		if (vsub && vsub->sgs_fsm->state == SGS_UE_ST_ASSOCIATED)
			vsub->cs.attached_via_ran = OSMO_RAT_EUTRAN_SGS;
	}

	if (vsub)
		vlr_subscr_put(vsub, __func__);
}

static void msc_a_fsm_releasing(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct msc_a *msc_a = fi->priv;

	msc_a_cleanup_rtp_streams(msc_a, event, data);

	switch (event) {
	case MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST:
	case MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST:
		msc_a_ran_dec(msc_a, data, MSC_ROLE_I);
		return;

	case MSC_A_EV_MO_CLOSE:
	case MSC_A_EV_CN_CLOSE:
	case MSC_A_EV_UNUSED:
		/* Already releasing */
		return;

	case MSC_EV_CALL_LEG_TERM:
	case MSC_MNCC_EV_CALL_ENDED:
		/* RTP streams cleaned up above */
		return;

	case MSC_A_EV_HANDOVER_END:
		/* msc_ho_fsm does cleanup. */
		return;

	default:
		OSMO_ASSERT(false);
	}
}


static void msc_a_fsm_released_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct msc_a *msc_a = msc_a_fi_priv(fi);
	char buf[128];
	LOG_MSC_A(msc_a, LOGL_DEBUG, "Released: msc_a use is %s\n",
		  osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count));
	if (osmo_use_count_total(&msc_a->use_count) == 0)
		osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, fi);
}

static void msc_a_fsm_released(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	if (event == MSC_A_EV_UNUSED)
		osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, fi);
}

void msc_a_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
{
	struct msc_a *msc_a = msc_a_fi_priv(fi);
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);

	trans_conn_closed(msc_a);

	if (msc_a_fsm_has_active_transactions(fi))
		LOG_MSC_A(msc_a, LOGL_ERROR, "Deallocating active transactions failed\n");

	LOG_MSC_A_CAT(msc_a, DREF, LOGL_DEBUG, "max total use count was %d\n", msc_a->max_total_use_count);

	/* Invalidate the active conn in VLR subscriber state, if any. */
	if (vsub && vsub->msc_conn_ref == msc_a)
		vsub->msc_conn_ref = NULL;
}

const struct value_string msc_a_fsm_event_names[] = {
	OSMO_VALUE_STRING(MSC_REMOTE_EV_RX_GSUP),
	OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE),
	OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_COMPLETE),
	OSMO_VALUE_STRING(MSC_EV_CALL_LEG_TERM),
	OSMO_VALUE_STRING(MSC_MNCC_EV_NEED_LOCAL_RTP),
	OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_PROCEEDING),
	OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_COMPLETE),
	OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_ENDED),
	OSMO_VALUE_STRING(MSC_A_EV_FROM_I_COMPLETE_LAYER_3),
	OSMO_VALUE_STRING(MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST),
	OSMO_VALUE_STRING(MSC_A_EV_FROM_I_PREPARE_SUBSEQUENT_HANDOVER_REQUEST),
	OSMO_VALUE_STRING(MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST),
	OSMO_VALUE_STRING(MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST),
	OSMO_VALUE_STRING(MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE),
	OSMO_VALUE_STRING(MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE),
	OSMO_VALUE_STRING(MSC_A_EV_FROM_T_SEND_END_SIGNAL_REQUEST),
	OSMO_VALUE_STRING(MSC_A_EV_COMPLETE_LAYER_3_OK),
	OSMO_VALUE_STRING(MSC_A_EV_CLASSMARK_UPDATE),
	OSMO_VALUE_STRING(MSC_A_EV_AUTHENTICATED),
	OSMO_VALUE_STRING(MSC_A_EV_TRANSACTION_ACCEPTED),
	OSMO_VALUE_STRING(MSC_A_EV_CN_CLOSE),
	OSMO_VALUE_STRING(MSC_A_EV_MO_CLOSE),
	OSMO_VALUE_STRING(MSC_A_EV_UNUSED),
	OSMO_VALUE_STRING(MSC_A_EV_HANDOVER_REQUIRED),
	OSMO_VALUE_STRING(MSC_A_EV_HANDOVER_END),
	{}
};

#define S(x)	(1 << (x))

static const struct osmo_fsm_state msc_a_fsm_states[] = {
	[MSC_A_ST_VALIDATE_L3] = {
		.name = OSMO_STRINGIFY(MSC_A_ST_VALIDATE_L3),
		.in_event_mask = 0
			| S(MSC_A_EV_FROM_I_COMPLETE_LAYER_3)
			| S(MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST)
			| S(MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST)
			| S(MSC_A_EV_COMPLETE_LAYER_3_OK)
			| S(MSC_A_EV_MO_CLOSE)
			| S(MSC_A_EV_CN_CLOSE)
			| S(MSC_A_EV_UNUSED)
			,
		.out_state_mask = 0
			| S(MSC_A_ST_VALIDATE_L3)
			| S(MSC_A_ST_AUTH_CIPH)
			| S(MSC_A_ST_RELEASING)
			,
		.action = msc_a_fsm_validate_l3,
	},
	[MSC_A_ST_AUTH_CIPH] = {
		.name = OSMO_STRINGIFY(MSC_A_ST_AUTH_CIPH),
		.in_event_mask = 0
			| S(MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST)
			| S(MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST)
			| S(MSC_A_EV_AUTHENTICATED)
			| S(MSC_A_EV_MO_CLOSE)
			| S(MSC_A_EV_CN_CLOSE)
			| S(MSC_A_EV_UNUSED)
			,
		.out_state_mask = 0
			| S(MSC_A_ST_WAIT_CLASSMARK_UPDATE)
			| S(MSC_A_ST_AUTHENTICATED)
			| S(MSC_A_ST_RELEASING)
			,
		.action = msc_a_fsm_auth_ciph,
	},
	[MSC_A_ST_WAIT_CLASSMARK_UPDATE] = {
		.name = OSMO_STRINGIFY(MSC_A_ST_WAIT_CLASSMARK_UPDATE),
		.in_event_mask = 0
			| S(MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST)
			| S(MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST)
			| S(MSC_A_EV_CLASSMARK_UPDATE)
			| S(MSC_A_EV_MO_CLOSE)
			| S(MSC_A_EV_CN_CLOSE)
			,
		.out_state_mask = 0
			| S(MSC_A_ST_AUTH_CIPH)
			| S(MSC_A_ST_RELEASING)
			,
		.action = msc_a_fsm_wait_classmark_update,
	},
	[MSC_A_ST_AUTHENTICATED] = {
		.name = OSMO_STRINGIFY(MSC_A_ST_AUTHENTICATED),
		/* allow everything to release for any odd behavior */
		.in_event_mask = 0
			| S(MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST)
			| S(MSC_A_EV_FROM_I_PREPARE_SUBSEQUENT_HANDOVER_REQUEST)
			| S(MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST)
			| S(MSC_A_EV_TRANSACTION_ACCEPTED)
			| S(MSC_A_EV_MO_CLOSE)
			| S(MSC_A_EV_CN_CLOSE)
			| S(MSC_A_EV_UNUSED)
			,
		.out_state_mask = 0
			| S(MSC_A_ST_RELEASING)
			| S(MSC_A_ST_COMMUNICATING)
			,
		.onenter = msc_a_fsm_authenticated_enter,
		.action = msc_a_fsm_authenticated,
	},
	[MSC_A_ST_COMMUNICATING] = {
		.name = OSMO_STRINGIFY(MSC_A_ST_COMMUNICATING),
		/* allow everything to release for any odd behavior */
		.in_event_mask = 0
			| S(MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST)
			| S(MSC_A_EV_FROM_I_PREPARE_SUBSEQUENT_HANDOVER_REQUEST)
			| S(MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST)
			| S(MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE)
			| S(MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE)
			| S(MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST)
			| S(MSC_A_EV_FROM_T_SEND_END_SIGNAL_REQUEST)
			| S(MSC_A_EV_TRANSACTION_ACCEPTED)
			| S(MSC_A_EV_MO_CLOSE)
			| S(MSC_A_EV_CN_CLOSE)
			| S(MSC_A_EV_UNUSED)
			| S(MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE)
			| S(MSC_EV_CALL_LEG_RTP_COMPLETE)
			| S(MSC_EV_CALL_LEG_TERM)
			| S(MSC_MNCC_EV_CALL_ENDED)
			| S(MSC_A_EV_HANDOVER_REQUIRED)
			| S(MSC_A_EV_HANDOVER_END)
			,
		.out_state_mask = 0
			| S(MSC_A_ST_RELEASING)
			,
		.action = msc_a_fsm_communicating,
	},
	[MSC_A_ST_RELEASING] = {
		.name = OSMO_STRINGIFY(MSC_A_ST_RELEASING),
		.in_event_mask = 0
			| S(MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST)
			| S(MSC_A_EV_FROM_I_SEND_END_SIGNAL_REQUEST)
			| S(MSC_A_EV_UNUSED)
			| S(MSC_EV_CALL_LEG_TERM)
			| S(MSC_MNCC_EV_CALL_ENDED)
			| S(MSC_A_EV_HANDOVER_END)
			| S(MSC_A_EV_CN_CLOSE)
			,
		.out_state_mask = 0
			| S(MSC_A_ST_RELEASED)
			,
		.onenter = msc_a_fsm_releasing_onenter,
		.action = msc_a_fsm_releasing,
	},
	[MSC_A_ST_RELEASED] = {
		.name = OSMO_STRINGIFY(MSC_A_ST_RELEASED),
		.in_event_mask = 0
			| S(MSC_A_EV_UNUSED)
			,
		.onenter = msc_a_fsm_released_onenter,
		.action = msc_a_fsm_released,
	},
};

static struct osmo_fsm msc_a_fsm = {
	.name = "msc_a",
	.states = msc_a_fsm_states,
	.num_states = ARRAY_SIZE(msc_a_fsm_states),
	.log_subsys = DMSC,
	.event_names = msc_a_fsm_event_names,
	.timer_cb = msc_a_fsm_timer_cb,
	.cleanup = msc_a_fsm_cleanup,
};

static __attribute__((constructor)) void msc_a_fsm_init()
{
	OSMO_ASSERT(osmo_fsm_register(&msc_a_fsm) == 0);
}

static int msc_a_use_cb(struct osmo_use_count_entry *e, int32_t old_use_count, const char *file, int line)
{
	struct msc_a *msc_a = e->use_count->talloc_object;
	char buf[128];
	int32_t total;
	int level;

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

	total = osmo_use_count_total(&msc_a->use_count);

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

	LOG_MSC_A_CAT_SRC(msc_a, DREF, level, file, line, "%s %s: now used by %s\n",
			  (e->count - old_use_count) > 0? "+" : "-", e->use,
			  osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count));

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

	msc_a->max_total_use_count = OSMO_MAX(msc_a->max_total_use_count, total);

	if (total == 0)
		osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_UNUSED, NULL);
	return 0;
}

struct msc_a *msc_a_alloc(struct msub *msub, struct ran_infra *ran)
{
	struct msc_a *msc_a = msub_role_alloc(msub, MSC_ROLE_A, &msc_a_fsm, struct msc_a, ran);
	msc_a->use_count = (struct osmo_use_count){
		.talloc_object = msc_a,
		.use_cb = msc_a_use_cb,
	};
	osmo_use_count_make_static_entries(&msc_a->use_count, msc_a->use_count_buf, ARRAY_SIZE(msc_a->use_count_buf));
	/* Start timeout for first state */
	msc_a_state_chg_always(msc_a, MSC_A_ST_VALIDATE_L3);
	return msc_a;
}

bool msc_a_is_establishing_auth_ciph(const struct msc_a *msc_a)
{
	if (!msc_a || !msc_a->c.fi)
		return false;
	return msc_a->c.fi->state == MSC_A_ST_AUTH_CIPH;
}

const struct value_string complete_layer3_type_names[] = {
	{ COMPLETE_LAYER3_NONE, "NONE" },
	{ COMPLETE_LAYER3_LU, "LU" },
	{ COMPLETE_LAYER3_CM_SERVICE_REQ, "CM_SERVICE_REQ" },
	{ COMPLETE_LAYER3_PAGING_RESP, "PAGING_RESP" },
	{ COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ, "CM_RE_ESTABLISH_REQ" },
	{ 0, NULL }
};

#define _msc_a_update_id(MSC_A, FMT, ARGS ...) \
	do { \
		if (osmo_fsm_inst_update_id_f(msc_a->c.fi, FMT ":%s:%s", \
					      ## ARGS, \
					      msub_ran_conn_name(msc_a->c.msub), \
					      complete_layer3_type_name(msc_a->complete_layer3_type)) \
		    == 0) { \
			struct vlr_subscr *_vsub = msc_a_vsub(MSC_A); \
			if (_vsub) { \
				if (_vsub->lu_fsm) \
					osmo_fsm_inst_update_id(_vsub->lu_fsm, (MSC_A)->c.fi->id); \
				if (_vsub->auth_fsm) \
					osmo_fsm_inst_update_id(_vsub->auth_fsm, (MSC_A)->c.fi->id); \
				if (_vsub->proc_arq_fsm) \
					osmo_fsm_inst_update_id(_vsub->proc_arq_fsm, (MSC_A)->c.fi->id); \
			} \
			LOG_MSC_A(MSC_A, LOGL_DEBUG, "Updated ID\n"); \
		} \
		/* otherwise osmo_fsm_inst_update_id_f() will log an error. */ \
	} while (0)


/* Compose an ID almost like gsm48_mi_to_string(), but print the MI type along, and print a TMSI as hex. */
void msc_a_update_id_from_mi(struct msc_a *msc_a, const struct osmo_mobile_identity *mi)
{
	_msc_a_update_id(msc_a, "%s", osmo_mobile_identity_to_str_c(OTC_SELECT, mi));
}

/* Update msc_a->fi id string from current msc_a->vsub and msc_a->complete_layer3_type. */
void msc_a_update_id(struct msc_a *msc_a)
{
	_msc_a_update_id(msc_a, "%s", vlr_subscr_name(msc_a_vsub(msc_a)));
}

/* Iterate all msc_a instances that are relevant for this subscriber, and update FSM ID strings for all of the FSM
 * instances. */
void msc_a_update_id_for_vsub(struct vlr_subscr *for_vsub)
{
	struct msub *msub;
	llist_for_each_entry(msub, &msub_list, entry) {
		struct vlr_subscr *vsub = msub_vsub(msub);
		if (vsub != for_vsub)
			continue;
		msc_a_update_id(msub_msc_a(msub));
	}
}

static bool msg_is_initially_permitted(const struct gsm48_hdr *hdr)
{
	uint8_t pdisc = gsm48_hdr_pdisc(hdr);
	uint8_t msg_type = gsm48_hdr_msg_type(hdr);

	switch (pdisc) {
	case GSM48_PDISC_MM:
		switch (msg_type) {
		case GSM48_MT_MM_LOC_UPD_REQUEST:
		case GSM48_MT_MM_CM_SERV_REQ:
		case GSM48_MT_MM_CM_REEST_REQ:
		case GSM48_MT_MM_AUTH_RESP:
		case GSM48_MT_MM_AUTH_FAIL:
		case GSM48_MT_MM_ID_RESP:
		case GSM48_MT_MM_TMSI_REALL_COMPL:
		case GSM48_MT_MM_IMSI_DETACH_IND:
			return true;
		default:
			break;
		}
		break;
	case GSM48_PDISC_RR:
		switch (msg_type) {
		/* GSM48_MT_RR_CIPH_M_COMPL is actually handled in bssmap_rx_ciph_compl() and gets redirected in the
		 * BSSAP layer to ran_conn_cipher_mode_compl() (before this here is reached) */
		case GSM48_MT_RR_PAG_RESP:
		case GSM48_MT_RR_CIPH_M_COMPL:
			return true;
		default:
			break;
		}
		break;
	default:
		break;
	}

	return false;
}

/* Main entry point for GSM 04.08/44.008 Layer 3 data (e.g. from the BSC). */
int msc_a_up_l3(struct msc_a *msc_a, struct msgb *msg)
{
	struct gsm48_hdr *gh;
	uint8_t pdisc;
	int rc;
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);
	int is_r99;

	OSMO_ASSERT(msg->l3h);
	OSMO_ASSERT(msg);

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

	LOG_MSC_A_CAT(msc_a, DRLL, LOGL_DEBUG, "Dispatching 04.08 message: %s %s\n",
		      gsm48_pdisc_name(pdisc), gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh)));

	/* To evaluate the 3GPP TS 24.007 Duplicate Detection, we need Classmark information on whether the MS is R99
	 * capable. If the subscriber is already actively connected, the Classmark information is stored with the
	 * vlr_subscr. Otherwise, this *must* be a Complete Layer 3 with Classmark info. */
	if (vsub)
		is_r99 = osmo_gsm48_classmark_is_r99(&vsub->classmark) ? 1 : 0;
	else
		is_r99 = compl_l3_msg_is_r99(msg);

	if (is_r99 < 0) {
		LOG_MSC_A(msc_a, LOGL_ERROR,
			  "No Classmark Information, dropping non-Complete-Layer3 message: %s\n",
			  gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh)));
		return -EACCES;
	}

	if (is_r99 >= 0
	    && ran_dec_dtap_undup_is_duplicate(msc_a->c.fi, msc_a->n_sd_next, is_r99 ? true : false, msg)) {
		LOG_MSC_A(msc_a, LOGL_DEBUG, "Dropping duplicate message"
			  " (3GPP TS 24.007 11.2.3.2 Message Type Octet / Duplicate Detection)\n");
		return 0;
	}

	if (!msc_a_is_accepted(msc_a)
	    && !msg_is_initially_permitted(gh)) {
		LOG_MSC_A(msc_a, LOGL_ERROR,
			  "Message not permitted for initial conn: %s\n",
			  gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh)));
		return -EACCES;
	}

	if (vsub && vsub->cs.attached_via_ran != msc_a->c.ran->type) {
		LOG_MSC_A(msc_a, LOGL_ERROR,
			  "Illegal situation: RAN type mismatch:"
			  " attached via %s, received message via %s\n",
			  osmo_rat_type_name(vsub->cs.attached_via_ran),
			  osmo_rat_type_name(msc_a->c.ran->type));
		return -EACCES;
	}

#if 0
	if (silent_call_reroute(conn, msg))
		return silent_call_rx(conn, msg);
#endif

	switch (pdisc) {
	case GSM48_PDISC_GROUP_CC:
	case GSM48_PDISC_BCAST_CC:
		rc = gsm44068_rcv_bcc_gcc(msc_a, NULL, msg);
		break;
	case GSM48_PDISC_CC:
		rc = gsm0408_rcv_cc(msc_a, msg);
		break;
	case GSM48_PDISC_MM:
		rc = gsm0408_rcv_mm(msc_a, msg);
		break;
	case GSM48_PDISC_RR:
		rc = gsm0408_rcv_rr(msc_a, msg);
		break;
	case GSM48_PDISC_SMS:
		rc = gsm0411_rcv_sms(msc_a, msg);
		break;
	case GSM48_PDISC_MM_GPRS:
	case GSM48_PDISC_SM_GPRS:
		LOG_MSC_A_CAT(msc_a, DRLL, LOGL_NOTICE, "Unimplemented "
			"GSM 04.08 discriminator 0x%02x\n", pdisc);
		rc = -ENOTSUP;
		break;
	case GSM48_PDISC_NC_SS:
		rc = gsm0911_rcv_nc_ss(msc_a, msg);
		break;
	case GSM48_PDISC_TEST:
		rc = gsm0414_rcv_test(msc_a, msg);
		break;
	default:
		LOG_MSC_A_CAT(msc_a, DRLL, LOGL_NOTICE, "Unknown "
			"GSM 04.08 discriminator 0x%02x\n", pdisc);
		rc = -EINVAL;
		break;
	}

	return rc;
}

static void msc_a_up_call_assignment_complete(struct msc_a *msc_a, const struct ran_msg *ac)
{
	struct gsm_trans *cc_trans = msc_a->cc.active_trans, *gcc_trans;
	struct rtp_stream *rtps_to_ran = msc_a->cc.call_leg ? msc_a->cc.call_leg->rtp[RTP_TO_RAN] : NULL;
	const struct gsm0808_speech_codec *codec_if_known = ac->assignment_complete.codec_present ?
							    &ac->assignment_complete.codec : NULL;

	/* For a voice group call, handling is performed by VGCS FSM */
	gcc_trans = trans_find_by_type(msc_a, TRANS_GCC);
	if (gcc_trans) {
		vgcs_vbs_caller_assign_cpl(gcc_trans);
		return;
	}
	gcc_trans = trans_find_by_type(msc_a, TRANS_BCC);
	if (gcc_trans) {
		vgcs_vbs_caller_assign_cpl(gcc_trans);
		return;
	}

	if (!rtps_to_ran) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "Rx Assignment Complete, but no RTP stream is set up\n");
		return;
	}
	if (!cc_trans) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "Rx Assignment Complete, but no CC transaction is active\n");
		return;
	}

	if (rtps_to_ran->use_osmux != ac->assignment_complete.osmux_present) {
		LOG_MSC_A_CAT(msc_a, DCC, LOGL_ERROR, "Osmux usage ass request and complete don't match: %d vs %d\n",
			 rtps_to_ran->use_osmux, ac->assignment_complete.osmux_present);
		call_leg_release(msc_a->cc.call_leg);
		return;
	}

	if (codec_if_known) {
		const struct codec_mapping *codec_assigned;

		/* Check for unexpected codec with CSD */
		switch (cc_trans->bearer_cap.transfer) {
		case GSM48_BCAP_ITCAP_FAX_G3:
		case GSM48_BCAP_ITCAP_3k1_AUDIO:
		case GSM48_BCAP_ITCAP_UNR_DIG_INF:
			if (codec_if_known->type == GSM0808_SCT_CSD)
				break; /* we're good */
			LOG_TRANS(cc_trans, LOGL_ERROR, "Unexpected codec in Assignment Complete for CSD: %s\n",
				  gsm0808_speech_codec_type_name(codec_if_known->type));
			call_leg_release(msc_a->cc.call_leg);
			return;
		default:
			break;
		}

		/* For 2G:
		 * - The Assignment Complete has returned a specific codec (e.g. FR3 for AMR FR).
		 * - Set this codec at the MGW endpoint facing the RAN.
		 * - Also set this codec at the MGW endpoint facing the CN -- we require an exact match on both call
		 *   legs.
		 *   - TODO: be aware of transcoding that the MGW is capable of, e.g. AMR octet-aligned to AMR
		 *     bandwidth-efficient...
		 *
		 * For 3G:
		 * - ran_infra->force_mgw_codecs_to_ran sets VND.3GPP.IUFP as single codec at the MGW towards RAN.
		 * - ran_msg_iu.c always returns FR3 (AMR FR) for the assigned codec. Set that at the MGW towards CN.
		 * - So the MGW decapsulates IuUP <-> AMR
		 */
		codec_assigned = codec_mapping_by_gsm0808_speech_codec_type(codec_if_known->type);
		/* TODO: use codec_mapping_by_gsm0808_speech_codec() to also match on codec_if_known->cfg */
		if (!codec_assigned) {
			LOG_TRANS(cc_trans, LOGL_ERROR, "Unknown codec in Assignment Complete: %s\n",
				  gsm0808_speech_codec_type_name(codec_if_known->type));
			call_leg_release(msc_a->cc.call_leg);
			return;
		}

		/* Update RAN-side endpoint CI from Assignment result -- unless it is forced by the ran_infra, in which
		 * case it remains unchanged as passed to the earlier call of call_leg_ensure_ci(). */
		if (msc_a->c.ran->force_mgw_codecs_to_ran.count == 0)
			rtp_stream_set_one_codec(rtps_to_ran, &codec_assigned->sdp);

		/* Update codec filter with Assignment result, for the CN side */
		cc_trans->cc.codecs.assignment = codec_assigned->sdp;
	} else {
		/* No codec passed in Assignment Complete, set 'codecs.assignment' to none. */
		cc_trans->cc.codecs.assignment = (struct sdp_audio_codec){};
		LOG_TRANS(cc_trans, LOGL_INFO, "Assignment Complete without voice codec\n");
	}

	rtp_stream_set_remote_addr(rtps_to_ran, &ac->assignment_complete.remote_rtp);
	if (rtps_to_ran->use_osmux)
		rtp_stream_set_remote_osmux_cid(rtps_to_ran,
						ac->assignment_complete.osmux_cid);
	rtp_stream_commit(rtps_to_ran);

	/* Remember the Codec List (BSS Supported) */
	if (ac->assignment_complete.codec_list_bss_supported)
		codec_filter_set_bss(&cc_trans->cc.codecs, ac->assignment_complete.codec_list_bss_supported);

	trans_cc_filter_run(cc_trans);
	LOG_TRANS(cc_trans, LOGL_INFO, "Assignment Complete: RAN: %s, CN: %s\n",
		  sdp_audio_codecs_to_str(&rtps_to_ran->codecs),
		  sdp_audio_codecs_to_str(&cc_trans->cc.local.audio_codecs));

	if (cc_on_assignment_done(cc_trans)) {
		/* If an error occurred, it was logged in cc_assignment_done() */
		call_leg_release(msc_a->cc.call_leg);
		return;
	}
}

static void msc_a_up_call_assignment_failure(struct msc_a *msc_a, const struct ran_msg *af)
{
	struct gsm_trans *trans;

	/* For a normal voice call, there will be an rtp_stream FSM. */
	if (msc_a->cc.call_leg && msc_a->cc.call_leg->rtp[RTP_TO_RAN]) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "Assignment Failure, releasing call\n");
		rtp_stream_release(msc_a->cc.call_leg->rtp[RTP_TO_RAN]);
		return;
	}

	/* For a voice group call, release is performed by VGCS FSM */
	trans = trans_find_by_type(msc_a, TRANS_GCC);
	if (trans) {
		vgcs_vbs_caller_assign_fail(trans);
		return;
	}
	trans = trans_find_by_type(msc_a, TRANS_BCC);
	if (trans) {
		vgcs_vbs_caller_assign_fail(trans);
		return;
	}

	/* Otherwise, a silent call might be active */
	trans = trans_find_by_type(msc_a, TRANS_SILENT_CALL);
	if (trans) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "Assignment Failure, releasing silent call\n");
		trans_free(trans);
		return;
	}

	/* Neither a voice call nor silent call assignment. Assume the worst and detach. */
	msc_a_release_cn(msc_a);
}

static void msc_a_up_classmark_update(struct msc_a *msc_a, const struct osmo_gsm48_classmark *classmark,
				      struct osmo_gsm48_classmark *dst)
{
	if (!dst) {
		struct vlr_subscr *vsub = msc_a_vsub(msc_a);

		if (!vsub)
			dst = &msc_a->temporary_classmark;
		else
			dst = &vsub->classmark;
	}

	LOG_MSC_A(msc_a, LOGL_DEBUG, "A5 capabilities received from Classmark Update: %s\n",
		  osmo_gsm48_classmark_a5_name(classmark));
	osmo_gsm48_classmark_update(dst, classmark);

	/* bump subscr conn FSM in case it is waiting for a Classmark Update */
	if (msc_a->c.fi->state == MSC_A_ST_WAIT_CLASSMARK_UPDATE)
		osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_CLASSMARK_UPDATE, NULL);
}

static void msc_a_up_sapi_n_reject(struct msc_a *msc_a, const struct ran_msg *msg)
{
	int sapi = msg->sapi_n_reject.dlci & 0x7;
	if (sapi == UM_SAPI_SMS)
		gsm411_sapi_n_reject(msc_a);
}

static int msc_a_up_ho(struct msc_a *msc_a, const struct msc_a_ran_dec_data *d, uint32_t ho_fi_event)
{
	if (!msc_a->ho.fi) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "Rx Handover message, but no Handover ongoing: %s\n", d->ran_dec->msg_name);
		return -EINVAL;
	}
	return osmo_fsm_inst_dispatch(msc_a->ho.fi, ho_fi_event, (void*)d);
}

int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
{
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);
	struct gsm_network *net = msc_a_net(msc_a);
	const struct ran_msg *msg = d->ran_dec;
	int rc = -99;

	switch (msg->msg_type) {

	case RAN_MSG_COMPL_L3:
		/* In case the cell_id from Complete Layer 3 Information lacks a PLMN, write the configured PLMN code
		 * into msc_a->via_cell. Then overwrite with those bits obtained from Complete Layer 3 Information. */
		msc_a->via_cell = (struct osmo_cell_global_id){
			.lai.plmn = msc_a_net(msc_a)->plmn,
		};
		gsm0808_cell_id_to_cgi(&msc_a->via_cell, msg->compl_l3.cell_id);

		/* If a codec list was sent along in the RAN_MSG_COMPL_L3, remember it for any upcoming codec
		 * resolution. */
		if (msg->compl_l3.codec_list_bss_supported) {
			msc_a->cc.compl_l3_codec_list_bss_supported = *msg->compl_l3.codec_list_bss_supported;
			if (log_check_level(msc_a->c.ran->log_subsys, LOGL_DEBUG)) {
				struct sdp_audio_codecs ac = {};
				sdp_audio_codecs_from_speech_codec_list(&ac, &msc_a->cc.compl_l3_codec_list_bss_supported);
				LOG_MSC_A(msc_a, LOGL_DEBUG, "Complete Layer 3: Codec List (BSS Supported): %s\n",
					  sdp_audio_codecs_to_str(&ac));
			}
		}

		/* Submit the Complete Layer 3 Information DTAP */
		rc = msc_a_up_l3(msc_a, msg->compl_l3.msg);
		if (!rc) {
			struct ran_conn *conn = msub_ran_conn(msc_a->c.msub);
			if (conn)
				ran_peer_cells_seen_add(conn->ran_peer, msg->compl_l3.cell_id);
		}
		break;

	case RAN_MSG_DTAP:
		rc = msc_a_up_l3(msc_a, msg->dtap);
		break;

	case RAN_MSG_CLEAR_REQUEST:
		rc = osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_MO_CLOSE, NULL);
		break;

	case RAN_MSG_CLEAR_COMPLETE:
		switch (msc_a->c.fi->state) {
		case MSC_A_ST_RELEASING:
			msc_a_put_all(msc_a, MSC_A_USE_WAIT_CLEAR_COMPLETE);
			msc_a_state_chg(msc_a, MSC_A_ST_RELEASED);
			break;
		case MSC_A_ST_RELEASED:
			break;
		default:
			LOG_MSC_A(msc_a, LOGL_ERROR, "Received Clear Complete event, but did not send Clear Command\n");
			msc_a_state_chg(msc_a, MSC_A_ST_RELEASING);
			break;
		}
		rc = 0;
		break;

	case RAN_MSG_CLASSMARK_UPDATE:
		msc_a_up_classmark_update(msc_a, msg->classmark_update.classmark, NULL);
		rc = 0;
		break;

	case RAN_MSG_CIPHER_MODE_COMPLETE:
		/* Remember what Ciphering was negotiated (e.g. for Handover) */
		if (msg->cipher_mode_complete.alg_id) {
			msc_a->geran_encr.alg_id = msg->cipher_mode_complete.alg_id;
			LOG_MSC_A(msc_a, LOGL_DEBUG, "Cipher Mode Complete: chosen encryption algorithm: A5/%u\n",
				  msc_a->geran_encr.alg_id - 1);
		}

		if (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU) {
			int16_t utran_encryption;

			/* utran: ensure chosen ciphering mode is allowed
			 * If the IE is missing (utran_encryption == -1), parse it as no encryption */
			utran_encryption = msg->cipher_mode_complete.utran_encryption;
			if (utran_encryption == -1)
				utran_encryption = 0;
			if ((net->uea_encryption_mask & (1 << utran_encryption)) == 0) {
				/* cipher disallowed */
				LOG_MSC_A(msc_a, LOGL_ERROR, "Cipher Mode Complete: RNC chosen forbidden ciphering UEA%d\n",
					  msg->cipher_mode_complete.utran_encryption);
				vlr_subscr_rx_ciph_res(vsub, VLR_CIPH_REJECT);
				rc = 0;
				break;
			}
		}
		vlr_subscr_rx_ciph_res(vsub, VLR_CIPH_COMPL);
		rc = 0;

		/* Evaluate enclosed L3 message, typically Identity Response (IMEISV) */
		if (msg->cipher_mode_complete.l3_msg) {
			unsigned char *data = (unsigned char*)(msg->cipher_mode_complete.l3_msg->val);
			uint16_t len = msg->cipher_mode_complete.l3_msg->len;
			struct msgb *dtap = msgb_alloc(len, "DTAP from Cipher Mode Complete");
			unsigned char *pos = msgb_put(dtap, len);
			memcpy(pos, data, len);
			dtap->l3h = pos;
			rc = msc_a_up_l3(msc_a, dtap);
			msgb_free(dtap);
		}
		break;

	case RAN_MSG_CIPHER_MODE_REJECT:
		vlr_subscr_rx_ciph_res(vsub, VLR_CIPH_REJECT);
		rc = 0;
		break;

	case RAN_MSG_ASSIGNMENT_COMPLETE:
		msc_a_up_call_assignment_complete(msc_a, msg);
		rc = 0;
		break;

	case RAN_MSG_ASSIGNMENT_FAILURE:
		msc_a_up_call_assignment_failure(msc_a, msg);
		rc = 0;
		break;

	case RAN_MSG_SAPI_N_REJECT:
		msc_a_up_sapi_n_reject(msc_a, msg);
		rc = 0;
		break;

	case RAN_MSG_HANDOVER_PERFORMED:
		/* The BSS lets us know that a handover happened within the BSS, which doesn't concern us. */
		LOG_MSC_A(msc_a, LOGL_ERROR, "'Handover Performed' handling not implemented\n");
		break;

	case RAN_MSG_HANDOVER_REQUIRED:
		/* The BSS lets us know that it wants to handover to a different cell */
		rc = osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_HANDOVER_REQUIRED, (void*)&msg->handover_required);
		break;

	case RAN_MSG_HANDOVER_FAILURE:
		rc = msc_a_up_ho(msc_a, d, MSC_HO_EV_RX_FAILURE);
		break;

	case RAN_MSG_LCLS_STATUS:
		/* The BSS sends us LCLS_STATUS. We do nothing for now, but it is not an error. */
		LOG_MSC_A(msc_a, LOGL_DEBUG, "LCLS_STATUS (%s) received from MSC-I\n",
			  gsm0808_lcls_status_name(msg->lcls_status.status));
		rc = 0;
		break;

	default:
		LOG_MSC_A(msc_a, LOGL_ERROR, "Message from MSC-I not implemented: %s\n", ran_msg_type_name(msg->msg_type));
		rc = -ENOTSUP;
		break;
	}
	return rc;
}

static int msc_a_rx_vgcs_bss_decoded(struct osmo_fsm_inst *caller_fi, void *caller_data, const struct ran_msg *msg)
{
	struct vgcs_bss *bss = caller_data;
	struct msc_a *msc_a = (bss->trans) ? bss->trans->msc_a : NULL;
	int rc = 0;

	switch (msg->msg_type) {
	case RAN_MSG_VGCS_VBS_SETUP_ACK:
		/* The BSS accepts VGCS/VBS and sends us supported features. */
		vgcs_vbs_setup_ack(bss, msg);
		break;
	case RAN_MSG_VGCS_VBS_SETUP_REFUSE:
		/* The BSS refuses VGCS/VBS. */
		vgcs_vbs_setup_refuse(bss, msg);
		break;
	case RAN_MSG_UPLINK_REQUEST:
		/* A mobile station requests the uplink on a VGCS channel. */
		vgcs_uplink_request(bss, msg);
		break;
	case RAN_MSG_UPLINK_REQUEST_CNF:
		/* The uplink on a VGCS channel has been established. */
		vgcs_uplink_request_cnf(bss, msg);
		break;
	case RAN_MSG_UPLINK_APPLICATION_DATA:
		/* Application data received on the uplink of a VGCS channel. */
		vgcs_app_data(bss, msg);
		break;
	case RAN_MSG_DTAP:
		/* BSS confirms the release of the channel. */
		vgcs_bss_dtap(bss, msg);
		break;
	case RAN_MSG_UPLINK_RELEASE_IND:
		/* A mobile station releases the uplink on a VGCS channel. */
		vgcs_uplink_release_ind(bss, msg);
		break;
	case RAN_MSG_CLEAR_REQUEST:
		/* BSS indicated that the channel has been released. */
		vgcs_vbs_clear_req(bss, msg);
		break;
	case RAN_MSG_CLEAR_COMPLETE:
		/* BSS confirms the release of the channel. */
		vgcs_vbs_clear_cpl(bss, msg);
		break;
	default:
		LOG_MSC_A(msc_a, LOGL_ERROR, "VGCS message from BSS not implemented: %s\n",
			  ran_msg_type_name(msg->msg_type));
		rc = -ENOTSUP;
		break;
	}
	return rc;
}

int msc_a_rx_vgcs_bss(struct vgcs_bss *bss, struct ran_conn *from_conn, struct msgb *msg)
{
	struct ran_dec ran_dec;

	/* Feed through the decoding mechanism ran_msg. The decoded message arrives in msc_a_rx_vgcs_decoded() */
	ran_dec = (struct ran_dec) {
		.caller_data = bss,
		.decode_cb = msc_a_rx_vgcs_bss_decoded,
	};
	struct ran_peer *ran_peer = from_conn->ran_peer;
	struct ran_infra *ran = ran_peer->sri->ran;
	if (!ran->ran_dec_l2) {
		LOGP(DMSC, LOGL_ERROR, "No ran_dec_l2() defined for RAN type %s\n",
		     osmo_rat_type_name(ran->type));
		return -ENOTSUP;
	}
	return ran->ran_dec_l2(&ran_dec, msg);
}

static int msc_a_rx_vgcs_cell_decoded(struct osmo_fsm_inst *caller_fi, void *caller_data, const struct ran_msg *msg)
{
	struct vgcs_bss_cell *cell = caller_data;
	struct msc_a *msc_a = (cell->bss && cell->bss->trans) ? cell->bss->trans->msc_a : NULL;
	int rc = 0;

	switch (msg->msg_type) {
	case RAN_MSG_VGCS_VBS_ASSIGN_RES:
		/* The BSS accepts VGCS/VBS channel assignment. */
		vgcs_vbs_assign_result(cell, msg);
		break;
	case RAN_MSG_VGCS_VBS_ASSIGN_FAIL:
		/* The BSS refuses VGCS/VBS channel assignment. */
		vgcs_vbs_assign_fail(cell, msg);
		break;
	case RAN_MSG_VGCS_VBS_QUEUING_IND:
		/* The BSS needs more time for VGCS/VBS channel assignment. */
		vgcs_vbs_queuing_ind(cell);
		break;
	case RAN_MSG_VGCS_VBS_ASSIGN_STATUS:
		/* The BSS gives cell status about VGCS/VBS channel. */
		vgcs_vbs_assign_status(cell, msg);
		break;
	case RAN_MSG_CLEAR_REQUEST:
		/* BSS indicated that the channel has been released. */
		vgcs_vbs_clear_req_channel(cell, msg);
		break;
	case RAN_MSG_CLEAR_COMPLETE:
		/* BSS confirms the release of the channel. */
		vgcs_vbs_clear_cpl_channel(cell, msg);
		break;
	default:
		LOG_MSC_A(msc_a, LOGL_ERROR, "Message from BSS leg not implemented: %s\n",
			  ran_msg_type_name(msg->msg_type));
		rc = -ENOTSUP;
		break;
	}
	return rc;
}

int msc_a_rx_vgcs_cell(struct vgcs_bss_cell *cell, struct ran_conn *from_conn, struct msgb *msg)
{
	struct ran_dec ran_dec;

	/* Feed through the decoding mechanism ran_msg. The decoded message arrives in msc_a_rx_vgcs_decoded() */
	ran_dec = (struct ran_dec) {
		.caller_data = cell,
		.decode_cb = msc_a_rx_vgcs_cell_decoded,
	};
	struct ran_peer *ran_peer = from_conn->ran_peer;
	struct ran_infra *ran = ran_peer->sri->ran;
	if (!ran->ran_dec_l2) {
		LOGP(DMSC, LOGL_ERROR, "No ran_dec_l2() defined for RAN type %s\n",
		     osmo_rat_type_name(ran->type));
		return -ENOTSUP;
	}
	return ran->ran_dec_l2(&ran_dec, msg);
}

static int msc_a_ran_dec_from_msc_t(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
{
	struct msc_t *msc_t = msc_a_msc_t(msc_a);
	int rc = -99;

	if (!msc_t) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "Rx message from MSC-T role, but I have no active MSC-T role.\n");
		return -EINVAL;
	}

	OSMO_ASSERT(d->ran_dec);

	switch (d->ran_dec->msg_type) {

	case RAN_MSG_CLEAR_REQUEST:
		rc = osmo_fsm_inst_dispatch(msc_t->c.fi, MSC_T_EV_MO_CLOSE, NULL);
		break;

	case RAN_MSG_CLEAR_COMPLETE:
		rc = osmo_fsm_inst_dispatch(msc_t->c.fi, MSC_T_EV_CLEAR_COMPLETE, NULL);
		break;

	case RAN_MSG_CLASSMARK_UPDATE:
		msc_a_up_classmark_update(msc_a, d->ran_dec->classmark_update.classmark, &msc_t->classmark);
		rc = 0;
		break;

	case RAN_MSG_HANDOVER_REQUEST_ACK:
		/* new BSS accepts Handover */
		rc = msc_a_up_ho(msc_a, d, MSC_HO_EV_RX_REQUEST_ACK);
		break;

	case RAN_MSG_HANDOVER_DETECT:
		/* new BSS signals the MS is DETECTed on the new lchan */
		rc = msc_a_up_ho(msc_a, d, MSC_HO_EV_RX_DETECT);
		break;

	case RAN_MSG_HANDOVER_COMPLETE:
		/* new BSS signals the MS has fully moved to the new lchan */
		rc = msc_a_up_ho(msc_a, d, MSC_HO_EV_RX_COMPLETE);
		break;

	case RAN_MSG_HANDOVER_FAILURE:
		rc = msc_a_up_ho(msc_a, d, MSC_HO_EV_RX_FAILURE);
		break;

	default:
		LOG_MSC_A(msc_a, LOGL_ERROR, "Message from MSC-T not implemented: %s\n",
			  ran_msg_type_name(d->ran_dec->msg_type));
		rc = -ENOTSUP;
		break;
	}
	return rc;
}

int msc_a_ran_decode_cb(struct osmo_fsm_inst *msc_a_fi, void *data, const struct ran_msg *msg)
{
	struct msc_a *msc_a = msc_a_fi_priv(msc_a_fi);
	struct msc_a_ran_dec_data *d = data;
	int rc = -99;

	d->ran_dec = msg;

	switch (d->from_role) {
	case MSC_ROLE_I:
		LOG_MSC_A(msc_a, LOGL_DEBUG, "RAN decode: %s\n", msg->msg_name ? : ran_msg_type_name(msg->msg_type));
		rc = msc_a_ran_dec_from_msc_i(msc_a, d);
		break;

	case MSC_ROLE_T:
		LOG_MSC_A(msc_a, LOGL_DEBUG, "RAN decode from MSC-T: %s\n",
			  msg->msg_name ? : ran_msg_type_name(msg->msg_type));
		rc = msc_a_ran_dec_from_msc_t(msc_a, d);
		break;

	default:
		LOG_MSC_A(msc_a, LOGL_ERROR, "Message from invalid role %s: %s\n", msc_role_name(d->from_role),
			  ran_msg_type_name(msg->msg_type));
		return -ENOTSUP;
	}

	if (rc)
		LOG_MSC_A(msc_a, LOGL_ERROR, "RAN decode error (rc=%d) for %s from %s\n", rc, ran_msg_type_name(msg->msg_type),
			  msc_role_name(d->from_role));
	return rc;
}

/* Your typical DTAP via FORWARD_ACCESS_SIGNALLING_REQUEST */
int _msc_a_ran_down(struct msc_a *msc_a, enum msc_role to_role, const struct ran_msg *ran_msg,
		   const char *file, int line)
{
	return _msc_a_msg_down(msc_a, to_role, msub_role_to_role_event(msc_a->c.msub, MSC_ROLE_A, to_role),
			       ran_msg, file, line);
}

/* To transmit more complex events than just FORWARD_ACCESS_SIGNALLING_REQUEST, e.g. an
 * MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST */
int _msc_a_msg_down(struct msc_a *msc_a, enum msc_role to_role, uint32_t to_role_event,
		    const struct ran_msg *ran_msg,
		    const char *file, int line)
{
	struct an_apdu an_apdu = {
		.an_proto = msc_a->c.ran->an_proto,
		.msg = msc_role_ran_encode(msc_a->c.fi, ran_msg),
	};
	if (!an_apdu.msg)
		return -EIO;
	return _msub_role_dispatch(msc_a->c.msub, to_role, to_role_event, &an_apdu, file, line);
}

int msc_a_tx_dtap_to_i(struct msc_a *msc_a, struct msgb *dtap)
{
	struct ran_msg ran_msg;
	struct gsm48_hdr *gh = msgb_l3(dtap) ? : dtap->data;
	uint8_t pdisc = gsm48_hdr_pdisc(gh);

	if (!msc_a) {
		LOGP(DMSC, LOGL_ERROR, "Attempt to send DTAP to NULL MSC-A, dropping message: %s %s\n",
		     gsm48_pdisc_name(pdisc), gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh)));
		msgb_free(dtap);
		return -EIO;
	}

	if (msc_a->c.ran->type == OSMO_RAT_EUTRAN_SGS) {
		/* The SGs connection to the MME always is at the MSC-A. */
		return sgs_iface_tx_dtap_ud(msc_a, dtap);
	}

	LOG_MSC_A(msc_a, LOGL_DEBUG, "Sending DTAP: %s %s\n",
		  gsm48_pdisc_name(pdisc), gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh)));

	ran_msg = (struct ran_msg){
		.msg_type = RAN_MSG_DTAP,
		.dtap = dtap,
	};
	return msc_a_ran_down(msc_a, MSC_ROLE_I, &ran_msg);
}

struct msc_a *msc_a_for_vsub(const struct vlr_subscr *vsub, bool valid_conn_only)
{
	struct msc_a *msc_a = msub_msc_a(msub_for_vsub(vsub));
	if (valid_conn_only && !msc_a_is_accepted(msc_a))
		return NULL;
	return msc_a;
}

int msc_tx_common_id(struct msc_a *msc_a, enum msc_role to_role)
{
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);
	if (vsub == NULL)
		return -ENODEV;
	struct ran_msg msg = {
		.msg_type = RAN_MSG_COMMON_ID,
		.common_id = {
			.imsi = vsub->imsi,
			.last_eutran_plmn_present = vsub->sgs.last_eutran_plmn_present,
		},
	};
	if (vsub->sgs.last_eutran_plmn_present) {
		memcpy(&msg.common_id.last_eutran_plmn, &vsub->sgs.last_eutran_plmn,
			sizeof(vsub->sgs.last_eutran_plmn));
	}

	return msc_a_ran_down(msc_a, to_role, &msg);
}

static int msc_a_start_assignment(struct msc_a *msc_a, struct gsm_trans *cc_trans)
{
	struct call_leg *cl;
	bool cn_rtp_available;
	bool ran_rtp_available;

	OSMO_ASSERT(!msc_a->cc.active_trans);
	msc_a->cc.active_trans = cc_trans;

	cc_trans->cc.codecs.assignment = (struct sdp_audio_codec){};

	OSMO_ASSERT(cc_trans && cc_trans->type == TRANS_CC);
	cl = msc_a_ensure_call_leg(msc_a, cc_trans);
	if (!cl)
		return -EINVAL;

	/* See if we can set a preliminary codec. If not, pass none for the time being. */
	trans_cc_filter_run(cc_trans);

	cn_rtp_available = call_leg_local_ip(cl, RTP_TO_CN);
	ran_rtp_available = call_leg_local_ip(cl, RTP_TO_RAN);

	/* Set up RTP ports for both RAN and CN side. Even though we ask for both at the same time, the
	 * osmo_mgcpc_ep_fsm automagically waits for the first CRCX to complete before firing the second CRCX. The one
	 * issued first here will also be the first CRCX sent to the MGW. Usually both still need to be set up. */
	if (!cn_rtp_available)
		call_leg_ensure_ci(cl, RTP_TO_CN, cc_trans->call_id, cc_trans,
				   &cc_trans->cc.local.audio_codecs, NULL);
	if (!ran_rtp_available) {
		struct sdp_audio_codecs *codecs;
		if (msc_a->c.ran->force_mgw_codecs_to_ran.count)
			codecs = &msc_a->c.ran->force_mgw_codecs_to_ran;
		else
			codecs = &cc_trans->cc.local.audio_codecs;
		return call_leg_ensure_ci(cl, RTP_TO_RAN, cc_trans->call_id, cc_trans, codecs, NULL);
	}

	/* Should these already be set up, immediately continue by retriggering the events signalling that the RTP
	 * ports are available. The ordering is: first CN, then RAN. */
	if (cn_rtp_available && ran_rtp_available)
		return osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, cl->rtp[RTP_TO_RAN]);
	else if (cn_rtp_available)
		return osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, cl->rtp[RTP_TO_CN]);
	/* Otherwise wait for MGCP response and continue from there.  */
	return 0;
}

int msc_a_try_call_assignment(struct gsm_trans *cc_trans)
{
	struct msc_a *msc_a = cc_trans->msc_a;
	OSMO_ASSERT(cc_trans->type == TRANS_CC);

	if (msc_a->cc.active_trans == cc_trans) {
		LOG_MSC_A(msc_a, LOGL_DEBUG, "Assignment for this trans already started earlier\n");
		return 0;
	}

	if (msc_a->cc.active_trans) {
		LOG_MSC_A(msc_a, LOGL_INFO, "Another call is already ongoing, not assigning yet\n");
		return 0;
	}

	LOG_MSC_A(msc_a, LOGL_DEBUG, "Starting call assignment\n");
	return msc_a_start_assignment(msc_a, cc_trans);
}

/* Map CM Service type to use token.
 * Given a CM Service type, return a matching token intended for osmo_use_count.
 * For unknown service type, return NULL.
 */
const char *msc_a_cm_service_type_to_use(struct msc_a *msc_a, enum osmo_cm_service_type cm_service_type)
{
	struct gsm_network *net = msc_a_net(msc_a);

	switch (cm_service_type) {
	case GSM48_CMSERV_MO_CALL_PACKET:
	case GSM48_CMSERV_EMERGENCY:
		return MSC_A_USE_CM_SERVICE_CC;

	case GSM48_CMSERV_SMS:
		return MSC_A_USE_CM_SERVICE_SMS;

	case GSM48_CMSERV_SUP_SERV:
		return MSC_A_USE_CM_SERVICE_SS;

	case GSM48_CMSERV_VGCS:
		if (net->asci.enable)
			return MSC_A_USE_CM_SERVICE_GCC;
		else
			return NULL;

	case GSM48_CMSERV_VBS:
		if (net->asci.enable)
			return MSC_A_USE_CM_SERVICE_BCC;
		else
			return NULL;

	default:
		return NULL;
	}
}

void msc_a_release_cn(struct msc_a *msc_a)
{
	osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_CN_CLOSE, NULL);
}

void msc_a_release_mo(struct msc_a *msc_a, enum gsm48_gsm_cause gsm_cause)
{
	osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_MO_CLOSE, NULL);
}
