/*
 * Callbacks for the FSM
 *
 * 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.
 */

/*
 * Fix: 19981230 - Carlos Morgado <chbm@techie.com>
 * Port of Nelson Escravana's <nelson.escravana@usa.net> fix to CalledPN
 * NULL pointer dereference in cb_in_1 (originally fixed in 2.0)
 */

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

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

#include <asm/io.h>

#include <linux/isdnif.h>

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

ushort last_ref_num = 1;

/*
 *  send_conn_req
 *
 */

void cb_out_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
	      struct callb_data *cbdata)
{
	struct sk_buff *skb;
	int len;
	ushort refnum;


#ifdef DEBUG
	printk(KERN_DEBUG "Called Party Number: %s\n",
	       cbdata->data.setup.CalledPN);
#endif
	/*
	 * hdr - kmalloc in capi_conn_req
	 *     - kfree   when msg has been sent
	 */

	if ((len = capi_conn_req(cbdata->data.setup.CalledPN, &skb,
				 chan->proto)) < 0)
	{
		printk("capi_conn_req failed\n");
		return;
	}


	refnum = last_ref_num++ & 0x7fffU;

	chan->callref = 0;
	chan->layer2link = 0;
	chan->snum = 0;
	chan->s_refnum = refnum;

	pcbit_l2_write(dev, MSG_CONN_REQ, refnum, skb, len);
}

/*
 *  rcv CONNECT
 *  will go into ACTIVE state
 *  send CONN_ACTIVE_RESP
 *  send Select protocol request
 */

void cb_out_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
	      struct callb_data *data)
{
	isdn_ctrl ictl;
	struct sk_buff *skb;
	int len;
	ushort refnum;

	if ((len = capi_conn_active_resp(chan, &skb)) < 0)
	{
		printk("capi_conn_active_req failed\n");
		return;
	}

	refnum = last_ref_num++ & 0x7fffU;
	chan->s_refnum = refnum;

	pcbit_l2_write(dev, MSG_CONN_ACTV_RESP, refnum, skb, len);


	ictl.command = ISDN_STAT_DCONN;
	ictl.driver = dev->id;
	ictl.arg = chan->id;
	dev->dev_if->statcallb(&ictl);

	/* ACTIVE D-channel */

	/* Select protocol  */

	if ((len = capi_select_proto_req(chan, &skb, 1 /*outgoing*/)) < 0) {
		printk("capi_select_proto_req failed\n");
		return;
	}

	refnum = last_ref_num++ & 0x7fffU;
	chan->s_refnum = refnum;

	pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
}


/*
 * Incoming call received
 * inform user
 */

void cb_in_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
	     struct callb_data *cbdata)
{
	isdn_ctrl ictl;
	unsigned short refnum;
	struct sk_buff *skb;
	int len;


	ictl.command = ISDN_STAT_ICALL;
	ictl.driver = dev->id;
	ictl.arg = chan->id;

	/*
	 *  ictl.num >= strlen() + strlen() + 5
	 */

	if (cbdata->data.setup.CallingPN == NULL) {
		printk(KERN_DEBUG "NULL CallingPN to phone; using 0\n");
		strcpy(ictl.parm.setup.phone, "0");
	}
	else {
		strcpy(ictl.parm.setup.phone, cbdata->data.setup.CallingPN);
	}
	if (cbdata->data.setup.CalledPN == NULL) {
		printk(KERN_DEBUG "NULL CalledPN to eazmsn; using 0\n");
		strcpy(ictl.parm.setup.eazmsn, "0");
	}
	else {
		strcpy(ictl.parm.setup.eazmsn, cbdata->data.setup.CalledPN);
	}
	ictl.parm.setup.si1 = 7;
	ictl.parm.setup.si2 = 0;
	ictl.parm.setup.plan = 0;
	ictl.parm.setup.screen = 0;

#ifdef DEBUG
	printk(KERN_DEBUG "statstr: %s\n", ictl.num);
#endif

	dev->dev_if->statcallb(&ictl);


	if ((len = capi_conn_resp(chan, &skb)) < 0) {
		printk(KERN_DEBUG "capi_conn_resp failed\n");
		return;
	}

