/* GSM 04.07 Transaction handling */

/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
 * 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/transaction.h>
#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/mncc.h>
#include <osmocom/msc/debug.h>
#include <osmocom/core/talloc.h>
#include <osmocom/msc/gsm_04_08.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/msc_a.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/paging.h>
#include <osmocom/msc/silent_call.h>

void *tall_trans_ctx;

void _gsm48_cc_trans_free(struct gsm_trans *trans);
void _gsm411_sms_trans_free(struct gsm_trans *trans);
void _gsm911_nc_ss_trans_free(struct gsm_trans *trans);

struct gsm_trans *trans_find_by_type(const struct msc_a *msc_a, enum trans_type type)
{
	struct gsm_trans *trans;
	struct gsm_network *net = msc_a_net(msc_a);
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);

	llist_for_each_entry(trans, &net->trans_list, entry) {
		if (trans->vsub == vsub && trans->type == type)
			return trans;
	}
	return NULL;
}

/*! Find a transaction in connection for given protocol + transaction ID
 * \param[in] conn Connection in which we want to find transaction
 * \param[in] proto Protocol of transaction
 * \param[in] trans_id Transaction ID of transaction
 * \returns Matching transaction, if any
 */
struct gsm_trans *trans_find_by_id(const struct msc_a *msc_a,
				   enum trans_type type, uint8_t trans_id)
{
	struct gsm_trans *trans;
	struct gsm_network *net = msc_a_net(msc_a);
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);

	llist_for_each_entry(trans, &net->trans_list, entry) {
		if (trans->vsub == vsub &&
		    trans->type == type &&
		    trans->transaction_id == trans_id)
			return trans;
	}
	return NULL;
}

/*! Find a transaction by call reference
 * \param[in] net Network in which we should search
 * \param[in] callref Call Reference of transaction
 * \returns Matching transaction, if any
 */
struct gsm_trans *trans_find_by_callref(const struct gsm_network *net,
					uint32_t callref)
{
	struct gsm_trans *trans;

	llist_for_each_entry(trans, &net->trans_list, entry) {
		if (trans->callref == callref)
			return trans;
	}
	return NULL;
}

/*! Find a transaction by SM-RP-MR (RP Message Reference)
 * \param[in] net Network in which we should search
 * \param[in] vsub Subscriber for which we should search
 * \param[in] sm_rp_mr RP Message Reference (see GSM TS 04.11, section 8.2.3)
 * \returns Matching transaction, NULL otherwise
 */
struct gsm_trans *trans_find_by_sm_rp_mr(const struct gsm_network *net,
					 const struct vlr_subscr *vsub,
					 uint8_t sm_rp_mr)
{
	struct gsm_trans *trans;

	llist_for_each_entry(trans, &net->trans_list, entry) {
		if (trans->vsub == vsub &&
		    trans->type == TRANS_SMS &&
		    trans->sms.sm_rp_mr == sm_rp_mr)
			return trans;
	}

	return NULL;
}

struct osmo_lcls *trans_lcls_compose(const struct gsm_trans *trans, bool use_lac)
{
	if (!trans) {
		LOGP(DCC, LOGL_ERROR, "LCLS: unable to fill parameters for unallocated transaction\n");
		return NULL;
	}

	if (!trans->net->a.sri->sccp)
		return NULL;

	struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(trans->net->a.sri->sccp);
	struct osmo_lcls *lcls;
	uint8_t w = osmo_ss7_pc_width(&ss7->cfg.pc_fmt);

	if (!trans->net->lcls_permitted) {
		LOGP(DCC, LOGL_NOTICE, "LCLS disabled globally\n");
		return NULL;
	}

	if (!trans->msc_a) {
		LOGP(DCC, LOGL_ERROR, "LCLS: unable to fill parameters for transaction without connection\n");
		return NULL;
	}

	if (trans->msc_a->c.ran->type != OSMO_RAT_GERAN_A) {
		LOGP(DCC, LOGL_ERROR, "LCLS: only A interface is supported at the moment\n");
		return NULL;
	}

	lcls = talloc_zero(trans, struct osmo_lcls);
	if (!lcls) {
		LOGP(DCC, LOGL_ERROR, "LCLS: failed to allocate osmo_lcls\n");
		return NULL;
	}

