/* Implementation for MSC decisions which interface to send messages out on. */

/* (C) 2016 by sysmocom s.m.f.c GmbH <info@sysmocom.de>
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <osmocom/core/logging.h>

#include <osmocom/msc/debug.h>
#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/msc_ifaces.h>
#include <osmocom/msc/gsm_subscriber.h>
#include <osmocom/msc/transaction.h>
#include <osmocom/mgcp_client/mgcp_client.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/a_iface.h>
#include <osmocom/msc/gsm_04_08.h>

#include "../../bscconfig.h"

#ifdef BUILD_IU
#include <osmocom/ranap/iu_client.h>
extern struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id,
						   uint32_t rtp_ip,
						   uint16_t rtp_port,
						   bool use_x213_nsap);
#else
#include <osmocom/msc/iu_dummy.h>
#endif /* BUILD_IU */

static int msc_tx(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
	if (!msg)
		return -EINVAL;
	if (!conn) {
		msgb_free(msg);
		return -EINVAL;
	}

	DEBUGP(DMSC, "msc_tx %u bytes to %s via %s\n",
	       msg->len, vlr_subscr_name(conn->vsub),
	       ran_type_name(conn->via_ran));
	switch (conn->via_ran) {
	case RAN_GERAN_A:
		msg->dst = conn;
		return a_iface_tx_dtap(msg);

	case RAN_UTRAN_IU:
		msg->dst = conn->iu.ue_ctx;
		return ranap_iu_tx(msg, 0);

	default:
		LOGP(DMSC, LOGL_ERROR,
		     "msc_tx(): conn->via_ran invalid (%d)\n",
		     conn->via_ran);
		msgb_free(msg);
		return -1;
	}
}


int msc_tx_dtap(struct gsm_subscriber_connection *conn,
		struct msgb *msg)
{
	return msc_tx(conn, msg);
}


/* 9.2.5 CM service accept */
int msc_gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn)
{
	struct msgb *msg;
	struct gsm48_hdr *gh;

	if (!conn)
		return -EINVAL;

	msg = gsm48_msgb_alloc_name("GSM 04.08 SERV ACC");

	gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
	gh->proto_discr = GSM48_PDISC_MM;
	gh->msg_type = GSM48_MT_MM_CM_SERV_ACC;

	DEBUGP(DMM, "-> CM SERVICE ACCEPT %s\n",
	       vlr_subscr_name(conn->vsub));

	return msc_tx_dtap(conn, msg);
}

/* 9.2.6 CM service reject */
int msc_gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn,
			     enum gsm48_reject_value value)
{
	struct msgb *msg;

	if (!conn)
		return -EINVAL;

	conn->received_cm_service_request = false;

	msg = gsm48_create_mm_serv_rej(value);
	if (!msg) {
		LOGP(DMM, LOGL_ERROR, "Failed to allocate CM Service Reject.\n");
		return -1;
	}

	DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value);

	return msc_tx_dtap(conn, msg);
}

int msc_tx_common_id(struct gsm_subscriber_connection *conn)
{
	if (!conn)
		return -EINVAL;

	/* Common ID is only sent over IuCS */
	if (conn->via_ran != RAN_UTRAN_IU) {
		LOGP(DMM, LOGL_INFO,
		     "%s: Asked to transmit Common ID, but skipping"
		     " because this is not on UTRAN\n",
		     vlr_subscr_name(conn->vsub));
		return 0;
	}

	DEBUGP(DIUCS, "%s: tx CommonID %s\n",
	       vlr_subscr_name(conn->vsub), conn->vsub->imsi);
	return ranap_iu_tx_common_id(conn->iu.ue_ctx, conn->vsub->imsi);
}

static int iu_rab_act_cs(struct ranap_ue_conn_ctx *uectx, uint8_t rab_id,
			 uint32_t rtp_ip, uint16_t rtp_port)
{
#ifdef BUILD_IU
	struct msgb *msg;
	bool use_x213_nsap;
	uint32_t conn_id = uectx->conn_id;

	use_x213_nsap = (uectx->rab_assign_addr_enc == RANAP_NSAP_ADDR_ENC_X213);

	LOGP(DIUCS, LOGL_DEBUG, "Assigning RAB: conn_id=%u, rab_id=%d,"
	     " rtp=%x:%u, use_x213_nsap=%d\n", conn_id, rab_id, rtp_ip,
	     rtp_port, use_x213_nsap);

	msg = ranap_new_msg_rab_assign_voice(rab_id, rtp_ip, rtp_port,
					     use_x213_nsap);
	msg->l2h = msg->data;

	if (ranap_iu_rab_act(uectx, msg))
		LOGP(DIUCS, LOGL_ERROR, "Failed to send RAB Assignment:"
		     " conn_id=%d rab_id=%d rtp=%x:%u\n",
		     conn_id, rab_id, rtp_ip, rtp_port);
	return 0;
#else
	LOGP(DMSC, LOGL_ERROR, "Cannot send Iu RAB Assignment: built without Iu support\n");
	return -ENOTSUP;
#endif
}

