/* OpenBSC Abis input driver for HSL Femto */

/* (C) 2011 by Harald Welte <laforge@gnumonks.org>
 * (C) 2011 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/>.
 *
 */

/* HSL uses a much more primitive/simplified version of the IPA multiplex.
 *
 * They have taken out the nice parts like the ID_GET / ID_RESP for resolving
 * the UNIT ID, as well as the keepalive ping/pong messages.  Furthermore, the
 * Stream Identifiers are fixed on the BTS side (RSL always 0, OML always 0xff)
 * and both OML+RSL share a single TCP connection.
 *
 * Other oddities include the encapsulation of BSSGP messages in the L3_INFO IE
 * of RSL
 */

#include "internal.h"

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>
#include <sys/fcntl.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>

#include <osmocom/core/select.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/core/msgb.h>
#include <osmocom/abis/e1_input.h>
#include <osmocom/core/logging.h>
#include <osmocom/abis/ipaccess.h>
#include <osmocom/core/socket.h>
#include <osmocom/abis/ipa.h>
#include <osmocom/core/talloc.h>

#define HSL_TCP_PORT	2500
#define HSL_PROTO_DEBUG	0xdd

#define PRIV_OML 1
#define PRIV_RSL 2

static void *tall_hsl_ctx;

/* data structure for one E1 interface with A-bis */
struct hsl_e1_handle {
	struct osmo_fd listen_fd;
	struct gsm_network *gsmnet;
};

static struct hsl_e1_handle *e1h;


#define TS1_ALLOC_SIZE	900

static void hsl_drop(struct e1inp_line *line, struct osmo_fd *bfd)
{
	line->ops->sign_link_down(line);

	if (bfd->fd != -1) {
		osmo_fd_unregister(bfd);
		close(bfd->fd);
		bfd->fd = -1;
	}
	/* put the virtual E1 line that we cloned for this socket, if
	 * it becomes unused, it gets released. */
	e1inp_line_put(line);
}

static int process_hsl_rsl(struct msgb *msg, struct e1inp_line *line,
			   struct osmo_fd *bfd)
{
	char serno_buf[16];
	uint8_t serno_len;
	struct e1inp_sign_link *sign_link;
	struct hsl_unit unit_data;

	switch (msg->l2h[1]) {
	case 0x80:
		/*, contains Serial Number + SW version */
		if (msg->l2h[2] != 0xc0)
			break;
		serno_len = msg->l2h[3];
		if (serno_len > sizeof(serno_buf)-1)
			serno_len = sizeof(serno_buf)-1;
		memcpy(serno_buf, msg->l2h+4, serno_len);
		serno_buf[serno_len] = '\0';
		unit_data.serno = strtoul(serno_buf, NULL, 10);

		if (!line->ops->sign_link_up) {
			LOGP(DLINP, LOGL_ERROR,
			     "Unable to set signal link, closing socket.\n");
			osmo_fd_unregister(bfd);
			close(bfd->fd);
			bfd->fd = -1;
			return -EINVAL;
		}
		sign_link = line->ops->sign_link_up(&unit_data,
						    line, E1INP_SIGN_NONE);
		if (sign_link == NULL) {
			LOGP(DLINP, LOGL_ERROR,
			     "Unable to set signal link, closing socket.\n");
			osmo_fd_unregister(bfd);
			close(bfd->fd);
			bfd->fd = -1;
			return -EINVAL;
		}
		msgb_free(msg);
		return 1;       /* == we have taken over the msg */
	case 0x82:
		/* FIXME: do something with BSSGP, i.e. forward it over
		 * NSIP to OsmoSGSN */
		msgb_free(msg);
		return 1;
	}
	return 0;
}

static int handle_ts1_read(struct osmo_fd *bfd)
{
	struct e1inp_line *line = bfd->data;
	unsigned int ts_nr = bfd->priv_nr;
	struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
	struct e1inp_sign_link *link;
	struct ipaccess_head *hh;
	struct msgb *msg;
	int ret = 0, error;

	error = ipa_msg_recv(bfd->fd, &msg);
	if (error < 0)
		return error;
	else if (error == 0) {
		hsl_drop(e1i_ts->line, bfd);
		LOGP(DLINP, LOGL_NOTICE, "Sign link vanished, dead socket\n");
		return error;
	}
	DEBUGP(DLMI, "RX %u: %s\n", ts_nr, osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));

	hh = (struct ipaccess_head *) msg->data;
	if (hh->proto == HSL_PROTO_DEBUG) {
		LOGP(DLINP, LOGL_NOTICE, "HSL debug: %s\n", msg->data + sizeof(*hh));
		msgb_free(msg);
		return ret;
	}

	/* HSL proprietary RSL extension */
	if (hh->proto == 0 && (msg->l2h[0] == 0x81 || msg->l2h[0] == 0x80)) {
                ret = process_hsl_rsl(msg, line, bfd);
                if (ret < 0) {
                        hsl_drop(e1i_ts->line, bfd);
                        return ret;
		} else if (ret == 1)
			return 0;
		/* else: continue... */
	}