	LOGP(DCC, LOGL_INFO, "LCLS: using %u bits (%u bytes) for node ID\n", w, w / 8);

	lcls->gcr.net_len = 3;
	lcls->gcr.node = ss7->cfg.primary_pc;

	/* net id from Q.1902.3 3-5 bytes, this function gives 3 bytes exactly */
	osmo_plmn_to_bcd(lcls->gcr.net, &trans->net->plmn);


	/* TS 29.205 Table B.2.1.9.2 Call Reference ID
	 * 3 octets Call ID + 2 octets BSS ID
	 */
	lcls->gcr.cr[2] = (trans->callref >>  0) & 0xff;
	lcls->gcr.cr[1] = (trans->callref >>  8) & 0xff;
	lcls->gcr.cr[0] = (trans->callref >> 16) & 0xff;
	osmo_store16be(use_lac ? trans->msc_a->via_cell.lai.lac : trans->msc_a->via_cell.cell_identity, &lcls->gcr.cr[3]);

	LOGP(DCC, LOGL_INFO, "LCLS: allocated %s-based CR-ID %sfor callref 0x%04x\n", use_lac ? "LAC" : "CI",
	     osmo_hexdump(lcls->gcr.cr, 5), trans->callref);

	lcls->config = GSM0808_LCLS_CFG_BOTH_WAY;
	lcls->control = GSM0808_LCLS_CSC_CONNECT;
	lcls->corr_needed = true;
	lcls->gcr_available = true;

	LOGP(DCC, LOGL_DEBUG, "Filled %s\n", osmo_lcls_dump(lcls));
	LOGP(DCC, LOGL_DEBUG, "Filled %s\n", osmo_gcr_dump(lcls));

	return lcls;
}

static const char *trans_vsub_use(enum trans_type type)
{
	return get_value_string_or_null(trans_type_names, type) ? : "trans-type-unknown";
}

static uint32_t new_call_id = 1;

/*! Allocate a new transaction and add it to network list
 *  \param[in] net Netwokr in which we allocate transaction
 *  \param[in] subscr Subscriber for which we allocate transaction
 *  \param[in] protocol Protocol (CC/SMS/...)
 *  \param[in] callref Call Reference
 *  \returns Transaction
 */
struct gsm_trans *trans_alloc(struct gsm_network *net,
			      struct vlr_subscr *vsub,
			      enum trans_type type, uint8_t trans_id,
			      uint32_t callref)
{
	int subsys = trans_log_subsys(type);
	struct gsm_trans *trans;

	/* a valid subscriber is indispensable */
	if (vsub == NULL) {
		LOGP(subsys, LOGL_ERROR, "unable to alloc transaction, invalid subscriber (NULL)\n");
		return NULL;
	}

	trans = talloc(tall_trans_ctx, struct gsm_trans);
	if (!trans)
		return NULL;

	*trans = (struct gsm_trans){
		.vsub = vsub,
		.type = type,
		.log_subsys = subsys,
		.transaction_id = trans_id,
		.callref = callref,
		.call_id = new_call_id++,
		.net = net,
		/* empty bearer_cap: make sure the speech_ver array is empty */
		.bearer_cap = {
			.speech_ver = { -1 },
		},
	};
	vlr_subscr_get(vsub, trans_vsub_use(type));
	llist_add_tail(&trans->entry, &net->trans_list);

	LOG_TRANS(trans, LOGL_DEBUG, "New transaction\n");
	return trans;
}

/*! Release a transaction
 * \param[in] trans Transaction to be released
 */
void trans_free(struct gsm_trans *trans)
{
	const char *usage_token;
	struct msc_a *msc_a;

	LOG_TRANS(trans, LOGL_DEBUG, "Freeing transaction\n");

	switch (trans->type) {
	case TRANS_CC:
		_gsm48_cc_trans_free(trans);
		usage_token = MSC_A_USE_CC;
		break;
	case TRANS_SMS:
		_gsm411_sms_trans_free(trans);
		usage_token = MSC_A_USE_SMS;
		break;
	case TRANS_USSD:
		_gsm911_nc_ss_trans_free(trans);
		usage_token = MSC_A_USE_NC_SS;
		break;
	case TRANS_SILENT_CALL:
		trans_silent_call_free(trans);
		usage_token = MSC_A_USE_SILENT_CALL;
		break;
	default:
		usage_token = NULL;
		break;
	}

	if (trans->paging_request) {
		paging_request_remove(trans->paging_request);
		trans->paging_request = NULL;
	}

	if (trans->vsub) {
		vlr_subscr_put(trans->vsub, trans_vsub_use(trans->type));
		trans->vsub = NULL;
	}

	msc_a = trans->msc_a;
	trans->msc_a = NULL;

	llist_del(&trans->entry);
	talloc_free(trans);

	if (msc_a && usage_token)
		msc_a_put(msc_a, usage_token);
}

