/*
 * (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;
	uint8_t rfci_cnt = 0;
	/* Find RFCI containing NO_DATA: */
	for (i = 0; i < ARRAY_SIZE(irp->u.status.u.initialization.rfci); i++) {
		struct osmo_iuup_rfci *rfci = &irp->u.status.u.initialization.rfci[i];
		int j;
		bool is_no_data;
		if (!rfci->used)
			continue;
		rfci_cnt++;

		is_no_data = true;
		for (j = 0; j < irp->u.status.u.initialization.num_subflows; j++) {
			if (rfci->subflow_sizes[j]) {
				is_no_data = false;
				break;
			}
		}
		if (is_no_data)
			return rfci->id;

		/* early loop termination: */
		if (rfci_cnt == irp->u.status.u.initialization.num_subflows)
			break;
	}
	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;
	uint8_t rfci_cnt = 0;
	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 < ARRAY_SIZE(irp->u.status.u.initialization.rfci); i++) {
		struct osmo_iuup_rfci *rfci = &irp->u.status.u.initialization.rfci[i];
		int j;
		unsigned num_bits;
		if (!rfci->used)
			continue;
		rfci_cnt++;

		num_bits = 0;
		for (j = 0; j < irp->u.status.u.initialization.num_subflows; j++)
			num_bits += rfci->subflow_sizes[j];
		if (match_bytes == (num_bits + 7)/8)
			return rfci->id;

		/* early loop termination: */
		if (rfci_cnt == irp->u.status.u.initialization.num_subflows)
			break;
	}
	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_id_no_data = _find_rfci_no_data(init_ind);

	/* Copy over the rfci_id_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;
	irp2->u.config.IPTIs_present = irp->u.status.u.initialization.IPTIs_present;
	memcpy(irp2->u.config.rfci, irp->u.status.u.initialization.rfci, sizeof(irp2->u.config.rfci));
	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_RTP_OSMUX:
	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;

	if (conn_rtp_src->iuup.init_ind) {
		/* We received more than one IuUP Initialization. It's probably
		 * a retransmission, so simply ignore it (lower layers take care
		 * of ACKing it). */
		LOGPCONN(conn_rtp_src->conn, DRTP, LOGL_INFO,
		  "Ignoring potential IuUP Initialization retrans\n");
		return 0;
	}

	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;

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

	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_id_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_id_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_id_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;
}
