/* 
   CMTP implementation for Linux Bluetooth stack (BlueZ).
   Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2 as
   published by the Free Software Foundation;

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
   SOFTWARE IS DISCLAIMED.
*/

#include <linux/module.h>

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/skbuff.h>
#include <linux/socket.h>
#include <linux/ioctl.h>
#include <linux/file.h>
#include <linux/wait.h>
#include <net/sock.h>

#include <linux/isdn/capilli.h>
#include <linux/isdn/capicmd.h>
#include <linux/isdn/capiutil.h>

#include "cmtp.h"

#ifndef CONFIG_BT_CMTP_DEBUG
#undef  BT_DBG
#define BT_DBG(D...)
#endif

#define CAPI_INTEROPERABILITY		0x20

#define CAPI_INTEROPERABILITY_REQ	CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
#define CAPI_INTEROPERABILITY_CONF	CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
#define CAPI_INTEROPERABILITY_IND	CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
#define CAPI_INTEROPERABILITY_RESP	CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)

#define CAPI_INTEROPERABILITY_REQ_LEN	(CAPI_MSG_BASELEN + 2)
#define CAPI_INTEROPERABILITY_CONF_LEN	(CAPI_MSG_BASELEN + 4)
#define CAPI_INTEROPERABILITY_IND_LEN	(CAPI_MSG_BASELEN + 2)
#define CAPI_INTEROPERABILITY_RESP_LEN	(CAPI_MSG_BASELEN + 2)

#define CAPI_FUNCTION_REGISTER		0
#define CAPI_FUNCTION_RELEASE		1
#define CAPI_FUNCTION_GET_PROFILE	2
#define CAPI_FUNCTION_GET_MANUFACTURER	3
#define CAPI_FUNCTION_GET_VERSION	4
#define CAPI_FUNCTION_GET_SERIAL_NUMBER	5
#define CAPI_FUNCTION_MANUFACTURER	6
#define CAPI_FUNCTION_LOOPBACK		7


#define CMTP_MSGNUM	1
#define CMTP_APPLID	2
#define CMTP_MAPPING	3

static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
{
	struct cmtp_application *app = kzalloc(sizeof(*app), GFP_KERNEL);

	BT_DBG("session %p application %p appl %d", session, app, appl);

	if (!app)
		return NULL;

	app->state = BT_OPEN;
	app->appl = appl;

	list_add_tail(&app->list, &session->applications);

	return app;
}

static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
{
	BT_DBG("session %p application %p", session, app);

	if (app) {
		list_del(&app->list);
		kfree(app);
	}
}

static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
{
	struct cmtp_application *app;
	struct list_head *p, *n;

	list_for_each_safe(p, n, &session->applications) {
		app = list_entry(p, struct cmtp_application, list);
		switch (pattern) {
		case CMTP_MSGNUM:
			if (app->msgnum == value)
				return app;
			break;
		case CMTP_APPLID:
			if (app->appl == value)
				return app;
			break;
		case CMTP_MAPPING:
			if (app->mapping == value)
				return app;
			break;
		}
	}

	return NULL;
}

static int cmtp_msgnum_get(struct cmtp_session *session)
{
	session->msgnum++;

	if ((session->msgnum & 0xff) > 200)
		session->msgnum = CMTP_INITIAL_MSGNUM + 1;

	return session->msgnum;
}

static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
{
	struct cmtp_scb *scb = (void *) skb->cb;

	BT_DBG("session %p skb %p len %d", session, skb, skb->len);

	scb->id = -1;
	scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);

	skb_queue_tail(&session->transmit, skb);

	cmtp_schedule(session);
}

static void cmtp_send_interopmsg(struct cmtp_session *session,
					__u8 subcmd, __u16 appl, __u16 msgnum,
					__u16 function, unsigned char *buf, int len)
{
	struct sk_buff *skb;
	unsigned char *s;

	BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);

	if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
		BT_ERR("Can't allocate memory for interoperability packet");
		return;
	}

	s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);

	capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
	capimsg_setu16(s, 2, appl);
	capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
	capimsg_setu8 (s, 5, subcmd);
	capimsg_setu16(s, 6, msgnum);

	/* Interoperability selector (Bluetooth Device Management) */
	capimsg_setu16(s, 8, 0x0001);

	capimsg_setu8 (s, 10, 3 + len);
	capimsg_setu16(s, 11, function);
	capimsg_setu8 (s, 13, len);

	if (len > 0)
		memcpy(s + 14, buf, len);

	cmtp_send_capimsg(session, skb);
}

