/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
 * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2009 by Mike Haben <michael.haben@btinternet.com>
 * (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com>
 *
 * 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/>.
 *
 */

/**
 * MSC-specific handling of call independent Supplementary
 * Services messages (NC_SS) according to GSM TS 09.11
 * "Signalling interworking for supplementary services".
 */

#include <stdio.h>
#include <errno.h>
#include <stdbool.h>

#include <osmocom/core/linuxlist.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stat_item.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/msgb.h>

#include <osmocom/gsm/protocol/gsm_04_80.h>
#include <osmocom/gsm/gsm0480.h>
#include <osmocom/gsm/tlv.h>

#include <osmocom/msc/gsm_04_80.h>
#include <osmocom/msc/gsm_subscriber.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/gsm_04_08.h>
#include <osmocom/msc/transaction.h>
#include <osmocom/gsupclient/gsup_client.h>
#include <osmocom/msc/msc_a.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/paging.h>
#include <osmocom/msc/gsup_client_mux.h>

/* FIXME: choose a proper range */
static uint32_t new_callref = 0x20000001;

static void ncss_session_timeout_handler(void *_trans)
{
	struct gsm_trans *trans = (struct gsm_trans *) _trans;
	struct osmo_gsup_message gsup_msg;

	/* The timeout might be disabled from the VTY */
	if (trans->net->ncss_guard_timeout == 0)
		return;

	LOG_TRANS(trans, LOGL_NOTICE, "SS/USSD session timeout, releasing\n");

	/* Indicate connection release to subscriber (if active) */
	if (trans->msc_a != NULL) {
		/* This pair of cause location and value is used by commercial networks */
		msc_send_ussd_release_complete_cause(trans->msc_a, trans->transaction_id,
			GSM48_CAUSE_LOC_PUN_S_LU, GSM48_CC_CAUSE_NORMAL_UNSPEC);
	}

	/* Terminate GSUP session with EUSE */
	gsup_msg = (struct osmo_gsup_message){
		.message_type = OSMO_GSUP_MSGT_PROC_SS_ERROR,

		.session_state = OSMO_GSUP_SESSION_STATE_END,
		.session_id = trans->callref,
		.cause = GMM_CAUSE_NET_FAIL,

		.message_class = OSMO_GSUP_MESSAGE_CLASS_USSD,
	};

	OSMO_STRLCPY_ARRAY(gsup_msg.imsi, trans->vsub->imsi);

	gsup_client_mux_tx(trans->net->gcm, &gsup_msg);

	/* Finally, release this transaction */
	trans_free(trans);
}

/* Entry point for call independent MO SS messages */
int gsm0911_rcv_nc_ss(struct msc_a *msc_a, struct msgb *msg)
{
	struct gsm_network *net;
	struct vlr_subscr *vsub;
	struct gsm48_hdr *gh = msgb_l3(msg);
	struct osmo_gsup_message gsup_msg;
	struct gsm_trans *trans;
	uint16_t facility_ie_len;
	uint8_t *facility_ie;
	uint8_t tid;
	uint8_t msg_type;
	int rc;

	net = msc_a_net(msc_a);
	OSMO_ASSERT(net);

	vsub = msc_a_vsub(msc_a);
	if (!vsub) {
		LOG_MSC_A(msc_a, LOGL_ERROR, "No vlr_subscr set for this conn\n");
		return -EINVAL;
	}

	msg_type = gsm48_hdr_msg_type(gh);
	tid = gsm48_hdr_trans_id_flip_ti(gh);

	/* Associate logging messages with this subscriber */
	log_set_context(LOG_CTX_VLR_SUBSCR, vsub);

	/* Reuse existing transaction, or create a new one */
	trans = trans_find_by_id(msc_a, TRANS_USSD, tid);
	if (!trans) {
		/* Count MS-initiated attempts to establish a NC SS/USSD session */
		rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS]);

		/**
		 * According to GSM TS 04.80, section 2.4.2 "Register
		 * (mobile station to network direction)", the REGISTER
		 * message is sent by the mobile station to the network
		 * to assign a new transaction identifier for call independent
		 * supplementary service control and to request or acknowledge
		 * a supplementary service.
		 */
		if (msg_type != GSM0480_MTYPE_REGISTER) {
			LOGP(DSS, LOGL_ERROR, "Rx %s message for non-existing transaction (tid-%u)\n",
				  gsm48_pdisc_msgtype_name(GSM48_PDISC_NC_SS, msg_type),
				  gsm48_hdr_trans_id(gh));
			gsm48_tx_simple(msc_a,
				GSM48_PDISC_NC_SS | (tid << 4),
				GSM0480_MTYPE_RELEASE_COMPLETE);
			return -EINVAL;
		}

		trans = trans_alloc(net, vsub, TRANS_USSD, tid, new_callref++);
		if (!trans) {
			LOGP(DSS, LOGL_ERROR, " -> No memory for trans\n");
			gsm48_tx_simple(msc_a,
				GSM48_PDISC_NC_SS | (tid << 4),
				GSM0480_MTYPE_RELEASE_COMPLETE);
			return -ENOMEM;
		}

		/* Init inactivity timer */
		osmo_timer_setup(&trans->ss.timer_guard,
			ncss_session_timeout_handler, trans);

		/* Count active NC SS/USSD sessions */
		osmo_stat_item_inc(net->statg->items[MSC_STAT_ACTIVE_NC_SS], 1);

		trans->dlci = OMSC_LINKID_CB(msg);
		trans->msc_a = msc_a;
		msc_a_get(msc_a, MSC_A_USE_NC_SS);

		osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_TRANSACTION_ACCEPTED, trans);

		/* An earlier CM Service Request for this SS message now has concluded */
		if (!osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_SS))
			LOG_MSC_A(msc_a, LOGL_ERROR,
				  "Creating new MO SS transaction without prior CM Service Request\n");
		else
			msc_a_put(msc_a, MSC_A_USE_CM_SERVICE_SS);
	}

	LOG_TRANS(trans, LOGL_DEBUG, "Received SS/USSD msg %s\n",
		  gsm48_pdisc_msgtype_name(GSM48_PDISC_NC_SS, msg_type));

	/* (Re)schedule the inactivity timer */
	if (net->ncss_guard_timeout > 0) {
		osmo_timer_schedule(&trans->ss.timer_guard, net->ncss_guard_timeout, 0);
	}

	/* Attempt to extract Facility IE */
	rc = gsm0480_extract_ie_by_tag(gh, msgb_l3len(msg),
		&facility_ie, &facility_ie_len, GSM0480_IE_FACILITY);
	if (rc) {
		LOG_TRANS(trans, LOGL_ERROR, "GSM 04.80 message parsing error, couldn't extract Facility IE\n");
		goto error;
	}

	/* Facility IE is optional for RELEASE COMPLETE */
	if (msg_type != GSM0480_MTYPE_RELEASE_COMPLETE) {
		if (!facility_ie || facility_ie_len < 2) {
			LOG_TRANS(trans, LOGL_ERROR, "GSM 04.80 message parsing error,"
				  " missing mandatory Facility IE\n");
			rc = -EINVAL;
			goto error;
		}
	}

	/* Compose a mew GSUP message */
	gsup_msg = (struct osmo_gsup_message){
		.message_type = OSMO_GSUP_MSGT_PROC_SS_REQUEST,
		.session_id = trans->callref,
		.message_class = OSMO_GSUP_MESSAGE_CLASS_USSD,
	};

	/**
	 * Perform A-interface to GSUP-interface mapping,
	 * according to GSM TS 09.11, table 4.2.
	 */
	switch (msg_type) {
	case GSM0480_MTYPE_REGISTER:
		gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_BEGIN;
		break;
	case GSM0480_MTYPE_FACILITY:
		gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_CONTINUE;
		break;
	case GSM0480_MTYPE_RELEASE_COMPLETE:
		gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_END;
		break;
	}

	/* Fill in the (optional) message payload */
	if (facility_ie) {
		gsup_msg.ss_info_len = facility_ie_len;
		gsup_msg.ss_info = facility_ie;
	}

	/* Fill in subscriber's IMSI */
	OSMO_STRLCPY_ARRAY(gsup_msg.imsi, vsub->imsi);

	rc = gsup_client_mux_tx(trans->net->gcm, &gsup_msg);

	/* Should we release connection? Or wait for response? */
	if (msg_type == GSM0480_MTYPE_RELEASE_COMPLETE)
		trans_free(trans);

	/* Count established MS-initiated NC SS/USSD sessions */
	if (msg_type == GSM0480_MTYPE_REGISTER)
		rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED]);

	return rc;

