/*
 * (C) 2021 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 * All rights not specifically granted under this license are reserved.
 *
 * Author: Pau Espin Pedrol
 *
 * 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.
 */

#include <stdint.h>

#include <osmocom/core/byteswap.h>

#include <osmocom/gsm/iuup.h>

#include <osmocom/netif/rtp.h>
#include <osmocom/netif/amr.h>

#include <osmocom/mgcp/mgcp_conn.h>
#include <osmocom/mgcp/mgcp_iuup.h>
#include <osmocom/mgcp/mgcp_endp.h>
#include <osmocom/mgcp/mgcp_codec.h>
#include <osmocom/mgcp/mgcp_network.h>
#include <osmocom/mgcp/debug.h>

#define MGW_IUUP_MSGB_SIZE 4096

static const struct osmo_iuup_rnl_config def_configure_req = {
	.transparent = false,
	.active = true,
	.supported_versions_mask = 0x0003,
	.num_rfci = 0,
	.num_subflows = 0,
	.IPTIs_present = false,
	.t_init = { .t_ms = IUUP_TIMER_INIT_T_DEFAULT, .n_max = IUUP_TIMER_INIT_N_DEFAULT },
	.t_ta = { .t_ms = IUUP_TIMER_TA_T_DEFAULT, .n_max = IUUP_TIMER_TA_N_DEFAULT },
	.t_rc = { .t_ms = IUUP_TIMER_RC_T_DEFAULT, .n_max = IUUP_TIMER_RC_N_DEFAULT },
};

/* Find a destination connection. */
static struct mgcp_conn *_find_dst_conn(struct mgcp_conn *conn)
{
	/* NOTE: This code path runs every time an RTP packet is received. The
	 * function mgcp_find_dst_conn() we use to determine the detination
	 * connection will iterate the connection list inside the endpoint.
	 * Since list iterations are quite costly, we will figure out the
	 * destination only once and use the optional private data pointer of
	 * the connection to cache the destination connection pointer. */

	struct mgcp_conn *conn_dst;
	if (!conn->priv) {
		conn_dst = mgcp_find_dst_conn(conn);
		conn->priv = conn_dst;
	} else {
		conn_dst = (struct mgcp_conn *)conn->priv;
	}
	return conn_dst;
}

/* Find RFCI containing all 0 sizes, -1 if not found. irp is an Initialization.ind prim */
static int _find_rfci_no_data(struct osmo_iuup_rnl_prim *irp)
{
	int i;
	/* Find RFCI containing NO_DATA: */
	for (i = 0; i < irp->u.status.u.initialization.num_rfci; i++) {
		int j;
		bool is_no_data = true;
		for (j = 0; j < irp->u.status.u.initialization.num_subflows; j++) {
			if (irp->u.status.u.initialization.subflow_sizes[i][j]) {
				is_no_data = false;
				break;
			}
		}
		if (is_no_data) {
			return i;
		}
	}
	return -1;
}

/* Lookup RFCI to use for specific AMR codec type. -1 if none found */
static int8_t _conn_iuup_amr_ft_2_rfci(struct mgcp_conn_rtp *conn_rtp, uint8_t ft)
{
	int8_t i;
	unsigned match_bytes = (unsigned)osmo_amr_bytes(ft);
	struct osmo_iuup_rnl_prim *irp = conn_rtp->iuup.init_ind;
	OSMO_ASSERT(irp);

	/* TODO: cache this somehow */
	for (i = 0; i < irp->u.status.u.initialization.num_rfci; i++) {
		int j;
		unsigned num_bits = 0;
		for (j = 0; j < irp->u.status.u.initialization.num_subflows; j++)
			num_bits += irp->u.status.u.initialization.subflow_sizes[i][j];
		if (match_bytes == (num_bits + 7)/8)
			return i;
	}

	return -1;
}

/* Helper function to configure IuUP layer FSM as Init-Passive, based on default config */
static int _conn_iuup_configure_as_passive(struct mgcp_conn_rtp *conn_rtp)
{
	struct osmo_iuup_rnl_prim *irp;
	int rc;

	conn_rtp->iuup.active_init = false;

	/* Tx CONFIG.req */
	irp = osmo_iuup_rnl_prim_alloc(conn_rtp->conn, OSMO_IUUP_RNL_CONFIG, PRIM_OP_REQUEST, MGW_IUUP_MSGB_SIZE);
	irp->u.config = def_configure_req;
	irp->u.config.active = conn_rtp->iuup.active_init;
	if ((rc = osmo_iuup_rnl_prim_down(conn_rtp->iuup.iui, irp)) == 0)
		conn_rtp->iuup.configured = true;
	else
		LOG_CONN_RTP(conn_rtp, LOGL_ERROR, "Failed configuring IuUP layer\n");
	return rc;
}