	refnum = last_ref_num++ & 0x7fffU;
	chan->s_refnum = refnum;

	pcbit_l2_write(dev, MSG_CONN_RESP, refnum, skb, len);
}

/*
 * user has replied
 * open the channel
 * send CONNECT message CONNECT_ACTIVE_REQ in CAPI
 */

void cb_in_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
	     struct callb_data *data)
{
	unsigned short refnum;
	struct sk_buff *skb;
	int len;

	if ((len = capi_conn_active_req(chan, &skb)) < 0) {
		printk(KERN_DEBUG "capi_conn_active_req failed\n");
		return;
	}


	refnum = last_ref_num++ & 0x7fffU;
	chan->s_refnum = refnum;

	printk(KERN_DEBUG "sending MSG_CONN_ACTV_REQ\n");
	pcbit_l2_write(dev, MSG_CONN_ACTV_REQ, refnum, skb, len);
}

/*
 * CONN_ACK arrived
 * start b-proto selection
 *
 */

void cb_in_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
	     struct callb_data *data)
{
	unsigned short refnum;
	struct sk_buff *skb;
	int len;

	if ((len = capi_select_proto_req(chan, &skb, 0 /*incoming*/)) < 0)
	{
		printk("capi_select_proto_req failed\n");
		return;
	}

	refnum = last_ref_num++ & 0x7fffU;
	chan->s_refnum = refnum;

	pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);

}


/*
 * Received disconnect ind on active state
 * send disconnect resp
 * send msg to user
 */
void cb_disc_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
	       struct callb_data *data)
{
	struct sk_buff *skb;
	int len;
	ushort refnum;
	isdn_ctrl ictl;

	if ((len = capi_disc_resp(chan, &skb)) < 0) {
		printk("capi_disc_resp failed\n");
		return;
	}

	refnum = last_ref_num++ & 0x7fffU;
	chan->s_refnum = refnum;

	pcbit_l2_write(dev, MSG_DISC_RESP, refnum, skb, len);

	ictl.command = ISDN_STAT_BHUP;
	ictl.driver = dev->id;
	ictl.arg = chan->id;
	dev->dev_if->statcallb(&ictl);
}


/*
 *  User HANGUP on active/call proceeding state
 *  send disc.req
 */
void cb_disc_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
	       struct callb_data *data)
{
	struct sk_buff *skb;
	int len;
	ushort refnum;

	if ((len = capi_disc_req(chan->callref, &skb, CAUSE_NORMAL)) < 0)
	{
		printk("capi_disc_req failed\n");
		return;
	}

	refnum = last_ref_num++ & 0x7fffU;
	chan->s_refnum = refnum;

	pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb, len);
}

/*
 *  Disc confirm received send BHUP
 *  Problem: when the HL driver sends the disc req itself
 *           LL receives BHUP
 */
void cb_disc_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
	       struct callb_data *data)
{
	isdn_ctrl ictl;

	ictl.command = ISDN_STAT_BHUP;
	ictl.driver = dev->id;
	ictl.arg = chan->id;
	dev->dev_if->statcallb(&ictl);
}

void cb_notdone(struct pcbit_dev *dev, struct pcbit_chan *chan,
		struct callb_data *data)
{
}

/*
 * send activate b-chan protocol
 */
void cb_selp_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
	       struct callb_data *data)
{
	struct sk_buff *skb;
	int len;
	ushort refnum;

	if ((len = capi_activate_transp_req(chan, &skb)) < 0)
	{
		printk("capi_conn_activate_transp_req failed\n");
		return;
	}

	refnum = last_ref_num++ & 0x7fffU;
	chan->s_refnum = refnum;

	pcbit_l2_write(dev, MSG_ACT_TRANSP_REQ, refnum, skb, len);
}

/*
 *  Inform User that the B-channel is available
 */
void cb_open(struct pcbit_dev *dev, struct pcbit_chan *chan,
	     struct callb_data *data)
{
	isdn_ctrl ictl;

	ictl.command = ISDN_STAT_BCONN;
	ictl.driver = dev->id;
	ictl.arg = chan->id;
	dev->dev_if->statcallb(&ictl);
}
