/* Mapper between RUA ContextID (24 bit, per HNB) and the SUA/SCCP
 * Connection ID (32bit, per signalling link) */

/* (C) 2015 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/>.
 *
 */

/* an expired mapping is destroyed  after 1..2 * EXPIRY_TIMER_SECS */
#define EXPIRY_TIMER_SECS	23

#include <osmocom/core/timer.h>

#include "hnbgw.h"
#include "context_map.h"

/* is a given SCCP USER SAP Connection ID in use for a given CN link? */
static int cn_id_in_use(struct hnbgw_cnlink *cn, uint32_t id)
{
	struct hnbgw_context_map *map;

	llist_for_each_entry(map, &cn->map_list, cn_list) {
		if (map->scu_conn_id == id)
			return 1;
	}
	return 0;
}

/* try to allocate a new SCCP User SAP Connection ID */
static int alloc_cn_conn_id(struct hnbgw_cnlink *cn, uint32_t *id_out)
{
	uint32_t i;
	uint32_t id;

	for (i = 0; i < 0xffffffff; i++) {
		id = cn->next_conn_id++;
		if (!cn_id_in_use(cn, id)) {
			*id_out = id;
			return 1;
		}
	}
	return -1;
}

/* Map from a HNB + ContextID to the SCCP-side Connection ID */
struct hnbgw_context_map *
context_map_alloc_by_hnb(struct hnb_context *hnb, uint32_t rua_ctx_id,
			 struct hnbgw_cnlink *cn_if_new)
{
	struct hnbgw_context_map *map;
	uint32_t new_scu_conn_id;

	llist_for_each_entry(map, &hnb->map_list, hnb_list) {
		if (map->state != MAP_S_ACTIVE)
			continue;
		if (map->rua_ctx_id == rua_ctx_id) {
			return map;
		}
	}

	if (alloc_cn_conn_id(cn_if_new, &new_scu_conn_id) < 0) {
		LOGP(DMAIN, LOGL_ERROR, "Unable to allocate CN connection ID\n");
		return NULL;
	}

	/* alloate a new map entry */
	map = talloc_zero(hnb, struct hnbgw_context_map);
	map->state = MAP_S_NULL;
	map->cn_link = cn_if_new;
	map->hnb_ctx = hnb;
	map->rua_ctx_id = rua_ctx_id;

	/* put it into both lists */
	llist_add_tail(&map->hnb_list, &hnb->map_list);
	llist_add_tail(&map->cn_list, &cn_if_new->map_list);
	map->state = MAP_S_ACTIVE;

	return map;
}

/* Map from a CN + Connection ID to HNB + Context ID */
struct hnbgw_context_map *
context_map_by_cn(struct hnbgw_cnlink *cn, uint32_t scu_conn_id)
{
	struct hnbgw_context_map *map;

	llist_for_each_entry(map, &cn->map_list, cn_list) {
		if (map->state != MAP_S_ACTIVE)
			continue;
		if (map->scu_conn_id == scu_conn_id) {
			return map;
		}
	}
	/* we don't allocate new mappings in the CN->HNB
	 * direction, as the RUA=SCCP=SUA connections are always
	 * established from HNB towards CN. */
	LOGP(DMAIN, LOGL_NOTICE, "Unable to resolve map for CN "
		"connection ID %u\n", scu_conn_id);
	return NULL;
}

void context_map_deactivate(struct hnbgw_context_map *map)
{
	/* set the state to reserved. We still show up in the list and
	 * avoid re-allocation of the context-id until we are cleaned up
	 * by the context_map garbage collector timer */

	if (map->state != MAP_S_RESERVED2)
		map->state = MAP_S_RESERVED1;
}

static struct osmo_timer_list context_map_tmr;

static void context_map_tmr_cb(void *data)
{
	struct hnb_gw *gw = data;
	struct hnbgw_cnlink *cn;

	DEBUGP(DMAIN, "Running context mapper garbage collection\n");
	/* iterate over list of core network (links) */
	llist_for_each_entry(cn, &gw->cn_list, list) {
		struct hnbgw_context_map *map;

		llist_for_each_entry(map, &cn->map_list, cn_list) {
			switch (map->state) {
			case MAP_S_RESERVED1:
				/* first time we see this reserved
				 * entry: mark it for stage 2 */
				map->state = MAP_S_RESERVED2;
				break;
			case MAP_S_RESERVED2:
				/* first time we see this reserved
				 * entry: remove it */
				map->state = MAP_S_NULL;
				llist_del(&map->cn_list);
				llist_del(&map->hnb_list);
				talloc_free(map);
				break;
			default:
				break;
			}
		}
	}
	/* re-schedule this timer */
	osmo_timer_schedule(&context_map_tmr, EXPIRY_TIMER_SECS, 0);
}

int context_map_init(struct hnb_gw *gw)
{
	context_map_tmr.cb = context_map_tmr_cb;
	context_map_tmr.data = gw;
	osmo_timer_schedule(&context_map_tmr, EXPIRY_TIMER_SECS, 0);
}