/* Helper function to configure IuUP layer FSM as Init-Active, based on received
 * RNL Status-Init primitive from the sister IuUP connection we will bridge to. */
static int _conn_iuup_configure_as_active(struct mgcp_conn_rtp *conn_rtp, struct osmo_iuup_rnl_prim *init_ind)
{
	struct osmo_iuup_rnl_prim *irp = init_ind;
	struct osmo_iuup_rnl_prim *irp2;
	struct msgb *msg;
	bool prev_output_enabled;
	int rc;

	conn_rtp->iuup.active_init = true;

	/* Find RFCI containing NO_DATA: */
	conn_rtp->iuup.rfci_idx_no_data = _find_rfci_no_data(init_ind);

	/* Copy over the rfci_idx_no_data, since we reuse the same subflow set: */
	msg = msgb_copy_c(conn_rtp->conn, irp->oph.msg, "iuup-init-copy");
	conn_rtp->iuup.init_ind = (struct osmo_iuup_rnl_prim *)msgb_data(msg);
	conn_rtp->iuup.init_ind->oph.msg = msg;

	/* Tx CONFIG.req */
	irp2 = osmo_iuup_rnl_prim_alloc(conn_rtp->conn, OSMO_IUUP_RNL_CONFIG, PRIM_OP_REQUEST, MGW_IUUP_MSGB_SIZE);
	irp2->u.config.transparent = false;
	irp2->u.config.active = conn_rtp->iuup.active_init;
	irp2->u.config.data_pdu_type = irp->u.status.u.initialization.data_pdu_type;
	irp2->u.config.supported_versions_mask = def_configure_req.supported_versions_mask;
	irp2->u.config.num_rfci = irp->u.status.u.initialization.num_rfci;
	irp2->u.config.num_subflows = irp->u.status.u.initialization.num_subflows;
	memcpy(irp2->u.config.subflow_sizes, irp->u.status.u.initialization.subflow_sizes,
	       IUUP_MAX_RFCIS * IUUP_MAX_SUBFLOWS * sizeof(irp2->u.config.subflow_sizes[0][0]));
	irp2->u.config.IPTIs_present = irp->u.status.u.initialization.IPTIs_present;
	if (irp->u.status.u.initialization.IPTIs_present)
		memcpy(irp2->u.config.IPTIs, irp->u.status.u.initialization.IPTIs,
		       IUUP_MAX_RFCIS * sizeof(irp2->u.config.IPTIs[0]));
	irp2->u.config.t_init = def_configure_req.t_init;
	irp2->u.config.t_ta = def_configure_req.t_ta;
	irp2->u.config.t_rc = def_configure_req.t_rc;

	/* We need to force allowance of RTP containing Init-ACK back: */
	prev_output_enabled = conn_rtp->end.output_enabled;
	conn_rtp->end.output_enabled = true;

	if ((rc = osmo_iuup_rnl_prim_down(conn_rtp->iuup.iui, irp2)) == 0)
		conn_rtp->iuup.configured = true;
	else
		LOG_CONN_RTP(conn_rtp, LOGL_ERROR, "Failed configuring IuUP layer\n");

	conn_rtp->end.output_enabled = prev_output_enabled;
	return rc;
}

/* Helper function to push an RTP+IuUP pkt up to the IuUP layer FSM through the
 * TNL primitive interface. */
static int _conn_iuup_rtp_pl_up(struct mgcp_conn_rtp *conn_rtp, struct msgb *msg)
{
	/* Send RTP payload (IuUP) up the stack: */
	struct osmo_iuup_tnl_prim *itp;
	int rc;

	msg->l2h = msgb_data(msg) + sizeof(struct rtp_hdr);

	itp = osmo_iuup_tnl_prim_alloc(conn_rtp->conn, OSMO_IUUP_TNL_UNITDATA, PRIM_OP_INDICATION, MGW_IUUP_MSGB_SIZE);
	itp->oph.msg->l2h = msgb_put(itp->oph.msg, msgb_l2len(msg));
	memcpy(itp->oph.msg->l2h, msgb_l2(msg), msgb_l2len(msg));
	if ((rc = osmo_iuup_tnl_prim_up(conn_rtp->iuup.iui, itp)) != 0) {
		LOG_CONN_RTP(conn_rtp, LOGL_ERROR, "Failed passing IuUP-Init to IuUP layer\n");
	}
	return rc;
}

