/* OpenBSC Abis interface to E1 */

/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
 *
 * All Rights Reserved
 *
 * SPDX-License-Identifier: AGPL-3.0+
 *
 * 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 "internal.h"
#include "../config.h"

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

#include <osmocom/abis/lapd.h>

#include <osmocom/core/linuxlist.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/signal.h>
#include <osmocom/core/endian.h>
#include <osmocom/gsm/i460_mux.h>
#include <osmocom/abis/e1_input.h>

#define NUM_E1_TS	32

static void *tall_e1inp_ctx;

/* list of all E1 drivers */
LLIST_HEAD(e1inp_driver_list);

/* list of all E1 lines */
LLIST_HEAD(e1inp_line_list);

static void *tall_sigl_ctx;

static const struct rate_ctr_desc e1inp_ctr_d[] = {
	[E1I_CTR_HDLC_ABORT]  = {
		"hdlc:abort", 	"HDLC abort"
	},
	[E1I_CTR_HDLC_BADFCS] = {
		"hdlc:bad_fcs",	"HLDC Bad FCS"
	},
	[E1I_CTR_HDLC_OVERR]  = {
		"hdlc:overrun",	"HDLC Overrun"
	},
	[E1I_CTR_ALARM] = {
		"alarm", 	"Alarm"
	},
	[E1I_CTR_REMOVED] = {
		"removed", 	"Line removed"
	},
};

static const struct rate_ctr_group_desc e1inp_ctr_g_d = {
	.group_name_prefix = "e1inp",
	.group_description = "E1 Input subsystem",
	.num_ctr = ARRAY_SIZE(e1inp_ctr_d),
	.ctr_desc = e1inp_ctr_d,
};

/*
 * pcap writing of the misdn load
 * pcap format is from http://wiki.wireshark.org/Development/LibpcapFileFormat
 */
#define DLT_LINUX_LAPD		177
#define PCAP_INPUT		0
#define PCAP_OUTPUT		1

struct pcap_hdr {
	uint32_t magic_number;
	uint16_t version_major;
	uint16_t version_minor;
	int32_t  thiszone;
	uint32_t sigfigs;
	uint32_t snaplen;
	uint32_t network;
} __attribute__((packed));

struct pcaprec_hdr {
	uint32_t ts_sec;
	uint32_t ts_usec;
	uint32_t incl_len;
	uint32_t orig_len;
} __attribute__((packed));

struct fake_linux_lapd_header {
        uint16_t pkttype;
	uint16_t hatype;
	uint16_t halen;
	uint64_t addr;
	int16_t protocol;
} __attribute__((packed));

struct lapd_header {
#if OSMO_IS_LITTLE_ENDIAN
	uint8_t ea1 : 1;
	uint8_t cr : 1;
	uint8_t sapi : 6;
	uint8_t ea2 : 1;
	uint8_t tei : 7;
	uint8_t control_foo; /* fake UM's ... */
#elif OSMO_IS_BIG_ENDIAN
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
	uint8_t sapi:6, cr:1, ea1:1;
	uint8_t tei:7, ea2:1;
	uint8_t control_foo;
#endif
} __attribute__((packed));

osmo_static_assert(offsetof(struct fake_linux_lapd_header, hatype) == 2,    hatype_offset);
osmo_static_assert(offsetof(struct fake_linux_lapd_header, halen) == 4,     halen_offset);
osmo_static_assert(offsetof(struct fake_linux_lapd_header, addr) == 6,      addr_offset);
osmo_static_assert(offsetof(struct fake_linux_lapd_header, protocol) == 14, proto_offset);
osmo_static_assert(sizeof(struct fake_linux_lapd_header) == 16,	       lapd_header_size);


static int pcap_fd = -1;

