/* 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);
}

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? */
}
