/* OpenBSC Abis receive lapd over a unix socket */

/* (C) 2016 by sysmocom - s.f.m.c. GmbH
 * Author: Alexander Couzens <lynxis@fe80.eu>
 * Based on other e1_input drivers.
 *
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <limits.h>
#include <string.h>

#include <osmocom/core/talloc.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/socket.h>

#include <osmocom/abis/e1_input.h>
#include <osmocom/abis/lapd.h>
#include <osmocom/abis/e1_input.h>

#include <osmocom/abis/unixsocket_proto.h>
#include "internal.h"

void *tall_unixsocket_ctx;
#define UNIXSOCKET_ALLOC_SIZE 1600
#define UNIXSOCKET_SOCK_PATH_DEFAULT "/tmp/osmo_abis_line_"

struct unixsocket_line {
	struct osmo_fd fd;
};

static int unixsocket_line_update(struct e1inp_line *line);
static int ts_want_write(struct e1inp_ts *e1i_ts);

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

	LOGPIL(line, DLINP, LOGL_ERROR, "Socket connection failure, reconnecting... (line=%p, fd=%d)\n",
		line, bfd->fd);

	/* Unregister faulty file descriptor from select loop */
	if(osmo_fd_is_registered(bfd)) {
		LOGPIL(line, DLINP, LOGL_DEBUG, "removing inactive socket from select loop... (line=%p, fd=%d)\n",
			line, bfd->fd);
		osmo_fd_unregister(bfd);
	}

	/* Close faulty file descriptor */
	close(bfd->fd);

	unixsocket_line_update(line);

	return 0;
}

static int unixsocket_read_cb(struct osmo_fd *bfd)
{
	struct e1inp_line *line = bfd->data;
	struct msgb *msg = msgb_alloc(UNIXSOCKET_ALLOC_SIZE, "UNIXSOCKET TS");
	uint8_t version;
	uint8_t controldata;
	int ret;

	if (!msg)
		return -ENOMEM;

	ret = read(bfd->fd, msg->data, UNIXSOCKET_ALLOC_SIZE - 16);
	if (ret == 0) {
		unixsocket_exception_cb(bfd);
		goto fail;
	} else if (ret < 0) {
		perror("read ");
		goto fail;
	} else if (ret < 2) {
		/* packet must be at least 2 byte long to hold version + control/data header */
		LOGPIL(line, DLMI, LOGL_ERROR, "received to small packet: %d < 2", ret);
		ret = -1;
		goto fail;
	}
	msgb_put(msg, ret);

	LOGPIL(line, DLMI, LOGL_DEBUG, "rx msg: %s (fd=%d)\n", osmo_hexdump_nospc(msg->data, msg->len), bfd->fd);

	/* check version header */
	version = msgb_pull_u8(msg);
	controldata = msgb_pull_u8(msg);

	if (version != UNIXSOCKET_PROTO_VERSION) {
		LOGPIL(line, DLMI, LOGL_ERROR, "received message with invalid version %d. valid: %d",
			ret, UNIXSOCKET_PROTO_VERSION);
		ret = -1;
		goto fail;
	}

	switch (controldata) {
	case UNIXSOCKET_PROTO_DATA:
		return e1inp_rx_ts_lapd(&line->ts[0], msg);
	case UNIXSOCKET_PROTO_CONTROL:
		LOGPIL(line, DLMI, LOGL_ERROR, "received (invalid) control message.");
		ret = -1;
		break;
	default:
		LOGPIL(line, DLMI, LOGL_ERROR, "received invalid message.");
		ret = -1;
		break;
	}
fail:
	msgb_free(msg);
	return ret;
}

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 unixsocket_write_cb(struct osmo_fd *bfd)
{
	struct e1inp_line *line = bfd->data;
	struct e1inp_ts *e1i_ts = &line->ts[0];
	struct msgb *msg;
	struct e1inp_sign_link *sign_link;

	osmo_fd_write_disable(bfd);

	/* get the next msg for this timeslot */
	msg = e1inp_tx_ts(e1i_ts, &sign_link);
	if (!msg) {
		/* no message after tx delay timer */
		LOGPITS(e1i_ts, DLINP, LOGL_INFO, "no message available (line=%p)\n", line);
		return 0;
	}

	/* set tx delay timer for next event */
	osmo_timer_setup(&e1i_ts->sign.tx_timer, timeout_ts1_write, e1i_ts);

	osmo_timer_schedule(&e1i_ts->sign.tx_timer, 0, e1i_ts->sign.delay);

	LOGPITS(e1i_ts, DLINP, LOGL_DEBUG, "sending: %s (line=%p)\n", msgb_hexdump(msg), line);
	lapd_transmit(e1i_ts->lapd, sign_link->tei,
			sign_link->sapi, msg);

	return 0;
}

static int unixsocket_cb(struct osmo_fd *bfd, unsigned int what)
{
	int ret = 0;

	if (what & OSMO_FD_READ)
		ret = unixsocket_read_cb(bfd);
	if (what & OSMO_FD_WRITE)
		ret = unixsocket_write_cb(bfd);

	return ret;
}

static int ts_want_write(struct e1inp_ts *e1i_ts)
{
	struct unixsocket_line *line = e1i_ts->line->driver_data;

	osmo_fd_write_enable(&line->fd);

	return 0;
}

