2 * Callbacks for the FSM
4 * Copyright (C) 1996 Universidade de Lisboa
6 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
8 * This software may be used and distributed according to the terms of
9 * the GNU General Public License, incorporated herein by reference.
13 * Fix: 19981230 - Carlos Morgado <chbm@techie.com>
14 * Port of Nelson Escravana's <nelson.escravana@usa.net> fix to CalledPN
15 * NULL pointer dereference in cb_in_1 (originally fixed in 2.0)
18 #include <linux/sched.h>
19 #include <linux/string.h>
20 #include <linux/kernel.h>
22 #include <linux/types.h>
23 #include <linux/slab.h>
25 #include <linux/skbuff.h>
29 #include <linux/isdnif.h>
34 #include "callbacks.h"
37 ushort last_ref_num = 1;
44 void cb_out_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
45 struct callb_data *cbdata)
53 printk(KERN_DEBUG "Called Party Number: %s\n",
54 cbdata->data.setup.CalledPN);
57 * hdr - kmalloc in capi_conn_req
58 * - kfree when msg has been sent
61 if ((len = capi_conn_req(cbdata->data.setup.CalledPN, &skb,
64 printk("capi_conn_req failed\n");
69 refnum = last_ref_num++ & 0x7fffU;
74 chan->s_refnum = refnum;
76 pcbit_l2_write(dev, MSG_CONN_REQ, refnum, skb, len);
81 * will go into ACTIVE state
82 * send CONN_ACTIVE_RESP
83 * send Select protocol request
86 void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
87 struct callb_data *data)
94 if ((len=capi_conn_active_resp(chan, &skb)) < 0)
96 printk("capi_conn_active_req failed\n");
100 refnum = last_ref_num++ & 0x7fffU;
101 chan->s_refnum = refnum;
103 pcbit_l2_write(dev, MSG_CONN_ACTV_RESP, refnum, skb, len);
106 ictl.command = ISDN_STAT_DCONN;
109 dev->dev_if->statcallb(&ictl);
111 /* ACTIVE D-channel */
113 /* Select protocol */
115 if ((len=capi_select_proto_req(chan, &skb, 1 /*outgoing*/)) < 0) {
116 printk("capi_select_proto_req failed\n");
120 refnum = last_ref_num++ & 0x7fffU;
121 chan->s_refnum = refnum;
123 pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
128 * Incoming call received
132 void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
133 struct callb_data *cbdata)
136 unsigned short refnum;
141 ictl.command = ISDN_STAT_ICALL;
146 * ictl.num >= strlen() + strlen() + 5
149 if (cbdata->data.setup.CallingPN == NULL) {
150 printk(KERN_DEBUG "NULL CallingPN to phone; using 0\n");
151 strcpy(ictl.parm.setup.phone, "0");
154 strcpy(ictl.parm.setup.phone, cbdata->data.setup.CallingPN);
156 if (cbdata->data.setup.CalledPN == NULL) {
157 printk(KERN_DEBUG "NULL CalledPN to eazmsn; using 0\n");
158 strcpy(ictl.parm.setup.eazmsn, "0");
161 strcpy(ictl.parm.setup.eazmsn, cbdata->data.setup.CalledPN);
163 ictl.parm.setup.si1 = 7;
164 ictl.parm.setup.si2 = 0;
165 ictl.parm.setup.plan = 0;
166 ictl.parm.setup.screen = 0;
169 printk(KERN_DEBUG "statstr: %s\n", ictl.num);
172 dev->dev_if->statcallb(&ictl);
175 if ((len=capi_conn_resp(chan, &skb)) < 0) {
176 printk(KERN_DEBUG "capi_conn_resp failed\n");
180 refnum = last_ref_num++ & 0x7fffU;
181 chan->s_refnum = refnum;
183 pcbit_l2_write(dev, MSG_CONN_RESP, refnum, skb, len);
189 * send CONNECT message CONNECT_ACTIVE_REQ in CAPI
192 void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
193 struct callb_data *data)
195 unsigned short refnum;
199 if ((len = capi_conn_active_req(chan, &skb)) < 0) {
200 printk(KERN_DEBUG "capi_conn_active_req failed\n");
205 refnum = last_ref_num++ & 0x7fffU;
206 chan->s_refnum = refnum;
208 printk(KERN_DEBUG "sending MSG_CONN_ACTV_REQ\n");
209 pcbit_l2_write(dev, MSG_CONN_ACTV_REQ, refnum, skb, len);
214 * start b-proto selection
218 void cb_in_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
219 struct callb_data *data)
221 unsigned short refnum;
225 if ((len = capi_select_proto_req(chan, &skb, 0 /*incoming*/)) < 0)
227 printk("capi_select_proto_req failed\n");
231 refnum = last_ref_num++ & 0x7fffU;
232 chan->s_refnum = refnum;
234 pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
240 * Received disconnect ind on active state
241 * send disconnect resp
244 void cb_disc_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
245 struct callb_data *data)
252 if ((len = capi_disc_resp(chan, &skb)) < 0) {
253 printk("capi_disc_resp failed\n");
257 refnum = last_ref_num++ & 0x7fffU;
258 chan->s_refnum = refnum;
260 pcbit_l2_write(dev, MSG_DISC_RESP, refnum, skb, len);
262 ictl.command = ISDN_STAT_BHUP;
265 dev->dev_if->statcallb(&ictl);
270 * User HANGUP on active/call proceeding state
273 void cb_disc_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
274 struct callb_data *data)
280 if ((len = capi_disc_req(chan->callref, &skb, CAUSE_NORMAL)) < 0)
282 printk("capi_disc_req failed\n");
286 refnum = last_ref_num++ & 0x7fffU;
287 chan->s_refnum = refnum;
289 pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb, len);
293 * Disc confirm received send BHUP
294 * Problem: when the HL driver sends the disc req itself
297 void cb_disc_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
298 struct callb_data *data)
302 ictl.command = ISDN_STAT_BHUP;
305 dev->dev_if->statcallb(&ictl);
308 void cb_notdone(struct pcbit_dev * dev, struct pcbit_chan* chan,
309 struct callb_data *data)
314 * send activate b-chan protocol
316 void cb_selp_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
317 struct callb_data *data)
323 if ((len = capi_activate_transp_req(chan, &skb)) < 0)
325 printk("capi_conn_activate_transp_req failed\n");
329 refnum = last_ref_num++ & 0x7fffU;
330 chan->s_refnum = refnum;
332 pcbit_l2_write(dev, MSG_ACT_TRANSP_REQ, refnum, skb, len);
336 * Inform User that the B-channel is available
338 void cb_open(struct pcbit_dev * dev, struct pcbit_chan* chan,
339 struct callb_data *data)
343 ictl.command = ISDN_STAT_BCONN;
346 dev->dev_if->statcallb(&ictl);