static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
{
	struct capi_ctr *ctrl = &session->ctrl;
	struct cmtp_application *application;
	__u16 appl, msgnum, func, info;
	__u32 controller;

	BT_DBG("session %p skb %p len %d", session, skb, skb->len);

	switch (CAPIMSG_SUBCOMMAND(skb->data)) {
	case CAPI_CONF:
		func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
		info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);

		switch (func) {
		case CAPI_FUNCTION_REGISTER:
			msgnum = CAPIMSG_MSGID(skb->data);

			application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
			if (application) {
				application->state = BT_CONNECTED;
				application->msgnum = 0;
				application->mapping = CAPIMSG_APPID(skb->data);
				wake_up_interruptible(&session->wait);
			}

			break;

		case CAPI_FUNCTION_RELEASE:
			appl = CAPIMSG_APPID(skb->data);

			application = cmtp_application_get(session, CMTP_MAPPING, appl);
			if (application) {
				application->state = BT_CLOSED;
				application->msgnum = 0;
				wake_up_interruptible(&session->wait);
			}

			break;

		case CAPI_FUNCTION_GET_PROFILE:
			controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
			msgnum = CAPIMSG_MSGID(skb->data);

			if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
				session->ncontroller = controller;
				wake_up_interruptible(&session->wait);
				break;
			}

			if (!info && ctrl) {
				memcpy(&ctrl->profile,
					skb->data + CAPI_MSG_BASELEN + 11,
					sizeof(capi_profile));
				session->state = BT_CONNECTED;
				capi_ctr_ready(ctrl);
			}

			break;

		case CAPI_FUNCTION_GET_MANUFACTURER:
			controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);

			if (!info && ctrl) {
				strncpy(ctrl->manu,
					skb->data + CAPI_MSG_BASELEN + 15,
					skb->data[CAPI_MSG_BASELEN + 14]);
			}

			break;

		case CAPI_FUNCTION_GET_VERSION:
			controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);

			if (!info && ctrl) {
				ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
				ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
				ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
				ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
			}

			break;

		case CAPI_FUNCTION_GET_SERIAL_NUMBER:
			controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);

			if (!info && ctrl) {
				memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
				strncpy(ctrl->serial,
					skb->data + CAPI_MSG_BASELEN + 17,
					skb->data[CAPI_MSG_BASELEN + 16]);
			}

			break;
		}

		break;

	case CAPI_IND:
		func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);

		if (func == CAPI_FUNCTION_LOOPBACK) {
			appl = CAPIMSG_APPID(skb->data);
			msgnum = CAPIMSG_MSGID(skb->data);
			cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
						skb->data + CAPI_MSG_BASELEN + 6,
						skb->data[CAPI_MSG_BASELEN + 5]);
		}

		break;
	}

	kfree_skb(skb);
}

void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
{
	struct capi_ctr *ctrl = &session->ctrl;
	struct cmtp_application *application;
	__u16 cmd, appl;
	__u32 contr;

	BT_DBG("session %p skb %p len %d", session, skb, skb->len);

	if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
		cmtp_recv_interopmsg(session, skb);
		return;
	}

	if (session->flags & (1 << CMTP_LOOPBACK)) {
		kfree_skb(skb);
		return;
	}

	cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
	appl = CAPIMSG_APPID(skb->data);
	contr = CAPIMSG_CONTROL(skb->data);

	application = cmtp_application_get(session, CMTP_MAPPING, appl);
	if (application) {
		appl = application->appl;
		CAPIMSG_SETAPPID(skb->data, appl);
	} else {
		BT_ERR("Can't find application with id %d", appl);
		kfree_skb(skb);
		return;
	}

	if ((contr & 0x7f) == 0x01) {
		contr = (contr & 0xffffff80) | session->num;
		CAPIMSG_SETCONTROL(skb->data, contr);
	}

	if (!ctrl) {
		BT_ERR("Can't find controller %d for message", session->num);
		kfree_skb(skb);
		return;
	}

	capi_ctr_handle_message(ctrl, appl, skb);
}

static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
{
	BT_DBG("ctrl %p data %p", ctrl, data);

	return 0;
}

static void cmtp_reset_ctr(struct capi_ctr *ctrl)
{
	struct cmtp_session *session = ctrl->driverdata;

	BT_DBG("ctrl %p", ctrl);

	capi_ctr_reseted(ctrl);

	atomic_inc(&session->terminate);
	cmtp_schedule(session);
}

static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
{
	DECLARE_WAITQUEUE(wait, current);
	struct cmtp_session *session = ctrl->driverdata;
	struct cmtp_application *application;
	unsigned long timeo = CMTP_INTEROP_TIMEOUT;
	unsigned char buf[8];
	int err = 0, nconn, want = rp->level3cnt;

	BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
		ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);

	application = cmtp_application_add(session, appl);
	if (!application) {
		BT_ERR("Can't allocate memory for new application");
		return;
	}

	if (want < 0)
		nconn = ctrl->profile.nbchannel * -want;
	else
		nconn = want;

	if (nconn == 0)
		nconn = ctrl->profile.nbchannel;

	capimsg_setu16(buf, 0, nconn);
	capimsg_setu16(buf, 2, rp->datablkcnt);
	capimsg_setu16(buf, 4, rp->datablklen);

	application->state = BT_CONFIG;
	application->msgnum = cmtp_msgnum_get(session);

	cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
				CAPI_FUNCTION_REGISTER, buf, 6);

	add_wait_queue(&session->wait, &wait);
	while (1) {
		set_current_state(TASK_INTERRUPTIBLE);

		if (!timeo) {
			err = -EAGAIN;
			break;
		}

		if (application->state == BT_CLOSED) {
			err = -application->err;
			break;
		}

		if (application->state == BT_CONNECTED)
			break;

		if (signal_pending(current)) {
			err = -EINTR;
			break;
		}

		timeo = schedule_timeout(timeo);
	}
	set_current_state(TASK_RUNNING);
	remove_wait_queue(&session->wait, &wait);

	if (err) {
		cmtp_application_del(session, application);
		return;
	}
}