int e1_set_pcap_fd(int fd)
{
	const struct pcap_hdr header = {
		.magic_number	= 0xa1b2c3d4,
		.version_major	= 2,
		.version_minor	= 4,
		.thiszone	= 0,
		.sigfigs	= 0,
		.snaplen	= 65535,
		.network	= DLT_LINUX_LAPD,
	};
	struct e1inp_line *line;
	int i;

	/* write header */
	if (fd >= 0) {
		int rc = write(fd, &header, sizeof(header));
		if (rc < 0)
			return rc;
	}

	/* update fd in all lines in our global list of e1 lines */
	llist_for_each_entry(line, &e1inp_line_list, list) {
		/* Set the PCAP file descriptor for all timeslots that have
		 * software LAPD instances, to ensure the osmo_lapd_pcap code is
		 * used to write PCAP files (if requested) */
		for (i = 0; i < ARRAY_SIZE(line->ts); i++) {
			struct e1inp_ts *e1i_ts = &line->ts[i];
			if (e1i_ts->lapd)
				e1i_ts->lapd->pcap_fd = fd;
		}
	}

	/* close previous and update global */
	if (pcap_fd >= 0)
		close(pcap_fd);
	pcap_fd = fd;

	return 0;
}

/* This currently only works for the D-Channel */
static void write_pcap_packet(int direction, int sapi, int tei,
			      struct msgb *msg) {
	if (pcap_fd < 0)
		return;

	time_t cur_time;
	struct tm *tm;

	struct fake_linux_lapd_header header = {
		.pkttype	= 4,
		.hatype		= 0,
		.halen		= 0,
		.addr		= direction == PCAP_OUTPUT ? 0x0 : 0x1,
		.protocol	= ntohs(48),
	};

	struct lapd_header lapd_header = {
		.ea1		= 0,
		.cr		= direction == PCAP_OUTPUT ? 1 : 0,
		.sapi		= sapi & 0x3F,
		.ea2		= 1,
		.tei		= tei & 0x7F,
		.control_foo	= 0x03 /* UI */,
	};

	struct pcaprec_hdr payload_header = {
		.ts_sec	    = 0,
		.ts_usec    = 0,
		.incl_len   = msgb_l2len(msg) + sizeof(struct fake_linux_lapd_header)
				+ sizeof(struct lapd_header),
		.orig_len   = msgb_l2len(msg) + sizeof(struct fake_linux_lapd_header)
				+ sizeof(struct lapd_header),
	};


	cur_time = time(NULL);
	tm = localtime(&cur_time);
	payload_header.ts_sec = mktime(tm);

	write(pcap_fd, &payload_header, sizeof(payload_header));
	write(pcap_fd, &header, sizeof(header));
	write(pcap_fd, &lapd_header, sizeof(lapd_header));
	write(pcap_fd, msg->l2h, msgb_l2len(msg));
}

const struct value_string e1inp_sign_type_names[5] = {
	{ E1INP_SIGN_NONE,	"None" },
	{ E1INP_SIGN_OML,	"OML" },
	{ E1INP_SIGN_RSL,	"RSL" },
	{ E1INP_SIGN_OSMO,	"OSMO" },
	{ 0, NULL }
};

const char *e1inp_signtype_name(enum e1inp_sign_type tp)
{
	return get_value_string(e1inp_sign_type_names, tp);
}

const struct value_string e1inp_ts_type_names[] = {
	{ E1INP_TS_TYPE_NONE,	"None" },
	{ E1INP_TS_TYPE_SIGN,	"Signalling" },
	{ E1INP_TS_TYPE_TRAU,	"TRAU" },
	{ E1INP_TS_TYPE_RAW,	"RAW" },
	{ E1INP_TS_TYPE_HDLC,	"HDLC" },
	{ E1INP_TS_TYPE_I460,	"I460" },
	{ 0, NULL }
};

const char *e1inp_tstype_name(enum e1inp_ts_type tp)
{
	return get_value_string(e1inp_ts_type_names, tp);
}

