/* OpenBSC Abis interface to mISDNuser
 *
 * (C) 2008 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 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 <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <mISDNif.h>

#define AF_COMPATIBILITY_FUNC
#include <compat_af_isdn.h>

#define NUM_E1_TS	32

/* data structure for one E1 interface with A-bis */
struct mi_e1_handle {
	struct gsm_bts *bts;

	/* The mISDN card number of the card we use */
	int cardnr;

	/* The RSL adress */
	struct sockaddr_mISDN l2addr;

	/* The OML adress */
	struct sockaddr_mISDN omladdr;

	struct gsm_fd fd[NUM_E1_TS];
};

#define SAPI_L2ML	0
#define SAPI_OML	62
#define SAPI_RSL	63

#define TEI_L2ML	127
#define TEI_OML		25
#define TEI_RSL		1

static void hexdump(unsigned char *buf, int len)
{
	int i;
	for (i = 0; i < len; i++) {
		fprintf(stdout, "%02x ", buf[i]);
	}
	fprintf(stdout, "\n");
}

#define TS1_ALLOC_SIZE	300

static int handle_ts1_read(struct bsc_fd *bfd)
{
	struct mi_e1_handle *e1h = bfd->data;
	struct msgb *msg = msgb_alloc(TS1_ALLOC_SIZE);
	struct sockaddr_mISDN l2dadr;
	socklen_t alen;

	if (!msg)
		return -ENOMEM;

	msg->bts = e1h->bts;

	alen = sizeof(l2addr);
	ret = recvfrom(bfd->fd, msg->data, 300, 0,
		       (struct sockaddr *) &l2addr, &alen);
	if (ret < 0) {
		fprintf(stderr, "recvfrom error  %s\n", strerror(errno));
		return ret;
	}

	if (alen != sizeof(l2addr))
		return -EINVAL;

	msgb_put(msg, ret);

	DEBUGP(DMI, "alen =%d, dev(%d) channel(%d) sapi(%d) tei(%d)\n",
		alen, l2addr.dev, l2addr.channel, l2addr.sapi, l2addr.tei);

	DEBUGP(DMI, "<= len = %d, prim(0x%x) id(0x%x)\n",
		ret, hh->prim, hh->id);

	switch (hh->prim) {
	case DL_INFORMATION_IND:
		DEBUGP(DMI, "got DL_INFORMATION_IND\n");
		struct sockaddr_mISDN *sa;
		char *lstr = "UNKN";

		switch (l2addr.tei) {
		case TEI_OML:
			sa = &e1h->omladdr;
			lstr = "OML";
			break;
		case TEI_RSL:
			sa = &e1h->l2addr;
			lstr = "RSL";
			break;
		default:
			continue;
		}
		DEBUGP(DMI, "%s use channel(%d) sapi(%d) tei(%d) for now\n",
			lstr, l2addr.channel, l2addr.sapi, l2addr.tei);
		memcpy(sa, &l2addr, sizeof(l2addr));
		break;
	case DL_ESTABLISH_IND:
		DEBUGP(DMI, "got DL_ESTABLISH_IND\n");
		break;
	case DL_ESTABLISH_CNF:
		DEBUGP(DMI, "got DL_ESTABLISH_CNF\n");
		break;
	case DL_RELEASE_IND:
		DEBUGP(DMI, "got DL_RELEASE_IND\n");
		break;
	case MPH_ACTIVATE_IND:
		DEBUGP(DMI, "got MPH_ACTIVATE_IND\n");
		break;
	case MPH_DEACTIVATE_IND:
		DEBUGP(DMI, "got MPH_DEACTIVATE_IND\n");
		break;
	case DL_DATA_IND:
		DEBUGP(DMI, "got DL_DATA_IND\n");
		msg->l2_off = MISDN_HEADER_LEN;
		hexdump(msgb_l2(msg), ret - MISDN_HEADER_LEN);
		switch (l2addr.tei) {
		case TEI_OML:
			ret = abis_nm_rcvmsg(msg);
			break;
		case TEI_RSL:
			ret = abis_rsl_rcvmsg(msg);
			break;
		default:
			fprintf(stderr, "DATA_IND for unknown TEI\n");
			break;
		}
		break;
	default:
		DEBUGP(DMI, "got unexpected 0x%x prim\n", hh->prim);
		break;
	}
	return ret;
}