#ifdef HSL_SR_1_0
	/* HSL for whatever reason chose to use 0x81 instead of 0x80 for FOM */
	if (hh->proto == 255 && msg->l2h[0] == (ABIS_OM_MDISC_FOM | 0x01))
		msg->l2h[0] = ABIS_OM_MDISC_FOM;
#endif
	link = e1inp_lookup_sign_link(e1i_ts, hh->proto, 0);
	if (!link) {
		LOGP(DLINP, LOGL_ERROR, "no matching signalling link for "
			"hh->proto=0x%02x\n", hh->proto);
		msgb_free(msg);
		return -EIO;
	}
	msg->dst = link;

	/* XXX: better use e1inp_ts_rx? */
	if (!e1i_ts->line->ops->sign_link) {
		LOGP(DLINP, LOGL_ERROR, "Fix your application, "
			"no action set for signalling messages.\n");
		return -ENOENT;
	}
	e1i_ts->line->ops->sign_link(msg);

	return ret;
}

static int ts_want_write(struct e1inp_ts *e1i_ts)
{
	e1i_ts->driver.ipaccess.fd.when |= BSC_FD_WRITE;

	return 0;
}

static void timeout_ts1_write(void *data)
{
	struct e1inp_ts *e1i_ts = (struct e1inp_ts *)data;

	/* trigger write of ts1, due to tx delay timer */
	ts_want_write(e1i_ts);
}

static int __handle_ts1_write(struct osmo_fd *bfd, struct e1inp_line *line)
{
	unsigned int ts_nr = bfd->priv_nr;
	struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
	struct e1inp_sign_link *sign_link;
	struct msgb *msg;
	int ret;

	bfd->when &= ~BSC_FD_WRITE;

	/* get the next msg for this timeslot */
	msg = e1inp_tx_ts(e1i_ts, &sign_link);
	if (!msg) {
		/* no message after tx delay timer */
		return 0;
	}

	switch (sign_link->type) {
	case E1INP_SIGN_OML:
#ifdef HSL_SR_1_0
		/* HSL uses 0x81 for FOM for some reason */
		if (msg->data[0] == ABIS_OM_MDISC_FOM)
			msg->data[0] = ABIS_OM_MDISC_FOM | 0x01;
#endif
		break;
	case E1INP_SIGN_RSL:
		break;
	default:
		msgb_free(msg);
		bfd->when |= BSC_FD_WRITE; /* come back for more msg */
		return -EINVAL;
	}

	msg->l2h = msg->data;
	ipaccess_prepend_header(msg, sign_link->tei);

	DEBUGP(DLMI, "TX %u: %s\n", ts_nr, osmo_hexdump(msg->l2h, msgb_l2len(msg)));

	ret = send(bfd->fd, msg->data, msg->len, 0);
	msgb_free(msg);

	/* set tx delay timer for next event */
	e1i_ts->sign.tx_timer.cb = timeout_ts1_write;
	e1i_ts->sign.tx_timer.data = e1i_ts;

	/* Reducing this might break the nanoBTS 900 init. */
	osmo_timer_schedule(&e1i_ts->sign.tx_timer, 0, e1i_ts->sign.delay);

	return ret;
}

static int handle_ts1_write(struct osmo_fd *bfd)
{
	struct e1inp_line *line = bfd->data;

	return __handle_ts1_write(bfd, line);
}

int hsl_bts_write(struct ipa_client_conn *link)
{
	struct e1inp_line *line = link->line;

	return __handle_ts1_write(link->ofd, line);
}