static int check_rtp_iuup(const struct mgcp_conn_rtp *conn_rtp, struct msgb *msg)
{
	size_t min_size = sizeof(struct rtp_hdr);
	/* Check there's at least 2 bytes of RTP payload (IuUP header). This is
	 ** mainly to avoid 0-byte payload copy cases */
	if (msgb_length(msg) < sizeof(struct rtp_hdr) + 2) {
		LOG_CONN_RTP(conn_rtp, LOGL_ERROR, "RTP-IuUP packet too short (%u < %zu)\n",
			     msgb_length(msg), min_size);
		return -1;
	}
	return 0;
}

/* Bridge received IuUP packet in conn_rtp_src to conn_rtp_dst, an IuUP sister
 * conn in the endpoint. The function takes ownsership of the irp */
static int bridge_iuup_to_iuup_peer(struct mgcp_conn_rtp *conn_rtp_src, struct mgcp_conn_rtp *conn_rtp_dst, struct osmo_iuup_rnl_prim *irp)
{
	int rc;

	/* If we are not configured and we received bridged data, it means
	 * conn_rtp_src is already configured and INITed, and we can infer
	 * conn_rtp_src is Init-passive (RNC side), so conn_rtp_dst needs to be
	 * configured as INIT-active: */
	if (!conn_rtp_dst->iuup.configured) {
		OSMO_ASSERT(conn_rtp_src->iuup.init_ind);
		rc = _conn_iuup_configure_as_active(conn_rtp_dst, conn_rtp_src->iuup.init_ind);
		if (rc < 0) {
			msgb_free(irp->oph.msg);
			return rc;
		}
	}

	/* We simply forward the msg, without freeing it: */
	talloc_steal(conn_rtp_dst->conn, irp->oph.msg);
	irp->oph.operation = PRIM_OP_REQUEST;
	if ((rc = osmo_iuup_rnl_prim_down(conn_rtp_dst->iuup.iui, irp)) != 0)
		LOG_CONN_RTP(conn_rtp_dst, LOGL_ERROR, "Failed Tx data down to IuUP layer\n");
	return rc;
}

/* Bridge received IuUP packet in conn_rtp_src to conn_rtp_dst, an RTP (no IuUP)
 * sister conn in the endpoint. The function takes ownsership of the irp */
static int bridge_iuup_to_rtp_peer(struct mgcp_conn_rtp *conn_rtp_src, struct mgcp_conn_rtp *conn_rtp_dst, struct osmo_iuup_rnl_prim *irp)
{
	/* FIXME: We probably need transcoding here?! Or at least look up AMR modes and translate to related RFCI */
	uint8_t frame_nr = irp->u.data.frame_nr;
	uint8_t fqc = irp->u.data.fqc;
	struct msgb *msg = irp->oph.msg;
	ssize_t amr_length = 0;
	int ft;
	uint8_t *amr_data;
	struct rtp_hdr *rtp_hdr;
	struct amr_hdr *amr_hdr;
	int rc;

	ft = osmo_amr_bytes_to_ft(msgb_l3len(msg));
	if (ft < 0) {
		LOGPCONN(conn_rtp_src->conn, DRTP, LOGL_ERROR,
			 "Unknown AMR format for size %u\n", msgb_l3len(msg));
		msgb_free(msg);
		return ft;
	}
	msgb_pull_to_l3(msg);
	LOGP(DLMGCP, LOGL_DEBUG, "Convert Iuup -> AMR: ft %d, len %d\n", ft, msgb_l3len(msg));

	if (mgcp_codec_amr_is_octet_aligned(conn_rtp_dst->end.codec)) {
		amr_hdr = (struct amr_hdr *) msgb_push(msg, sizeof(struct amr_hdr));
		amr_hdr->cmr = 15; /* no change */
		amr_hdr->f = 0;
		amr_hdr->q = !fqc;
		amr_hdr->ft = ft & 0xff;
		amr_hdr->pad1 = 0;
		amr_hdr->pad2 = 0;
	} else {
		OSMO_ASSERT(msgb_tailroom(msg) >= 2);
		msgb_put(msg, 2);
		osmo_amr_iuup_to_bwe(msgb_data(msg), msgb_length(msg) - 2, msgb_length(msg) + 2);
		/* fill bwe header */
		amr_data = msgb_data(msg);
		/* CMR no change      | follow bit | ft (3 of 4 bits) */
		amr_data[0] = 15 << 4 | (0 << 3) | (ft >> 1);
		amr_data[1] |= ((ft & 0x1) << 7) | (((!fqc) & 0x1) << 6);
		amr_length = (osmo_amr_bits(ft) + 10 + 7) / 8;
		msgb_trim(msg, amr_length);
	}
	rtp_hdr = (struct rtp_hdr *) msgb_push(msg, sizeof(*rtp_hdr));
	*rtp_hdr = (struct rtp_hdr){
		.csrc_count = 0,
		.extension = 0,
		.padding = 0,
		.version = 0,
		.payload_type = conn_rtp_dst->end.codec->payload_type,
		.marker = 0,
		.sequence = frame_nr,
		.timestamp = 0,
		.ssrc = 0
	};

	rc = mgcp_send(conn_rtp_dst->conn->endp, true, NULL, msg, conn_rtp_src, conn_rtp_dst);
	msgb_free(msg);
	return rc;
}

