/*
 * 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 <linux/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);
}
