/* The MSC-T role, a transitional RAN connection during Handover. */
/*
 * (C) 2019 by sysmocom - s.m.f.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 <inttypes.h>

#include <osmocom/gsm/gsm48_ie.h>

#include <osmocom/msc/msc_t.h>
#include <osmocom/msc/msc_a.h>
#include <osmocom/msc/msc_a_remote.h>
#include <osmocom/msc/ran_infra.h>
#include <osmocom/msc/ran_peer.h>
#include <osmocom/msc/ran_conn.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/rtp_stream.h>
#include <osmocom/msc/ran_infra.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/msc_i.h>
#include <osmocom/msc/gsm_data.h>

static struct osmo_fsm msc_t_fsm;

static struct msc_t *msc_t_find_by_handover_number(const char *handover_number)
{
	struct msub *msub;

	llist_for_each_entry(msub, &msub_list, entry) {
		struct msc_t *msc_t = msub_msc_t(msub);
		if (!msc_t)
			continue;
		if (!*msc_t->inter_msc.handover_number)
			continue;
		if (strcmp(msc_t->inter_msc.handover_number, handover_number))
			continue;
		/* Found the assigned Handover Number */
		return msc_t;
	}
	return NULL;
}

static uint64_t net_handover_number_next(struct gsm_network *net)
{
	uint64_t nr;
	if (net->handover_number.next < net->handover_number.range_start
	    || net->handover_number.next > net->handover_number.range_end)
		net->handover_number.next = net->handover_number.range_start;
	nr = net->handover_number.next;
	net->handover_number.next++;
	return nr;
}

static int msc_t_assign_handover_number(struct msc_t *msc_t)
{
	int rc;
	uint64_t started_at;
	uint64_t ho_nr;
	char ho_nr_str[VLR_MSISDN_LENGTH+1];
	struct gsm_network *net = msc_t_net(msc_t);
	bool usable = false;

	started_at = ho_nr = net_handover_number_next(net);

	if (!ho_nr) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "No Handover Number range defined in MSC config\n");
		return -ENOENT;
	}

	do {
		rc = snprintf(ho_nr_str, sizeof(ho_nr_str), "%"PRIu64, ho_nr);
		if (rc <= 0 || rc >= sizeof(ho_nr_str)) {
			LOG_MSC_T(msc_t, LOGL_ERROR, "Cannot compose Handover Number string (rc=%d)\n", rc);
			return -EINVAL;
		}

		if (!msc_t_find_by_handover_number(ho_nr_str)) {
			usable = true;
			break;
		}

		ho_nr = net_handover_number_next(net);
	} while(ho_nr != started_at);

	if (!usable) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "No Handover Number available\n");
		return -EINVAL;
	}

	LOG_MSC_T(msc_t, LOGL_INFO, "Assigning Handover Number %s\n", ho_nr_str);
	OSMO_STRLCPY_ARRAY(msc_t->inter_msc.handover_number, ho_nr_str);
	return 0;
}


static struct msc_t *msc_t_priv(struct osmo_fsm_inst *fi)
{
	OSMO_ASSERT(fi);
	OSMO_ASSERT(fi->fsm == &msc_t_fsm);
	OSMO_ASSERT(fi->priv);
	return fi->priv;
}

/* As a macro to log the caller's source file and line.
 * Assumes presence of local msc_t variable. */
#define msc_t_error(fmt, args...) do { \
		msc_t->ho_success = false; \
		LOG_MSC_T(msc_t, LOGL_ERROR, fmt, ##args); \
		msc_t_clear(msc_t); \
	} while(0)

static void msc_t_send_handover_failure(struct msc_t *msc_t, enum gsm0808_cause cause)
{
	struct ran_msg ran_enc_msg = {
		.msg_type = RAN_MSG_HANDOVER_FAILURE,
		.handover_failure = {
			.cause = cause,
		},
	};
	struct an_apdu an_apdu = {
		.an_proto = msc_t->c.ran->an_proto,
		.msg = msc_role_ran_encode(msc_t->c.fi, &ran_enc_msg),
	};
	msc_t->ho_fail_sent = true;
	if (!an_apdu.msg)
		return;

	msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, &an_apdu);
	msgb_free(an_apdu.msg);
}

