/* main MSC management code... */

/*
 * (C) 2010,2013 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010 by On-Waves
 *
 * 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/msc/osmo_msc.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/transaction.h>
#include <osmocom/msc/db.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/osmo_msc.h>
#include <osmocom/msc/a_iface.h>
#include <osmocom/msc/gsm_04_08.h>
#include <osmocom/msc/gsm_04_11.h>

#include "../../bscconfig.h"
#ifdef BUILD_IU
#include <osmocom/ranap/iu_client.h>
#else
#include <osmocom/msc/iu_dummy.h>
#endif

/* Receive a SAPI-N-REJECT from BSC */
void msc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci)
{
	int sapi = dlci & 0x7;

	if (sapi == UM_SAPI_SMS)
		gsm411_sapi_n_reject(conn);
}

static void subscr_conn_release_when_unused(struct gsm_subscriber_connection *conn)
{
	if (!conn)
		return;
	if (!conn->conn_fsm)
		return;
	if (!(conn->conn_fsm->state == SUBSCR_CONN_S_ACCEPTED
	      || conn->conn_fsm->state == SUBSCR_CONN_S_COMMUNICATING)) {
		DEBUGP(DMM, "%s: %s: conn still being established (%s)\n",
		       vlr_subscr_name(conn->vsub), __func__,
		       osmo_fsm_inst_state_name(conn->conn_fsm));
		return;
	}
	osmo_fsm_inst_dispatch(conn->conn_fsm, SUBSCR_CONN_E_RELEASE_WHEN_UNUSED, NULL);
}

/* receive a Level 3 Complete message and return MSC_CONN_ACCEPT or
 * MSC_CONN_REJECT */
int msc_compl_l3(struct gsm_subscriber_connection *conn,
		 struct msgb *msg, uint16_t chosen_channel)
{
	msc_subscr_conn_get(conn, MSC_CONN_USE_COMPL_L3);
	gsm0408_dispatch(conn, msg);

	subscr_conn_release_when_unused(conn);

	/* If this should be kept, the conn->conn_fsm has placed a use_count */
	msc_subscr_conn_put(conn, MSC_CONN_USE_COMPL_L3);

	/* Always return acceptance, because even if the conn was not accepted,
	 * we assumed ownership of it and the caller shall not interfere with
	 * that. We may even already have discarded the conn. */
	return MSC_CONN_ACCEPT;

#if 0
	/*
	 * If this is a silent call we want the channel to remain open as long as
	 * possible and this is why we accept this connection regardless of any
	 * pending transaction or ongoing operation.
	 */
	if (conn->silent_call)
		return MSC_CONN_ACCEPT;
	if (conn->loc_operation || conn->sec_operation || conn->anch_operation)
		return MSC_CONN_ACCEPT;
	if (trans_has_conn(conn))
		return MSC_CONN_ACCEPT;

	LOGP(DRR, LOGL_INFO, "MSC Complete L3: Rejecting connection.\n");
	return MSC_CONN_REJECT;
#endif
}

/* Receive a DTAP message from BSC */
void msc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg)
{
	msc_subscr_conn_get(conn, MSC_CONN_USE_DTAP);
	gsm0408_dispatch(conn, msg);

	subscr_conn_release_when_unused(conn);
	msc_subscr_conn_put(conn, MSC_CONN_USE_DTAP);
}

/* Receive an ASSIGNMENT COMPLETE from BSC */
void msc_assign_compl(struct gsm_subscriber_connection *conn,
		      uint8_t rr_cause, uint8_t chosen_channel,
		      uint8_t encr_alg_id, uint8_t speec)
{
	LOGP(DRR, LOGL_DEBUG, "MSC assign complete (do nothing).\n");
}

/* Receive an ASSIGNMENT FAILURE from BSC */
void msc_assign_fail(struct gsm_subscriber_connection *conn,
		     uint8_t cause, uint8_t *rr_cause)
{
	LOGP(DRR, LOGL_DEBUG, "MSC assign failure (do nothing).\n");
}

/* Receive a CLASSMARK CHANGE from BSC */
void msc_classmark_chg(struct gsm_subscriber_connection *conn,
		       const uint8_t *cm2, uint8_t cm2_len,
		       const uint8_t *cm3, uint8_t cm3_len)
{
	if (cm2 && cm2_len) {
		if (cm2_len > sizeof(conn->classmark.classmark2)) {
			LOGP(DRR, LOGL_NOTICE, "%s: classmark2 is %u bytes, truncating at %zu bytes\n",
			     vlr_subscr_name(conn->vsub), cm2_len, sizeof(conn->classmark.classmark2));
			cm2_len = sizeof(conn->classmark.classmark2);
		}
		conn->classmark.classmark2_len = cm2_len;
		memcpy(conn->classmark.classmark2, cm2, cm2_len);
	}
	if (cm3 && cm3_len) {
		if (cm3_len > sizeof(conn->classmark.classmark3)) {
			LOGP(DRR, LOGL_NOTICE, "%s: classmark3 is %u bytes, truncating at %zu bytes\n",
			     vlr_subscr_name(conn->vsub), cm3_len, sizeof(conn->classmark.classmark3));
			cm3_len = sizeof(conn->classmark.classmark3);
		}
		conn->classmark.classmark3_len = cm3_len;
		memcpy(conn->classmark.classmark3, cm3, cm3_len);
	}
}

