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

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