static int msc_t_ho_request_decode_and_store_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
						const struct ran_msg *ran_dec)
{
	struct msc_t *msc_t = msc_t_priv(msc_t_fi);

	if (ran_dec->msg_type != RAN_MSG_HANDOVER_REQUEST) {
		LOG_MSC_T(msc_t, LOGL_DEBUG, "Expected %s in incoming inter-MSC Handover message, got %s\n",
			  ran_msg_type_name(RAN_MSG_HANDOVER_REQUEST), ran_msg_type_name(ran_dec->msg_type));
		return -EINVAL;
	}

	msc_t->inter_msc.cell_id_target = ran_dec->handover_request.cell_id_target;
	msc_t->inter_msc.callref = ran_dec->handover_request.call_id;

	/* TODO other parameters...?
	 * Global Call Reference
	 */
	return 0;
}

/* On an icoming Handover Request from a remote MSC, we first need to set up an MGW endpoint, because the BSC needs to
 * know our AoIP Transport Layer Address in the Handover Request message (which obviously the remote MSC doesn't send,
 * it needs to be our local RTP address). Creating the MGW endpoint this is asynchronous, so we need to store the
 * Handover Request data to forward to the BSC once the MGW endpoint is known.
 */
static int msc_t_decode_and_store_ho_request(struct msc_t *msc_t, const struct an_apdu *an_apdu)
{
	if (msc_role_ran_decode(msc_t->c.fi, an_apdu, msc_t_ho_request_decode_and_store_cb, NULL)) {
		msc_t_error("Failed to decode Handover Request\n");
		return -ENOTSUP;
	}
	/* Ok, decoding done, and above msc_t_ho_request_decode_and_store_cb() has retrieved what info we need at this
	 * point and stored it in msc_t->inter_msc.* */

	/* We're storing this for use after async events, so need to make sure that each and every bit of data is copied
	 * and no longer references some msgb that might be deallocated when this returns, nor remains in a local stack
	 * variable of some ran_decode implementation. The simplest is to store the entire msgb. */
	msc_t->inter_msc.ho_request = (struct an_apdu) {
		.an_proto = an_apdu->an_proto,
		.msg = msgb_copy(an_apdu->msg, "saved inter-MSC Handover Request"),
		/* A decoded osmo_gsup_message often still references memory of within the msgb the GSUP was received
		 * in. So, any info from an_apdu->e_info that would be needed would have to be copied separately.
		 * Omit e_info completely. */
	};
	return 0;
}

/* On an incoming Handover Request from a remote MSC, the target cell was transmitted in the Handover Request message.
 * Find the RAN peer and assign from the cell id decoded above in msc_t_decode_and_store_ho_request(). */
static int msc_t_find_ran_peer_from_ho_request(struct msc_t *msc_t)
{
	struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
	const struct neighbor_ident_entry *nie;
	struct ran_peer *rp_from_neighbor_ident;
	struct ran_peer *rp;

	switch (msc_ho_find_target_cell(msc_a, &msc_t->inter_msc.cell_id_target,
					&nie, &rp_from_neighbor_ident, &rp)) {
	case MSC_NEIGHBOR_TYPE_REMOTE_MSC:
		msc_t_error("Incoming Handover Request indicated target cell that belongs to a remote MSC:"
			    " Cell ID: %s; remote MSC: %s\n",
			    gsm0808_cell_id_name(&msc_t->inter_msc.cell_id_target),
			    neighbor_ident_addr_name(&nie->addr));
		return -EINVAL;

	case MSC_NEIGHBOR_TYPE_NONE:
		msc_t_error("Incoming Handover Request for unknown cell %s\n",
			    gsm0808_cell_id_name(&msc_t->inter_msc.cell_id_target));
		return -EINVAL;

	case MSC_NEIGHBOR_TYPE_LOCAL_RAN_PEER:
		/* That's what is expected: a local RAN peer, e.g. BSC, or a remote BSC from neighbor cfg. */
		if (!rp)
			rp = rp_from_neighbor_ident;
		break;
	}

	OSMO_ASSERT(rp);
	LOG_MSC_T(msc_t, LOGL_DEBUG, "Incoming Handover Request indicates target cell %s,"
		  " which belongs to RAN peer %s\n",
		  gsm0808_cell_id_name(&msc_t->inter_msc.cell_id_target), rp->fi->id);

	/* Finally we know where to direct the Handover */
	msc_t_set_ran_peer(msc_t, rp);
	return 0;
}

