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/string.h>
19 #include <linux/kernel.h>
21 #include <linux/types.h>
23 #include <linux/skbuff.h>
27 #include <linux/isdnif.h>
32 #include "callbacks.h"
35 ushort last_ref_num
= 1;
42 void cb_out_1(struct pcbit_dev
*dev
, struct pcbit_chan
*chan
,
43 struct callb_data
*cbdata
)
51 printk(KERN_DEBUG
"Called Party Number: %s\n",
52 cbdata
->data
.setup
.CalledPN
);
55 * hdr - kmalloc in capi_conn_req
56 * - kfree when msg has been sent
59 if ((len
= capi_conn_req(cbdata
->data
.setup
.CalledPN
, &skb
,
62 printk("capi_conn_req failed\n");
67 refnum
= last_ref_num
++ & 0x7fffU
;
72 chan
->s_refnum
= refnum
;
74 pcbit_l2_write(dev
, MSG_CONN_REQ
, refnum
, skb
, len
);
79 * will go into ACTIVE state
80 * send CONN_ACTIVE_RESP
81 * send Select protocol request
84 void cb_out_2(struct pcbit_dev
*dev
, struct pcbit_chan
*chan
,
85 struct callb_data
*data
)
92 if ((len
= capi_conn_active_resp(chan
, &skb
)) < 0)
94 printk("capi_conn_active_req failed\n");
98 refnum
= last_ref_num
++ & 0x7fffU
;
99 chan
->s_refnum
= refnum
;
101 pcbit_l2_write(dev
, MSG_CONN_ACTV_RESP
, refnum
, skb
, len
);
104 ictl
.command
= ISDN_STAT_DCONN
;
105 ictl
.driver
= dev
->id
;
107 dev
->dev_if
->statcallb(&ictl
);
109 /* ACTIVE D-channel */
111 /* Select protocol */
113 if ((len
= capi_select_proto_req(chan
, &skb
, 1 /*outgoing*/)) < 0) {
114 printk("capi_select_proto_req failed\n");
118 refnum
= last_ref_num
++ & 0x7fffU
;
119 chan
->s_refnum
= refnum
;
121 pcbit_l2_write(dev
, MSG_SELP_REQ
, refnum
, skb
, len
);
126 * Incoming call received
130 void cb_in_1(struct pcbit_dev
*dev
, struct pcbit_chan
*chan
,
131 struct callb_data
*cbdata
)
134 unsigned short refnum
;
139 ictl
.command
= ISDN_STAT_ICALL
;
140 ictl
.driver
= dev
->id
;
144 * ictl.num >= strlen() + strlen() + 5
147 if (cbdata
->data
.setup
.CallingPN
== NULL
) {
148 printk(KERN_DEBUG
"NULL CallingPN to phone; using 0\n");
149 strcpy(ictl
.parm
.setup
.phone
, "0");
152 strcpy(ictl
.parm
.setup
.phone
, cbdata
->data
.setup
.CallingPN
);
154 if (cbdata
->data
.setup
.CalledPN
== NULL
) {
155 printk(KERN_DEBUG
"NULL CalledPN to eazmsn; using 0\n");
156 strcpy(ictl
.parm
.setup
.eazmsn
, "0");
159 strcpy(ictl
.parm
.setup
.eazmsn
, cbdata
->data
.setup
.CalledPN
);
161 ictl
.parm
.setup
.si1
= 7;
162 ictl
.parm
.setup
.si2
= 0;
163 ictl
.parm
.setup
.plan
= 0;
164 ictl
.parm
.setup
.screen
= 0;
167 printk(KERN_DEBUG
"statstr: %s\n", ictl
.num
);
170 dev
->dev_if
->statcallb(&ictl
);
173 if ((len
= capi_conn_resp(chan
, &skb
)) < 0) {
174 printk(KERN_DEBUG
"capi_conn_resp failed\n");
178 refnum
= last_ref_num
++ & 0x7fffU
;
179 chan
->s_refnum
= refnum
;
181 pcbit_l2_write(dev
, MSG_CONN_RESP
, refnum
, skb
, len
);
187 * send CONNECT message CONNECT_ACTIVE_REQ in CAPI
190 void cb_in_2(struct pcbit_dev
*dev
, struct pcbit_chan
*chan
,
191 struct callb_data
*data
)
193 unsigned short refnum
;
197 if ((len
= capi_conn_active_req(chan
, &skb
)) < 0) {
198 printk(KERN_DEBUG
"capi_conn_active_req failed\n");
203 refnum
= last_ref_num
++ & 0x7fffU
;
204 chan
->s_refnum
= refnum
;
206 printk(KERN_DEBUG
"sending MSG_CONN_ACTV_REQ\n");
207 pcbit_l2_write(dev
, MSG_CONN_ACTV_REQ
, refnum
, skb
, len
);
212 * start b-proto selection
216 void cb_in_3(struct pcbit_dev
*dev
, struct pcbit_chan
*chan
,
217 struct callb_data
*data
)
219 unsigned short refnum
;
223 if ((len
= capi_select_proto_req(chan
, &skb
, 0 /*incoming*/)) < 0)
225 printk("capi_select_proto_req failed\n");
229 refnum
= last_ref_num
++ & 0x7fffU
;
230 chan
->s_refnum
= refnum
;
232 pcbit_l2_write(dev
, MSG_SELP_REQ
, refnum
, skb
, len
);
238 * Received disconnect ind on active state
239 * send disconnect resp
242 void cb_disc_1(struct pcbit_dev
*dev
, struct pcbit_chan
*chan
,
243 struct callb_data
*data
)
250 if ((len
= capi_disc_resp(chan
, &skb
)) < 0) {
251 printk("capi_disc_resp failed\n");
255 refnum
= last_ref_num
++ & 0x7fffU
;
256 chan
->s_refnum
= refnum
;
258 pcbit_l2_write(dev
, MSG_DISC_RESP
, refnum
, skb
, len
);
260 ictl
.command
= ISDN_STAT_BHUP
;
261 ictl
.driver
= dev
->id
;
263 dev
->dev_if
->statcallb(&ictl
);
268 * User HANGUP on active/call proceeding state
271 void cb_disc_2(struct pcbit_dev
*dev
, struct pcbit_chan
*chan
,
272 struct callb_data
*data
)
278 if ((len
= capi_disc_req(chan
->callref
, &skb
, CAUSE_NORMAL
)) < 0)
280 printk("capi_disc_req failed\n");
284 refnum
= last_ref_num
++ & 0x7fffU
;
285 chan
->s_refnum
= refnum
;
287 pcbit_l2_write(dev
, MSG_DISC_REQ
, refnum
, skb
, len
);
291 * Disc confirm received send BHUP
292 * Problem: when the HL driver sends the disc req itself
295 void cb_disc_3(struct pcbit_dev
*dev
, struct pcbit_chan
*chan
,
296 struct callb_data
*data
)
300 ictl
.command
= ISDN_STAT_BHUP
;
301 ictl
.driver
= dev
->id
;
303 dev
->dev_if
->statcallb(&ictl
);
306 void cb_notdone(struct pcbit_dev
*dev
, struct pcbit_chan
*chan
,
307 struct callb_data
*data
)
312 * send activate b-chan protocol
314 void cb_selp_1(struct pcbit_dev
*dev
, struct pcbit_chan
*chan
,
315 struct callb_data
*data
)
321 if ((len
= capi_activate_transp_req(chan
, &skb
)) < 0)
323 printk("capi_conn_activate_transp_req failed\n");
327 refnum
= last_ref_num
++ & 0x7fffU
;
328 chan
->s_refnum
= refnum
;
330 pcbit_l2_write(dev
, MSG_ACT_TRANSP_REQ
, refnum
, skb
, len
);
334 * Inform User that the B-channel is available
336 void cb_open(struct pcbit_dev
*dev
, struct pcbit_chan
*chan
,
337 struct callb_data
*data
)
341 ictl
.command
= ISDN_STAT_BCONN
;
342 ictl
.driver
= dev
->id
;
344 dev
->dev_if
->statcallb(&ictl
);