/*
 * CAPI encoder/decoder for
 * Portugal Telecom CAPI 2.0
 *
 * Copyright (C) 1996 Universidade de Lisboa
 *
 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
 *
 * This software may be used and distributed according to the terms of
 * the GNU General Public License, incorporated herein by reference.
 *
 * Not compatible with the AVM Gmbh. CAPI 2.0
 *
 */

/*
 *        Documentation:
 *        - "Common ISDN API - Perfil Português - Versão 2.1",
 *           Telecom Portugal, Fev 1992.
 *        - "Common ISDN API - Especificação de protocolos para
 *           acesso aos canais B", Inesc, Jan 1994.
 */

/*
 *        TODO: better decoding of Information Elements
 *              for debug purposes mainly
 *              encode our number in CallerPN and ConnectedPN
 */

#include <linux/string.h>
#include <linux/kernel.h>

#include <linux/types.h>
#include <linux/slab.h>
#include <linux/mm.h>

#include <linux/skbuff.h>

#include <asm/io.h>
#include <asm/string.h>

#include <linux/isdnif.h>

#include "pcbit.h"
#include "edss1.h"
#include "capi.h"


/*
 *  Encoding of CAPI messages
 *
 */

int capi_conn_req(const char *calledPN, struct sk_buff **skb, int proto)
{
	ushort len;

	/*
	 * length
	 *   AppInfoMask - 2
	 *   BC0         - 3
	 *   BC1         - 1
	 *   Chan        - 2
	 *   Keypad      - 1
	 *   CPN         - 1
	 *   CPSA        - 1
	 *   CalledPN    - 2 + strlen
	 *   CalledPSA   - 1
	 *   rest...     - 4
	 *   ----------------
	 *   Total        18 + strlen
	 */

	len = 18 + strlen(calledPN);

	if (proto == ISDN_PROTO_L2_TRANS)
		len++;

	if ((*skb = dev_alloc_skb(len)) == NULL) {

		printk(KERN_WARNING "capi_conn_req: alloc_skb failed\n");
		return -1;
	}

	/* InfoElmMask */
	*((ushort *)skb_put(*skb, 2)) = AppInfoMask;

	if (proto == ISDN_PROTO_L2_TRANS)
	{
		/* Bearer Capability - Mandatory*/
		*(skb_put(*skb, 1)) = 3;        /* BC0.Length		*/
		*(skb_put(*skb, 1)) = 0x80;     /* Speech		*/
		*(skb_put(*skb, 1)) = 0x10;     /* Circuit Mode		*/
		*(skb_put(*skb, 1)) = 0x23;     /* A-law		*/
	}
	else
	{
		/* Bearer Capability - Mandatory*/
		*(skb_put(*skb, 1)) = 2;        /* BC0.Length		*/
		*(skb_put(*skb, 1)) = 0x88;     /* Digital Information	*/
		*(skb_put(*skb, 1)) = 0x90;     /* BC0.Octect4		*/
	}

	/* Bearer Capability - Optional*/
	*(skb_put(*skb, 1)) = 0;        /* BC1.Length = 0                    */

	*(skb_put(*skb, 1)) = 1;        /* ChannelID.Length = 1              */
	*(skb_put(*skb, 1)) = 0x83;     /* Basic Interface - Any Channel     */

	*(skb_put(*skb, 1)) = 0;        /* Keypad.Length = 0                 */


	*(skb_put(*skb, 1)) = 0;        /* CallingPN.Length = 0              */
	*(skb_put(*skb, 1)) = 0;        /* CallingPSA.Length = 0             */

	/* Called Party Number */
	*(skb_put(*skb, 1)) = strlen(calledPN) + 1;
	*(skb_put(*skb, 1)) = 0x81;
	memcpy(skb_put(*skb, strlen(calledPN)), calledPN, strlen(calledPN));

	/* '#' */

	*(skb_put(*skb, 1)) = 0;       /* CalledPSA.Length = 0     */

	/* LLC.Length  = 0; */
	/* HLC0.Length = 0; */
	/* HLC1.Length = 0; */
	/* UTUS.Length = 0; */
	memset(skb_put(*skb, 4), 0, 4);

	return len;
}

int capi_conn_resp(struct pcbit_chan *chan, struct sk_buff **skb)
{

	if ((*skb = dev_alloc_skb(5)) == NULL) {

		printk(KERN_WARNING "capi_conn_resp: alloc_skb failed\n");
		return -1;
	}

	*((ushort *)skb_put(*skb, 2)) = chan->callref;
	*(skb_put(*skb, 1)) = 0x01;  /* ACCEPT_CALL */
	*(skb_put(*skb, 1)) = 0;
	*(skb_put(*skb, 1)) = 0;

	return 5;
}