error:
	/* Abort transaction on DTAP-interface */
	msc_send_ussd_reject(msc_a, tid, -1,
		GSM_0480_PROBLEM_CODE_TAG_GENERAL,
		GSM_0480_GEN_PROB_CODE_UNRECOGNISED);
	if (trans)
		trans_free(trans);

	/* TODO: abort transaction on GSUP interface if any */
	return rc;
}

/* Call-back from paging the B-end of the connection */
static void ss_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans)
{
	struct gsm48_hdr *gh;
	struct msgb *ss_msg;

	if (trans->msc_a) {
		LOG_MSC_A_CAT(msc_a, DPAG, LOGL_ERROR,
			      "Handle paging error: transaction already associated with subscriber,"
			      " apparently it was already handled. Skip.\n");
		return;
	}
	OSMO_ASSERT(trans->ss.msg);

	if (msc_a) {
		struct gsm_network *net = msc_a_net(msc_a);
		LOG_MSC_A_CAT(msc_a, DSS, LOGL_DEBUG, "Paging succeeded\n");

		/* Assign connection */
		msc_a_get(msc_a, MSC_A_USE_NC_SS);
		trans->msc_a = msc_a;
		trans->paging_request = NULL;

		/* (Re)schedule the inactivity timer */
		if (net->ncss_guard_timeout > 0) {
			osmo_timer_schedule(&trans->ss.timer_guard, net->ncss_guard_timeout, 0);
		}

		/* Send stored message */
		ss_msg = trans->ss.msg;
		gh = (struct gsm48_hdr *) msgb_push(ss_msg, sizeof(*gh));
		gh->proto_discr  = GSM48_PDISC_NC_SS;
		gh->proto_discr |= trans->transaction_id << 4;
		gh->msg_type = GSM0480_MTYPE_REGISTER;

		/* Sent to the MS, give ownership of ss_msg */
		msc_a_tx_dtap_to_i(msc_a, ss_msg);
		trans->ss.msg = NULL;

		/* Count established network-initiated NC SS/USSD sessions */
		rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED]);
	} else {
		struct osmo_gsup_message gsup_msg;

		LOG_MSC_A_CAT(msc_a, DSS, LOGL_DEBUG, "Paging expired\n");

		gsup_msg = (struct osmo_gsup_message){
			.message_class = OSMO_GSUP_MESSAGE_CLASS_USSD,
			.message_type = OSMO_GSUP_MSGT_PROC_SS_ERROR,

			.session_state = OSMO_GSUP_SESSION_STATE_END,
			.session_id = trans->callref,
			/* FIXME: we need message class specific cause values */
			.cause = GMM_CAUSE_IMPL_DETACHED,
		};

		/* Fill in subscriber's IMSI */
		OSMO_STRLCPY_ARRAY(gsup_msg.imsi, trans->vsub->imsi);

		/* Inform HLR/EUSE about the failure */
		gsup_client_mux_tx(trans->net->gcm, &gsup_msg);

		msgb_free(trans->ss.msg);
		trans->ss.msg = NULL;

		trans->callref = 0;
		trans->paging_request = NULL;
		trans_free(trans);
	}
}