static int msc_t_send_stored_ho_request__decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
						  const struct ran_msg *ran_dec)
{
	int rc;
	struct an_apdu an_apdu;
	struct msc_t *msc_t = msc_t_priv(msc_t_fi);
	struct osmo_sockaddr_str *rtp_ran_local = data;

	/* Copy ran_dec message to un-const so we can add the AoIP Transport Layer Address. All pointer references still
	 * remain on the same memory as ran_dec, which is fine. We're just going to encode it again right away. */
	struct ran_msg ran_enc = *ran_dec;

	if (ran_dec->msg_type != RAN_MSG_HANDOVER_REQUEST) {
		LOG_MSC_T(msc_t, LOGL_DEBUG, "Expected %s in incoming inter-MSC Handover message, got %s\n",
			  ran_msg_type_name(RAN_MSG_HANDOVER_REQUEST), ran_msg_type_name(ran_dec->msg_type));
		return -EINVAL;
	}

	/* Insert AoIP Transport Layer Address */
	ran_enc.handover_request.rtp_ran_local = rtp_ran_local;

	/* Finally ready to forward to BSC: encode and send out. */
	an_apdu = (struct an_apdu){
		.an_proto = msc_t->inter_msc.ho_request.an_proto,
		.msg = msc_role_ran_encode(msc_t->c.fi, &ran_enc),
	};
	if (!an_apdu.msg)
		return -EIO;
	rc = msc_t_down_l2_co(msc_t, &an_apdu, true);
	msgb_free(an_apdu.msg);
	return rc;
}

/* The MGW endpoint is created, we know our AoIP Transport Layer Address and can send the Handover Request to the RAN
 * peer. */
static int msc_t_send_stored_ho_request(struct msc_t *msc_t)
{
	struct osmo_sockaddr_str *rtp_ran_local = call_leg_local_ip(msc_t->inter_msc.call_leg, RTP_TO_RAN);
	if (!rtp_ran_local) {
		msc_t_error("Local RTP address towards RAN is not set up properly, cannot send Handover Request\n");
		return -EINVAL;
	}

	/* The Handover Request received from the remote MSC is fed through, except we need to insert our local AoIP
	 * Transport Layer Address, i.e. the RTP IP:port of the MGW towards the RAN side. So we actually need to decode,
	 * add the AoIP and re-encode. By nature of decoding, it goes through the decode callback. */
	return msc_role_ran_decode(msc_t->c.fi, &msc_t->inter_msc.ho_request,
				   msc_t_send_stored_ho_request__decode_cb, rtp_ran_local);
}

static void msc_t_fsm_pending_first_co_initial_msg(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct msc_t *msc_t = msc_t_priv(fi);
	struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
	struct an_apdu *an_apdu;

	OSMO_ASSERT(msc_a);

	switch (event) {

	case MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST:
		/* For an inter-MSC Handover coming in from a remote MSC, we do not yet know the RAN peer and AoIP
		 * Transport Layer Address.
		 * - RAN peer is found by decoding the actual Handover Request message and looking for the Cell
		 *   Identifier (Target).
		 * - To be able to tell the BSC about an AoIP Transport Layer Address, we first need to create an MGW
		 *   endpoint.
		 * For mere inter-BSC Handover, we know all of the above already. Find out which one this is.
		 */
		an_apdu = data;
		if (!msc_a->c.remote_to) {
			/* Inter-BSC */

			osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_HO_REQUEST_ACK, 0, 0);
			/* Inter-BSC. All should be set up, just forward the message. */
			if (msc_t_down_l2_co(msc_t, an_apdu, true))
				msc_t_error("Failed to send AN-APDU to RAN peer\n");
		} else {
			/* Inter-MSC */

			if (msc_t->ran_conn) {
				msc_t_error("Unexpected state for inter-MSC Handover: RAN peer is already set up\n");
				return;
			}

			if (msc_t_decode_and_store_ho_request(msc_t, an_apdu))
				return;

			if (msc_t_find_ran_peer_from_ho_request(msc_t))
				return;

			/* Relying on timeout of the MGW operations, see onenter() for this state. */
			osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_LOCAL_RTP, 0, 0);
		}
		return;

	case MSC_T_EV_CN_CLOSE:
		msc_t_clear(msc_t);
		return;

	default:
		OSMO_ASSERT(false);
	}
}

void msc_t_fsm_wait_local_rtp_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct msc_t *msc_t = msc_t_priv(fi);
	struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);

	/* This only happens on inter-MSC HO incoming from a remote MSC */
	if (!msc_a->c.remote_to) {
		msc_t_error("Unexpected state: this is not an inter-MSC Handover\n");
		return;
	}

	if (msc_t->inter_msc.call_leg) {
		msc_t_error("Unexpected state: call leg already set up\n");
		return;
	}

	msc_t->inter_msc.call_leg = call_leg_alloc(msc_t->c.fi,
						   MSC_EV_CALL_LEG_TERM,
						   MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
						   MSC_EV_CALL_LEG_RTP_COMPLETE);
	if (!msc_t->inter_msc.call_leg
	    || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_RAN, msc_t->inter_msc.callref, NULL, NULL, NULL)
	    || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_CN, msc_t->inter_msc.callref, NULL, NULL, NULL)) {
		msc_t_error("Failed to set up call leg\n");
		return;
	}
	/* Now wait for two MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, one per RTP connection */
}

