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

	/* FIXME: allocated CN side ID! */
	if (alloc_cn_conn_id(cn_if_new, &new_scu_conn_id) < 0)
		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;

	/* FIXME: allocated HNB side ID! */

	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. */ 
	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;

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