/* Interface handler for Nuran Wireless Litecell 1.5 L1 (real hardware) */

/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
 * based on:
 *     femto_l1_hw.c
 *     (C) 2011 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 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 <assert.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <limits.h>

#include <sys/types.h>
#include <sys/stat.h>

#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/select.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/core/timer.h>
#include <osmocom/gsm/gsm_utils.h>

#include <nrw/litecell15/litecell15.h>
#include <nrw/litecell15/gsml1prim.h>
#include <nrw/litecell15/gsml1const.h>
#include <nrw/litecell15/gsml1types.h>

#include "gprs_debug.h"
#include "lc15bts.h"
#include "lc15_l1_if.h"

#define DEV_SYS_DSP2ARM_NAME    "/dev/msgq/litecell15_dsp2arm_trx"
#define DEV_SYS_ARM2DSP_NAME    "/dev/msgq/litecell15_arm2dsp_trx"
#define DEV_L1_DSP2ARM_NAME     "/dev/msgq/gsml1_sig_dsp2arm_trx"
#define DEV_L1_ARM2DSP_NAME     "/dev/msgq/gsml1_sig_arm2dsp_trx"

#define DEV_TCH_DSP2ARM_NAME    "/dev/msgq/gsml1_tch_dsp2arm_trx"
#define DEV_TCH_ARM2DSP_NAME    "/dev/msgq/gsml1_tch_arm2dsp_trx"
#define DEV_PDTCH_DSP2ARM_NAME  "/dev/msgq/gsml1_pdtch_dsp2arm_trx"
#define DEV_PDTCH_ARM2DSP_NAME  "/dev/msgq/gsml1_pdtch_arm2dsp_trx"

static const char *rd_devnames[] = {
        [MQ_SYS_READ]   = DEV_SYS_DSP2ARM_NAME,
        [MQ_L1_READ]    = DEV_L1_DSP2ARM_NAME,
        [MQ_TCH_READ]   = DEV_TCH_DSP2ARM_NAME,
        [MQ_PDTCH_READ] = DEV_PDTCH_DSP2ARM_NAME,
};

static const char *wr_devnames[] = {
        [MQ_SYS_WRITE]  = DEV_SYS_ARM2DSP_NAME,
        [MQ_L1_WRITE]   = DEV_L1_ARM2DSP_NAME,
        [MQ_TCH_WRITE]  = DEV_TCH_ARM2DSP_NAME,
        [MQ_PDTCH_WRITE]= DEV_PDTCH_ARM2DSP_NAME,
};

/* callback when there's something to read from the l1 msg_queue */
static int l1if_fd_cb(struct osmo_fd *ofd, unsigned int what)
{
	//struct msgb *msg = l1p_msgb_alloc();
	struct msgb *msg = msgb_alloc_headroom(sizeof(Litecell15_Prim_t) + 128,
		128, "1l_fd");
	struct lc15l1_hdl *fl1h = ofd->data;
	int rc;

	msg->l1h = msg->data;
	rc = read(ofd->fd, msg->l1h, msgb_tailroom(msg));
	if (rc < 0) {
		if (rc != -1)
			LOGP(DL1IF, LOGL_ERROR, "error reading from L1 msg_queue: %s\n",
				strerror(errno));
		msgb_free(msg);
		return rc;
	}
	msgb_put(msg, rc);

	switch (ofd->priv_nr) {
	case MQ_SYS_WRITE:
		if (rc != sizeof(Litecell15_Prim_t))
			LOGP(DL1IF, LOGL_NOTICE, "%u != "
			     "sizeof(Litecell15_Prim_t)\n", rc);
		return l1if_handle_sysprim(fl1h, msg);
	case MQ_L1_WRITE:
	case MQ_TCH_WRITE:
	case MQ_PDTCH_WRITE:
		if (rc != sizeof(GsmL1_Prim_t))
			LOGP(DL1IF, LOGL_NOTICE, "%u != "
			     "sizeof(GsmL1_Prim_t)\n", rc);
		return l1if_handle_l1prim(ofd->priv_nr, fl1h, msg);
	default:
		/* The compiler can't know that priv_nr is an enum. Assist. */
		LOGP(DL1IF, LOGL_FATAL, "writing on a wrong queue: %d\n",
			ofd->priv_nr);
		exit(0);
		break;
	}
};

/* callback when we can write to one of the l1 msg_queue devices */
static int l1fd_write_cb(struct osmo_fd *ofd, struct msgb *msg)
{
	int rc;

	rc = write(ofd->fd, msg->l1h, msgb_l1len(msg));
	if (rc < 0) {
		LOGP(DL1IF, LOGL_ERROR, "error writing to L1 msg_queue: %s\n",
			strerror(errno));
		return rc;
	} else if (rc < msg->len) {
		LOGP(DL1IF, LOGL_ERROR, "short write to L1 msg_queue: "
			"%u < %u\n", rc, msg->len);
		return -EIO;
	}

	return 0;
}

int l1if_transport_open(int q, struct lc15l1_hdl *hdl)
{
	int rc;
        char buf[PATH_MAX];

	/* Step 1: Open all msg_queue file descriptors */
	struct osmo_fd *read_ofd = &hdl->read_ofd[q];
	struct osmo_wqueue *wq = &hdl->write_q[q];
	struct osmo_fd *write_ofd = &hdl->write_q[q].bfd;

        snprintf(buf, sizeof(buf)-1, "%s%d", rd_devnames[q], hdl->hw_info.trx_nr);
        buf[sizeof(buf)-1] = '\0';

	rc = open(buf, O_RDONLY);
	if (rc < 0) {
		LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue %s: %s\n",
			buf, strerror(errno));
		return rc;
	}
	read_ofd->fd = rc;
	read_ofd->priv_nr = q;
	read_ofd->data = hdl;
	read_ofd->cb = l1if_fd_cb;
	read_ofd->when = BSC_FD_READ;
	rc = osmo_fd_register(read_ofd);
	if (rc < 0) {
		close(read_ofd->fd);
		read_ofd->fd = -1;
		return rc;
	}

        snprintf(buf, sizeof(buf)-1, "%s%d", wr_devnames[q], hdl->hw_info.trx_nr);
        buf[sizeof(buf)-1] = '\0';

	rc = open(buf, O_WRONLY);
	if (rc < 0) {
		LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue %s: %s\n",
			buf, strerror(errno));
		goto out_read;
	}
	osmo_wqueue_init(wq, 10);
	wq->write_cb = l1fd_write_cb;
	write_ofd->fd = rc;
	write_ofd->priv_nr = q;
	write_ofd->data = hdl;
	write_ofd->when = BSC_FD_WRITE;
	rc = osmo_fd_register(write_ofd);
	if (rc < 0) {
		close(write_ofd->fd);
		write_ofd->fd = -1;
		goto out_read;
	}

	return 0;

out_read:
	close(hdl->read_ofd[q].fd);
	osmo_fd_unregister(&hdl->read_ofd[q]);

	return rc;
}

int l1if_transport_close(int q, struct lc15l1_hdl *hdl)
{
	struct osmo_fd *read_ofd = &hdl->read_ofd[q];
	struct osmo_fd *write_ofd = &hdl->write_q[q].bfd;

	osmo_fd_unregister(read_ofd);
	close(read_ofd->fd);
	read_ofd->fd = -1;

	osmo_fd_unregister(write_ofd);
	close(write_ofd->fd);
	write_ofd->fd = -1;

	return 0;
}