static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
{
	struct cmtp_session *session = ctrl->driverdata;
	struct cmtp_application *application;

	BT_DBG("ctrl %p appl %d", ctrl, appl);

	application = cmtp_application_get(session, CMTP_APPLID, appl);
	if (!application) {
		BT_ERR("Can't find application");
		return;
	}

	application->msgnum = cmtp_msgnum_get(session);

	cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
				CAPI_FUNCTION_RELEASE, NULL, 0);

	wait_event_interruptible_timeout(session->wait,
			(application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);

	cmtp_application_del(session, application);
}

static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
{
	struct cmtp_session *session = ctrl->driverdata;
	struct cmtp_application *application;
	__u16 appl;
	__u32 contr;

	BT_DBG("ctrl %p skb %p", ctrl, skb);

	appl = CAPIMSG_APPID(skb->data);
	contr = CAPIMSG_CONTROL(skb->data);

	application = cmtp_application_get(session, CMTP_APPLID, appl);
	if ((!application) || (application->state != BT_CONNECTED)) {
		BT_ERR("Can't find application with id %d", appl);
		return CAPI_ILLAPPNR;
	}

	CAPIMSG_SETAPPID(skb->data, application->mapping);

	if ((contr & 0x7f) == session->num) {
		contr = (contr & 0xffffff80) | 0x01;
		CAPIMSG_SETCONTROL(skb->data, contr);
	}

	cmtp_send_capimsg(session, skb);

	return CAPI_NOERROR;
}

static char *cmtp_procinfo(struct capi_ctr *ctrl)
{
	return "CAPI Message Transport Protocol";
}

static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
{
	struct cmtp_session *session = ctrl->driverdata;
	struct cmtp_application *app;
	struct list_head *p, *n;
	int len = 0;

	len += sprintf(page + len, "%s\n\n", cmtp_procinfo(ctrl));
	len += sprintf(page + len, "addr %s\n", session->name);
	len += sprintf(page + len, "ctrl %d\n", session->num);

	list_for_each_safe(p, n, &session->applications) {
		app = list_entry(p, struct cmtp_application, list);
		len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
	}

	if (off + count >= len)
		*eof = 1;

	if (len < off)
		return 0;

	*start = page + off;

	return ((count < len - off) ? count : len - off);
}


int cmtp_attach_device(struct cmtp_session *session)
{
	unsigned char buf[4];
	long ret;

	BT_DBG("session %p", session);

	capimsg_setu32(buf, 0, 0);

	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
				CAPI_FUNCTION_GET_PROFILE, buf, 4);

	ret = wait_event_interruptible_timeout(session->wait,
			session->ncontroller, CMTP_INTEROP_TIMEOUT);
	
	BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);

	if (!ret)
		return -ETIMEDOUT;

	if (!session->ncontroller)
		return -ENODEV;

	if (session->ncontroller > 1)
		BT_INFO("Setting up only CAPI controller 1");

	session->ctrl.owner      = THIS_MODULE;
	session->ctrl.driverdata = session;
	strcpy(session->ctrl.name, session->name);

	session->ctrl.driver_name   = "cmtp";
	session->ctrl.load_firmware = cmtp_load_firmware;
	session->ctrl.reset_ctr     = cmtp_reset_ctr;
	session->ctrl.register_appl = cmtp_register_appl;
	session->ctrl.release_appl  = cmtp_release_appl;
	session->ctrl.send_message  = cmtp_send_message;

	session->ctrl.procinfo      = cmtp_procinfo;
	session->ctrl.ctr_read_proc = cmtp_ctr_read_proc;

	if (attach_capi_ctr(&session->ctrl) < 0) {
		BT_ERR("Can't attach new controller");
		return -EBUSY;
	}

	session->num = session->ctrl.cnr;

	BT_DBG("session %p num %d", session, session->num);

	capimsg_setu32(buf, 0, 1);

	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
				CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);

	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
				CAPI_FUNCTION_GET_VERSION, buf, 4);

	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
				CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);

	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
				CAPI_FUNCTION_GET_PROFILE, buf, 4);

	return 0;
}

void cmtp_detach_device(struct cmtp_session *session)
{
	BT_DBG("session %p", session);

	detach_capi_ctr(&session->ctrl);
}
