/* Code to manage MSC subscriber connections over IuCS interface */

/*
 * (C) 2016,2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 *
 * Author: Neels Hofmeyr <nhofmeyr@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 <inttypes.h>

#include <osmocom/core/logging.h>
#include <osmocom/ranap/iu_client.h>
#include <osmocom/msc/debug.h>

#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/gsm_subscriber.h>
#include <osmocom/msc/transaction.h>
#include <osmocom/msc/osmo_msc.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/core/byteswap.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 */

/* For A-interface see libbsc/bsc_api.c subscr_con_allocate() */
static struct gsm_subscriber_connection *subscr_conn_allocate_iu(struct gsm_network *network,
								 struct ranap_ue_conn_ctx *ue,
								 uint16_t lac)
{
	struct gsm_subscriber_connection *conn;

	DEBUGP(DIUCS, "Allocating IuCS subscriber conn: lac %d, conn_id %" PRIx32 "\n",
	       lac, ue->conn_id);

	conn = msc_subscr_conn_alloc(network, RAN_UTRAN_IU, lac);
	if (!conn)
		return NULL;

	conn->iu.ue_ctx = ue;
	conn->iu.ue_ctx->rab_assign_addr_enc = network->iu.rab_assign_addr_enc;
	return conn;
}

static int same_ue_conn(struct ranap_ue_conn_ctx *a, struct ranap_ue_conn_ctx *b)
{
	if (a == b)
		return 1;
	return (a->conn_id == b->conn_id);
}

static inline void log_subscribers(struct gsm_network *network)
{
	if (!log_check_level(DIUCS, LOGL_DEBUG))
		return;

	struct gsm_subscriber_connection *conn;
	int i = 0;
	llist_for_each_entry(conn, &network->subscr_conns, entry) {
		DEBUGP(DIUCS, "%3d: %s", i, vlr_subscr_name(conn->vsub));
		switch (conn->via_ran) {
		case RAN_UTRAN_IU:
			DEBUGPC(DIUCS, " Iu");
			if (conn->iu.ue_ctx) {
				DEBUGPC(DIUCS, " conn_id %d",
					conn->iu.ue_ctx->conn_id
				       );
			}
			break;
		case RAN_GERAN_A:
			DEBUGPC(DIUCS, " A");
			/* TODO log A-interface connection details */
			break;
		case RAN_UNKNOWN:
			DEBUGPC(DIUCS, " ?");
			break;
		default:
			DEBUGPC(DIUCS, " invalid");
			break;
		}
		DEBUGPC(DIUCS, "\n");
		i++;
	}
	DEBUGP(DIUCS, "subscribers registered: %d\n", i);
}

/* Return an existing IuCS subscriber connection record for the given
 * connection IDs, or return NULL if not found. */
struct gsm_subscriber_connection *subscr_conn_lookup_iu(
						struct gsm_network *network,
						struct ranap_ue_conn_ctx *ue)
{
	struct gsm_subscriber_connection *conn;

	DEBUGP(DIUCS, "Looking for IuCS subscriber: conn_id %" PRIx32 "\n",
	       ue->conn_id);
	log_subscribers(network);

	llist_for_each_entry(conn, &network->subscr_conns, entry) {
		if (conn->via_ran != RAN_UTRAN_IU)
			continue;
		if (!same_ue_conn(conn->iu.ue_ctx, ue))
			continue;
		DEBUGP(DIUCS, "Found IuCS subscriber for conn_id %" PRIx32 "\n",
		       ue->conn_id);
		return conn;
	}
	DEBUGP(DIUCS, "No IuCS subscriber found for conn_id %" PRIx32 "\n",
	       ue->conn_id);
	return NULL;
}

/* Receive MM/CC/... message from IuCS (SCCP user SAP).
 * msg->dst must reference a struct ranap_ue_conn_ctx, which identifies the peer that
 * sent the msg.
 *
 * For A-interface see libbsc/bsc_api.c gsm0408_rcvmsg(). */
int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg,
			uint16_t *lac)
{
	int rc;
	struct ranap_ue_conn_ctx *ue_ctx;
	struct gsm_subscriber_connection *conn;

	ue_ctx = (struct ranap_ue_conn_ctx*)msg->dst;

	/* TODO: are there message types that could allow us to skip this
	 * search? */
	conn = subscr_conn_lookup_iu(network, ue_ctx);

	if (conn && lac && (conn->lac != *lac)) {
		LOGP(DIUCS, LOGL_ERROR, "IuCS subscriber has changed LAC"
		     " within the same connection, discarding connection:"
		     " %s from LAC %d to %d\n",
		     vlr_subscr_name(conn->vsub), conn->lac, *lac);
		/* Deallocate conn with previous LAC */
		msc_subscr_conn_close(conn, GSM_CAUSE_INV_MAND_INFO);
		/* At this point we could be tolerant and allocate a new
		 * connection, but changing the LAC within the same connection
		 * is shifty. Rather cancel everything. */
		return -1;
	}

	if (conn) {
		/* Make sure we don't receive RR over IuCS; otherwise all
		 * messages handled by gsm0408_dispatch() are of interest (CC,
		 * MM, SMS, NS_SS, maybe even MM_GPRS and SM_GPRS). */
		struct gsm48_hdr *gh = msgb_l3(msg);
		uint8_t pdisc = gh->proto_discr & 0x0f;
		OSMO_ASSERT(pdisc != GSM48_PDISC_RR);

		msc_dtap(conn, ue_ctx->conn_id, msg);
		rc = 0;
	} else {
		/* allocate a new connection */

		if (!lac) {
			LOGP(DIUCS, LOGL_ERROR, "New IuCS subscriber"
			     " but no LAC available. Expecting an InitialUE"
			     " message containing a LAI IE."
			     " Dropping connection.\n");
			return -1;
		}

		conn = subscr_conn_allocate_iu(network, ue_ctx, *lac);
		if (!conn)
			abort();

		/* ownership of conn hereby goes to the MSC: */
		rc = msc_compl_l3(conn, msg, 0);
	}

	return rc;
}

int iu_rab_act_cs(struct gsm_trans *trans)
{
	struct gsm_subscriber_connection *conn;
	struct msgb *msg;
	bool use_x213_nsap;
	uint32_t conn_id;
	struct ranap_ue_conn_ctx *uectx;
	uint8_t rab_id;
	uint32_t rtp_ip;
	uint16_t rtp_port;

	conn = trans->conn;
	uectx = conn->iu.ue_ctx;
	rab_id = conn->iu.rab_id;
	rtp_ip = osmo_htonl(inet_addr(conn->rtp.local_addr_ran));
	rtp_port = conn->rtp.local_port_ran;
	conn_id = uectx->conn_id;

	if (rtp_ip == INADDR_NONE) {
		LOGP(DIUCS, LOGL_DEBUG,
		     "Assigning RAB: conn_id=%u, rab_id=%d, invalid RTP IP-Address\n",
		     conn_id, rab_id);
		return -EINVAL;
	}
	if (rtp_port == 0) {
		LOGP(DIUCS, LOGL_DEBUG,
		     "Assigning RAB: conn_id=%u, rab_id=%d, invalid RTP Port\n",
		     conn_id, rab_id);
		return -EINVAL;
	}

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

uint32_t iu_get_conn_id(const struct ranap_ue_conn_ctx *ue)
{
	return ue->conn_id;
}