int capi_conn_active_req(struct pcbit_chan *chan, struct sk_buff **skb)
{
	/*
	 * 8 bytes
	 */

	if ((*skb = dev_alloc_skb(8)) == NULL) {

		printk(KERN_WARNING "capi_conn_active_req: alloc_skb failed\n");
		return -1;
	}

	*((ushort *)skb_put(*skb, 2)) = chan->callref;

#ifdef DEBUG
	printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref);
#endif

	*(skb_put(*skb, 1)) = 0;       /*  BC.Length = 0;          */
	*(skb_put(*skb, 1)) = 0;       /*  ConnectedPN.Length = 0  */
	*(skb_put(*skb, 1)) = 0;       /*  PSA.Length              */
	*(skb_put(*skb, 1)) = 0;       /*  LLC.Length = 0;         */
	*(skb_put(*skb, 1)) = 0;       /*  HLC.Length = 0;         */
	*(skb_put(*skb, 1)) = 0;       /*  UTUS.Length = 0;        */

	return 8;
}

int capi_conn_active_resp(struct pcbit_chan *chan, struct sk_buff **skb)
{
	/*
	 * 2 bytes
	 */

	if ((*skb = dev_alloc_skb(2)) == NULL) {

		printk(KERN_WARNING "capi_conn_active_resp: alloc_skb failed\n");
		return -1;
	}

	*((ushort *)skb_put(*skb, 2)) = chan->callref;

	return 2;
}


int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb,
			  int outgoing)
{

	/*
	 * 18 bytes
	 */

	if ((*skb = dev_alloc_skb(18)) == NULL) {

		printk(KERN_WARNING "capi_select_proto_req: alloc_skb failed\n");
		return -1;
	}

	*((ushort *)skb_put(*skb, 2)) = chan->callref;

	/* Layer2 protocol */

	switch (chan->proto) {
	case ISDN_PROTO_L2_X75I:
		*(skb_put(*skb, 1)) = 0x05;            /* LAPB */
		break;
	case ISDN_PROTO_L2_HDLC:
		*(skb_put(*skb, 1)) = 0x02;
		break;
	case ISDN_PROTO_L2_TRANS:
		/*
		 *	Voice (a-law)
		 */
		*(skb_put(*skb, 1)) = 0x06;
		break;
	default:
#ifdef DEBUG
		printk(KERN_DEBUG "Transparent\n");
#endif
		*(skb_put(*skb, 1)) = 0x03;
		break;
	}

	*(skb_put(*skb, 1)) = (outgoing ? 0x02 : 0x42);    /* Don't ask */
	*(skb_put(*skb, 1)) = 0x00;

	*((ushort *) skb_put(*skb, 2)) = MRU;


	*(skb_put(*skb, 1)) = 0x08;           /* Modulo */
	*(skb_put(*skb, 1)) = 0x07;           /* Max Window */

	*(skb_put(*skb, 1)) = 0x01;           /* No Layer3 Protocol */

	/*
	 * 2 - layer3 MTU       [10]
	 *   - Modulo           [12]
	 *   - Window
	 *   - layer1 proto     [14]
	 *   - bitrate
	 *   - sub-channel      [16]
	 *   - layer1dataformat [17]
	 */

	memset(skb_put(*skb, 8), 0, 8);

	return 18;
}


int capi_activate_transp_req(struct pcbit_chan *chan, struct sk_buff **skb)
{

	if ((*skb = dev_alloc_skb(7)) == NULL) {

		printk(KERN_WARNING "capi_activate_transp_req: alloc_skb failed\n");
		return -1;
	}

	*((ushort *)skb_put(*skb, 2)) = chan->callref;


	*(skb_put(*skb, 1)) = chan->layer2link; /* Layer2 id */
	*(skb_put(*skb, 1)) = 0x00;             /* Transmit by default */

	*((ushort *) skb_put(*skb, 2)) = MRU;

	*(skb_put(*skb, 1)) = 0x01;             /* Enables reception*/

	return 7;
}

