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 * Disconnect received (actually RELEASE COMPLETE)
129 * This means we were not able to establish connection with remote
130 * Inform the big boss above
132 void cb_out_3(struct pcbit_dev
* dev
, struct pcbit_chan
* chan
,
133 struct callb_data
*data
)
137 ictl
.command
= ISDN_STAT_DHUP
;
140 dev
->dev_if
->statcallb(&ictl
);
145 * Incoming call received
149 void cb_in_1(struct pcbit_dev
* dev
, struct pcbit_chan
* chan
,
150 struct callb_data
*cbdata
)
153 unsigned short refnum
;
158 ictl
.command
= ISDN_STAT_ICALL
;
163 * ictl.num >= strlen() + strlen() + 5
166 if (cbdata
->data
.setup
.CallingPN
== NULL
) {
167 printk(KERN_DEBUG
"NULL CallingPN to phone; using 0\n");
168 strcpy(ictl
.parm
.setup
.phone
, "0");
171 strcpy(ictl
.parm
.setup
.phone
, cbdata
->data
.setup
.CallingPN
);
173 if (cbdata
->data
.setup
.CalledPN
== NULL
) {
174 printk(KERN_DEBUG
"NULL CalledPN to eazmsn; using 0\n");
175 strcpy(ictl
.parm
.setup
.eazmsn
, "0");
178 strcpy(ictl
.parm
.setup
.eazmsn
, cbdata
->data
.setup
.CalledPN
);
180 ictl
.parm
.setup
.si1
= 7;
181 ictl
.parm
.setup
.si2
= 0;
182 ictl
.parm
.setup
.plan
= 0;
183 ictl
.parm
.setup
.screen
= 0;
186 printk(KERN_DEBUG
"statstr: %s\n", ictl
.num
);
189 dev
->dev_if
->statcallb(&ictl
);
192 if ((len
=capi_conn_resp(chan
, &skb
)) < 0) {
193 printk(KERN_DEBUG
"capi_conn_resp failed\n");
197 refnum
= last_ref_num
++ & 0x7fffU
;
198 chan
->s_refnum
= refnum
;
200 pcbit_l2_write(dev
, MSG_CONN_RESP
, refnum
, skb
, len
);
206 * send CONNECT message CONNECT_ACTIVE_REQ in CAPI
209 void cb_in_2(struct pcbit_dev
* dev
, struct pcbit_chan
* chan
,
210 struct callb_data
*data
)
212 unsigned short refnum
;
216 if ((len
= capi_conn_active_req(chan
, &skb
)) < 0) {
217 printk(KERN_DEBUG
"capi_conn_active_req failed\n");
222 refnum
= last_ref_num
++ & 0x7fffU
;
223 chan
->s_refnum
= refnum
;
225 printk(KERN_DEBUG
"sending MSG_CONN_ACTV_REQ\n");
226 pcbit_l2_write(dev
, MSG_CONN_ACTV_REQ
, refnum
, skb
, len
);
231 * start b-proto selection
235 void cb_in_3(struct pcbit_dev
* dev
, struct pcbit_chan
* chan
,
236 struct callb_data
*data
)
238 unsigned short refnum
;
242 if ((len
= capi_select_proto_req(chan
, &skb
, 0 /*incoming*/)) < 0)
244 printk("capi_select_proto_req failed\n");
248 refnum
= last_ref_num
++ & 0x7fffU
;
249 chan
->s_refnum
= refnum
;
251 pcbit_l2_write(dev
, MSG_SELP_REQ
, refnum
, skb
, len
);
257 * Received disconnect ind on active state
258 * send disconnect resp
261 void cb_disc_1(struct pcbit_dev
* dev
, struct pcbit_chan
* chan
,
262 struct callb_data
*data
)
269 if ((len
= capi_disc_resp(chan
, &skb
)) < 0) {
270 printk("capi_disc_resp failed\n");
274 refnum
= last_ref_num
++ & 0x7fffU
;
275 chan
->s_refnum
= refnum
;
277 pcbit_l2_write(dev
, MSG_DISC_RESP
, refnum
, skb
, len
);
279 ictl
.command
= ISDN_STAT_BHUP
;
282 dev
->dev_if
->statcallb(&ictl
);
287 * User HANGUP on active/call proceeding state
290 void cb_disc_2(struct pcbit_dev
* dev
, struct pcbit_chan
* chan
,
291 struct callb_data
*data
)
297 if ((len
= capi_disc_req(chan
->callref
, &skb
, CAUSE_NORMAL
)) < 0)
299 printk("capi_disc_req failed\n");
303 refnum
= last_ref_num
++ & 0x7fffU
;
304 chan
->s_refnum
= refnum
;
306 pcbit_l2_write(dev
, MSG_DISC_REQ
, refnum
, skb
, len
);
310 * Disc confirm received send BHUP
311 * Problem: when the HL driver sends the disc req itself
314 void cb_disc_3(struct pcbit_dev
* dev
, struct pcbit_chan
* chan
,
315 struct callb_data
*data
)
319 ictl
.command
= ISDN_STAT_BHUP
;
322 dev
->dev_if
->statcallb(&ictl
);
325 void cb_notdone(struct pcbit_dev
* dev
, struct pcbit_chan
* chan
,
326 struct callb_data
*data
)
331 * send activate b-chan protocol
333 void cb_selp_1(struct pcbit_dev
* dev
, struct pcbit_chan
* chan
,
334 struct callb_data
*data
)
340 if ((len
= capi_activate_transp_req(chan
, &skb
)) < 0)
342 printk("capi_conn_activate_transp_req failed\n");
346 refnum
= last_ref_num
++ & 0x7fffU
;
347 chan
->s_refnum
= refnum
;
349 pcbit_l2_write(dev
, MSG_ACT_TRANSP_REQ
, refnum
, skb
, len
);
353 * Inform User that the B-channel is available
355 void cb_open(struct pcbit_dev
* dev
, struct pcbit_chan
* chan
,
356 struct callb_data
*data
)
360 ictl
.command
= ISDN_STAT_BCONN
;
363 dev
->dev_if
->statcallb(&ictl
);