/* Handle RNL Data primitive received from the IuUP layer FSM: Bridge it to the
 * sister connection in the endpoint: */
static int _conn_iuup_rx_rnl_data(struct mgcp_conn_rtp *conn_rtp_src, struct osmo_iuup_rnl_prim *irp)
{
	struct mgcp_conn *conn_dst;
	struct mgcp_conn_rtp *conn_rtp_dst;
	int rc;

	conn_dst = _find_dst_conn(conn_rtp_src->conn);

	/* There is no destination conn, stop here */
	if (!conn_dst) {
		LOGPCONN(conn_rtp_src->conn, DRTP, LOGL_DEBUG,
			 "no connection to forward an incoming IuUP payload to\n");
		rc = -1;
		goto free_ret;
	}

	/* The destination conn is not an RTP/IuUP connection */
	if (conn_dst->type != MGCP_CONN_TYPE_RTP) {
		LOGPCONN(conn_rtp_src->conn, DRTP, LOGL_ERROR,
			 "unable to find suitable destination conn\n");
		 rc = -1;
		goto free_ret;
	}
	conn_rtp_dst = &conn_dst->u.rtp;

	switch (conn_rtp_dst->type) {
	case MGCP_RTP_IUUP:
		return bridge_iuup_to_iuup_peer(conn_rtp_src, conn_rtp_dst, irp);
	case MGCP_RTP_DEFAULT:
		return bridge_iuup_to_rtp_peer(conn_rtp_src, conn_rtp_dst, irp);
	case MGCP_OSMUX_BSC:
	case MGCP_OSMUX_BSC_NAT:
	default:
		LOGPCONN(conn_rtp_src->conn, DRTP, LOGL_ERROR,
			 "Forward of IuUP payload to RTP connection type %u not supported!\n",
			 conn_rtp_dst->type);
		rc = 0;
	}

free_ret:
	msgb_free(irp->oph.msg);
	return rc;
}

/* Handle RNL Status-Init primitive received from the IuUP layer FSM.
 * Potentially configure sister conn as IuUP Init-Active: */
static int _conn_iuup_rx_rnl_status_init(struct mgcp_conn_rtp *conn_rtp_src, struct osmo_iuup_rnl_prim *irp)
{
	struct mgcp_conn *conn_dst;
	struct mgcp_conn_rtp *conn_rtp_dst;
	int rc = 0;
	struct msgb *msg;

	/* Find RFCI containing NO_DATA: */
	conn_rtp_src->iuup.rfci_idx_no_data = _find_rfci_no_data(irp);

	msg = msgb_copy_c(conn_rtp_src->conn, irp->oph.msg, "iuup-init-copy");
	conn_rtp_src->iuup.init_ind = (struct osmo_iuup_rnl_prim *)msgb_data(msg);
	conn_rtp_src->iuup.init_ind->oph.msg = msg;

	conn_dst = _find_dst_conn(conn_rtp_src->conn);
	/* If not yet there, peer will potentially be IuUP-Initialized later
	 * when we attempt to bridge audio towards it. See bridge_iuup_to_iuup_peer() */
	if (!conn_dst)
		return 0;
	conn_rtp_dst = &conn_dst->u.rtp;
	if (!mgcp_conn_rtp_is_iuup(conn_rtp_dst))
		return 0; /* Nothing to do */

	/* We received IuUP parameters on the peer (RNC), Init actively this conn (against CN): */
	if (!conn_rtp_dst->iuup.configured)
		rc = _conn_iuup_configure_as_active(conn_rtp_dst, irp);

	return rc;
}