void msc_t_fsm_wait_local_rtp(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct msc_t *msc_t = msc_t_priv(fi);
	struct rtp_stream *rtps;

	switch (event) {
	case MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE:
		rtps = data;
		if (!rtps) {
			msc_t_error("Invalid data for MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE\n");
			return;
		}
		/* If both to-RAN and to-CN sides have a CI set up, we can continue. */
		if (!call_leg_local_ip(msc_t->inter_msc.call_leg, RTP_TO_RAN)
		    || !call_leg_local_ip(msc_t->inter_msc.call_leg, RTP_TO_CN))
			return;

		osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_HO_REQUEST_ACK, 0, 0);
		msc_t_send_stored_ho_request(msc_t);
		return;

	case MSC_EV_CALL_LEG_TERM:
		msc_t->inter_msc.call_leg = NULL;
		msc_t_error("Failed to set up MGW endpoint\n");
		return;

	case MSC_MNCC_EV_CALL_ENDED:
		msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
		return;

	case MSC_T_EV_CN_CLOSE:
	case MSC_T_EV_MO_CLOSE:
		msc_t_clear(msc_t);
		return;

	default:
		OSMO_ASSERT(false);
	}
}

static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct an_apdu *incoming_an_apdu,
					       const struct ran_msg *ran_dec)
{
	int rc;
	struct rtp_stream *rtp_ran = msc_t->inter_msc.call_leg? msc_t->inter_msc.call_leg->rtp[RTP_TO_RAN] : NULL;
	struct rtp_stream *rtp_cn = msc_t->inter_msc.call_leg? msc_t->inter_msc.call_leg->rtp[RTP_TO_CN] : NULL;
	/* Since it's BCD, it needs rounded-up half the char* length of an MSISDN plus a type byte.
	 * But no need to introduce obscure math to save a few stack bytes, just have more. */
	uint8_t msisdn_enc_buf[VLR_MSISDN_LENGTH + 1];
	/* Copy an_apdu and an_apdu->e_info in "copy-on-write" method, because they are const and we
	 * need to add the Handover Number to e_info. */
	const struct ran_handover_request_ack *r = &ran_dec->handover_request_ack;
	struct ran_msg ran_enc = *ran_dec;
	struct osmo_gsup_message e_info = {};
	struct an_apdu an_apdu = {
		.an_proto = incoming_an_apdu->an_proto,
		.e_info = &e_info,
	};
	if (incoming_an_apdu->e_info)
		e_info = *incoming_an_apdu->e_info;

	rc = msc_t_assign_handover_number(msc_t);
	if (rc)
		return rc;

	rc = gsm48_encode_bcd_number(msisdn_enc_buf, sizeof(msisdn_enc_buf), 0,
				     msc_t->inter_msc.handover_number);
	if (rc <= 0)
		return -EINVAL;

	e_info.msisdn_enc = msisdn_enc_buf;
	e_info.msisdn_enc_len = rc;

	/* Also need to fetch the RTP IP:port from AoIP Transport Address IE to tell the MGW about it */
	if (rtp_ran) {
		if (osmo_sockaddr_str_is_set(&r->remote_rtp)) {
			LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got " OSMO_SOCKADDR_STR_FMT "\n",
				  OSMO_SOCKADDR_STR_FMT_ARGS(&r->remote_rtp));
			rtp_stream_set_remote_addr(rtp_ran, &r->remote_rtp);
		} else {
			LOG_MSC_T(msc_t, LOGL_DEBUG, "No RTP IP:port in Handover Request Ack\n");
		}
		if (r->codec_present) {
			LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got %s\n",
				  osmo_mgcpc_codec_name(r->codec));
			rtp_stream_set_codec(rtp_ran, r->codec);
			if (rtp_cn)
				rtp_stream_set_codec(rtp_cn, r->codec);
		} else {
			LOG_MSC_T(msc_t, LOGL_DEBUG, "No codec in Handover Request Ack\n");
		}
		rtp_stream_commit(rtp_ran);
	} else {
		LOG_MSC_T(msc_t, LOGL_DEBUG, "No RTP to RAN set up yet\n");
	}

	/* Remove that AoIP Transport Layer IE so it doesn't get sent to the remote MSC */
	ran_enc.handover_request_ack.remote_rtp = (struct osmo_sockaddr_str){};

	an_apdu.msg = msc_role_ran_encode(msc_t->c.fi, &ran_enc);
	if (!an_apdu.msg)
		return -EIO;
	/* Send to remote MSC via msc_a_remote role */
	rc = msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE, &an_apdu);
	msgb_free(an_apdu.msg);
	return rc;
}