static struct gsm_trans *establish_nc_ss_trans(struct gsm_network *net,
	struct vlr_subscr *vsub, const struct osmo_gsup_message *gsup_msg)
{
	struct msc_a *msc_a;
	struct gsm_trans *trans;
	int tid;

	if (gsup_msg->session_state != OSMO_GSUP_SESSION_STATE_BEGIN) {
		LOGP(DSS, LOGL_ERROR, "Received non-BEGIN message for non-existing transaction\n");
		return NULL;
	}

	LOGP(DSS, LOGL_DEBUG, "(%s) Establishing a network-originated session (id=0x%x)\n",
			      vlr_subscr_name(vsub), gsup_msg->session_id);

	if (!gsup_msg->ss_info || gsup_msg->ss_info_len < 2) {
		LOGP(DSS, LOGL_ERROR, "Missing mandatory Facility IE\n");
		return NULL;
	}

	/* Obtain an unused transaction ID */
	tid = trans_assign_trans_id(net, vsub, TRANS_USSD);
	if (tid < 0) {
		LOGP(DSS, LOGL_ERROR, "No free transaction ID\n");
		return NULL;
	}

	/* Allocate a new NCSS transaction */
	trans = trans_alloc(net, vsub, TRANS_USSD, tid, gsup_msg->session_id);
	if (!trans) {
		LOGP(DSS, LOGL_ERROR, " -> No memory for trans\n");
		return NULL;
	}