int capi_tdata_req(struct pcbit_chan *chan, struct sk_buff *skb)
{
	ushort data_len;


	/*
	 * callref      - 2
	 * layer2link   - 1
	 * wBlockLength - 2
	 * data         - 4
	 * sernum       - 1
	 */

	data_len = skb->len;

	if (skb_headroom(skb) < 10)
	{
		printk(KERN_CRIT "No headspace (%u) on headroom %p for capi header\n", skb_headroom(skb), skb);
	}
	else
	{
		skb_push(skb, 10);
	}

	*((u16 *) (skb->data)) = chan->callref;
	skb->data[2] = chan->layer2link;
	*((u16 *) (skb->data + 3)) = data_len;

	chan->s_refnum = (chan->s_refnum + 1) % 8;
	*((u32 *) (skb->data + 5)) = chan->s_refnum;

	skb->data[9] = 0;                           /* HDLC frame number */

	return 10;
}

int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff **skb)

{
	if ((*skb = dev_alloc_skb(4)) == NULL) {

		printk(KERN_WARNING "capi_tdata_resp: alloc_skb failed\n");
		return -1;
	}

	*((ushort *)skb_put(*skb, 2)) = chan->callref;

	*(skb_put(*skb, 1)) = chan->layer2link;
	*(skb_put(*skb, 1)) = chan->r_refnum;

	return (*skb)->len;
}

int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause)
{

	if ((*skb = dev_alloc_skb(6)) == NULL) {

		printk(KERN_WARNING "capi_disc_req: alloc_skb failed\n");
		return -1;
	}

	*((ushort *)skb_put(*skb, 2)) = callref;

	*(skb_put(*skb, 1)) = 2;                  /* Cause.Length = 2; */
	*(skb_put(*skb, 1)) = 0x80;
	*(skb_put(*skb, 1)) = 0x80 | cause;

	/*
	 * Change it: we should send 'Sic transit gloria Mundi' here ;-)
	 */

	*(skb_put(*skb, 1)) = 0;                   /* UTUS.Length = 0;  */

	return 6;
}

int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb)
{
	if ((*skb = dev_alloc_skb(2)) == NULL) {

		printk(KERN_WARNING "capi_disc_resp: alloc_skb failed\n");
		return -1;
	}

	*((ushort *)skb_put(*skb, 2)) = chan->callref;

	return 2;
}


/*
 *  Decoding of CAPI messages
 *
 */

int capi_decode_conn_ind(struct pcbit_chan *chan,
			 struct sk_buff *skb,
			 struct callb_data *info)
{
	int CIlen, len;

	/* Call Reference [CAPI] */
	chan->callref = *((ushort *)skb->data);
	skb_pull(skb, 2);

#ifdef DEBUG
	printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref);
#endif

	/* Channel Identification */

	/* Expect
	   Len = 1
	   Octect 3 = 0100 10CC - [ 7 Basic, 4 , 2-1 chan ]
	*/

	CIlen = skb->data[0];
#ifdef DEBUG
	if (CIlen == 1) {

		if (((skb->data[1]) & 0xFC) == 0x48)
			printk(KERN_DEBUG "decode_conn_ind: chan ok\n");
		printk(KERN_DEBUG "phyChan = %d\n", skb->data[1] & 0x03);
	}
	else
		printk(KERN_DEBUG "conn_ind: CIlen = %d\n", CIlen);
#endif
	skb_pull(skb, CIlen + 1);

	/* Calling Party Number */
	/* An "additional service" as far as Portugal Telecom is concerned */

	len = skb->data[0];

	if (len > 0) {
		int count = 1;

#ifdef DEBUG
		printk(KERN_DEBUG "CPN: Octect 3 %02x\n", skb->data[1]);
#endif
		if ((skb->data[1] & 0x80) == 0)
			count = 2;

		if (!(info->data.setup.CallingPN = kmalloc(len - count + 1, GFP_ATOMIC)))
			return -1;

		skb_copy_from_linear_data_offset(skb, count + 1,
						 info->data.setup.CallingPN,
						 len - count);
		info->data.setup.CallingPN[len - count] = 0;

	}
	else {
		info->data.setup.CallingPN = NULL;
		printk(KERN_DEBUG "NULL CallingPN\n");
	}

	skb_pull(skb, len + 1);

	/* Calling Party Subaddress */
	skb_pull(skb, skb->data[0] + 1);

	/* Called Party Number */

	len = skb->data[0];

	if (len > 0) {
		int count = 1;

		if ((skb->data[1] & 0x80) == 0)
			count = 2;

		if (!(info->data.setup.CalledPN = kmalloc(len - count + 1, GFP_ATOMIC)))
			return -1;

		skb_copy_from_linear_data_offset(skb, count + 1,
						 info->data.setup.CalledPN,
						 len - count);
		info->data.setup.CalledPN[len - count] = 0;

	}
	else {
		info->data.setup.CalledPN = NULL;
		printk(KERN_DEBUG "NULL CalledPN\n");
	}

	skb_pull(skb, len + 1);

	/* Called Party Subaddress */
	skb_pull(skb, skb->data[0] + 1);

	/* LLC */
	skb_pull(skb, skb->data[0] + 1);

	/* HLC */
	skb_pull(skb, skb->data[0] + 1);

	/* U2U */
	skb_pull(skb, skb->data[0] + 1);

	return 0;
}