static int msc_t_wait_ho_request_ack_decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
					       const struct ran_msg *ran_dec)
{
	int rc;
	struct msc_t *msc_t = msc_t_priv(msc_t_fi);
	struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
	const struct an_apdu *an_apdu = data;

	switch (ran_dec->msg_type) {
	case RAN_MSG_HANDOVER_REQUEST_ACK:
		if (msc_a->c.remote_to) {
			/* inter-MSC. Add Handover Number, remove AoIP Transport Layer Address. */
			rc = msc_t_patch_and_send_ho_request_ack(msc_t, an_apdu, ran_dec);
		} else {
			/* inter-BSC. Just send as-is, with correct event. */
			rc = msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE,
						an_apdu);
		}
		if (rc)
			msc_t_error("Failed to send HO Request Ack\n");
		else
			osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_HO_COMPLETE, 0, 0);
		return 0;

	case RAN_MSG_HANDOVER_FAILURE:
		msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, an_apdu);
		return 0;

	case RAN_MSG_CLEAR_REQUEST:
		msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST,
				   an_apdu);
		return 0;

	default:
		LOG_MSC_T(msc_t, LOGL_ERROR, "Unexpected message during Prepare Handover procedure: %s\n",
			  ran_msg_type_name(ran_dec->msg_type));
		/* Let's just forward anyway. */
		msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST,
				   an_apdu);
		return 0;
	}
}

static void msc_t_fsm_wait_ho_request_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct msc_t *msc_t = msc_t_priv(fi);
	struct an_apdu *an_apdu;

	switch (event) {

	case MSC_EV_FROM_RAN_UP_L2:
		an_apdu = data;
		/* For inter-MSC Handover, we need to examine the message type. Depending on the response, we must
		 * dispatch MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE or MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, which
		 * ensures the correct E-interface message type. And we need to include the Handover Number.
		 * For mere inter-BSC Handover, we know that our osmo-msc internals don't care much about which event
		 * dispatches a Handover Failure or Handover Request Ack, so we could skip the decoding. But it is a
		 * premature optimization that complicates comparing an inter-BSC with an inter-MSC HO. */
		msc_role_ran_decode(msc_t->c.fi, an_apdu, msc_t_wait_ho_request_ack_decode_cb, an_apdu);
		/* Action continues in msc_t_wait_ho_request_ack_decode_cb() */
		return;

	case MSC_EV_FROM_RAN_CONN_RELEASED:
		msc_t_clear(msc_t);
		return;

	case MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST:
		an_apdu = data;
		msc_t_down_l2_co(msc_t, an_apdu, false);
		return;

	case MSC_EV_CALL_LEG_TERM:
		msc_t->inter_msc.call_leg = NULL;
		msc_t_error("Failed to set up MGW endpoint\n");
		return;

	case MSC_MNCC_EV_CALL_ENDED:
		msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
		return;

	case MSC_T_EV_CN_CLOSE:
	case MSC_T_EV_MO_CLOSE:
		msc_t_clear(msc_t);
		return;

	default:
		OSMO_ASSERT(false);
	}
}