/* Handle RNL Status primitives received from the IuUP layer FSM: */
static int _conn_iuup_rx_rnl_status(struct mgcp_conn_rtp *conn_rtp_src, struct osmo_iuup_rnl_prim *irp)
{
	int rc;

	switch (irp->u.status.procedure) {
	case IUUP_PROC_INIT:
		rc = _conn_iuup_rx_rnl_status_init(conn_rtp_src, irp);
		break;
	case IUUP_PROC_RATE_CTRL:
	case IUUP_PROC_TIME_ALIGN:
	case IUUP_PROC_ERR_EVENT:
	default:
		LOG_CONN_RTP(conn_rtp_src, LOGL_ERROR,
			     "Received IuUP RNL STATUS procedure type %u not handled\n",
			     irp->u.status.procedure);
		rc = 0;
	}

	return rc;
}

/* Received RNL primitive from the IuUP layer FSM containing IuUP Status or
 * data. Continue pushing it up the stack, either IuUP Status or Data: */
static int _conn_iuup_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
{
	struct mgcp_conn_rtp *conn_rtp_src = ctx;
	struct osmo_iuup_rnl_prim *irp = (struct osmo_iuup_rnl_prim *)oph;
	struct msgb *msg = oph->msg;
	int rc;

	switch (OSMO_PRIM_HDR(&irp->oph)) {
	case OSMO_PRIM(OSMO_IUUP_RNL_DATA, PRIM_OP_INDICATION):
		/* we pass ownsership of msg here: */
		rc = _conn_iuup_rx_rnl_data(conn_rtp_src, irp);
		break;
	case OSMO_PRIM(OSMO_IUUP_RNL_STATUS, PRIM_OP_INDICATION):
		rc = _conn_iuup_rx_rnl_status(conn_rtp_src, irp);
		msgb_free(msg);
		break;
	default:
		msgb_free(msg);
		OSMO_ASSERT(false);
	}

	return rc;
}

/*! Send |RTP+IuUP| data down the stack of the specified destination connection.
 *  \param[in] endp associated endpoint (for configuration, logging).
 *  \param[in] buf buffer that contains the |RTP+IuUP| data.
 *  \param[in] len length of the buffer that contains the |RTP+IuUP| data.
 *  \param[in] conn_src associated source connection.
 *  \param[in] conn_dst associated destination connection.
 *  \returns 0 on success, -1 on ERROR. */
static int mgcp_send_iuup(struct mgcp_endpoint *endp, struct msgb *msg,
		   struct mgcp_conn_rtp *conn_src, struct mgcp_conn_rtp *conn_dst)
{
	/*! When no destination connection is available (e.g. when only one
	 *  connection in loopback mode exists), then the source connection
	 *  shall be specified as destination connection */

	struct mgcp_rtp_end *rtp_end;
	struct mgcp_rtp_state *rtp_state;
	char ipbuf[INET6_ADDRSTRLEN];
	struct rtp_hdr *hdr = (struct rtp_hdr *)msgb_data(msg);
	int buflen = msgb_length(msg);
	char *dest_name;
	int len;

	OSMO_ASSERT(conn_src);
	OSMO_ASSERT(conn_dst);

	LOGPENDP(endp, DRTP, LOGL_DEBUG, "delivering IuUP packet...\n");

	/* Note: In case of loopback configuration, both, the source and the
	 * destination will point to the same connection. */
	rtp_end = &conn_dst->end;
	rtp_state = &conn_src->state;
	dest_name = conn_dst->conn->name;

	/* Ensure we have an alternative SSRC in case we need it, see also
	 * gen_rtp_header() */
	if (rtp_state->alt_rtp_tx_ssrc == 0)
		rtp_state->alt_rtp_tx_ssrc = rand();