int abis_sendmsg(struct msgb *msg)
{
	struct e1inp_sign_link *sign_link = msg->dst;
	struct e1inp_driver *e1inp_driver;
	struct e1inp_ts *e1i_ts;

	msg->l2h = msg->data;

	/* don't know how to route this message. */
	if (sign_link == NULL) {
		LOGP(DLINP, LOGL_ERROR, "abis_sendmsg: msg->dst == NULL: %s\n",
			osmo_hexdump(msg->data, msg->len));
		talloc_free(msg);
		return -EINVAL;
	}
	e1i_ts = sign_link->ts;
	if (!osmo_timer_pending(&e1i_ts->sign.tx_timer)) {
		/* notify the driver we have something to write */
		e1inp_driver = sign_link->ts->line->driver;
		e1inp_driver->want_write(e1i_ts);
	}
	msgb_enqueue(&sign_link->tx_list, msg);

	/* we only need to write a 'Fake LAPD' packet here, if the
	 * underlying driver hides LAPD from us.  If we use the
	 * libosmocore LAPD implementation, it will take care of writing
	 * the _actual_ LAPD packet */
	if (!e1i_ts->lapd) {
		write_pcap_packet(PCAP_OUTPUT, sign_link->sapi,
				  sign_link->tei, msg);
	}

	return 0;
}

int abis_rsl_sendmsg(struct msgb *msg)
{
	return abis_sendmsg(msg);
}

/* Timeslot */
int e1inp_ts_config_trau(struct e1inp_ts *ts, struct e1inp_line *line,
			 int (*trau_rcv_cb)(struct subch_demux *dmx, int ch,
					const ubit_t *data, int len, void *_priv))
{
	if (ts->type == E1INP_TS_TYPE_TRAU && ts->line && line)
		return 0;

	ts->type = E1INP_TS_TYPE_TRAU;
	ts->line = line;

	subchan_mux_init(&ts->trau.mux);
	ts->trau.demux.out_cb = trau_rcv_cb;
	ts->trau.demux.data = ts;
	subch_demux_init(&ts->trau.demux);
	return 0;
}

int e1inp_ts_config_i460(struct e1inp_ts *ts, struct e1inp_line *line)
{
	if (ts->type == E1INP_TS_TYPE_I460 && ts->line && line)
		return 0;

	ts->type = E1INP_TS_TYPE_I460;
	ts->line = line;
	osmo_i460_ts_init(&ts->i460.i460_ts);
	return 0;
}

void e1inp_ts_name(char *out, size_t out_len, const struct e1inp_ts *ts)
{
	if (ts->line->name)
		snprintf(out, out_len, "%s:%u", ts->line->name, ts->num);
	else
		snprintf(out, out_len, "%u:%u", ts->line->num, ts->num);
}

int e1inp_ts_config_sign(struct e1inp_ts *ts, struct e1inp_line *line)
{
	if (ts->type == E1INP_TS_TYPE_SIGN && ts->line && line)
		return 0;

	ts->type = E1INP_TS_TYPE_SIGN;
	ts->line = line;

	if (line && line->driver)
		ts->sign.delay = line->driver->default_delay;
	else
		ts->sign.delay = 100000;
	INIT_LLIST_HEAD(&ts->sign.sign_links);
	return 0;
}

int e1inp_ts_config_raw(struct e1inp_ts *ts, struct e1inp_line *line,
			void (*raw_recv_cb)(struct e1inp_ts *ts,
					    struct msgb *msg))
{
	if (ts->type == E1INP_TS_TYPE_RAW && ts->line && line)
		return 0;

	ts->type = E1INP_TS_TYPE_RAW;
	ts->line = line;
	ts->raw.recv_cb = raw_recv_cb;
	INIT_LLIST_HEAD(&ts->raw.tx_queue);

	return 0;
}

int e1inp_ts_config_hdlc(struct e1inp_ts *ts, struct e1inp_line *line,
			 void (*hdlc_recv_cb)(struct e1inp_ts *ts,
					      struct msgb *msg))
{
	if (ts->type == E1INP_TS_TYPE_HDLC && ts->line && line)
		return 0;

	ts->type = E1INP_TS_TYPE_HDLC;
	ts->line = line;
	ts->hdlc.recv_cb = hdlc_recv_cb;
	INIT_LLIST_HEAD(&ts->hdlc.tx_queue);

