1 /* $Id: capi.c,v 1.8 1998/11/05 22:12:46 fritz Exp $
3 * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
6 * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
7 * Thanks to Friedemann Baitinger and IBM Germany
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * Revision 1.8 1998/11/05 22:12:46 fritz
25 * Changed mail-address.
27 * Revision 1.7 1998/02/23 23:35:41 fritz
28 * Eliminated some compiler warnings.
30 * Revision 1.6 1998/02/12 23:06:50 keil
31 * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
33 * Revision 1.5 1997/10/09 22:23:02 fritz
34 * New HL<->LL interface:
35 * New BSENT callback with nr. of bytes included.
36 * Sending without ACK.
38 * Revision 1.4 1997/09/25 17:25:39 fritz
39 * Support for adding cards at runtime.
40 * Support for new Firmware.
42 * Revision 1.3 1997/09/24 19:44:14 fritz
43 * Added MSN mapping support, some cleanup.
45 * Revision 1.2 1997/09/23 19:41:24 fritz
46 * Disabled Logging of DATA_B3_IND/RESP/REQ/CONF Messages.
48 * Revision 1.1 1997/09/23 18:00:08 fritz
49 * New driver for IBM Active 2000.
53 #define __NO_VERSION__
57 static actcapi_msgdsc valid_msg
[] = {
58 {{ 0x86, 0x02}, "DATA_B3_IND"}, /* DATA_B3_IND/CONF must be first because of speed!!! */
59 {{ 0x86, 0x01}, "DATA_B3_CONF"},
60 {{ 0x02, 0x01}, "CONNECT_CONF"},
61 {{ 0x02, 0x02}, "CONNECT_IND"},
62 {{ 0x09, 0x01}, "CONNECT_INFO_CONF"},
63 {{ 0x03, 0x02}, "CONNECT_ACTIVE_IND"},
64 {{ 0x04, 0x01}, "DISCONNECT_CONF"},
65 {{ 0x04, 0x02}, "DISCONNECT_IND"},
66 {{ 0x05, 0x01}, "LISTEN_CONF"},
67 {{ 0x06, 0x01}, "GET_PARAMS_CONF"},
68 {{ 0x07, 0x01}, "INFO_CONF"},
69 {{ 0x07, 0x02}, "INFO_IND"},
70 {{ 0x08, 0x01}, "DATA_CONF"},
71 {{ 0x08, 0x02}, "DATA_IND"},
72 {{ 0x40, 0x01}, "SELECT_B2_PROTOCOL_CONF"},
73 {{ 0x80, 0x01}, "SELECT_B3_PROTOCOL_CONF"},
74 {{ 0x81, 0x01}, "LISTEN_B3_CONF"},
75 {{ 0x82, 0x01}, "CONNECT_B3_CONF"},
76 {{ 0x82, 0x02}, "CONNECT_B3_IND"},
77 {{ 0x83, 0x02}, "CONNECT_B3_ACTIVE_IND"},
78 {{ 0x84, 0x01}, "DISCONNECT_B3_CONF"},
79 {{ 0x84, 0x02}, "DISCONNECT_B3_IND"},
80 {{ 0x85, 0x01}, "GET_B3_PARAMS_CONF"},
81 {{ 0x01, 0x01}, "RESET_B3_CONF"},
82 {{ 0x01, 0x02}, "RESET_B3_IND"},
83 /* {{ 0x87, 0x02, "HANDSET_IND"}, not implemented */
84 {{ 0xff, 0x01}, "MANUFACTURER_CONF"},
85 {{ 0xff, 0x02}, "MANUFACTURER_IND"},
88 {{ 0x01, 0x00}, "RESET_B3_REQ"},
89 {{ 0x02, 0x00}, "CONNECT_REQ"},
90 {{ 0x04, 0x00}, "DISCONNECT_REQ"},
91 {{ 0x05, 0x00}, "LISTEN_REQ"},
92 {{ 0x06, 0x00}, "GET_PARAMS_REQ"},
93 {{ 0x07, 0x00}, "INFO_REQ"},
94 {{ 0x08, 0x00}, "DATA_REQ"},
95 {{ 0x09, 0x00}, "CONNECT_INFO_REQ"},
96 {{ 0x40, 0x00}, "SELECT_B2_PROTOCOL_REQ"},
97 {{ 0x80, 0x00}, "SELECT_B3_PROTOCOL_REQ"},
98 {{ 0x81, 0x00}, "LISTEN_B3_REQ"},
99 {{ 0x82, 0x00}, "CONNECT_B3_REQ"},
100 {{ 0x84, 0x00}, "DISCONNECT_B3_REQ"},
101 {{ 0x85, 0x00}, "GET_B3_PARAMS_REQ"},
102 {{ 0x86, 0x00}, "DATA_B3_REQ"},
103 {{ 0xff, 0x00}, "MANUFACTURER_REQ"},
105 {{ 0x01, 0x03}, "RESET_B3_RESP"},
106 {{ 0x02, 0x03}, "CONNECT_RESP"},
107 {{ 0x03, 0x03}, "CONNECT_ACTIVE_RESP"},
108 {{ 0x04, 0x03}, "DISCONNECT_RESP"},
109 {{ 0x07, 0x03}, "INFO_RESP"},
110 {{ 0x08, 0x03}, "DATA_RESP"},
111 {{ 0x82, 0x03}, "CONNECT_B3_RESP"},
112 {{ 0x83, 0x03}, "CONNECT_B3_ACTIVE_RESP"},
113 {{ 0x84, 0x03}, "DISCONNECT_B3_RESP"},
114 {{ 0x86, 0x03}, "DATA_B3_RESP"},
115 {{ 0xff, 0x03}, "MANUFACTURER_RESP"},
118 {{ 0x05, 0x80}, "LISTEN_REQ (CAPI 2.0)"},
121 {{ 0x00, 0x00}, NULL
},
123 #define num_valid_msg (sizeof(valid_msg)/sizeof(actcapi_msgdsc))
124 #define num_valid_imsg 27 /* MANUFACTURER_IND */
127 * Check for a valid incoming CAPI message.
129 * 0 = Invalid message
130 * 1 = Valid message, no B-Channel-data
131 * 2 = Valid message, B-Channel-data
134 actcapi_chkhdr(act2000_card
* card
, actcapi_msghdr
*hdr
)
138 if (hdr
->applicationID
!= 1)
142 for (i
= 0; i
< num_valid_imsg
; i
++)
143 if ((hdr
->cmd
.cmd
== valid_msg
[i
].cmd
.cmd
) &&
144 (hdr
->cmd
.subcmd
== valid_msg
[i
].cmd
.subcmd
)) {
150 #define ACTCAPI_MKHDR(l, c, s) { \
151 skb = alloc_skb(l + 8, GFP_ATOMIC); \
153 m = (actcapi_msg *)skb_put(skb, l + 8); \
154 m->hdr.len = l + 8; \
155 m->hdr.applicationID = 1; \
156 m->hdr.cmd.cmd = c; \
157 m->hdr.cmd.subcmd = s; \
158 m->hdr.msgnum = actcapi_nextsmsg(card); \
162 #define ACTCAPI_CHKSKB if (!skb) { \
163 printk(KERN_WARNING "actcapi: alloc_skb failed\n"); \
167 #define ACTCAPI_QUEUE_TX { \
168 actcapi_debug_msg(skb, 1); \
169 skb_queue_tail(&card->sndq, skb); \
170 act2000_schedule_tx(card); \
174 actcapi_listen_req(act2000_card
*card
)
181 for (i
= 0; i
< ACT2000_BCH
; i
++)
182 eazmask
|= card
->bch
[i
].eazmask
;
183 ACTCAPI_MKHDR(9, 0x05, 0x00);
185 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
188 m
->msg
.listen_req
.controller
= 0;
189 m
->msg
.listen_req
.infomask
= 0x3f; /* All information */
190 m
->msg
.listen_req
.eazmask
= eazmask
;
191 m
->msg
.listen_req
.simask
= (eazmask
)?0x86:0; /* All SI's */
197 actcapi_connect_req(act2000_card
*card
, act2000_chan
*chan
, char *phone
,
198 char eaz
, int si1
, int si2
)
203 ACTCAPI_MKHDR((11 + strlen(phone
)), 0x02, 0x00);
205 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
206 chan
->fsm_state
= ACT2000_STATE_NULL
;
209 m
->msg
.connect_req
.controller
= 0;
210 m
->msg
.connect_req
.bchan
= 0x83;
211 m
->msg
.connect_req
.infomask
= 0x3f;
212 m
->msg
.connect_req
.si1
= si1
;
213 m
->msg
.connect_req
.si2
= si2
;
214 m
->msg
.connect_req
.eaz
= eaz
?eaz
:'0';
215 m
->msg
.connect_req
.addr
.len
= strlen(phone
) + 1;
216 m
->msg
.connect_req
.addr
.tnp
= 0x81;
217 memcpy(m
->msg
.connect_req
.addr
.num
, phone
, strlen(phone
));
218 chan
->callref
= m
->hdr
.msgnum
;
224 actcapi_connect_b3_req(act2000_card
*card
, act2000_chan
*chan
)
229 ACTCAPI_MKHDR(17, 0x82, 0x00);
231 m
->msg
.connect_b3_req
.plci
= chan
->plci
;
232 memset(&m
->msg
.connect_b3_req
.ncpi
, 0,
233 sizeof(m
->msg
.connect_b3_req
.ncpi
));
234 m
->msg
.connect_b3_req
.ncpi
.len
= 13;
235 m
->msg
.connect_b3_req
.ncpi
.modulo
= 8;
240 * Set net type (1TR6) or (EDSS1)
243 actcapi_manufacturer_req_net(act2000_card
*card
)
248 ACTCAPI_MKHDR(5, 0xff, 0x00);
250 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
253 m
->msg
.manufacturer_req_net
.manuf_msg
= 0x11;
254 m
->msg
.manufacturer_req_net
.controller
= 1;
255 m
->msg
.manufacturer_req_net
.nettype
= (card
->ptype
== ISDN_PTYPE_EURO
)?1:0;
257 printk(KERN_INFO
"act2000 %s: D-channel protocol now %s\n",
258 card
->interface
.id
, (card
->ptype
== ISDN_PTYPE_EURO
)?"euro":"1tr6");
259 card
->interface
.features
&=
260 ~(ISDN_FEATURE_P_UNKNOWN
| ISDN_FEATURE_P_EURO
| ISDN_FEATURE_P_1TR6
);
261 card
->interface
.features
|=
262 ((card
->ptype
== ISDN_PTYPE_EURO
)?ISDN_FEATURE_P_EURO
:ISDN_FEATURE_P_1TR6
);
267 * Switch V.42 on or off
270 actcapi_manufacturer_req_v42(act2000_card
*card
, ulong arg
)
275 ACTCAPI_MKHDR(8, 0xff, 0x00);
278 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
281 m
->msg
.manufacturer_req_v42
.manuf_msg
= 0x10;
282 m
->msg
.manufacturer_req_v42
.controller
= 0;
283 m
->msg
.manufacturer_req_v42
.v42control
= (arg
?1:0);
292 actcapi_manufacturer_req_errh(act2000_card
*card
)
297 ACTCAPI_MKHDR(4, 0xff, 0x00);
300 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
303 m
->msg
.manufacturer_req_err
.manuf_msg
= 0x03;
304 m
->msg
.manufacturer_req_err
.controller
= 0;
313 actcapi_manufacturer_req_msn(act2000_card
*card
)
315 msn_entry
*p
= card
->msn_list
;
323 len
= strlen(p
->msn
);
324 for (i
= 0; i
< 2; i
++) {
325 ACTCAPI_MKHDR(6 + len
, 0xff, 0x00);
327 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
330 m
->msg
.manufacturer_req_msn
.manuf_msg
= 0x13 + i
;
331 m
->msg
.manufacturer_req_msn
.controller
= 0;
332 m
->msg
.manufacturer_req_msn
.msnmap
.eaz
= p
->eaz
;
333 m
->msg
.manufacturer_req_msn
.msnmap
.len
= len
;
334 memcpy(m
->msg
.manufacturer_req_msn
.msnmap
.msn
, p
->msn
, len
);
343 actcapi_select_b2_protocol_req(act2000_card
*card
, act2000_chan
*chan
)
348 ACTCAPI_MKHDR(10, 0x40, 0x00);
350 m
->msg
.select_b2_protocol_req
.plci
= chan
->plci
;
351 memset(&m
->msg
.select_b2_protocol_req
.dlpd
, 0,
352 sizeof(m
->msg
.select_b2_protocol_req
.dlpd
));
353 m
->msg
.select_b2_protocol_req
.dlpd
.len
= 6;
354 switch (chan
->l2prot
) {
355 case ISDN_PROTO_L2_TRANS
:
356 m
->msg
.select_b2_protocol_req
.protocol
= 0x03;
357 m
->msg
.select_b2_protocol_req
.dlpd
.dlen
= 4000;
359 case ISDN_PROTO_L2_HDLC
:
360 m
->msg
.select_b2_protocol_req
.protocol
= 0x02;
361 m
->msg
.select_b2_protocol_req
.dlpd
.dlen
= 4000;
363 case ISDN_PROTO_L2_X75I
:
364 case ISDN_PROTO_L2_X75UI
:
365 case ISDN_PROTO_L2_X75BUI
:
366 m
->msg
.select_b2_protocol_req
.protocol
= 0x01;
367 m
->msg
.select_b2_protocol_req
.dlpd
.dlen
= 4000;
368 m
->msg
.select_b2_protocol_req
.dlpd
.laa
= 3;
369 m
->msg
.select_b2_protocol_req
.dlpd
.lab
= 1;
370 m
->msg
.select_b2_protocol_req
.dlpd
.win
= 7;
371 m
->msg
.select_b2_protocol_req
.dlpd
.modulo
= 8;
378 actcapi_select_b3_protocol_req(act2000_card
*card
, act2000_chan
*chan
)
383 ACTCAPI_MKHDR(17, 0x80, 0x00);
385 m
->msg
.select_b3_protocol_req
.plci
= chan
->plci
;
386 memset(&m
->msg
.select_b3_protocol_req
.ncpd
, 0,
387 sizeof(m
->msg
.select_b3_protocol_req
.ncpd
));
388 switch (chan
->l3prot
) {
389 case ISDN_PROTO_L3_TRANS
:
390 m
->msg
.select_b3_protocol_req
.protocol
= 0x04;
391 m
->msg
.select_b3_protocol_req
.ncpd
.len
= 13;
392 m
->msg
.select_b3_protocol_req
.ncpd
.modulo
= 8;
399 actcapi_listen_b3_req(act2000_card
*card
, act2000_chan
*chan
)
404 ACTCAPI_MKHDR(2, 0x81, 0x00);
406 m
->msg
.listen_b3_req
.plci
= chan
->plci
;
411 actcapi_disconnect_req(act2000_card
*card
, act2000_chan
*chan
)
416 ACTCAPI_MKHDR(3, 0x04, 0x00);
418 m
->msg
.disconnect_req
.plci
= chan
->plci
;
419 m
->msg
.disconnect_req
.cause
= 0;
424 actcapi_disconnect_b3_req(act2000_card
*card
, act2000_chan
*chan
)
429 ACTCAPI_MKHDR(17, 0x84, 0x00);
431 m
->msg
.disconnect_b3_req
.ncci
= chan
->ncci
;
432 memset(&m
->msg
.disconnect_b3_req
.ncpi
, 0,
433 sizeof(m
->msg
.disconnect_b3_req
.ncpi
));
434 m
->msg
.disconnect_b3_req
.ncpi
.len
= 13;
435 m
->msg
.disconnect_b3_req
.ncpi
.modulo
= 8;
436 chan
->fsm_state
= ACT2000_STATE_BHWAIT
;
441 actcapi_connect_resp(act2000_card
*card
, act2000_chan
*chan
, __u8 cause
)
446 ACTCAPI_MKHDR(3, 0x02, 0x03);
448 m
->msg
.connect_resp
.plci
= chan
->plci
;
449 m
->msg
.connect_resp
.rejectcause
= cause
;
451 chan
->fsm_state
= ACT2000_STATE_NULL
;
454 chan
->fsm_state
= ACT2000_STATE_IWAIT
;
459 actcapi_connect_active_resp(act2000_card
*card
, act2000_chan
*chan
)
464 ACTCAPI_MKHDR(2, 0x03, 0x03);
466 m
->msg
.connect_resp
.plci
= chan
->plci
;
467 if (chan
->fsm_state
== ACT2000_STATE_IWAIT
)
468 chan
->fsm_state
= ACT2000_STATE_IBWAIT
;
473 actcapi_connect_b3_resp(act2000_card
*card
, act2000_chan
*chan
, __u8 rejectcause
)
478 ACTCAPI_MKHDR((rejectcause
?3:17), 0x82, 0x03);
480 m
->msg
.connect_b3_resp
.ncci
= chan
->ncci
;
481 m
->msg
.connect_b3_resp
.rejectcause
= rejectcause
;
483 memset(&m
->msg
.connect_b3_resp
.ncpi
, 0,
484 sizeof(m
->msg
.connect_b3_resp
.ncpi
));
485 m
->msg
.connect_b3_resp
.ncpi
.len
= 13;
486 m
->msg
.connect_b3_resp
.ncpi
.modulo
= 8;
487 chan
->fsm_state
= ACT2000_STATE_BWAIT
;
493 actcapi_connect_b3_active_resp(act2000_card
*card
, act2000_chan
*chan
)
498 ACTCAPI_MKHDR(2, 0x83, 0x03);
500 m
->msg
.connect_b3_active_resp
.ncci
= chan
->ncci
;
501 chan
->fsm_state
= ACT2000_STATE_ACTIVE
;
506 actcapi_info_resp(act2000_card
*card
, act2000_chan
*chan
)
511 ACTCAPI_MKHDR(2, 0x07, 0x03);
513 m
->msg
.info_resp
.plci
= chan
->plci
;
518 actcapi_disconnect_b3_resp(act2000_card
*card
, act2000_chan
*chan
)
523 ACTCAPI_MKHDR(2, 0x84, 0x03);
525 m
->msg
.disconnect_b3_resp
.ncci
= chan
->ncci
;
532 actcapi_disconnect_resp(act2000_card
*card
, act2000_chan
*chan
)
537 ACTCAPI_MKHDR(2, 0x04, 0x03);
539 m
->msg
.disconnect_resp
.plci
= chan
->plci
;
545 new_plci(act2000_card
*card
, __u16 plci
)
548 for (i
= 0; i
< ACT2000_BCH
; i
++)
549 if (card
->bch
[i
].plci
== 0x8000) {
550 card
->bch
[i
].plci
= plci
;
557 find_plci(act2000_card
*card
, __u16 plci
)
560 for (i
= 0; i
< ACT2000_BCH
; i
++)
561 if (card
->bch
[i
].plci
== plci
)
567 find_ncci(act2000_card
*card
, __u16 ncci
)
570 for (i
= 0; i
< ACT2000_BCH
; i
++)
571 if (card
->bch
[i
].ncci
== ncci
)
577 find_dialing(act2000_card
*card
, __u16 callref
)
580 for (i
= 0; i
< ACT2000_BCH
; i
++)
581 if ((card
->bch
[i
].callref
== callref
) &&
582 (card
->bch
[i
].fsm_state
== ACT2000_STATE_OCALL
))
588 actcapi_data_b3_ind(act2000_card
*card
, struct sk_buff
*skb
) {
594 actcapi_msg
*msg
= (actcapi_msg
*)skb
->data
;
596 EVAL_NCCI(msg
->msg
.data_b3_ind
.fakencci
, plci
, controller
, ncci
);
597 chan
= find_ncci(card
, ncci
);
600 if (card
->bch
[chan
].fsm_state
!= ACT2000_STATE_ACTIVE
)
602 if (card
->bch
[chan
].plci
!= plci
)
604 blocknr
= msg
->msg
.data_b3_ind
.blocknr
;
606 card
->interface
.rcvcallb_skb(card
->myid
, chan
, skb
);
607 if (!(skb
= alloc_skb(11, GFP_ATOMIC
))) {
608 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
611 msg
= (actcapi_msg
*)skb_put(skb
, 11);
613 msg
->hdr
.applicationID
= 1;
614 msg
->hdr
.cmd
.cmd
= 0x86;
615 msg
->hdr
.cmd
.subcmd
= 0x03;
616 msg
->hdr
.msgnum
= actcapi_nextsmsg(card
);
617 msg
->msg
.data_b3_resp
.ncci
= ncci
;
618 msg
->msg
.data_b3_resp
.blocknr
= blocknr
;
624 * Walk over ackq, unlink DATA_B3_REQ from it, if
625 * ncci and blocknr are matching.
626 * Decrement queued-bytes counter.
629 handle_ack(act2000_card
*card
, act2000_chan
*chan
, __u8 blocknr
) {
633 struct actcapi_msg
*m
;
638 skb
= skb_peek(&card
->ackq
);
639 restore_flags(flags
);
641 printk(KERN_WARNING
"act2000: handle_ack nothing found!\n");
646 m
= (actcapi_msg
*)tmp
->data
;
647 if ((((m
->msg
.data_b3_req
.fakencci
>> 8) & 0xff) == chan
->ncci
) &&
648 (m
->msg
.data_b3_req
.blocknr
== blocknr
)) {
649 /* found corresponding DATA_B3_REQ */
651 chan
->queued
-= m
->msg
.data_b3_req
.datalen
;
652 if (m
->msg
.data_b3_req
.flags
)
653 ret
= m
->msg
.data_b3_req
.datalen
;
655 if (chan
->queued
< 0)
661 tmp
= skb_peek((struct sk_buff_head
*)tmp
);
662 restore_flags(flags
);
663 if ((tmp
== skb
) || (tmp
== NULL
)) {
664 /* reached end of queue */
665 printk(KERN_WARNING
"act2000: handle_ack nothing found!\n");
672 actcapi_dispatch(act2000_card
*card
)
683 while ((skb
= skb_dequeue(&card
->rcvq
))) {
684 actcapi_debug_msg(skb
, 0);
685 msg
= (actcapi_msg
*)skb
->data
;
686 ccmd
= ((msg
->hdr
.cmd
.cmd
<< 8) | msg
->hdr
.cmd
.subcmd
);
690 if (actcapi_data_b3_ind(card
, skb
))
695 chan
= find_ncci(card
, msg
->msg
.data_b3_conf
.ncci
);
696 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_ACTIVE
)) {
697 if (msg
->msg
.data_b3_conf
.info
!= 0)
698 printk(KERN_WARNING
"act2000: DATA_B3_CONF: %04x\n",
699 msg
->msg
.data_b3_conf
.info
);
700 len
= handle_ack(card
, &card
->bch
[chan
],
701 msg
->msg
.data_b3_conf
.blocknr
);
703 cmd
.driver
= card
->myid
;
704 cmd
.command
= ISDN_STAT_BSENT
;
706 cmd
.parm
.length
= len
;
707 card
->interface
.statcallb(&cmd
);
713 chan
= find_dialing(card
, msg
->hdr
.msgnum
);
715 if (msg
->msg
.connect_conf
.info
) {
716 card
->bch
[chan
].fsm_state
= ACT2000_STATE_NULL
;
717 cmd
.driver
= card
->myid
;
718 cmd
.command
= ISDN_STAT_DHUP
;
720 card
->interface
.statcallb(&cmd
);
722 card
->bch
[chan
].fsm_state
= ACT2000_STATE_OWAIT
;
723 card
->bch
[chan
].plci
= msg
->msg
.connect_conf
.plci
;
729 chan
= new_plci(card
, msg
->msg
.connect_ind
.plci
);
731 ctmp
= (act2000_chan
*)tmp
;
732 ctmp
->plci
= msg
->msg
.connect_ind
.plci
;
733 actcapi_connect_resp(card
, ctmp
, 0x11); /* All Card-Cannels busy */
735 card
->bch
[chan
].fsm_state
= ACT2000_STATE_ICALL
;
736 cmd
.driver
= card
->myid
;
737 cmd
.command
= ISDN_STAT_ICALL
;
739 cmd
.parm
.setup
.si1
= msg
->msg
.connect_ind
.si1
;
740 cmd
.parm
.setup
.si2
= msg
->msg
.connect_ind
.si2
;
741 if (card
->ptype
== ISDN_PTYPE_EURO
)
742 strcpy(cmd
.parm
.setup
.eazmsn
,
743 act2000_find_eaz(card
, msg
->msg
.connect_ind
.eaz
));
745 cmd
.parm
.setup
.eazmsn
[0] = msg
->msg
.connect_ind
.eaz
;
746 cmd
.parm
.setup
.eazmsn
[1] = 0;
748 memset(cmd
.parm
.setup
.phone
, 0, sizeof(cmd
.parm
.setup
.phone
));
749 memcpy(cmd
.parm
.setup
.phone
, msg
->msg
.connect_ind
.addr
.num
,
750 msg
->msg
.connect_ind
.addr
.len
- 1);
751 cmd
.parm
.setup
.plan
= msg
->msg
.connect_ind
.addr
.tnp
;
752 cmd
.parm
.setup
.screen
= 0;
753 if (card
->interface
.statcallb(&cmd
) == 2)
754 actcapi_connect_resp(card
, &card
->bch
[chan
], 0x15); /* Reject Call */
758 /* CONNECT_ACTIVE_IND */
759 chan
= find_plci(card
, msg
->msg
.connect_active_ind
.plci
);
761 switch (card
->bch
[chan
].fsm_state
) {
762 case ACT2000_STATE_IWAIT
:
763 actcapi_connect_active_resp(card
, &card
->bch
[chan
]);
765 case ACT2000_STATE_OWAIT
:
766 actcapi_connect_active_resp(card
, &card
->bch
[chan
]);
767 actcapi_select_b2_protocol_req(card
, &card
->bch
[chan
]);
773 chan
= find_plci(card
, msg
->msg
.connect_b3_ind
.plci
);
774 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_IBWAIT
)) {
775 card
->bch
[chan
].ncci
= msg
->msg
.connect_b3_ind
.ncci
;
776 actcapi_connect_b3_resp(card
, &card
->bch
[chan
], 0);
778 ctmp
= (act2000_chan
*)tmp
;
779 ctmp
->ncci
= msg
->msg
.connect_b3_ind
.ncci
;
780 actcapi_connect_b3_resp(card
, ctmp
, 0x11); /* All Card-Cannels busy */
784 /* CONNECT_B3_ACTIVE_IND */
785 chan
= find_ncci(card
, msg
->msg
.connect_b3_active_ind
.ncci
);
786 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_BWAIT
)) {
787 actcapi_connect_b3_active_resp(card
, &card
->bch
[chan
]);
788 cmd
.driver
= card
->myid
;
789 cmd
.command
= ISDN_STAT_BCONN
;
791 card
->interface
.statcallb(&cmd
);
795 /* DISCONNECT_B3_IND */
796 chan
= find_ncci(card
, msg
->msg
.disconnect_b3_ind
.ncci
);
798 ctmp
= &card
->bch
[chan
];
799 actcapi_disconnect_b3_resp(card
, ctmp
);
800 switch (ctmp
->fsm_state
) {
801 case ACT2000_STATE_ACTIVE
:
802 ctmp
->fsm_state
= ACT2000_STATE_DHWAIT2
;
803 cmd
.driver
= card
->myid
;
804 cmd
.command
= ISDN_STAT_BHUP
;
806 card
->interface
.statcallb(&cmd
);
808 case ACT2000_STATE_BHWAIT2
:
809 actcapi_disconnect_req(card
, ctmp
);
810 ctmp
->fsm_state
= ACT2000_STATE_DHWAIT
;
811 cmd
.driver
= card
->myid
;
812 cmd
.command
= ISDN_STAT_BHUP
;
814 card
->interface
.statcallb(&cmd
);
821 chan
= find_plci(card
, msg
->msg
.disconnect_ind
.plci
);
823 ctmp
= &card
->bch
[chan
];
824 actcapi_disconnect_resp(card
, ctmp
);
825 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
826 cmd
.driver
= card
->myid
;
827 cmd
.command
= ISDN_STAT_DHUP
;
829 card
->interface
.statcallb(&cmd
);
831 ctmp
= (act2000_chan
*)tmp
;
832 ctmp
->plci
= msg
->msg
.disconnect_ind
.plci
;
833 actcapi_disconnect_resp(card
, ctmp
);
837 /* SELECT_B2_PROTOCOL_CONF */
838 chan
= find_plci(card
, msg
->msg
.select_b2_protocol_conf
.plci
);
840 switch (card
->bch
[chan
].fsm_state
) {
841 case ACT2000_STATE_ICALL
:
842 case ACT2000_STATE_OWAIT
:
843 ctmp
= &card
->bch
[chan
];
844 if (msg
->msg
.select_b2_protocol_conf
.info
== 0)
845 actcapi_select_b3_protocol_req(card
, ctmp
);
847 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
848 cmd
.driver
= card
->myid
;
849 cmd
.command
= ISDN_STAT_DHUP
;
851 card
->interface
.statcallb(&cmd
);
857 /* SELECT_B3_PROTOCOL_CONF */
858 chan
= find_plci(card
, msg
->msg
.select_b3_protocol_conf
.plci
);
860 switch (card
->bch
[chan
].fsm_state
) {
861 case ACT2000_STATE_ICALL
:
862 case ACT2000_STATE_OWAIT
:
863 ctmp
= &card
->bch
[chan
];
864 if (msg
->msg
.select_b3_protocol_conf
.info
== 0)
865 actcapi_listen_b3_req(card
, ctmp
);
867 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
868 cmd
.driver
= card
->myid
;
869 cmd
.command
= ISDN_STAT_DHUP
;
871 card
->interface
.statcallb(&cmd
);
877 chan
= find_plci(card
, msg
->msg
.listen_b3_conf
.plci
);
879 switch (card
->bch
[chan
].fsm_state
) {
880 case ACT2000_STATE_ICALL
:
881 ctmp
= &card
->bch
[chan
];
882 if (msg
->msg
.listen_b3_conf
.info
== 0)
883 actcapi_connect_resp(card
, ctmp
, 0);
885 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
886 cmd
.driver
= card
->myid
;
887 cmd
.command
= ISDN_STAT_DHUP
;
889 card
->interface
.statcallb(&cmd
);
892 case ACT2000_STATE_OWAIT
:
893 ctmp
= &card
->bch
[chan
];
894 if (msg
->msg
.listen_b3_conf
.info
== 0) {
895 actcapi_connect_b3_req(card
, ctmp
);
896 ctmp
->fsm_state
= ACT2000_STATE_OBWAIT
;
897 cmd
.driver
= card
->myid
;
898 cmd
.command
= ISDN_STAT_DCONN
;
900 card
->interface
.statcallb(&cmd
);
902 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
903 cmd
.driver
= card
->myid
;
904 cmd
.command
= ISDN_STAT_DHUP
;
906 card
->interface
.statcallb(&cmd
);
912 /* CONNECT_B3_CONF */
913 chan
= find_plci(card
, msg
->msg
.connect_b3_conf
.plci
);
914 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_OBWAIT
)) {
915 ctmp
= &card
->bch
[chan
];
916 if (msg
->msg
.connect_b3_conf
.info
) {
917 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
918 cmd
.driver
= card
->myid
;
919 cmd
.command
= ISDN_STAT_DHUP
;
921 card
->interface
.statcallb(&cmd
);
923 ctmp
->ncci
= msg
->msg
.connect_b3_conf
.ncci
;
924 ctmp
->fsm_state
= ACT2000_STATE_BWAIT
;
929 /* DISCONNECT_B3_CONF */
930 chan
= find_ncci(card
, msg
->msg
.disconnect_b3_conf
.ncci
);
931 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_BHWAIT
))
932 card
->bch
[chan
].fsm_state
= ACT2000_STATE_BHWAIT2
;
936 chan
= find_plci(card
, msg
->msg
.info_ind
.plci
);
938 /* TODO: Eval Charging info / cause */
939 actcapi_info_resp(card
, &card
->bch
[chan
]);
946 /* MANUFACTURER_CONF */
949 /* MANUFACTURER_IND */
950 if (msg
->msg
.manuf_msg
== 3) {
951 memset(tmp
, 0, sizeof(tmp
));
953 &msg
->msg
.manufacturer_ind_err
.errstring
,
955 if (msg
->msg
.manufacturer_ind_err
.errcode
)
956 printk(KERN_WARNING
"act2000: %s\n", tmp
);
958 printk(KERN_DEBUG
"act2000: %s\n", tmp
);
959 if ((!strncmp(tmp
, "INFO: Trace buffer con", 22)) ||
960 (!strncmp(tmp
, "INFO: Compile Date/Tim", 22))) {
961 card
->flags
|= ACT2000_FLAGS_RUNNING
;
962 cmd
.command
= ISDN_STAT_RUN
;
963 cmd
.driver
= card
->myid
;
965 actcapi_manufacturer_req_net(card
);
966 actcapi_manufacturer_req_msn(card
);
967 actcapi_listen_req(card
);
968 card
->interface
.statcallb(&cmd
);
974 printk(KERN_WARNING
"act2000: UNHANDLED Message %04x\n", ccmd
);
983 actcapi_debug_caddr(actcapi_addr
*addr
)
987 printk(KERN_DEBUG
" Alen = %d\n", addr
->len
);
989 printk(KERN_DEBUG
" Atnp = 0x%02x\n", addr
->tnp
);
992 memcpy(tmp
, addr
->num
, addr
->len
- 1);
993 printk(KERN_DEBUG
" Anum = '%s'\n", tmp
);
998 actcapi_debug_ncpi(actcapi_ncpi
*ncpi
)
1000 printk(KERN_DEBUG
" ncpi.len = %d\n", ncpi
->len
);
1002 printk(KERN_DEBUG
" ncpi.lic = 0x%04x\n", ncpi
->lic
);
1004 printk(KERN_DEBUG
" ncpi.hic = 0x%04x\n", ncpi
->hic
);
1006 printk(KERN_DEBUG
" ncpi.ltc = 0x%04x\n", ncpi
->ltc
);
1008 printk(KERN_DEBUG
" ncpi.htc = 0x%04x\n", ncpi
->htc
);
1009 if (ncpi
->len
>= 10)
1010 printk(KERN_DEBUG
" ncpi.loc = 0x%04x\n", ncpi
->loc
);
1011 if (ncpi
->len
>= 12)
1012 printk(KERN_DEBUG
" ncpi.hoc = 0x%04x\n", ncpi
->hoc
);
1013 if (ncpi
->len
>= 13)
1014 printk(KERN_DEBUG
" ncpi.mod = %d\n", ncpi
->modulo
);
1018 actcapi_debug_dlpd(actcapi_dlpd
*dlpd
)
1020 printk(KERN_DEBUG
" dlpd.len = %d\n", dlpd
->len
);
1022 printk(KERN_DEBUG
" dlpd.dlen = 0x%04x\n", dlpd
->dlen
);
1024 printk(KERN_DEBUG
" dlpd.laa = 0x%02x\n", dlpd
->laa
);
1026 printk(KERN_DEBUG
" dlpd.lab = 0x%02x\n", dlpd
->lab
);
1028 printk(KERN_DEBUG
" dlpd.modulo = %d\n", dlpd
->modulo
);
1030 printk(KERN_DEBUG
" dlpd.win = %d\n", dlpd
->win
);
1033 #ifdef DEBUG_DUMP_SKB
1034 static void dump_skb(struct sk_buff
*skb
) {
1036 char *p
= skb
->data
;
1040 for (i
= 0; i
< skb
->len
; i
++) {
1041 t
+= sprintf(t
, "%02x ", *p
++ & 0xff);
1042 if ((i
& 0x0f) == 8) {
1043 printk(KERN_DEBUG
"dump: %s\n", tmp
);
1048 printk(KERN_DEBUG
"dump: %s\n", tmp
);
1053 actcapi_debug_msg(struct sk_buff
*skb
, int direction
)
1055 actcapi_msg
*msg
= (actcapi_msg
*)skb
->data
;
1060 #ifndef DEBUG_DATA_MSG
1061 if (msg
->hdr
.cmd
.cmd
== 0x86)
1065 #ifdef DEBUG_DUMP_SKB
1068 for (i
= 0; i
< num_valid_msg
; i
++)
1069 if ((msg
->hdr
.cmd
.cmd
== valid_msg
[i
].cmd
.cmd
) &&
1070 (msg
->hdr
.cmd
.subcmd
== valid_msg
[i
].cmd
.subcmd
)) {
1071 descr
= valid_msg
[i
].description
;
1074 printk(KERN_DEBUG
"%s %s msg\n", direction
?"Outgoing":"Incoming", descr
);
1075 printk(KERN_DEBUG
" ApplID = %d\n", msg
->hdr
.applicationID
);
1076 printk(KERN_DEBUG
" Len = %d\n", msg
->hdr
.len
);
1077 printk(KERN_DEBUG
" MsgNum = 0x%04x\n", msg
->hdr
.msgnum
);
1078 printk(KERN_DEBUG
" Cmd = 0x%02x\n", msg
->hdr
.cmd
.cmd
);
1079 printk(KERN_DEBUG
" SubCmd = 0x%02x\n", msg
->hdr
.cmd
.subcmd
);
1083 printk(KERN_DEBUG
" BLOCK = 0x%02x\n",
1084 msg
->msg
.data_b3_ind
.blocknr
);
1088 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1089 msg
->msg
.connect_conf
.plci
);
1090 printk(KERN_DEBUG
" Info = 0x%04x\n",
1091 msg
->msg
.connect_conf
.info
);
1095 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1096 msg
->msg
.connect_ind
.plci
);
1097 printk(KERN_DEBUG
" Contr = %d\n",
1098 msg
->msg
.connect_ind
.controller
);
1099 printk(KERN_DEBUG
" SI1 = %d\n",
1100 msg
->msg
.connect_ind
.si1
);
1101 printk(KERN_DEBUG
" SI2 = %d\n",
1102 msg
->msg
.connect_ind
.si2
);
1103 printk(KERN_DEBUG
" EAZ = '%c'\n",
1104 msg
->msg
.connect_ind
.eaz
);
1105 actcapi_debug_caddr(&msg
->msg
.connect_ind
.addr
);
1108 /* CONNECT ACTIVE IND */
1109 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1110 msg
->msg
.connect_active_ind
.plci
);
1111 actcapi_debug_caddr(&msg
->msg
.connect_active_ind
.addr
);
1115 printk(KERN_DEBUG
" Contr = %d\n",
1116 msg
->msg
.listen_conf
.controller
);
1117 printk(KERN_DEBUG
" Info = 0x%04x\n",
1118 msg
->msg
.listen_conf
.info
);
1122 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1123 msg
->msg
.info_ind
.plci
);
1124 printk(KERN_DEBUG
" Imsk = 0x%04x\n",
1125 msg
->msg
.info_ind
.nr
.mask
);
1126 if (msg
->hdr
.len
> 12) {
1127 int l
= msg
->hdr
.len
- 12;
1130 for (j
= 0; j
< l
; j
++)
1131 p
+= sprintf(p
, "%02x ", msg
->msg
.info_ind
.el
.display
[j
]);
1132 printk(KERN_DEBUG
" D = '%s'\n", tmp
);
1136 /* SELECT B2 PROTOCOL CONF */
1137 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1138 msg
->msg
.select_b2_protocol_conf
.plci
);
1139 printk(KERN_DEBUG
" Info = 0x%04x\n",
1140 msg
->msg
.select_b2_protocol_conf
.info
);
1143 /* SELECT B3 PROTOCOL CONF */
1144 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1145 msg
->msg
.select_b3_protocol_conf
.plci
);
1146 printk(KERN_DEBUG
" Info = 0x%04x\n",
1147 msg
->msg
.select_b3_protocol_conf
.info
);
1150 /* LISTEN B3 CONF */
1151 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1152 msg
->msg
.listen_b3_conf
.plci
);
1153 printk(KERN_DEBUG
" Info = 0x%04x\n",
1154 msg
->msg
.listen_b3_conf
.info
);
1157 /* CONNECT B3 IND */
1158 printk(KERN_DEBUG
" NCCI = 0x%04x\n",
1159 msg
->msg
.connect_b3_ind
.ncci
);
1160 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1161 msg
->msg
.connect_b3_ind
.plci
);
1162 actcapi_debug_ncpi(&msg
->msg
.connect_b3_ind
.ncpi
);
1165 /* CONNECT B3 ACTIVE IND */
1166 printk(KERN_DEBUG
" NCCI = 0x%04x\n",
1167 msg
->msg
.connect_b3_active_ind
.ncci
);
1168 actcapi_debug_ncpi(&msg
->msg
.connect_b3_active_ind
.ncpi
);
1171 /* MANUFACTURER IND */
1172 printk(KERN_DEBUG
" Mmsg = 0x%02x\n",
1173 msg
->msg
.manufacturer_ind_err
.manuf_msg
);
1174 switch (msg
->msg
.manufacturer_ind_err
.manuf_msg
) {
1176 printk(KERN_DEBUG
" Contr = %d\n",
1177 msg
->msg
.manufacturer_ind_err
.controller
);
1178 printk(KERN_DEBUG
" Code = 0x%08x\n",
1179 msg
->msg
.manufacturer_ind_err
.errcode
);
1180 memset(tmp
, 0, sizeof(tmp
));
1181 strncpy(tmp
, &msg
->msg
.manufacturer_ind_err
.errstring
,
1183 printk(KERN_DEBUG
" Emsg = '%s'\n", tmp
);
1189 printk(KERN_DEBUG
" Imsk = 0x%08x\n",
1190 msg
->msg
.listen_req
.infomask
);
1191 printk(KERN_DEBUG
" Emsk = 0x%04x\n",
1192 msg
->msg
.listen_req
.eazmask
);
1193 printk(KERN_DEBUG
" Smsk = 0x%04x\n",
1194 msg
->msg
.listen_req
.simask
);
1197 /* SELECT_B2_PROTOCOL_REQ */
1198 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1199 msg
->msg
.select_b2_protocol_req
.plci
);
1200 printk(KERN_DEBUG
" prot = 0x%02x\n",
1201 msg
->msg
.select_b2_protocol_req
.protocol
);
1202 if (msg
->hdr
.len
>= 11)
1203 printk(KERN_DEBUG
"No dlpd\n");
1205 actcapi_debug_dlpd(&msg
->msg
.select_b2_protocol_req
.dlpd
);
1209 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1210 msg
->msg
.connect_resp
.plci
);
1211 printk(KERN_DEBUG
" CAUSE = 0x%02x\n",
1212 msg
->msg
.connect_resp
.rejectcause
);
1215 /* CONNECT ACTIVE RESP */
1216 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1217 msg
->msg
.connect_active_resp
.plci
);