/* SCCP patching and handling routines */
/*
 * (C) 2010 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 <openbsc/debug.h>
#include <openbsc/bsc_nat.h>
#include <openbsc/bsc_nat_sccp.h>

#include <osmocom/sccp/sccp.h>

#include <osmocom/core/talloc.h>

#include <string.h>
#include <time.h>

static int equal(struct sccp_source_reference *ref1, struct sccp_source_reference *ref2)
{
	return memcmp(ref1, ref2, sizeof(*ref1)) == 0;
}

/*
 * SCCP patching below
 */

/* check if we are using this ref for patched already */
static int sccp_ref_is_free(struct sccp_source_reference *ref, struct bsc_nat *nat)
{
	struct sccp_connections *conn;

	llist_for_each_entry(conn, &nat->sccp_connections, list_entry) {
		if (memcmp(ref, &conn->patched_ref, sizeof(*ref)) == 0)
			return -1;
	}

	return 0;
}

/* copied from sccp.c */
static int assign_src_local_reference(struct sccp_source_reference *ref, struct bsc_nat *nat)
{
	static uint32_t last_ref = 0x50000;
	int wrapped = 0;

	do {
		struct sccp_source_reference reference;
		reference.octet1 = (last_ref >>  0) & 0xff;
		reference.octet2 = (last_ref >>  8) & 0xff;
		reference.octet3 = (last_ref >> 16) & 0xff;

		++last_ref;
		/* do not use the reversed word and wrap around */
		if ((last_ref & 0x00FFFFFF) == 0x00FFFFFF) {
			LOGP(DNAT, LOGL_NOTICE, "Wrapped searching for a free code\n");
			last_ref = 0;
			++wrapped;
		}

		if (sccp_ref_is_free(&reference, nat) == 0) {
			*ref = reference;
			return 0;
		}
	} while (wrapped != 2);

	LOGP(DNAT, LOGL_ERROR, "Finding a free reference failed\n");
	return -1;
}

struct sccp_connections *create_sccp_src_ref(struct bsc_connection *bsc,
					     struct bsc_nat_parsed *parsed)
{
	struct sccp_connections *conn;

	/* Some commercial BSCs like to reassign there SRC ref */
	llist_for_each_entry(conn, &bsc->nat->sccp_connections, list_entry) {
		if (conn->bsc != bsc)
			continue;
		if (memcmp(&conn->real_ref, parsed->src_local_ref, sizeof(conn->real_ref)) != 0)
			continue;

		/* the BSC has reassigned the SRC ref and we failed to keep track */
		memset(&conn->remote_ref, 0, sizeof(conn->remote_ref));
		if (assign_src_local_reference(&conn->patched_ref, bsc->nat) != 0) {
			LOGP(DNAT, LOGL_ERROR, "BSC %d reused src ref: %d and we failed to generate a new id.\n",
			     bsc->cfg->nr, sccp_src_ref_to_int(parsed->src_local_ref));
			bsc_mgcp_dlcx(conn);
			llist_del(&conn->list_entry);
			talloc_free(conn);
			return NULL;
		} else {
			clock_gettime(CLOCK_MONOTONIC, &conn->creation_time);
			bsc_mgcp_dlcx(conn);
			return conn;
		}
	}


	conn = talloc_zero(bsc->nat, struct sccp_connections);
	if (!conn) {
		LOGP(DNAT, LOGL_ERROR, "Memory allocation failure.\n");
		return NULL;
	}

	conn->bsc = bsc;
	clock_gettime(CLOCK_MONOTONIC, &conn->creation_time);
	conn->real_ref = *parsed->src_local_ref;
	if (assign_src_local_reference(&conn->patched_ref, bsc->nat) != 0) {
		LOGP(DNAT, LOGL_ERROR, "Failed to assign a ref.\n");
		talloc_free(conn);
		return NULL;
	}

	bsc_mgcp_init(conn);
	llist_add_tail(&conn->list_entry, &bsc->nat->sccp_connections);
	rate_ctr_inc(&bsc->cfg->stats.ctrg->ctr[BCFG_CTR_SCCP_CONN]);
	counter_inc(bsc->cfg->nat->stats.sccp.conn);