	return 0;
}

static int e1inp_line_use_cb(struct osmo_use_count_entry *use_count_entry, int32_t old_use_count,
			     const char *file, int file_line)
{
	char buf[512];
	struct osmo_use_count *uc = use_count_entry->use_count;
	struct e1inp_line *line = uc->talloc_object;

	LOGPSRC(DLINP, LOGL_INFO, file, file_line,
		"E1L(%u) Line (%p) reference count %s changed %" PRId32 " -> %" PRId32 " [%s]\n",
		(line)->num, line, use_count_entry->use,
		old_use_count, use_count_entry->count,
		osmo_use_count_name_buf(buf, sizeof(buf), uc));

	if (!use_count_entry->count)
		osmo_use_count_free(use_count_entry);

	if (osmo_use_count_total(uc) > 0)
		return 0;

	/* Remove our counter group from libosmocore's global counter
	 * list if we are freeing the last remaining talloc context.
	 * Otherwise we get a use-after-free when libosmocore's timer
	 * ticks again and attempts to update these counters (OS#3011).
	 *
	 * Note that talloc internally counts "secondary" references
	 * _in addition to_ the initial allocation context, so yes,
	 * we must check for *zero* remaining secondary contexts here. */
	if (talloc_reference_count(line->rate_ctr) == 0) {
		rate_ctr_group_free(line->rate_ctr);
	} else {
		/* We are not freeing the last talloc context.
		 * Instead of calling talloc_free(), unlink this 'line' pointer
		 * which serves as one of several talloc contexts for the rate
		 * counters and driver private state. */
		talloc_unlink(line, line->rate_ctr);
		if (line->driver_data)
			talloc_unlink(line, line->driver_data);
	}
	talloc_free(line);
	return 0;
}

struct e1inp_line *e1inp_line_find(uint8_t e1_nr)
{
	struct e1inp_line *e1i_line;

	/* iterate over global list of e1 lines */
	llist_for_each_entry(e1i_line, &e1inp_line_list, list) {
		if (e1i_line->num == e1_nr)
			return e1i_line;
	}
	return NULL;
}

struct e1inp_line *
e1inp_line_create(uint8_t e1_nr, const char *driver_name)
{
	struct e1inp_driver *driver;
	struct e1inp_line *line;
	int i;

	line = e1inp_line_find(e1_nr);
	if (line) {
		LOGPIL(line, DLINP, LOGL_ERROR, "E1 Line %u already exists\n", e1_nr);
		return NULL;
	}

	driver = e1inp_driver_find(driver_name);
	if (!driver) {
		LOGP(DLINP, LOGL_ERROR, "No such E1 driver '%s'\n",
		     driver_name);
		return NULL;
	}

	line = talloc_zero(tall_e1inp_ctx, struct e1inp_line);
	if (!line)
		return NULL;

	line->driver = driver;
	line->num = e1_nr;

	line->rate_ctr = rate_ctr_group_alloc(line, &e1inp_ctr_g_d, line->num);
	if (!line->rate_ctr) {
		LOGPIL(line, DLINP, LOGL_ERROR, "Cannot allocate counter group\n");
		talloc_free(line);
		return NULL;
	}

	line->num_ts = NUM_E1_TS;
	for (i = 0; i < line->num_ts; i++) {
		line->ts[i].num = i+1;
		line->ts[i].line = line;
	}

	line->use_count.talloc_object = line;
	line->use_count.use_cb = e1inp_line_use_cb;
	e1inp_line_get2(line, "ctor");

	llist_add_tail(&line->list, &e1inp_line_list);

	return line;
}