/* Receive a CIPHERING MODE COMPLETE from BSC */
void msc_cipher_mode_compl(struct gsm_subscriber_connection *conn,
			   struct msgb *msg, uint8_t alg_id)
{
	struct vlr_ciph_result ciph_res = { .cause = VLR_CIPH_REJECT };

	if (!conn) {
		LOGP(DRR, LOGL_ERROR, "invalid: rx Ciphering Mode Complete on NULL conn\n");
		return;
	}
	if (!conn->vsub) {
		LOGP(DRR, LOGL_ERROR, "invalid: rx Ciphering Mode Complete for NULL subscr\n");
		return;
	}

	DEBUGP(DRR, "%s: CIPHERING MODE COMPLETE\n", vlr_subscr_name(conn->vsub));

	if (msg) {
		struct gsm48_hdr *gh = msgb_l3(msg);
		unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
		struct tlv_parsed tp;
		uint8_t mi_type;

		if (!gh) {
			LOGP(DRR, LOGL_ERROR, "invalid: msgb without l3 header\n");
			return;
		}

		tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);

		/* bearer capability */
		if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
			mi_type = TLVP_VAL(&tp, GSM48_IE_MOBILE_ID)[0] & GSM_MI_TYPE_MASK;
			if (mi_type == GSM_MI_TYPE_IMEISV
			    && TLVP_LEN(&tp, GSM48_IE_MOBILE_ID) > 0) {
				gsm48_mi_to_string(ciph_res.imeisv, sizeof(ciph_res.imeisv),
						   TLVP_VAL(&tp, GSM48_IE_MOBILE_ID),
						   TLVP_LEN(&tp, GSM48_IE_MOBILE_ID));
			}
		}
	}

	ciph_res.cause = VLR_CIPH_COMPL;
	vlr_subscr_rx_ciph_res(conn->vsub, &ciph_res);
}

struct gsm_subscriber_connection *msc_subscr_con_allocate(struct gsm_network *network)
{
	struct gsm_subscriber_connection *conn;

	conn = talloc_zero(network, struct gsm_subscriber_connection);
	if (!conn)
		return NULL;

	conn->network = network;
	llist_add_tail(&conn->entry, &network->subscr_conns);
	return conn;
}

void msc_subscr_cleanup(struct vlr_subscr *vsub)
{
	if (!vsub)
		return;
	vsub->lu_fsm = NULL;
}

void msc_subscr_con_cleanup(struct gsm_subscriber_connection *conn)
{
	if (!conn)
		return;

	if (conn->vsub) {
		DEBUGP(DRLL, "subscr %s: Freeing subscriber connection\n",
		       vlr_subscr_name(conn->vsub));
		msc_subscr_cleanup(conn->vsub);
		conn->vsub->msc_conn_ref = NULL;
		vlr_subscr_put(conn->vsub);
		conn->vsub = NULL;
	} else
		DEBUGP(DRLL, "Freeing subscriber connection"
		       " with NULL subscriber\n");

	if (!conn->conn_fsm)
		return;

	osmo_fsm_inst_term(conn->conn_fsm,
			   (conn->conn_fsm->state == SUBSCR_CONN_S_RELEASED)
				? OSMO_FSM_TERM_REGULAR
				: OSMO_FSM_TERM_ERROR,
			   NULL);
}

void msc_subscr_con_free(struct gsm_subscriber_connection *conn)
{
	if (!conn)
		return;

	msc_subscr_con_cleanup(conn);

	llist_del(&conn->entry);
	talloc_free(conn);
}

/* Receive a CLEAR REQUEST from BSC */
int msc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
{
	msc_subscr_conn_close(conn, cause);
	return 1;
}

static void msc_subscr_conn_release_all(struct gsm_subscriber_connection *conn, uint32_t cause)
{
	if (conn->in_release)
		return;
	conn->in_release = true;

	/* If we're closing in a middle of a trans, we need to clean up */
	trans_conn_closed(conn);

	switch (conn->via_ran) {
	case RAN_UTRAN_IU:
		ranap_iu_tx_release(conn->iu.ue_ctx, NULL);
		/* FIXME: keep the conn until the Iu Release Outcome is
		 * received from the UE, or a timeout expires. For now, the log
		 * says "unknown UE" for each release outcome. */
		break;
	case RAN_GERAN_A:
		a_iface_tx_clear_cmd(conn);
		break;
	default:
		LOGP(DMM, LOGL_ERROR, "%s: Unknown RAN type, cannot tx release/clear\n",
		     vlr_subscr_name(conn->vsub));
		break;
	}
}

/* If the conn->conn_fsm is still present, dispatch SUBSCR_CONN_E_CN_CLOSE
 * event to gracefully terminate the connection. If the conn_fsm is already
 * cleared, call msc_subscr_conn_release_all() to take release actions.
 * \param cause  a GSM_CAUSE_* constant, e.g. GSM_CAUSE_AUTH_FAILED.
 */