/* callback from select.c in case one of the fd's can be read/written */
static int hsl_fd_cb(struct osmo_fd *bfd, unsigned int what)
{
	struct e1inp_line *line = bfd->data;
	unsigned int ts_nr = bfd->priv_nr;
	unsigned int idx = ts_nr-1;
	struct e1inp_ts *e1i_ts;
	int rc = 0;

	/* In case of early RSL we might not yet have a line */

	if (line)
		e1i_ts = &line->ts[idx];

	if (!line || e1i_ts->type == E1INP_TS_TYPE_SIGN) {
		if (what & BSC_FD_READ)
			rc = handle_ts1_read(bfd);
		if (what & BSC_FD_WRITE)
			rc = handle_ts1_write(bfd);
	} else
		LOGP(DLINP, LOGL_ERROR, "unknown E1 TS type %u\n", e1i_ts->type);

	return rc;
}

static void hsl_close(struct e1inp_sign_link *sign_link)
{
	struct e1inp_ts *ts = sign_link->ts;
	struct osmo_fd *bfd = &ts->driver.ipaccess.fd;
	e1inp_event(ts, S_L_INP_TEI_DN, sign_link->tei, sign_link->sapi);
	/* the first e1inp_sign_link_destroy call closes the socket. */
	if (bfd->fd != -1) {
		osmo_fd_unregister(bfd);
		close(bfd->fd);
		bfd->fd = -1;
	}
}

static int hsl_line_update(struct e1inp_line *line);

struct e1inp_driver hsl_driver = {
	.name = "hsl",
	.want_write = ts_want_write,
	.line_update = hsl_line_update,
	.close = hsl_close,
	.default_delay = 0,
};

/* callback of the OML listening filedescriptor */
static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what)
{
	int ret;
	int idx = 0;
	int i;
	struct e1inp_line *line;
	struct e1inp_ts *e1i_ts;
	struct osmo_fd *bfd;
	struct sockaddr_in sa;
	socklen_t sa_len = sizeof(sa);

	if (!(what & BSC_FD_READ))
		return 0;

	ret = accept(listen_bfd->fd, (struct sockaddr *) &sa, &sa_len);
	if (ret < 0) {
		perror("accept");
		return ret;
	}
	LOGP(DLINP, LOGL_NOTICE, "accept()ed new HSL link from %s\n",
		inet_ntoa(sa.sin_addr));

	/* clone virtual E1 line for this new signalling link. */
	line = e1inp_line_clone(tall_hsl_ctx, listen_bfd->data);
	if (line == NULL) {
		LOGP(DLINP, LOGL_ERROR, "could not clone E1 line\n");
		return -1;
	}
	/* create virrtual E1 timeslots for signalling */
	e1inp_ts_config_sign(&line->ts[1-1], line);

	/* initialize the fds */
	for (i = 0; i < ARRAY_SIZE(line->ts); ++i)
		line->ts[i].driver.ipaccess.fd.fd = -1;

	e1i_ts = &line->ts[idx];

	bfd = &e1i_ts->driver.ipaccess.fd;
	bfd->fd = ret;
	bfd->data = line;
	bfd->priv_nr = PRIV_OML;
	bfd->cb = hsl_fd_cb;
	bfd->when = BSC_FD_READ;
	ret = osmo_fd_register(bfd);
	if (ret < 0) {
		LOGP(DLINP, LOGL_ERROR, "could not register FD\n");
		close(bfd->fd);
		e1inp_line_put(line);
		return ret;
	}

        return ret;
}

static int hsl_bts_process(struct ipa_client_conn *link, struct msgb *msg)
{
	struct ipaccess_head *hh;
	struct e1inp_sign_link *sign_link;
	struct e1inp_ts *e1i_ts = &link->line->ts[0];

	hh = (struct ipaccess_head *) msg->data;
	if (hh->proto == HSL_PROTO_DEBUG) {
		LOGP(DLINP, LOGL_NOTICE, "HSL debug: %s\n",
						msg->data + sizeof(*hh));
		msgb_free(msg);
		return 0;
	}
	sign_link = e1inp_lookup_sign_link(e1i_ts, hh->proto, 0);
	if (!sign_link) {
		LOGP(DLINP, LOGL_ERROR, "no matching signalling link for "
			"hh->proto=0x%02x\n", hh->proto);
		msgb_free(msg);
		return -EIO;
	}
	msg->dst = sign_link;

	/* XXX better use e1inp_ts_rx? */
	if (!link->line->ops->sign_link) {
		LOGP(DLINP, LOGL_ERROR, "Fix your application, "
			"no action set for signalling messages.\n");
		return -ENOENT;
	}
	link->line->ops->sign_link(msg);
	return 0;
}