struct e1inp_line *
e1inp_line_clone(void *ctx, struct e1inp_line *line, const char *use)
{
	struct e1inp_line *clone;

	/* clone virtual E1 line for this new OML link. */
	clone = talloc_zero(ctx, struct e1inp_line);
	if (clone == NULL)
	        return NULL;

	memcpy(clone, line, sizeof(struct e1inp_line));

	if (line->name) {
		clone->name = talloc_strdup(clone, line->name);
		OSMO_ASSERT(clone->name);
	}
	if (line->sock_path) {
		clone->sock_path = talloc_strdup(clone, line->sock_path);
		OSMO_ASSERT(clone->sock_path);
	}

	/*
	 * Rate counters and driver data are shared between clones. These are pointers
	 * to dynamic memory so we use reference counting to avoid a double-free (see OS#3137).
	 */
	OSMO_ASSERT(line->rate_ctr);
	clone->rate_ctr = talloc_reference(clone, line->rate_ctr);
	if (line->driver_data)
		clone->driver_data = talloc_reference(clone, line->driver_data);

	clone->use_count = (struct osmo_use_count) {
		.talloc_object = clone,
		.use_cb = e1inp_line_use_cb,
		.use_counts = {0},
	};
	e1inp_line_get2(clone, use); /* Clone is used internally for bfd */
	return clone;
}

void e1inp_line_get(struct e1inp_line *line)
{
	e1inp_line_get2(line, "unknown");
}

void e1inp_line_put(struct e1inp_line *line)
{
	e1inp_line_put2(line, "unknown");
}

void
e1inp_line_bind_ops(struct e1inp_line *line, const struct e1inp_line_ops *ops)
{
	line->ops = ops;
}

#if 0
struct e1inp_line *e1inp_line_find_create(uint8_t e1_nr)
{
	struct e1inp_line *line;
	int i;

	line = e1inp_line_find(e1_nr);
	if (line)
		return line;

	line = talloc_zero(tall_e1inp_ctx, struct e1inp_line);
	if (!line)
		return NULL;

	line->num = e1_nr;
	for (i = 0; i < NUM_E1_TS; i++) {
		line->ts[i].num = i+1;
		line->ts[i].line = line;
	}
	llist_add_tail(&line->list, &e1inp_line_list);

	return line;
}
#endif

static struct e1inp_ts *e1inp_ts_get(uint8_t e1_nr, uint8_t ts_nr)
{
	struct e1inp_line *e1i_line;

	e1i_line = e1inp_line_find(e1_nr);
	if (!e1i_line)
		return NULL;

	return &e1i_line->ts[ts_nr-1];
}

struct subch_mux *e1inp_get_mux(uint8_t e1_nr, uint8_t ts_nr)
{
	struct e1inp_ts *e1i_ts = e1inp_ts_get(e1_nr, ts_nr);

	if (!e1i_ts)
		return NULL;

	return &e1i_ts->trau.mux;
}

/* Signalling Link */

struct e1inp_sign_link *e1inp_lookup_sign_link(struct e1inp_ts *e1i,
						uint8_t tei, uint8_t sapi)
{
	struct e1inp_sign_link *link;

	llist_for_each_entry(link, &e1i->sign.sign_links, list) {
		if (link->sapi == sapi && link->tei == tei)
			return link;
	}

	return NULL;
}

/* create a new signalling link in a E1 timeslot */

struct e1inp_sign_link *
e1inp_sign_link_create(struct e1inp_ts *ts, enum e1inp_sign_type type,
			struct gsm_bts_trx *trx, uint8_t tei,
			uint8_t sapi)
{
	struct e1inp_sign_link *link;

	if (ts->type != E1INP_TS_TYPE_SIGN)
		return NULL;

	link = talloc_zero(tall_sigl_ctx, struct e1inp_sign_link);
	if (!link)
		return NULL;

	link->ts = ts;
	link->type = type;
	INIT_LLIST_HEAD(&link->tx_list);
	link->trx = trx;
	link->tei = tei;
	link->sapi = sapi;

	e1inp_line_get2(link->ts->line, "e1inp_sign_link");

	llist_add_tail(&link->list, &ts->sign.sign_links);

	return link;
}