	LOGP(DNAT, LOGL_DEBUG, "Created 0x%x <-> 0x%x mapping for con %p\n",
	     sccp_src_ref_to_int(&conn->real_ref),
	     sccp_src_ref_to_int(&conn->patched_ref), bsc);

	return conn;
}

int update_sccp_src_ref(struct sccp_connections *sccp, struct bsc_nat_parsed *parsed)
{
	if (!parsed->dest_local_ref || !parsed->src_local_ref) {
		LOGP(DNAT, LOGL_ERROR, "CC MSG should contain both local and dest address.\n");
		return -1;
	}

	sccp->remote_ref = *parsed->src_local_ref;
	sccp->has_remote_ref = 1;
	LOGP(DNAT, LOGL_DEBUG, "Updating 0x%x to remote 0x%x on %p\n",
	     sccp_src_ref_to_int(&sccp->patched_ref),
	     sccp_src_ref_to_int(&sccp->remote_ref), sccp->bsc);

	return 0;
}

void remove_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed)
{
	struct sccp_connections *conn;

	llist_for_each_entry(conn, &bsc->nat->sccp_connections, list_entry) {
		if (memcmp(parsed->src_local_ref,
			   &conn->patched_ref, sizeof(conn->patched_ref)) == 0) {

			sccp_connection_destroy(conn);
			return;
		}
	}

	LOGP(DNAT, LOGL_ERROR, "Can not remove connection: 0x%x\n",
	     sccp_src_ref_to_int(parsed->src_local_ref));
}

/*
 * We have a message from the MSC to the BSC. The MSC is using
 * an address that was assigned by the MUX, we need to update the
 * dest reference to the real network.
 */
struct sccp_connections *patch_sccp_src_ref_to_bsc(struct msgb *msg,
						   struct bsc_nat_parsed *parsed,
						   struct bsc_nat *nat)
{
	struct sccp_connections *conn;

	if (!parsed->dest_local_ref) {
		LOGP(DNAT, LOGL_ERROR, "MSG should contain dest_local_ref.\n");
		return NULL;
	}


	llist_for_each_entry(conn, &nat->sccp_connections, list_entry) {
		if (!equal(parsed->dest_local_ref, &conn->patched_ref))
			continue;

		/* Change the dest address to the real one */
		*parsed->dest_local_ref = conn->real_ref;
		return conn;
	}

	return NULL;
}

/*
 * These are message to the MSC. We will need to find the BSC
 * Connection by either the SRC or the DST local reference.
 *
 * In case of a CR we need to work by the SRC local reference
 * in all other cases we need to work by the destination local
 * reference..
 */
struct sccp_connections *patch_sccp_src_ref_to_msc(struct msgb *msg,
						   struct bsc_nat_parsed *parsed,
						   struct bsc_connection *bsc)
{
	struct sccp_connections *conn;

	llist_for_each_entry(conn, &bsc->nat->sccp_connections, list_entry) {
		if (conn->bsc != bsc)
			continue;

		if (parsed->src_local_ref) {
			if (equal(parsed->src_local_ref, &conn->real_ref)) {
				*parsed->src_local_ref = conn->patched_ref;
				return conn;
			}
		} else if (parsed->dest_local_ref) {
			if (equal(parsed->dest_local_ref, &conn->remote_ref))
				return conn;
		} else {
			LOGP(DNAT, LOGL_ERROR, "Header has neither loc/dst ref.\n");
			return NULL;
		}
	}

	return NULL;
}

struct sccp_connections *bsc_nat_find_con_by_bsc(struct bsc_nat *nat,
						 struct sccp_source_reference *ref)
{
	struct sccp_connections *conn;

	llist_for_each_entry(conn, &nat->sccp_connections, list_entry) {
		if (memcmp(ref, &conn->real_ref, sizeof(*ref)) == 0)
			return conn;
	}

	return NULL;
}
