/* MSC RAN connection implementation */

/*
 * (C) 2016-2018 by sysmocom s.m.f.c. <info@sysmocom.de>
 * All Rights Reserved
 *
 * 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 <osmocom/core/logging.h>
#include <osmocom/core/fsm.h>
#include <osmocom/core/signal.h>

#include <osmocom/msc/ran_conn.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/transaction.h>
#include <osmocom/msc/signal.h>
#include <osmocom/msc/sgs_iface.h>
#include <osmocom/msc/ran_peer.h>
#include <osmocom/msc/sccp_ran.h>
#include <osmocom/msc/ran_infra.h>
#include <osmocom/msc/msub.h>

struct ran_conn *ran_conn_create_incoming(struct ran_peer *ran_peer, uint32_t sccp_conn_id)
{
	struct ran_conn *conn;

	conn = talloc(ran_peer, struct ran_conn);
	OSMO_ASSERT(conn);

	*conn = (struct ran_conn){
		.ran_peer = ran_peer,
		.sccp_conn_id = sccp_conn_id,
	};

	llist_add(&conn->entry, &ran_peer->sri->ran_conns);
	return conn;
}

struct ran_conn *ran_conn_create_outgoing(struct ran_peer *ran_peer)
{
	/* FIXME use method being developed in gerrit id Ifd55c6b7ed2558ff072042079cf45f5068a971de */
	static uint32_t next_outgoing_conn_id = 2342;
	uint32_t conn_id = 0;
	int attempts = 1000;
	bool already_used = true;
	while (attempts--) {
		struct ran_conn *conn;

		conn_id = next_outgoing_conn_id;
		next_outgoing_conn_id++;

		already_used = false;
		llist_for_each_entry(conn, &ran_peer->sri->ran_conns, entry) {
			if (conn->sccp_conn_id == conn_id) {
				already_used = true;
				break;
			}
		}

		if (!already_used)
			break;
	}
	if (already_used)
		return NULL;
	LOG_RAN_PEER(ran_peer, LOGL_DEBUG, "Outgoing conn id: %u\n", conn_id);
	return ran_conn_create_incoming(ran_peer, conn_id);
}

/* Return statically allocated string of the ran_conn RAT type and id. */
const char *ran_conn_name(struct ran_conn *conn)
{
	static char id[42];
	int rc;
	const char *ran_peer_name;

	if (!conn)
		return "ran_conn==NULL";

	if (!conn->ran_peer || !conn->ran_peer->sri || !conn->ran_peer->sri->ran)
		ran_peer_name = "no-RAN-peer";
	else
		ran_peer_name = osmo_rat_type_name(conn->ran_peer->sri->ran->type);

	rc = snprintf(id, sizeof(id), "%s-%u", ran_peer_name, conn->sccp_conn_id);
	/* < 0 is error, == 0 is empty, >= size means truncation. Not really expecting this to catch on in any practical
	 * situation. */
	if (rc <= 0 || rc >= sizeof(id))
		return "conn-name-error";
	return id;
}

int ran_conn_down_l2_co(struct ran_conn *conn, struct msgb *l3, bool initial)
{
	struct ran_peer_ev_ctx co = {
		.conn_id = conn->sccp_conn_id,
		.conn = conn,
		.msg = l3,
	};
	if (!conn->ran_peer)
		return -EIO;
	return osmo_fsm_inst_dispatch(conn->ran_peer->fi,
				      initial ? RAN_PEER_EV_MSG_DOWN_CO_INITIAL : RAN_PEER_EV_MSG_DOWN_CO,
				      &co);
}

void ran_conn_msc_role_gone(struct ran_conn *conn, struct osmo_fsm_inst *msc_role)
{
	if (!conn)
		return;

	if (conn->msc_role != msc_role)
		return;

	conn->msc_role = NULL;
	ran_conn_close(conn);
}

/* Regularly close the conn */
void ran_conn_close(struct ran_conn *conn)
{
	if (!conn)
		return;
	if (conn->closing)
		return;
	conn->closing = true;
	LOG_RAN_PEER(conn->ran_peer, LOGL_DEBUG, "Closing %s\n", ran_conn_name(conn));

	if (conn->msc_role) {
		osmo_fsm_inst_dispatch(conn->msc_role, MSC_EV_FROM_RAN_CONN_RELEASED, NULL);
		conn->msc_role = NULL;
	}

	if (conn->ran_peer) {
		/* Todo: pass a useful SCCP cause? */
		sccp_ran_disconnect(conn->ran_peer->sri, conn->sccp_conn_id, 0);
		conn->ran_peer = NULL;
	}

	LOG_RAN_PEER(conn->ran_peer, LOGL_DEBUG, "Deallocating %s\n", ran_conn_name(conn));
	llist_del(&conn->entry);
	talloc_free(conn);
}

/* Same as ran_conn_close() but without sending any SCCP messages (e.g. after RESET) */
void ran_conn_discard(struct ran_conn *conn)
{
	if (!conn)
		return;
	/* Make sure to drop dead and don't dispatch things like DISCONNECT requests on SCCP. */
	conn->ran_peer = NULL;
	ran_conn_close(conn);
}