void e1inp_sign_link_destroy(struct e1inp_sign_link *link)
{
	struct msgb *msg;

	llist_del(&link->list);
	while (!llist_empty(&link->tx_list)) {
		msg = msgb_dequeue(&link->tx_list);
		msgb_free(msg);
	}

	if (link->ts->type == E1INP_TS_TYPE_SIGN)
		osmo_timer_del(&link->ts->sign.tx_timer);

	if (link->ts->line->driver->close)
		link->ts->line->driver->close(link);

	e1inp_line_put2(link->ts->line, "e1inp_sign_link");
	talloc_free(link);
}

/* XXX */
/* the E1 driver tells us he has received something on a TS */
int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
		uint8_t tei, uint8_t sapi)
{
	struct e1inp_sign_link *link;
	int ret = 0;

	switch (ts->type) {
	case E1INP_TS_TYPE_SIGN:
		/* we only need to write a 'Fake LAPD' packet here, if
		 * the underlying driver hides LAPD from us.  If we use
		 * the libosmocore LAPD implementation, it will take
		 * care of writing the _actual_ LAPD packet */
		if (!ts->lapd)
			write_pcap_packet(PCAP_INPUT, sapi, tei, msg);
		/* consult the list of signalling links */
		link = e1inp_lookup_sign_link(ts, tei, sapi);
		if (!link) {
			LOGPITS(ts, DLMI, LOGL_ERROR, "didn't find signalling link for "
				"tei %d, sapi %d\n", tei, sapi);
			msgb_free(msg);
			return -EINVAL;
		}
		if (!ts->line->ops->sign_link) {
	                LOGPITS(ts, DLINP, LOGL_ERROR, "Fix your application, "
				"no action set for signalling messages.\n");
			msgb_free(msg);
			return -ENOENT;
		}
		msg->dst = link;
		ts->line->ops->sign_link(msg);
		break;
	case E1INP_TS_TYPE_TRAU:
		ret = subch_demux_in(&ts->trau.demux, msg->l2h, msgb_l2len(msg));
		msgb_free(msg);
		break;
	case E1INP_TS_TYPE_RAW:
		ts->raw.recv_cb(ts, msg);
		break;
	case E1INP_TS_TYPE_HDLC:
		ts->hdlc.recv_cb(ts, msg);
		break;
	case E1INP_TS_TYPE_I460:
		osmo_i460_demux_in(&ts->i460.i460_ts, msg->l2h, msgb_l2len(msg));
		msgb_free(msg);
		break;
	default:
		ret = -EINVAL;
		LOGPITS(ts, DLMI, LOGL_ERROR, "unknown TS type %u\n", ts->type);
		msgb_free(msg);
		break;
	}

	return ret;
}

/*! \brief Receive some data from the L1/HDLC into LAPD of a timeslot
 *  \param[in] e1i_ts E1 Timeslot data structure
 *  \param[in] msg Message buffer containing full LAPD message
 *
 * This is a wrapper around e1inp_rx_ts(), but feeding the incoming
 * message first into our LAPD code.  This allows a driver to read raw
 * (HDLC decoded) data from the timeslot, instead of a LAPD stack
 * present in any underlying driver.
 */
int e1inp_rx_ts_lapd(struct e1inp_ts *e1i_ts, struct msgb *msg)
{
	unsigned int sapi, tei;
	int ret = 0, error = 0;

	sapi = msg->data[0] >> 2;
	if ((msg->data[0] & 0x1))
		tei = 0;
	else
		tei = msg->data[1] >> 1;

	LOGPITS(e1i_ts, DLMI, LOGL_DEBUG, "<= len = %d, sapi(%d) tei(%d)\n", msg->len, sapi, tei);

	ret = lapd_receive(e1i_ts->lapd, msg, &error);
	if (ret < 0) {
		switch(error) {
		case LAPD_ERR_UNKNOWN_TEI:
			/* We don't know about this TEI, probably the BSC
			 * lost local states (it crashed or it was stopped),
			 * notify the driver to see if it can do anything to
			 * recover the existing signalling links with the BTS.
			 */
			e1inp_event(e1i_ts, S_L_INP_TEI_UNKNOWN, tei, sapi);
			return -EIO;
		}
	}

	return 0;
}