	if (!rtp_end->output_enabled) {
		rtpconn_rate_ctr_add(conn_dst, endp, RTP_DROPPED_PACKETS_CTR, 1);
		LOGPENDP(endp, DRTP, LOGL_DEBUG,
			 "output disabled, drop to %s %s "
			 "rtp_port:%u rtcp_port:%u\n",
			 dest_name,
			 osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),
			 ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)
			);
		return 0;
	}

	/* Specs say, in IuUP, the RTP seqnum and timestamp should actually be
	 * ignored by the receiver, but still it's useful for debug purposes
	 * to set it. Moreover, it seems ip.access nano3g produces much worse
	 * audio output on the air side if timestamp is not set properly. */
	hdr->timestamp = osmo_htonl(mgcp_get_current_ts(rtp_end->codec->rate));
	hdr->sequence = osmo_htons(rtp_state->alt_rtp_tx_sequence);
	hdr->ssrc = rtp_state->alt_rtp_tx_ssrc;

	LOGPENDP(endp, DRTP, LOGL_DEBUG,
		 "process/send IuUP to %s %s rtp_port:%u rtcp_port:%u\n",
		 dest_name, osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),
		 ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port));

	/* Forward a copy of the RTP data to a debug ip/port */
	forward_data_tap(rtp_end->rtp.fd, &conn_src->tap_out,
		     msg);

	len = mgcp_udp_send(rtp_end->rtp.fd, &rtp_end->addr, rtp_end->rtp_port,
			    (char *)hdr, buflen);

	if (len <= 0)
		return len;

	rtpconn_rate_ctr_add(conn_dst, endp, RTP_PACKETS_TX_CTR, 1);
	rtpconn_rate_ctr_add(conn_dst, endp, RTP_OCTETS_TX_CTR, len);
	rtp_state->alt_rtp_tx_sequence++;

	return len;
}

/* Received TNL primitive from IuUP layer FSM, transmit it further down to the
 * socket towards destination peer. */
static int _conn_iuup_transport_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
{
	struct mgcp_conn_rtp *conn_rtp_dst = ctx;
	struct mgcp_conn *conn_dst = conn_rtp_dst->conn;
	struct osmo_iuup_tnl_prim *itp = (struct osmo_iuup_tnl_prim *)oph;
	struct mgcp_conn *conn_src;
	struct msgb *msg;
	struct rtp_hdr *rtph;

	OSMO_ASSERT(OSMO_PRIM_HDR(&itp->oph) == OSMO_PRIM(OSMO_IUUP_TNL_UNITDATA, PRIM_OP_REQUEST));

	msg = oph->msg;
	talloc_steal(conn_rtp_dst->conn, msg);

	msgb_pull_to_l2(msg);
	rtph = (struct rtp_hdr *)msgb_push(msg, sizeof(*rtph));
	/* TODO: fill rtph properly: */
	*rtph = (struct rtp_hdr){
		.csrc_count = 0,
		.extension = 0,
		.padding = 0,
		.version = 2,
		.payload_type = conn_rtp_dst->end.codec->payload_type,
		.marker = 0,
		.sequence = 0,
		.timestamp = 0,
		.ssrc = 0
	};

	/* The destination of the destination conn is the source conn, right? */
	conn_src = _find_dst_conn(conn_dst);
	if (!conn_src) {
		LOG_CONN_RTP(conn_rtp_dst, LOGL_NOTICE,
			     "Couldn't find source conn for IuUP dst conn\n");
		/* If there's no sister connection we are either still
		 * initializing (so we want to send back Init (ACK)), or we are
		 * probably in loopback mode anyway, so use dst as src. */
		conn_src = conn_dst;
	}

	return mgcp_send_iuup(conn_dst->endp, msg, &conn_src->u.rtp, conn_rtp_dst);
}

/* Used to upgrade a regular RTP connection (MGCP_RTP_DEFAULT) to become a IuUP
 * connection (MGCP_RTP_IUUP) */
int mgcp_conn_iuup_init(struct mgcp_conn_rtp *conn_rtp)
{
	conn_rtp->type = MGCP_RTP_IUUP;
	conn_rtp->iuup.iui = osmo_iuup_instance_alloc(conn_rtp->conn, conn_rtp->conn->id);
	OSMO_ASSERT(conn_rtp->iuup.iui);
	osmo_iuup_instance_set_user_prim_cb(conn_rtp->iuup.iui, _conn_iuup_user_prim_cb, conn_rtp);
	osmo_iuup_instance_set_transport_prim_cb(conn_rtp->iuup.iui, _conn_iuup_transport_prim_cb, conn_rtp);
	conn_rtp->iuup.rfci_idx_no_data = -1;
	return 0;
}