/*
 *  returns errcode
 */

int capi_decode_conn_conf(struct pcbit_chan *chan, struct sk_buff *skb,
			  int *complete)
{
	int errcode;

	chan->callref = *((ushort *)skb->data);     /* Update CallReference */
	skb_pull(skb, 2);

	errcode = *((ushort *) skb->data);   /* read errcode */
	skb_pull(skb, 2);

	*complete = *(skb->data);
	skb_pull(skb, 1);

	/* FIX ME */
	/* This is actually a firmware bug */
	if (!*complete)
	{
		printk(KERN_DEBUG "complete=%02x\n", *complete);
		*complete = 1;
	}


	/* Optional Bearer Capability */
	skb_pull(skb, *(skb->data) + 1);

	/* Channel Identification */
	skb_pull(skb, *(skb->data) + 1);

	/* High Layer Compatibility follows */
	skb_pull(skb, *(skb->data) + 1);

	return errcode;
}

int capi_decode_conn_actv_ind(struct pcbit_chan *chan, struct sk_buff *skb)
{
	ushort len;
#ifdef DEBUG
	char str[32];
#endif

	/* Yet Another Bearer Capability */
	skb_pull(skb, *(skb->data) + 1);


	/* Connected Party Number */
	len = *(skb->data);

#ifdef DEBUG
	if (len > 1 && len < 31) {
		skb_copy_from_linear_data_offset(skb, 2, str, len - 1);
		str[len] = 0;
		printk(KERN_DEBUG "Connected Party Number: %s\n", str);
	}
	else
		printk(KERN_DEBUG "actv_ind CPN len = %d\n", len);
#endif

	skb_pull(skb, len + 1);

	/* Connected Subaddress */
	skb_pull(skb, *(skb->data) + 1);

	/* Low Layer Capability */
	skb_pull(skb, *(skb->data) + 1);

	/* High Layer Capability */
	skb_pull(skb, *(skb->data) + 1);

	return 0;
}

int capi_decode_conn_actv_conf(struct pcbit_chan *chan, struct sk_buff *skb)
{
	ushort errcode;

	errcode = *((ushort *)skb->data);
	skb_pull(skb, 2);

	/* Channel Identification
	   skb_pull(skb, skb->data[0] + 1);
	*/
	return errcode;
}


int capi_decode_sel_proto_conf(struct pcbit_chan *chan, struct sk_buff *skb)
{
	ushort errcode;

	chan->layer2link = *(skb->data);
	skb_pull(skb, 1);

	errcode = *((ushort *)skb->data);
	skb_pull(skb, 2);

	return errcode;
}

int capi_decode_actv_trans_conf(struct pcbit_chan *chan, struct sk_buff *skb)
{
	ushort errcode;

	if (chan->layer2link != *(skb->data))
		printk("capi_decode_actv_trans_conf: layer2link doesn't match\n");

	skb_pull(skb, 1);

	errcode = *((ushort *)skb->data);
	skb_pull(skb, 2);

	return errcode;
}

int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb)
{
	ushort len;
#ifdef DEBUG
	int i;
#endif
	/* Cause */

	len = *(skb->data);
	skb_pull(skb, 1);

#ifdef DEBUG

	for (i = 0; i < len; i++)
		printk(KERN_DEBUG "Cause Octect %d: %02x\n", i + 3,
		       *(skb->data + i));
#endif

	skb_pull(skb, len);

	return 0;
}

#ifdef DEBUG
int capi_decode_debug_188(u_char *hdr, ushort hdrlen)
{
	char str[64];
	int len;

	len = hdr[0];

	if (len < 64 && len == hdrlen - 1) {
		memcpy(str, hdr + 1, hdrlen - 1);
		str[hdrlen - 1] = 0;
		printk("%s\n", str);
	}
	else
		printk("debug message incorrect\n");

	return 0;
}
#endif