void e1inp_dlsap_up(struct osmo_dlsap_prim *dp, uint8_t tei, uint8_t sapi,
        void *rx_cbdata)
{
	struct e1inp_ts *e1i_ts = rx_cbdata;
	struct msgb *msg = dp->oph.msg;

	switch (dp->oph.primitive) {
	case PRIM_DL_EST:
		LOGPITS(e1i_ts, DLMI, LOGL_DEBUG, "DL_EST: sapi(%d) tei(%d)\n", sapi, tei);
		e1inp_event(e1i_ts, S_L_INP_TEI_UP, tei, sapi);
		break;
	case PRIM_DL_REL:
		LOGPITS(e1i_ts, DLMI, LOGL_DEBUG, "DL_REL: sapi(%d) tei(%d)\n", sapi, tei);
		e1inp_event(e1i_ts, S_L_INP_TEI_DN, tei, sapi);
		break;
	case PRIM_DL_DATA:
	case PRIM_DL_UNIT_DATA:
		if (dp->oph.operation == PRIM_OP_INDICATION) {
			msg->l2h = msg->l3h;
			LOGPITS(e1i_ts, DLMI, LOGL_DEBUG, "RX: %s sapi=%d tei=%d\n",
				osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)),
				sapi, tei);
			e1inp_rx_ts(e1i_ts, msg, tei, sapi);
			return;
		}
		break;
	case PRIM_MDL_ERROR:
		LOGPITS(e1i_ts, DLMI, LOGL_DEBUG, "MDL_EERROR: cause(%d)\n", dp->u.error_ind.cause);
		break;
	default:
		printf("ERROR: unknown prim\n");
		break;
	}

	msgb_free(msg);

	return;
}

#define TSX_ALLOC_SIZE 4096

/* called by driver if it wants to transmit on a given TS */
struct msgb *e1inp_tx_ts(struct e1inp_ts *e1i_ts,
			 struct e1inp_sign_link **sign_link)
{
	struct e1inp_sign_link *link;
	struct msgb *msg = NULL;
	int len;

	switch (e1i_ts->type) {
	case E1INP_TS_TYPE_SIGN:
		/* FIXME: implement this round robin */
		llist_for_each_entry(link, &e1i_ts->sign.sign_links, list) {
			msg = msgb_dequeue(&link->tx_list);
			if (msg) {
				if (sign_link)
					*sign_link = link;
				break;
			}
		}
		break;
	case E1INP_TS_TYPE_TRAU:
		msg = msgb_alloc(TSX_ALLOC_SIZE, "TRAU_TX");
		if (!msg)
			return NULL;
		len = subchan_mux_out(&e1i_ts->trau.mux, msg->data, 40);
		if (len != 40) {
			LOGPITS(e1i_ts, DLMI, LOGL_ERROR, "cannot transmit, failed to mux\n");
			msgb_free(msg);
			return NULL;
		}
		msgb_put(msg, 40);
		break;
	case E1INP_TS_TYPE_RAW:
		/* Get msgb from tx_queue */
		msg = msgb_dequeue(&e1i_ts->raw.tx_queue);
		break;
	case E1INP_TS_TYPE_HDLC:
		/* Get msgb from tx_queue */
		msg = msgb_dequeue(&e1i_ts->hdlc.tx_queue);
		break;
	case E1INP_TS_TYPE_I460:
		msg = msgb_alloc(TSX_ALLOC_SIZE, "I460_TX");
		if (!msg)
			return NULL;
		len = osmo_i460_mux_out(&e1i_ts->i460.i460_ts, msg->data, 160);
		msgb_put(msg, len);
		break;
	default:
		LOGPITS(e1i_ts, DLMI, LOGL_ERROR, "unsupported E1 TS type %u\n", e1i_ts->type);
		return NULL;
	}
	return msg;
}