/*! allocate an unused transaction ID for the given subscriber
 * in the given protocol using TI flag = 0 (allocated by us).
 * See GSM 04.07, section 11.2.3.1.3 "Transaction identifier".
 * \param[in] net GSM network
 * \param[in] subscr Subscriber for which to assign a new TID
 * \param[in] protocol Protocol of to be assigned TID
 */
int trans_assign_trans_id(const struct gsm_network *net, const struct vlr_subscr *vsub,
			  enum trans_type type)
{
	struct gsm_trans *trans;
	unsigned int used_tid_bitmask = 0;
	int i, j, h;
	uint8_t proto = trans_type_to_gsm48_proto(type);

	/* generate bitmask of already-used TIDs for this (subscr,proto) */
	llist_for_each_entry(trans, &net->trans_list, entry) {
		if (trans->vsub != vsub ||
		    proto != trans_type_to_gsm48_proto(trans->type) ||
		    trans->transaction_id == TRANS_ID_UNASSIGNED)
			continue;
		used_tid_bitmask |= (1 << trans->transaction_id);
	}

	/* find a new one, trying to go in a 'circular' pattern */
	for (h = 6; h > 0; h--)
		if (used_tid_bitmask & (1 << h))
			break;
	for (i = 0; i < 7; i++) {
		j = (h + i) % 7;
		if ((used_tid_bitmask & (1 << j)) == 0)
			return j;
	}

	return -1;
}

/*! Check if we have any transaction for given connection
 * \param[in] conn Connection to check
 * \returns transaction pointer if found, NULL otherwise
 */
struct gsm_trans *trans_has_conn(const struct msc_a *msc_a)
{
	struct gsm_trans *trans;
	struct gsm_network *net = msc_a_net(msc_a);

	llist_for_each_entry(trans, &net->trans_list, entry)
		if (trans->msc_a == msc_a)
			return trans;

	return NULL;
}

/*! Free all transactions associated with a connection, presumably when the
 * conn is being closed. The transaction code will inform the CC or SMS
 * facilities, which will then send the necessary release indications.
 * \param[in] conn Connection that is going to be closed.
 */
void trans_conn_closed(const struct msc_a *msc_a)
{
	/* As part of the CC REL_IND the remote leg might be released and this
	 * will trigger another call to trans_free. This is something the llist
	 * macro can not handle and we need to re-iterate the list every time.
	 */
	struct gsm_trans *trans;
	while ((trans = trans_has_conn(msc_a)))
		trans_free(trans);
}

const struct value_string trans_type_names[] = {
	{ TRANS_CC, "CC" },
	{ TRANS_SMS, "SMS" },
	{ TRANS_USSD, "NCSS" },
	{ TRANS_SILENT_CALL, "silent-call" },
	{}
};

uint8_t trans_type_to_gsm48_proto(enum trans_type type)
{
	switch (type) {
	case TRANS_CC:
	case TRANS_SILENT_CALL:
		return GSM48_PDISC_CC;
	case TRANS_SMS:
		return GSM48_PDISC_SMS;
	case TRANS_USSD:
		return GSM48_PDISC_NC_SS;
	default:
		return GSM48_PDISC_TEST;
	}

}

const char *trans_name(const struct gsm_trans *trans)
{
	static char namebuf[32];
	if (!trans)
		return "NULL";
	switch (trans->type) {
	case TRANS_CC:
		snprintf(namebuf, sizeof(namebuf), "%s:%s",
			 trans_type_name(trans->type), gsm48_cc_state_name(trans->cc.state));
		return namebuf;

	default:
		return trans_type_name(trans->type);
	}
}