/* Cleanup specific IuUP connection (MGCP_RTP_IUUP) state, allocated by mgcp_conn_iuup_init() */
void mgcp_conn_iuup_cleanup(struct mgcp_conn_rtp *conn_rtp)
{
	osmo_iuup_instance_free(conn_rtp->iuup.iui);
	conn_rtp->iuup.iui = NULL;
}

/* Received RTP+IuUP pkt from socket of conn_rtp_src, build a TNL primitive to
 * push it further up the stack to the IuUP layer FSM to handle and/or bridge it */
int mgcp_conn_iuup_dispatch_rtp(struct msgb *msg)
{
	struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);
	struct mgcp_conn_rtp *conn_rtp_src = mc->conn_src;
	int rc = 0;
	bool force_output_enabled = false;
	bool prev_output_enabled;
	struct osmo_sockaddr prev_rem_addr;
	uint16_t prev_rem_rtp_port;

	OSMO_ASSERT(mgcp_conn_rtp_is_iuup(conn_rtp_src));

	if ((rc = check_rtp_iuup(conn_rtp_src, msg)) < 0)
		goto free_ret;

	if (!conn_rtp_src->iuup.configured) {
		/* We received the first message without sending any, the peer is the active side (RNC). */
		rc = _conn_iuup_configure_as_passive(conn_rtp_src);
		if (rc < 0)
			goto free_ret;
		/* We need to force allowance of RTP containing Init-ACK back: */
		prev_output_enabled = conn_rtp_src->end.output_enabled;
		conn_rtp_src->end.output_enabled = true;
		force_output_enabled = true;
		/* Fill in the peer address so that we can send Init-ACK back: */
		prev_rem_addr = conn_rtp_src->end.addr;
		prev_rem_rtp_port = conn_rtp_src->end.rtp_port;
		conn_rtp_src->end.addr = *mc->from_addr;
		conn_rtp_src->end.rtp_port = htons(osmo_sockaddr_port(&mc->from_addr->u.sa));
	}

	rc = _conn_iuup_rtp_pl_up(conn_rtp_src, msg);

	if (force_output_enabled) {
		conn_rtp_src->end.output_enabled = prev_output_enabled;
		conn_rtp_src->end.addr = prev_rem_addr;
		conn_rtp_src->end.rtp_port = prev_rem_rtp_port;
	}

	return rc;
free_ret:
	msgb_free(msg);
	return rc;
}

/* Build IuUP RNL Data primitive from msg containing an incoming RTP pkt from
 * peer and send it down the IuUP layer towards the destination as IuUP/RTP: */