static int msc_t_wait_ho_complete_decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
					       const struct ran_msg *ran_dec)
{
	struct msc_t *msc_t = msc_t_priv(msc_t_fi);
	struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
	struct msc_i *msc_i;
	const struct an_apdu *an_apdu = data;

	switch (ran_dec->msg_type) {
	case RAN_MSG_HANDOVER_COMPLETE:
		msc_t->ho_success = true;

		/* For both inter-BSC local to this MSC and inter-MSC Handover for a remote MSC-A, forward the Handover
		 * Complete message so that the MSC-A can change the MSC-T (transitional) to a proper MSC-I role. */
		msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_SEND_END_SIGNAL_REQUEST, an_apdu);

		/* For inter-BSC Handover, the Handover Complete event has already cleaned up this msc_t, and it is
		 * already gone and deallocated. */
		if (!msc_a->c.remote_to)
			return 0;

		/* For inter-MSC Handover, the remote MSC-A only turns its msc_t_remote into an msc_i_remote on
		 * the same GSUP link. We are here on the MSC-B side of the GSUP link and have to take care of
		 * creating an MSC-I over here to match the msc_i_remote at MSC-A. */
		msc_i = msc_i_alloc(msc_t->c.msub, msc_t->c.ran);
		if (!msc_i) {
			msc_t_error("Failed to create MSC-I role\n");
			return -1;
		}

		msc_i->inter_msc.mncc_forwarding_to_remote_cn = msc_t->inter_msc.mncc_forwarding_to_remote_cn;
		mncc_call_reparent(msc_i->inter_msc.mncc_forwarding_to_remote_cn,
				   msc_i->c.fi, -1, MSC_MNCC_EV_CALL_ENDED, NULL, NULL);

		msc_i->inter_msc.call_leg = msc_t->inter_msc.call_leg;
		call_leg_reparent(msc_i->inter_msc.call_leg,
				  msc_i->c.fi,
				  MSC_EV_CALL_LEG_TERM,
				  MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
				  MSC_EV_CALL_LEG_RTP_COMPLETE);

		/* msc_i_set_ran_conn() properly "steals" the ran_conn from msc_t */
		msc_i_set_ran_conn(msc_i, msc_t->ran_conn);

		/* Nicked everything worth keeping from MSC-T, discard now. */
		msc_t_clear(msc_t);
		return 0;

	case RAN_MSG_HANDOVER_FAILURE:
		msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, an_apdu);
		return 0;

	default:
		LOG_MSC_T(msc_t, LOGL_ERROR, "Unexpected message during Prepare Handover procedure: %s\n",
			  ran_msg_type_name(ran_dec->msg_type));
		/* Let's just forward anyway. Fall thru */
	case RAN_MSG_HANDOVER_DETECT:
	case RAN_MSG_CLEAR_REQUEST:
		msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST,
				   an_apdu);
		return 0;
	}
}

static void msc_t_fsm_wait_ho_complete(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct msc_t *msc_t = msc_t_priv(fi);
	struct an_apdu *an_apdu;

	switch (event) {

	case MSC_EV_FROM_RAN_UP_L2:
		an_apdu = data;
		/* We need to catch the Handover Complete message in order to send it as a SendEndSignal Request */
		msc_role_ran_decode(msc_t->c.fi, an_apdu, msc_t_wait_ho_complete_decode_cb, an_apdu);
		return;

	case MSC_EV_FROM_RAN_CONN_RELEASED:
		msc_t_clear(msc_t);
		return;

	case MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST:
		an_apdu = data;
		msc_t_down_l2_co(msc_t, an_apdu, false);
		return;

	case MSC_EV_CALL_LEG_TERM:
		msc_t->inter_msc.call_leg = NULL;
		msc_t_error("Failed to set up MGW endpoint\n");
		return;

	case MSC_MNCC_EV_CALL_ENDED:
		msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
		return;

	case MSC_T_EV_CN_CLOSE:
	case MSC_T_EV_MO_CLOSE:
		msc_t_clear(msc_t);
		return;

	default:
		OSMO_ASSERT(false);
	}
}

void msc_t_mncc_cb(struct mncc_call *mncc_call, const union mncc_msg *mncc_msg, void *data)
{
	struct msc_t *msc_t = data;
	struct gsm_mncc_number nr = {
		.plan = 1,
	};
	OSMO_STRLCPY_ARRAY(nr.number, msc_t->inter_msc.handover_number);

	switch (mncc_msg->msg_type) {
	case MNCC_RTP_CREATE:
		mncc_call_incoming_tx_setup_cnf(mncc_call, &nr);
		return;
	default:
		return;
	}
}

struct mncc_call *msc_t_check_call_to_handover_number(const struct gsm_mncc *msg)
{
	struct msc_t *msc_t;
	const char *handover_number;
	struct mncc_call_incoming_req req;
	struct mncc_call *mncc_call;

	if (!(msg->fields & MNCC_F_CALLED))
		return NULL;

	handover_number = msg->called.number;
	msc_t = msc_t_find_by_handover_number(handover_number);

	if (!msc_t)
		return NULL;