static void unixsocket_write_msg(struct msgb *msg, struct osmo_fd *bfd)
{
	struct e1inp_line *line = bfd->data;
	int ret;

	LOGPIL(line, DLMI, LOGL_DEBUG, "tx msg: %s (fd=%d)\n",
		osmo_hexdump_nospc(msg->data, msg->len), bfd->fd);

	ret = write(bfd->fd, msg->data, msg->len);
	msgb_free(msg);
	if (ret == -1)
		unixsocket_exception_cb(bfd);
	else if (ret < 0)
		LOGPIL(line, DLMI, LOGL_NOTICE, "%s write failed %d\n", __func__, ret);
}

/*!
 * \brief unixsocket_write_msg lapd callback for data to unixsocket
 * \param msg
 * \param cbdata
 */
static void unixsocket_write_msg_lapd_cb(struct msgb *msg, void *cbdata)
{
	struct osmo_fd *bfd = cbdata;

	/* data|control */
	msgb_push_u8(msg, UNIXSOCKET_PROTO_DATA);
	/* add version header */
	msgb_push_u8(msg, UNIXSOCKET_PROTO_VERSION);

	unixsocket_write_msg(msg, bfd);
}

static int unixsocket_line_update(struct e1inp_line *line)
{
	struct unixsocket_line *config;
	struct sockaddr_un un;
	const char *sock_path;
	int ret = 0;
	int i;

	LOGPIL(line, DLINP, LOGL_NOTICE, "line update (line=%p)\n", line);

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

	if (!line->driver_data) {
		LOGPIL(line, DLINP, LOGL_ERROR, "OOM in line update (line=%p)\n", line);
		return -ENOMEM;
	}

	config = line->driver_data;

	/* Open unix domain socket */
	if (line->sock_path == NULL) {
		ret = snprintf(un.sun_path, sizeof(un.sun_path), "%s%d",
		    UNIXSOCKET_SOCK_PATH_DEFAULT, line->num);
		if (ret == -1) {
			LOGPIL(line, DLINP, LOGL_ERROR, "Cannot create default socket path: %s\n", strerror(errno));
			return -errno;
		} else if (ret >= sizeof(un.sun_path)) {
			LOGPIL(line, DLINP, LOGL_ERROR, "Default socket path exceeds %zd bytes: %s%d\n",
			     sizeof(un.sun_path), UNIXSOCKET_SOCK_PATH_DEFAULT, line->num);
			return -ENOSPC;
		}
		sock_path = un.sun_path;
	} else
		sock_path = line->sock_path;
	ret = osmo_sock_unix_init(SOCK_SEQPACKET, 0, sock_path,
				  OSMO_SOCK_F_CONNECT);
	if (ret < 0) {
		/* Note: We will not free the allocated driver_data memory if
		 * opening the socket fails. The caller may want to call this
		 * function multiple times using config->fd.data as line
		 * parameter. Freeing now would destroy that reference. */
		LOGPIL(line, DLINP, LOGL_ERROR, "unable to open socket: %s (line=%p, fd=%d)\n", sock_path,
			line, config->fd.fd);
		return ret;
	}
	LOGPIL(line, DLINP, LOGL_DEBUG, "successfully opend (new) socket: %s (line=%p, fd=%d, ret=%d)\n",
		sock_path, line, config->fd.fd, ret);
	osmo_fd_setup(&config->fd, ret, OSMO_FD_READ, unixsocket_cb, line, 0);

	/* Register socket in select loop */
	if (osmo_fd_register(&config->fd) < 0) {
		LOGPIL(line, DLINP, LOGL_ERROR, "error registering new socket (line=%p, fd=%d)\n",
			line, config->fd.fd);
		close(config->fd.fd);
		return -EIO;
	}

	/* Set line parameter */
	for (i = 0; i < ARRAY_SIZE(line->ts); i++) {
		struct e1inp_ts *e1i_ts = &line->ts[i];
		char name[32];
		if (!e1i_ts->lapd) {
			e1inp_ts_name(name, sizeof(name), e1i_ts);
			e1i_ts->lapd = lapd_instance_alloc2(1,
				unixsocket_write_msg_lapd_cb, &config->fd,
				e1inp_dlsap_up, e1i_ts, &lapd_profile_abis, name);
		}
	}

	/* Ensure ericsson-superchannel is turned of when
	 * a new connection is made */
	e1inp_ericsson_set_altc(line, 0);

	return ret;
}

struct e1inp_driver unixsocket_driver = {
	.name = "unixsocket",
	.want_write = ts_want_write,
	.line_update = unixsocket_line_update,
	.default_delay = 0,
};

void e1inp_unixsocket_init(void)
{
	tall_unixsocket_ctx = talloc_named_const(libosmo_abis_ctx, 1, "unixsocket");
	e1inp_driver_register(&unixsocket_driver);
}

void e1inp_ericsson_set_altc(struct e1inp_line *unixline, int superchannel)
{
	struct unixsocket_line *config;
	struct msgb *msg;

	if (!unixline)
		return;

	if (unixline->driver != &unixsocket_driver) {
		LOGPIL(unixline, DLMI, LOGL_NOTICE, "altc is only supported by unixsocket\n");
		return;
	}

	config = unixline->driver_data;
	if (!config) {
		LOGPIL(unixline, DLMI, LOGL_NOTICE, "e1inp driver not yet initialized.\n");
		return;
	}


	msg = msgb_alloc_headroom(200, 100, "ALTC");

	/* version header */
	msgb_put_u8(msg, UNIXSOCKET_PROTO_VERSION);
	/* data|control */
	msgb_put_u8(msg, UNIXSOCKET_PROTO_CONTROL);

	/* magic */
	msgb_put_u32(msg, 0x23004200);
	msgb_put_u8(msg, superchannel ? 1 : 0);

	unixsocket_write_msg(msg, &config->fd);
}