static void mgcp_response_rab_act_cs_crcx(struct mgcp_response *r, void *priv)
{
	struct gsm_trans *trans = priv;
	struct gsm_subscriber_connection *conn = trans->conn;
	uint32_t rtp_ip;
	int rc;

	if (r->head.response_code != 200) {
		LOGP(DMGCP, LOGL_ERROR,
		     "MGCPGW response yields error: %d %s\n",
		     r->head.response_code, r->head.comment);
		goto rab_act_cs_error;
	}

	rc = mgcp_response_parse_params(r);
	if (rc) {
		LOGP(DMGCP, LOGL_ERROR,
		     "Cannot parse MGCP response, for %s\n",
		     vlr_subscr_name(trans->vsub));
		goto rab_act_cs_error;
	}

	conn->rtp.port_cn = r->audio_port;

	rtp_ip = mgcp_client_remote_addr_n(conn->network->mgw.client);

	if (trans->conn->via_ran == RAN_UTRAN_IU) {
		/* Assign a voice channel via RANAP on 3G */
		if (iu_rab_act_cs(conn->iu.ue_ctx, conn->iu.rab_id, rtp_ip, conn->rtp.port_subscr))
			goto rab_act_cs_error;
	} else if (trans->conn->via_ran == RAN_GERAN_A) {
		/* Assign a voice channel via A on 2G */
		if (a_iface_tx_assignment(trans))
			goto rab_act_cs_error;
	} else
		goto rab_act_cs_error;

	/* Respond back to MNCC (if requested) */
	if (trans->tch_rtp_create) {
		if (gsm48_tch_rtp_create(trans))
			goto rab_act_cs_error;
	}
	return;

rab_act_cs_error:
	/* FIXME abort call, invalidate conn, ... */
	LOGP(DMSC, LOGL_ERROR, "%s: failure during assignment\n",
	     vlr_subscr_name(trans->vsub));
	return;
}

int msc_call_assignment(struct gsm_trans *trans)
{
	struct gsm_subscriber_connection *conn;
	struct mgcp_client *mgcp;
	struct msgb *msg;
	uint16_t bts_base;

	if (!trans)
		return -EINVAL;
	if (!trans->conn)
		return -EINVAL;

	conn = trans->conn;
	mgcp = conn->network->mgw.client;

#ifdef BUILD_IU
	/* FIXME: HACK. where to scope the RAB Id? At the conn / subscriber / ranap_ue_conn_ctx? */
	static uint8_t next_iu_rab_id = 1;
	if (conn->via_ran == RAN_UTRAN_IU)
		conn->iu.rab_id = next_iu_rab_id ++;
#endif

	conn->rtp.mgcp_rtp_endpoint =
		mgcp_client_next_endpoint(conn->network->mgw.client);

	/* This will calculate the port we assign to the BTS via AoIP
	 * assignment command (or rab-assignment on 3G) The BTS will send
	 * its RTP traffic to that port on the MGCPGW side. The MGCPGW only
	 * gets the endpoint ID via the CRCX. It will do the same calculation
	 * on his side too to get knowledge of the rtp port. */
	bts_base = mgcp_client_conf_actual(mgcp)->bts_base;
	conn->rtp.port_subscr = bts_base + 2 * conn->rtp.mgcp_rtp_endpoint;

	/* Establish the RTP stream first as looping back to the originator.
	 * The MDCX will patch through to the counterpart. TODO: play a ring
	 * tone instead. */
	msg = mgcp_msg_crcx(mgcp, conn->rtp.mgcp_rtp_endpoint,
			    conn->rtp.mgcp_rtp_endpoint, MGCP_CONN_LOOPBACK);
	return mgcp_client_tx(mgcp, msg, mgcp_response_rab_act_cs_crcx, trans);
}

static void mgcp_response_bridge_mdcx(struct mgcp_response *r, void *priv);

static void mgcp_bridge(struct gsm_trans *from, struct gsm_trans *to,
			enum bridge_state state,
			enum mgcp_connection_mode mode)
{
	struct gsm_subscriber_connection *conn1 = from->conn;
	struct gsm_subscriber_connection *conn2 = to->conn;
	struct mgcp_client *mgcp = conn1->network->mgw.client;
	const char *ip;
	struct msgb *msg;

	OSMO_ASSERT(mgcp);

	from->bridge.peer = to;
	from->bridge.state = state;

	/* Loop back to the same MGCP GW */
	ip = mgcp_client_remote_addr_str(mgcp);

	msg = mgcp_msg_mdcx(mgcp,
			    conn1->rtp.mgcp_rtp_endpoint,
			    ip, conn2->rtp.port_cn,
			    mode);
	if (mgcp_client_tx(mgcp, msg, mgcp_response_bridge_mdcx, from))
		LOGP(DMGCP, LOGL_ERROR,
		     "Failed to send MDCX message for %s\n",
		     vlr_subscr_name(from->vsub));
}