	if (msc_t->inter_msc.mncc_forwarding_to_remote_cn) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "Incoming call for inter-MSC call forwarding,"
			  " but this MSC-T role already has an MNCC FSM set up\n");
		return NULL;
	}

	if (!msc_t->inter_msc.call_leg
	    || !msc_t->inter_msc.call_leg->rtp[RTP_TO_CN]) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "Incoming call for inter-MSC call forwarding,"
			  " but this MSC-T has no RTP stream ready for MNCC\n");
		return NULL;
	}

	mncc_call = mncc_call_alloc(msc_t_vsub(msc_t),
				    msc_t->c.fi,
				    MSC_MNCC_EV_CALL_COMPLETE,
				    MSC_MNCC_EV_CALL_ENDED,
				    msc_t_mncc_cb, msc_t);
	if (!mncc_call) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
		return NULL;
	}
	msc_t->inter_msc.mncc_forwarding_to_remote_cn = mncc_call;

	if (mncc_call_set_rtp_stream(mncc_call, msc_t->inter_msc.call_leg->rtp[RTP_TO_CN])) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
		osmo_fsm_inst_term(mncc_call->fi, OSMO_FSM_TERM_REGULAR, NULL);
		return NULL;
	}

	req = (struct mncc_call_incoming_req){
		.setup_req_msg = *msg,
		.bearer_cap_present = true,
		.bearer_cap = {
			/* TODO derive values from actual config */
			/* FIXME are there no defines or enums for these numbers!? */
			/* Table 10.5.102/3GPP TS 24.008: Bearer capability information element:
			 * octet 3 of bearer cap for speech says 3 = "1 1 dual rate support MS/full rate speech version
			 * 1 preferred, half rate speech version 1 also supported" */
			.radio = 3,
			/* Table 10.5.103/3GPP TS 24.008 Bearer capability information element:
			 * 0: FR1, 2: FR2, 4: FR3, 1: HR1, 5: HR3, actually in this order. -1 marks the end of the list. */
			.speech_ver = { 0, 2, 4, 1, 5, -1 },
		},
	};
	if (mncc_call_incoming_start(mncc_call, &req)) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
		osmo_fsm_inst_term(mncc_call->fi, OSMO_FSM_TERM_REGULAR, NULL);
		return NULL;
	}
	return mncc_call;
}

static void msc_t_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
{
	struct msc_t *msc_t = msc_t_priv(fi);

	if (!msc_t->ho_success && !msc_t->ho_fail_sent)
		msc_t_send_handover_failure(msc_t, GSM0808_CAUSE_EQUIPMENT_FAILURE);

	if (msc_t->ran_conn)
		ran_conn_msc_role_gone(msc_t->ran_conn, msc_t->c.fi);
}

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

static const struct osmo_fsm_state msc_t_fsm_states[] = {
	[MSC_T_ST_PENDING_FIRST_CO_INITIAL_MSG] = {
		.name = "PENDING_FIRST_CO_INITIAL_MSG",
		.action = msc_t_fsm_pending_first_co_initial_msg,
		.in_event_mask = 0
			| S(MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST)
			| S(MSC_T_EV_CN_CLOSE)
			,
		.out_state_mask = 0
			| S(MSC_T_ST_WAIT_LOCAL_RTP)
			| S(MSC_T_ST_WAIT_HO_REQUEST_ACK)
			,
	},
	[MSC_T_ST_WAIT_LOCAL_RTP] = {
		.name = "WAIT_LOCAL_RTP",
		.onenter = msc_t_fsm_wait_local_rtp_onenter,
		.action = msc_t_fsm_wait_local_rtp,
		.in_event_mask = 0
			| S(MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE)
			| S(MSC_EV_CALL_LEG_TERM)
			| S(MSC_MNCC_EV_CALL_ENDED)
			| S(MSC_T_EV_CN_CLOSE)
			,
		.out_state_mask = 0
			| S(MSC_T_ST_WAIT_HO_REQUEST_ACK)
			,
	},
	[MSC_T_ST_WAIT_HO_REQUEST_ACK] = {
		.name = "WAIT_HO_REQUEST_ACK",
		.action = msc_t_fsm_wait_ho_request_ack,
		.in_event_mask = 0
			| S(MSC_EV_FROM_RAN_UP_L2)
			| S(MSC_EV_FROM_RAN_CONN_RELEASED)
			| S(MSC_EV_CALL_LEG_TERM)
			| S(MSC_MNCC_EV_CALL_ENDED)
			| S(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST)
			| S(MSC_T_EV_CN_CLOSE)
			| S(MSC_T_EV_MO_CLOSE)
			,
		.out_state_mask = 0
			| S(MSC_T_ST_WAIT_HO_COMPLETE)
			,
	},
	[MSC_T_ST_WAIT_HO_COMPLETE] = {
		.name = "WAIT_HO_COMPLETE",
		.action = msc_t_fsm_wait_ho_complete,
		.in_event_mask = 0
			| S(MSC_EV_FROM_RAN_UP_L2)
			| S(MSC_EV_FROM_RAN_CONN_RELEASED)
			| S(MSC_EV_CALL_LEG_TERM)
			| S(MSC_MNCC_EV_CALL_ENDED)
			| S(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST)
			| S(MSC_T_EV_CN_CLOSE)
			| S(MSC_T_EV_MO_CLOSE)
			,
	},
};