static int hsl_bts_connect(struct ipa_client_conn *link)
{
	struct msgb *msg;
	uint8_t *serno;
	char serno_buf[16];
	struct hsl_unit *unit = link->line->ops->cfg.ipa.dev;
	struct e1inp_sign_link *sign_link;

	/* send the minimal message to identify this BTS. */
	msg = ipa_msg_alloc(0);
	if (!msg)
		return -ENOMEM;

	*msgb_put(msg, 1) = 0x80;
	*msgb_put(msg, 1) = 0x80;
	*msgb_put(msg, 1) = unit->swversion;
	snprintf(serno_buf, sizeof(serno_buf), "%"PRIx64, unit->serno);
	serno = msgb_put(msg, strlen(serno_buf)+1);
	memcpy(serno, serno_buf, strlen(serno_buf));
	ipa_msg_push_header(msg, 0);
	send(link->ofd->fd, msg->data, msg->len, 0);
	msgb_free(msg);

	/* ... and enable the signalling link. */
	if (!link->line->ops->sign_link_up) {
		LOGP(DLINP, LOGL_ERROR,
			"Unable to set signal link, closing socket.\n");
		ipa_client_conn_close(link);
		return -EINVAL;
	}
	sign_link = link->line->ops->sign_link_up(&unit,
						  link->line, E1INP_SIGN_NONE);
	if (sign_link == NULL) {
		LOGP(DLINP, LOGL_ERROR,
		     "Unable to set signal link, closing socket.\n");
		ipa_client_conn_close(link);
		return -EINVAL;
	}
	return 0;
}

struct hsl_line {
	int line_already_initialized;
};

static int hsl_line_update(struct e1inp_line *line)
{
	int ret = -ENOENT;
	struct hsl_line *hl;

	if (!line->driver_data)
		line->driver_data = talloc_zero(line, struct hsl_line);

	if (!line->driver_data) {
		LOGP(DLINP, LOGL_NOTICE, "hsl: OOM in line update\n");
		return -ENOMEM;
	}
	hl = line->driver_data;

	/* We only initialize this line once. */
	if (hl->line_already_initialized)
		return 0;

	hl->line_already_initialized = 1;

	switch(line->ops->cfg.ipa.role) {
	case E1INP_LINE_R_BSC:
		LOGP(DLINP, LOGL_NOTICE, "enabling hsl BSC mode\n");

		ret = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP,
				     line->ops->cfg.ipa.addr,
				     HSL_TCP_PORT, OSMO_SOCK_F_BIND);
		if (ret < 0)
			return ret;

		e1h->listen_fd.fd = ret;
		e1h->listen_fd.when |= BSC_FD_READ;
		e1h->listen_fd.cb = listen_fd_cb;
		e1h->listen_fd.data = line;

		if (osmo_fd_register(&e1h->listen_fd) < 0) {
			close(ret);
			return ret;
		}
		break;
	case E1INP_LINE_R_BTS: {
		struct ipa_client_conn *link;

		LOGP(DLINP, LOGL_NOTICE, "enabling hsl BTS mode\n");

		link = ipa_client_conn_create(tall_hsl_ctx,
					      &line->ts[E1INP_SIGN_OML-1],
					      E1INP_SIGN_OML,
					      line->ops->cfg.ipa.addr,
					      HSL_TCP_PORT,
					      hsl_bts_connect,
					      hsl_bts_process,
					      hsl_bts_write,
					      NULL);
		if (link == NULL) {
			LOGP(DLINP, LOGL_ERROR, "cannot create BTS link: %s\n",
				strerror(errno));
			return -ENOMEM;
		}
		if (ipa_client_conn_open(link) < 0) {
			LOGP(DLINP, LOGL_ERROR, "cannot open BTS link: %s\n",
				strerror(errno));
			ipa_client_conn_close(link);
			ipa_client_conn_destroy(link);
			return -EIO;
		}
		ret = 0;
		break;
	}
	default:
		break;
	}
	return ret;
}

void e1inp_hsl_init(void)
{
	tall_hsl_ctx = talloc_named_const(libosmo_abis_ctx, 1, "hsl");

	e1h = talloc_zero(tall_hsl_ctx, struct hsl_e1_handle);
	if (!e1h)
		return;

	e1inp_driver_register(&hsl_driver);
}