static void mgcp_response_bridge_mdcx(struct mgcp_response *r, void *priv)
{
	struct gsm_trans *trans = priv;
	struct gsm_trans *peer = trans->bridge.peer;

	switch (trans->bridge.state) {
	case BRIDGE_STATE_LOOPBACK_PENDING:
		trans->bridge.state = BRIDGE_STATE_LOOPBACK_ESTABLISHED;

		switch (peer->bridge.state) {
		case BRIDGE_STATE_LOOPBACK_PENDING:
			/* Wait until the other is done as well. */
			return;
		case BRIDGE_STATE_LOOPBACK_ESTABLISHED:
			/* Now that both are in loopback, switch both to
			 * forwarding. */
			mgcp_bridge(trans, peer, BRIDGE_STATE_BRIDGE_PENDING,
				    MGCP_CONN_RECV_SEND);
			mgcp_bridge(peer, trans, BRIDGE_STATE_BRIDGE_PENDING,
				    MGCP_CONN_RECV_SEND);
			break;
		default:
			LOGP(DMGCP, LOGL_ERROR,
			     "Unexpected bridge state: %d for %s\n",
			     trans->bridge.state, vlr_subscr_name(trans->vsub));
			break;
		}
		break;

	case BRIDGE_STATE_BRIDGE_PENDING:
		trans->bridge.state = BRIDGE_STATE_BRIDGE_ESTABLISHED;
		break;

	default:
		LOGP(DMGCP, LOGL_ERROR,
		     "Unexpected bridge state: %d for %s\n",
		     trans->bridge.state, vlr_subscr_name(trans->vsub));
		break;
	}
}

int msc_call_connect(struct gsm_trans *trans, uint16_t port, uint32_t ip)
{
	/* With this function we inform the MGCP-GW  where (ip/port) it
	 * has to send its outgoing voic traffic. The receiving end will
	 * usually be a PBX (e.g. Asterisk). The IP-Address we tell, will
	 * not only be used to direct the traffic, it will also be used
	 * as a filter to make sure only RTP packets from the right
	 * remote end will reach the BSS. This is also the reason why
	 * inbound audio will not work until this step is performed */

	/* NOTE: This function is used when msc_call_bridge(), is not
	 * applicable. This is usually the case when an external MNCC
	 * is in use */

	struct gsm_subscriber_connection *conn;
	struct mgcp_client *mgcp;
	struct msgb *msg;

	if (!trans)
		return -EINVAL;
	if (!trans->conn)
		return -EINVAL;
	if (!trans->conn->network)
		return -EINVAL;
	if (!trans->conn->network->mgw.client)
		return -EINVAL;

	mgcp = trans->conn->network->mgw.client;

	struct in_addr ip_addr;
	ip_addr.s_addr = ntohl(ip);

	conn = trans->conn;

	msg = mgcp_msg_mdcx(mgcp,
			    conn->rtp.mgcp_rtp_endpoint,
			    inet_ntoa(ip_addr), port, MGCP_CONN_RECV_SEND);
	if (mgcp_client_tx(mgcp, msg, NULL, trans))
		LOGP(DMGCP, LOGL_ERROR,
		     "Failed to send MDCX message for %s\n",
		     vlr_subscr_name(trans->vsub));

	return 0;
}

int msc_call_bridge(struct gsm_trans *trans1, struct gsm_trans *trans2)
{
	if (!trans1)
		return -EINVAL;
	if (!trans2)
		return -EINVAL;

	/* First setup as loopback and configure the counterparts' endpoints,
	 * so that when transmission starts the originating addresses are
	 * already known to be valid. The mgcp callback will continue. */
	mgcp_bridge(trans1, trans2, BRIDGE_STATE_LOOPBACK_PENDING,
		    MGCP_CONN_LOOPBACK);
	mgcp_bridge(trans2, trans1, BRIDGE_STATE_LOOPBACK_PENDING,
		    MGCP_CONN_LOOPBACK);

	return 0;
}

void msc_call_release(struct gsm_trans *trans)
{
	struct msgb *msg;
	struct gsm_subscriber_connection *conn;
	struct mgcp_client *mgcp;

	if (!trans)
		return;
	if (!trans->conn)
		return;
	if (!trans->conn->network)
		return;

	conn = trans->conn;
	mgcp = conn->network->mgw.client;

	/* Send DLCX */
	msg = mgcp_msg_dlcx(mgcp, conn->rtp.mgcp_rtp_endpoint,
			    conn->rtp.mgcp_rtp_endpoint);
	if (mgcp_client_tx(mgcp, msg, NULL, NULL))
		LOGP(DMGCP, LOGL_ERROR,
		     "Failed to send DLCX message for %s\n",
		     vlr_subscr_name(trans->vsub));

	/* Release endpoint id */
	mgcp_client_release_endpoint(conn->rtp.mgcp_rtp_endpoint, mgcp);
}