const struct value_string msc_t_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_EV_FROM_RAN_COMPLETE_LAYER_3),
	OSMO_VALUE_STRING(MSC_EV_FROM_RAN_UP_L2),
	OSMO_VALUE_STRING(MSC_EV_FROM_RAN_CONN_RELEASED),

	OSMO_VALUE_STRING(MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST),
	OSMO_VALUE_STRING(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST),
	OSMO_VALUE_STRING(MSC_T_EV_CN_CLOSE),
	OSMO_VALUE_STRING(MSC_T_EV_MO_CLOSE),
	OSMO_VALUE_STRING(MSC_T_EV_CLEAR_COMPLETE),
	{}
};

static struct osmo_fsm msc_t_fsm = {
	.name = "msc_t",
	.states = msc_t_fsm_states,
	.num_states = ARRAY_SIZE(msc_t_fsm_states),
	.log_subsys = DMSC,
	.event_names = msc_t_fsm_event_names,
	.cleanup = msc_t_fsm_cleanup,
};

static __attribute__((constructor)) void msc_t_fsm_init(void)
{
	OSMO_ASSERT(osmo_fsm_register(&msc_t_fsm) == 0);
}

/* Send connection-oriented L3 message to RAN peer (MSC->[BSC|RNC]) */
int msc_t_down_l2_co(struct msc_t *msc_t, const struct an_apdu *an_apdu, bool initial)
{
	int rc;
	if (!msc_t->ran_conn) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "Cannot Tx L2 message: no RAN conn\n");
		return -EIO;
	}

	if (an_apdu->an_proto != msc_t->c.ran->an_proto) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "Mismatching AN-APDU proto: %s -- Dropping message\n",
			  an_proto_name(an_apdu->an_proto));
		return -EIO;
	}

	rc = ran_conn_down_l2_co(msc_t->ran_conn, an_apdu->msg, initial);
	if (rc)
		LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to transfer message down to new RAN peer (rc=%d)\n", rc);
	return rc;
}

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

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

struct msc_t *msc_t_alloc_without_ran_peer(struct msub *msub, struct ran_infra *ran)
{
	struct msc_t *msc_t;

	msub_role_alloc(msub, MSC_ROLE_T, &msc_t_fsm, struct msc_t, ran);
	msc_t = msub_msc_t(msub);
	if (!msc_t)
		return NULL;

	return msc_t;
}

int msc_t_set_ran_peer(struct msc_t *msc_t, struct ran_peer *ran_peer)
{
	if (!ran_peer || !ran_peer->sri || !ran_peer->sri->ran) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "Invalid RAN peer: %s\n", ran_peer ? ran_peer->fi->id : "NULL");
		return -EINVAL;
	}

	if (ran_peer->sri->ran != msc_t->c.ran) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "This MSC-T was set up for %s, cannot assign RAN peer for %s\n",
			  osmo_rat_type_name(msc_t->c.ran->type), osmo_rat_type_name(ran_peer->sri->ran->type));
		return -EINVAL;
	}

	/* Create a new ran_conn with a fresh conn_id for the outgoing initial message. The msc_t FSM definition ensures
	 * that the first message sent or received is a Connection-Oriented Initial message. */
	msc_t->ran_conn = ran_conn_create_outgoing(ran_peer);
	if (!msc_t->ran_conn) {
		LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to create outgoing RAN conn\n");
		return -EINVAL;
	}
	msc_t->ran_conn->msc_role = msc_t->c.fi;
	msub_update_id(msc_t->c.msub);
	return 0;
}

struct msc_t *msc_t_alloc(struct msub *msub, struct ran_peer *ran_peer)
{
	struct msc_t *msc_t = msc_t_alloc_without_ran_peer(msub, ran_peer->sri->ran);
	if (!msc_t)
		return NULL;
	if (msc_t_set_ran_peer(msc_t, ran_peer)) {
		msc_t_clear(msc_t);
		return NULL;
	}
	return msc_t;
}

void msc_t_clear(struct msc_t *msc_t)
{
	if (!msc_t)
		return;
	osmo_fsm_inst_term(msc_t->c.fi, OSMO_FSM_TERM_REGULAR, msc_t->c.fi);
}