	/* Count active NC SS/USSD sessions */
	osmo_stat_item_inc(net->statg->items[MSC_STAT_ACTIVE_NC_SS], 1);

	/* Init inactivity timer */
	osmo_timer_setup(&trans->ss.timer_guard,
		ncss_session_timeout_handler, trans);

	/* Attempt to find connection */
	msc_a = msc_a_for_vsub(vsub, true);
	if (msc_a) {
		/* Assign connection */
		msc_a_get(msc_a, MSC_A_USE_NC_SS);
		trans->msc_a = msc_a;
		trans->dlci = 0x00; /* SAPI=0, not SACCH */
		return trans;
	}

	LOG_TRANS(trans, LOGL_DEBUG, "Triggering Paging Request\n");

	/* Trigger Paging Request */
	trans->paging_request = paging_request_start(vsub, PAGING_CAUSE_SIGNALLING_HIGH_PRIO,
						     ss_paging_cb, trans, "GSM 09.11 SS/USSD");
	if (!trans->paging_request) {
		LOG_TRANS(trans, LOGL_ERROR, "Failed to allocate paging token\n");
		trans_free(trans);
		return NULL;
	}

	/* Store the Facility IE to be sent */
	OSMO_ASSERT(trans->ss.msg == NULL);
	trans->ss.msg = gsm48_msgb_alloc_name("GSM 04.08 SS/USSD");
	msgb_tlv_put(trans->ss.msg, GSM0480_IE_FACILITY,
		gsup_msg->ss_info_len, gsup_msg->ss_info);

	return trans;
}

/* NC SS specific transaction release.
 * Gets called by trans_free, DO NOT CALL YOURSELF! */
void _gsm911_nc_ss_trans_free(struct gsm_trans *trans)
{
	/**
	 * TODO: if transaction wasn't properly terminated,
	 * we need to do it here by releasing the subscriber
	 * connection and sending notification via GSUP...
	 */
	if (trans->ss.msg != NULL)
		msgb_free(trans->ss.msg);

	/* Stop inactivity timer */
	osmo_timer_del(&trans->ss.timer_guard);

	/* One session less */
	osmo_stat_item_dec(trans->net->statg->items[MSC_STAT_ACTIVE_NC_SS], 1);
}