int e1inp_int_snd_event(struct e1inp_ts *ts, struct e1inp_sign_link *link, int evt)
{
	struct input_signal_data isd;
	isd.line = ts->line;
	isd.ts_nr = ts->num;
	isd.link_type = link->type;
	isd.trx = link->trx;
	isd.tei = link->tei;
	isd.sapi = link->sapi;

	/* report further upwards */
	osmo_signal_dispatch(SS_L_INPUT, evt, &isd);
	return 0;
}


/* called by driver in case some kind of link state event */
int e1inp_event(struct e1inp_ts *ts, int evt, uint8_t tei, uint8_t sapi)
{
	struct e1inp_sign_link *link;

	link = e1inp_lookup_sign_link(ts, tei, sapi);
	if (!link)
		return -EINVAL;
	return e1inp_int_snd_event(ts, link, evt);
}

/* register a driver with the E1 core */
int e1inp_driver_register(struct e1inp_driver *drv)
{
	llist_add_tail(&drv->list, &e1inp_driver_list);
	return 0;
}

struct e1inp_driver *e1inp_driver_find(const char *name)
{
	struct e1inp_driver *drv;

	llist_for_each_entry(drv, &e1inp_driver_list, list) {
		if (!strcasecmp(name, drv->name))
			return drv;
	}
	return NULL;
}

int e1inp_line_update(struct e1inp_line *line)
{
	struct input_signal_data isd;
	int i, rc;

	if (line->driver && line->ops && line->driver->line_update) {
		rc = line->driver->line_update(line);
	} else
		rc = 0;

	/* Set the PCAP file descriptor for all timeslots that have
	 * software LAPD instances, to ensure the osmo_lapd_pcap code is
	 * used to write PCAP files (if requested) */
	for (i = 0; i < ARRAY_SIZE(line->ts); i++) {
		struct e1inp_ts *e1i_ts = &line->ts[i];
		if (e1i_ts->lapd)
			e1i_ts->lapd->pcap_fd = pcap_fd;
	}

	/* Send a signal to anyone who is interested in new lines being
	 * configured */
	memset(&isd, 0, sizeof(isd));
	isd.line = line;
	osmo_signal_dispatch(SS_L_INPUT, S_L_INP_LINE_INIT, &isd);

	return rc;
}

static int e1i_sig_cb(unsigned int subsys, unsigned int signal,
		      void *handler_data, void *signal_data)
{
	if (subsys != SS_L_GLOBAL ||
	    signal != S_L_GLOBAL_SHUTDOWN)
		return 0;

	if (pcap_fd) {
		close(pcap_fd);
		pcap_fd = -1;
	}

	return 0;
}

const struct value_string e1inp_signal_names[] = {
	{ S_L_INP_NONE,		"NONE" },
	{ S_L_INP_TEI_UP,	"TEI-UP" },
	{ S_L_INP_TEI_DN,	"TEI-DOWN" },
	{ S_L_INP_TEI_UNKNOWN,	"TEI-UNKNOWN" },
	{ S_L_INP_LINE_INIT,	"LINE-INIT" },
	{ S_L_INP_LINE_ALARM,	"LINE-ALARM" },
	{ S_L_INP_LINE_NOALARM,	"LINE-NOALARM" },
	{ 0, NULL }
};

void e1inp_misdn_init(void);
void e1inp_dahdi_init(void);
void e1inp_e1d_init(void);
void e1inp_ipaccess_init(void);
void e1inp_rs232_init(void);
void e1inp_unixsocket_init(void);

void e1inp_init(void)
{
	tall_e1inp_ctx = talloc_named_const(libosmo_abis_ctx, 1, "e1inp");
	tall_sigl_ctx = talloc_named_const(tall_e1inp_ctx, 1,
					   "e1inp_sign_link");
	osmo_signal_register_handler(SS_L_GLOBAL, e1i_sig_cb, NULL);

	e1inp_misdn_init();
#ifdef HAVE_DAHDI_USER_H
	e1inp_dahdi_init();
#endif
#ifdef HAVE_E1D
	e1inp_e1d_init();
#endif
	e1inp_ipaccess_init();
	e1inp_rs232_init();
	e1inp_unixsocket_init();
}