int mgcp_conn_iuup_send_rtp(struct mgcp_conn_rtp *conn_src_rtp, struct mgcp_conn_rtp *conn_dest_rtp, struct msgb *msg)
{
	struct osmo_iuup_rnl_prim *irp;
	struct rtp_hdr *rtph;
	int rc = -1;
	int iuup_length = 0;
	int8_t rfci;

	/* Tx RNL-DATA.req */
	rtph = (struct rtp_hdr *)msgb_data(msg);
	msgb_pull(msg, sizeof(*rtph));

	/* FIXME: validate amr packets */
	irp = osmo_iuup_rnl_prim_alloc(conn_dest_rtp->conn, OSMO_IUUP_RNL_DATA, PRIM_OP_REQUEST, MGW_IUUP_MSGB_SIZE);
	irp->u.data.frame_nr = htons(rtph->sequence) % 16;

	/* TODO: CMR handling & multiple frames handling */

	if (strcmp(conn_src_rtp->end.codec->subtype_name, "AMR") != 0) {
		LOG_CONN_RTP(conn_src_rtp, LOGL_ERROR,
			     "Bridge RTP=>IuUP: Bridging src codec %s to IuUP AMR not supported\n",
			     conn_src_rtp->end.codec->subtype_name);
		goto free_ret;
	}
	if (mgcp_codec_amr_is_octet_aligned(conn_src_rtp->end.codec)) {
		struct amr_hdr *amr_hdr = (struct amr_hdr *) msgb_data(msg);
		if (msgb_length(msg) < (sizeof(*amr_hdr))) {
			LOG_CONN_RTP(conn_src_rtp, LOGL_NOTICE,
				     "Bridge RTP=>IuUP: too short for AMR OA hdr (%u)\n", msgb_length(msg));
			goto free_ret;
		}
		if (amr_hdr->ft >= AMR_FT_MAX) {
			LOG_CONN_RTP(conn_src_rtp, LOGL_NOTICE, "Bridge RTP=>IuUP: wrong AMR OA ft=%u\n", amr_hdr->ft);
			goto free_ret;
		}
		if ((rfci =  _conn_iuup_amr_ft_2_rfci(conn_dest_rtp, amr_hdr->ft)) < 0) {
			LOG_CONN_RTP(conn_dest_rtp, LOGL_NOTICE, "Bridge RTP=>IuUP: No RFCI found for AMR OA ft=%u\n", amr_hdr->ft);
			goto free_ret;
		}
		irp->u.data.fqc = amr_hdr->q;
		irp->u.data.rfci = rfci;
		msgb_pull(msg, 2);
	} else {
		uint8_t *amr_bwe_hdr = (uint8_t *) msgb_data(msg);
		int8_t ft;
		if (msgb_length(msg) < 2) {
			LOG_CONN_RTP(conn_src_rtp, LOGL_NOTICE,
				     "Bridge RTP=>IuUP: too short for AMR BE hdr (%u)\n", msgb_length(msg));
			goto free_ret;
		}
		ft = ((amr_bwe_hdr[0] & 0x07) << 1) | ((amr_bwe_hdr[1] & 0x80) >> 7);
		if (ft >= AMR_FT_MAX) {
			LOG_CONN_RTP(conn_src_rtp, LOGL_NOTICE, "Bridge RTP=>IuUP: wrong AMR BE ft=%u\n", ft);
			goto free_ret;
		}
		if ((rfci =  _conn_iuup_amr_ft_2_rfci(conn_dest_rtp, ft)) < 0) {
			LOG_CONN_RTP(conn_dest_rtp, LOGL_NOTICE, "Bridge RTP=>IuUP: No RFCI found for AMR BE ft=%u\n", ft);
			goto free_ret;
		}
		irp->u.data.fqc = ((amr_bwe_hdr[1] & 0x40) >> 6);
		irp->u.data.rfci = rfci;
		rc = iuup_length = osmo_amr_bwe_to_iuup(msgb_data(msg), msgb_length(msg));
		if (rc < 0) {
			LOG_CONN_RTP(conn_dest_rtp, LOGL_ERROR, "Bridge RTP=>IuUP: Failed convert the RTP/AMR to IuUP payload\n");
			return rc;
		}
		msgb_trim(msg, iuup_length);
	}

	irp->oph.msg->l3h = msgb_put(irp->oph.msg, msgb_length(msg));
	memcpy(irp->oph.msg->l3h, msgb_data(msg), msgb_length(msg));
	if ((rc = osmo_iuup_rnl_prim_down(conn_dest_rtp->iuup.iui, irp)) != 0)
		LOG_CONN_RTP(conn_dest_rtp, LOGL_ERROR, "Bridge RTP=>IuUP: Failed Tx RTP payload down the IuUP layer\n");
	return rc;

free_ret:
	msgb_free(irp->oph.msg);
	return -1;
}

/* Build IuUP RNL Data primitive from msg containing dummy content and send it
 * down the IuUP layer towards the destination as IuUP/RTP: */
int mgcp_conn_iuup_send_dummy(struct mgcp_conn_rtp *conn_rtp)
{
	struct osmo_iuup_rnl_prim *irp;
	int rc;

	if (conn_rtp->iuup.rfci_idx_no_data == -1) {
		LOG_CONN_RTP(conn_rtp, LOGL_NOTICE, "No RFCI NO_DATA found, unable to send dummy packet\n");
		return -ENOTSUP;
	}

	irp = osmo_iuup_rnl_prim_alloc(conn_rtp->conn, OSMO_IUUP_RNL_DATA, PRIM_OP_REQUEST, MGW_IUUP_MSGB_SIZE);
	irp->u.data.frame_nr = 0;
	irp->u.data.fqc = IUUP_FQC_FRAME_GOOD;
	irp->u.data.rfci = conn_rtp->iuup.rfci_idx_no_data;
	irp->oph.msg->l3h = irp->oph.msg->tail;
	if ((rc = osmo_iuup_rnl_prim_down(conn_rtp->iuup.iui, irp)) != 0) {
		LOG_CONN_RTP(conn_rtp, LOGL_ERROR, "Failed Tx RTP dummy payload down the IuUP layer\n");
		return -EINVAL;
	}

	return 0;
}