int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_message *gsup_msg)
{
	struct gsm_network *net = (struct gsm_network *) data;
	struct gsm_trans *trans;
	struct gsm48_hdr *gh;
	struct msgb *ss_msg;
	bool trans_end;
	struct msc_a *msc_a;
	struct vlr_subscr *vsub;

	vsub = vlr_subscr_find_by_imsi(net->vlr, gsup_msg->imsi, __func__);
	if (!vsub) {
		LOGP(DSS, LOGL_ERROR, "Rx %s for unknown subscriber, rejecting\n",
		     osmo_gsup_message_type_name(gsup_msg->message_type));
		gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_IMSI_UNKNOWN);
		return -GMM_CAUSE_IMSI_UNKNOWN;
	}

	/* Associate logging messages with this subscriber */
	log_set_context(LOG_CTX_VLR_SUBSCR, vsub);

	/* Attempt to find DTAP-transaction */
	trans = trans_find_by_callref(net, gsup_msg->session_id);

	/* Handle errors */
	if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) {
		LOGP(DSS, LOGL_NOTICE, "Rx %s from HLR/EUSE (cause=0x%02x, sid=0x%x)\n",
		     osmo_gsup_message_type_name(gsup_msg->message_type),
		     gsup_msg->cause, gsup_msg->session_id);

		/* We don't need subscriber info anymore */
		vlr_subscr_put(vsub, __func__);

		if (!trans) {
			LOGP(DSS, LOGL_ERROR, "No transaction found for "
			     "sid=0x%x, nothing to abort\n", gsup_msg->session_id);
			return -ENODEV;
		}

		LOG_TRANS(trans, LOGL_NOTICE, "Aborting the session: sending RELEASE COMPLETE\n");

		/* Indicate connection release to subscriber (if active) */
		if (trans->msc_a != NULL) {
			/* TODO: implement GSUP - GSM 04.80 cause mapping */
			msc_send_ussd_release_complete_cause(trans->msc_a, trans->transaction_id,
				GSM48_CAUSE_LOC_PUN_S_LU, GSM48_CC_CAUSE_TEMP_FAILURE);
		}

		/* Terminate transaction */
		trans_free(trans);

		return 0;
	}

	if (!trans) {
		/* Count network-initiated attempts to establish a NC SS/USSD session */
		rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS]);

		/* Attempt to establish a new transaction */
		trans = establish_nc_ss_trans(net, vsub, gsup_msg);
		if (!trans) {
			LOGP(DSS, LOGL_ERROR, "Failed to establish a network-originated "
					      "SS/USSD transaction, rejecting %s\n",
					      osmo_gsup_message_type_name(gsup_msg->message_type));
			gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_NET_FAIL);
			vlr_subscr_put(vsub, __func__);
			return -EINVAL;
		}

		/* Wait for Paging Response */
		if (trans->paging_request) {
			vlr_subscr_put(vsub, __func__);
			return 0;
		}
	}

	/* We don't need subscriber info anymore */
	vlr_subscr_put(vsub, __func__);

	/* (Re)schedule the inactivity timer */
	if (net->ncss_guard_timeout > 0) {
		osmo_timer_schedule(&trans->ss.timer_guard,
			net->ncss_guard_timeout, 0);
	}

	/* Allocate and prepare a new MT message */
	ss_msg = gsm48_msgb_alloc_name("GSM 04.08 SS/USSD");
	gh = (struct gsm48_hdr *) msgb_push(ss_msg, sizeof(*gh));
	gh->proto_discr  = GSM48_PDISC_NC_SS;
	gh->proto_discr |= trans->transaction_id << 4;

	/**
	 * Perform GSUP-interface to A-interface mapping,
	 * according to GSM TS 09.11, table 4.1.
	 *
	 * TODO: see (note 3), both CONTINUE and END may
	 * be also mapped to REGISTER if a new transaction
	 * has to be established.
	 */
	switch (gsup_msg->session_state) {
	case OSMO_GSUP_SESSION_STATE_BEGIN:
		gh->msg_type = GSM0480_MTYPE_REGISTER;
		break;
	case OSMO_GSUP_SESSION_STATE_CONTINUE:
		gh->msg_type = GSM0480_MTYPE_FACILITY;
		break;
	case OSMO_GSUP_SESSION_STATE_END:
		gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE;
		break;

	/* Missing or incorrect session state */
	case OSMO_GSUP_SESSION_STATE_NONE:
	default:
		LOG_TRANS(trans, LOGL_ERROR, "Unexpected session state %d\n",
			gsup_msg->session_state);
		gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_MSGT_INCOMP_P_STATE);
		msgb_free(ss_msg);
		return -EINVAL;
	}

	/* Facility IE is optional only for RELEASE COMPLETE */
	if (gh->msg_type != GSM0480_MTYPE_RELEASE_COMPLETE) {
		if (!gsup_msg->ss_info || gsup_msg->ss_info_len < 2) {
			LOG_TRANS(trans, LOGL_ERROR, "Missing mandatory Facility IE "
				"for mapped 0x%02x message\n", gh->msg_type);
			gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_INV_MAND_INFO);
			msgb_free(ss_msg);
			return -EINVAL;
		}
	}

	/* Append Facility IE if preset */
	if (gsup_msg->ss_info && gsup_msg->ss_info_len > 2) {
		/* Facility IE carries LV, others carry TLV */
		if (gh->msg_type == GSM0480_MTYPE_FACILITY)
			msgb_lv_put(ss_msg, gsup_msg->ss_info_len, gsup_msg->ss_info);
		else
			msgb_tlv_put(ss_msg, GSM0480_IE_FACILITY,
				gsup_msg->ss_info_len, gsup_msg->ss_info);
	}

	/* Should we release the transaction? */
	trans_end = (gh->msg_type == GSM0480_MTYPE_RELEASE_COMPLETE);

	/* Sent to the MS, give ownership of ss_msg */
	msc_a = trans->msc_a;
	if (!msc_a) {
		LOG_TRANS(trans, LOGL_ERROR, "Cannot send SS message, no local MSC-A role defined for subscriber\n");
		gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_NET_FAIL);
		msgb_free(ss_msg);
		return -EINVAL;
	}
	msc_a_tx_dtap_to_i(msc_a, ss_msg);

	/* Release transaction if required */
	if (trans_end)
		trans_free(trans);

	/* Count established network-initiated NC SS/USSD sessions */
	if (gsup_msg->session_state == OSMO_GSUP_SESSION_STATE_BEGIN)
		rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED]);

	return 0;
}