void msc_subscr_conn_close(struct gsm_subscriber_connection *conn,
			   uint32_t cause)
{
	if (!conn)
		return;
	if (conn->in_release) {
		DEBUGP(DMM, "msc_subscr_conn_close(vsub=%s, cause=%u):"
		       " already dispatching release, ignore.\n",
		       vlr_subscr_name(conn->vsub), cause);
		return;
	}
	if (!conn->conn_fsm) {
		DEBUGP(DMM, "msc_subscr_conn_close(vsub=%s, cause=%u): no conn fsm,"
		       " releasing directly without release event.\n",
		       vlr_subscr_name(conn->vsub), cause);
		/* In case of an IMSI Detach, we don't have conn_fsm. Release
		 * anyway to ensure a timely Iu Release / BSSMAP Clear. */
		msc_subscr_conn_release_all(conn, cause);
		return;
	}
	if (conn->conn_fsm->state == SUBSCR_CONN_S_RELEASED) {
		DEBUGP(DMM, "msc_subscr_conn_close(vsub=%s, cause=%u):"
		       " conn fsm already releasing, ignore.\n",
		       vlr_subscr_name(conn->vsub), cause);
		return;
	}
	osmo_fsm_inst_dispatch(conn->conn_fsm, SUBSCR_CONN_E_CN_CLOSE, &cause);
}

/* increment the ref-count. Needs to be called by every user */
struct gsm_subscriber_connection *
_msc_subscr_conn_get(struct gsm_subscriber_connection *conn,
		     enum msc_subscr_conn_use balance_token,
		     const char *file, int line)
{
	OSMO_ASSERT(conn);

	if (conn->in_release)
		LOGPSRC(DREF, LOGL_ERROR, file, line,
			"%s: MSC conn use error: using conn that is already in release (%s)\n",
			vlr_subscr_name(conn->vsub),
			msc_subscr_conn_use_name(balance_token));

	if (balance_token != MSC_CONN_USE_UNTRACKED) {
		uint32_t flag = 1 << balance_token;
		OSMO_ASSERT(balance_token < 32);
		if (conn->use_tokens & flag)
			LOGPSRC(DREF, LOGL_ERROR, file, line,
				"%s: MSC conn use error: using an already used token: %s\n",
				vlr_subscr_name(conn->vsub),
				msc_subscr_conn_use_name(balance_token));
		conn->use_tokens |= flag;
	}

	conn->use_count++;
	LOGPSRC(DREF, LOGL_DEBUG, file, line,
		"%s: MSC conn use + %s == %u (0x%x)\n",
		vlr_subscr_name(conn->vsub), msc_subscr_conn_use_name(balance_token),
		conn->use_count, conn->use_tokens);

	return conn;
}

/* decrement the ref-count. Once it reaches zero, we release */
void _msc_subscr_conn_put(struct gsm_subscriber_connection *conn,
			  enum msc_subscr_conn_use balance_token,
			  const char *file, int line)
{
	OSMO_ASSERT(conn);

	if (balance_token != MSC_CONN_USE_UNTRACKED) {
		uint32_t flag = 1 << balance_token;
		OSMO_ASSERT(balance_token < 32);
		if (!(conn->use_tokens & flag))
			LOGPSRC(DREF, LOGL_ERROR, file, line,
				"%s: MSC conn use error: freeing an unused token: %s\n",
				vlr_subscr_name(conn->vsub),
				msc_subscr_conn_use_name(balance_token));
		conn->use_tokens &= ~flag;
	}

	if (conn->use_count == 0) {
		LOGPSRC(DREF, LOGL_ERROR, file, line,
			"%s: MSC conn use - %s failed: is already 0\n",
			vlr_subscr_name(conn->vsub),
			msc_subscr_conn_use_name(balance_token));
		return;
	}

	conn->use_count--;
	LOGPSRC(DREF, LOGL_DEBUG, file, line,
		"%s: MSC conn use - %s == %u (0x%x)\n",
		vlr_subscr_name(conn->vsub), msc_subscr_conn_use_name(balance_token),
		conn->use_count, conn->use_tokens);

	if (conn->use_count == 0)
		msc_subscr_con_free(conn);
}

const struct value_string msc_subscr_conn_use_names[] = {
	{MSC_CONN_USE_UNTRACKED,	"UNTRACKED"},
	{MSC_CONN_USE_COMPL_L3,		"compl_l3"},
	{MSC_CONN_USE_DTAP,		"dtap"},
	{MSC_CONN_USE_FSM,		"fsm"},
	{MSC_CONN_USE_TRANS_CC,		"trans_cc"},
	{MSC_CONN_USE_TRANS_SMS,	"trans_sms"},
	{MSC_CONN_USE_TRANS_USSD,	"trans_ussd"},
	{MSC_CONN_USE_SILENT_CALL,	"silent_call"},
	{0, NULL},
};

void msc_stop_paging(struct vlr_subscr *vsub)
{
	DEBUGP(DPAG, "Paging can stop for %s\n", vlr_subscr_name(vsub));
	/* tell BSCs and RNCs to stop paging? How? */
}