static int handle_ts1_write(struct bsc_fd *bfd)
{
	struct mi_e1_handle *e1h = bfd->data;

	/* FIXME: dequeue a pending msgb for RSL / OML */
	
	/* prepend the mISDNhead */
	hh = (struct mISDNhed *) msg_
	hh->prim = DL_DATA_REQ;

	/* FIXME: send it off */
}

static int handle_tsX_read(struct bsc_fd *bfd)
{
	/* FIXME: read from a B channel TS */
}

static int handle_TsX_write(struct bsc_fd *bfd)
{
	/* FIXME: write to a B channel TS */
}

/* callback from select.c in case one of the fd's can be read/written */
static int misdn_fd_cb(struct gsm_fd *bfd, unsigned int what)
{
	unsigned int e1_ts = bfd->priv_nr;
	int rc = 0;

	switch (e1_ts) {
	case 1:
		if (what & BSC_FD_READ)
			rc = handle_ts1_read(bfd);
		if (what & BSC_FD_WRITE)
			rc = handle_ts1_write(bfd);
		break;
	default:
		if (what & BSC_FD_READ)
			rc = handle_tsX_read(bfd);
		if (what & BSC_FD_WRITE)
			rc = handle_tsX_write(bfd);
		break;
	}

	return rc;
}

static int mi_setup(devinfo_t *di)
{
	int ts, sk, ret;
	struct mISDN_devinfo	devinfo;

	sk = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
	if (sk < 0)
		fprintf(stderr, "could not open socket %s\n", strerror(errno));
		return sk;
	}

	ret = ioctl(sk, IMGETCOUNT, &cnt);
	if (ret) {
		fprintf(stderr, "error getting interf count: %s\n",
			strerror(errno));
		close(sk);
		return -ENODEV;
	}
	DEBUGP(DMI,"%d device%s found\n", cnt, (cnt==1)?"":"s");
#if 0
	devinfo.id = di->cardnr;
	ret = ioctl(sk, IMGETDEVINFO, &devinfo);
	if (ret < 0) {
		fprintf(stdout, "error getting info for device %d: %s\n",
			di->cardnr, strerror(errno));
		return -ENODEV;
	}
	fprintf(stdout, "        id:             %d\n", devinfo.id);
	fprintf(stdout, "        Dprotocols:     %08x\n", devinfo.Dprotocols);
	fprintf(stdout, "        Bprotocols:     %08x\n", devinfo.Bprotocols);
	fprintf(stdout, "        protocol:       %d\n", devinfo.protocol);
	fprintf(stdout, "        nrbchan:        %d\n", devinfo.nrbchan);
	fprintf(stdout, "        name:           %s\n", devinfo.name);
#endif

	/* TS0 is CRC4, don't need any fd for it */
	for (ts = 1; ts < NUM_E1_TS; ts++) {
		unsigned int idx = i-1;
		struct bsc_fd *bfd = &e1h->fd[idx];
		struct sockaddr_mISDN addr;

		if (ts == 1)
			bfd->fd = socket(PF_ISDN, SOCK_RAW, ISDN_P_LAPD_NT);
		else
			bfd->fd = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW);

		if (bfd->fd < 0)
			fprintf(stderr, "could not open socket %s\n",
				strerror(errno));
			return bfd->fd;
		}

		memset(&addr, 0, sizeof(addr));
		addr.family = AF_ISDN;
		addr.dev = e1h->cardnr;
		if (ts == 1) {
			addr.channel = 0;
			addr.sapi = 0;/* SAPI not supported yet in kernel */
			addr.tei = TEI_L2ML;
		} else
			addr.channel = ts;

		ret = bind(bfd->fd, (struct sockaddr *) &addr, sizeof(addr));
		if (ret < 0) {
			fprintf(stdout, "could not bind l2 socket %s\n",
				strerror(errno));
			return -EIO;
		}
	}
}

