1 /* $Id: capi.c,v 1.9 2000/11/12 16:32:06 kai 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.
25 #define __NO_VERSION__
29 static actcapi_msgdsc valid_msg
[] = {
30 {{ 0x86, 0x02}, "DATA_B3_IND"}, /* DATA_B3_IND/CONF must be first because of speed!!! */
31 {{ 0x86, 0x01}, "DATA_B3_CONF"},
32 {{ 0x02, 0x01}, "CONNECT_CONF"},
33 {{ 0x02, 0x02}, "CONNECT_IND"},
34 {{ 0x09, 0x01}, "CONNECT_INFO_CONF"},
35 {{ 0x03, 0x02}, "CONNECT_ACTIVE_IND"},
36 {{ 0x04, 0x01}, "DISCONNECT_CONF"},
37 {{ 0x04, 0x02}, "DISCONNECT_IND"},
38 {{ 0x05, 0x01}, "LISTEN_CONF"},
39 {{ 0x06, 0x01}, "GET_PARAMS_CONF"},
40 {{ 0x07, 0x01}, "INFO_CONF"},
41 {{ 0x07, 0x02}, "INFO_IND"},
42 {{ 0x08, 0x01}, "DATA_CONF"},
43 {{ 0x08, 0x02}, "DATA_IND"},
44 {{ 0x40, 0x01}, "SELECT_B2_PROTOCOL_CONF"},
45 {{ 0x80, 0x01}, "SELECT_B3_PROTOCOL_CONF"},
46 {{ 0x81, 0x01}, "LISTEN_B3_CONF"},
47 {{ 0x82, 0x01}, "CONNECT_B3_CONF"},
48 {{ 0x82, 0x02}, "CONNECT_B3_IND"},
49 {{ 0x83, 0x02}, "CONNECT_B3_ACTIVE_IND"},
50 {{ 0x84, 0x01}, "DISCONNECT_B3_CONF"},
51 {{ 0x84, 0x02}, "DISCONNECT_B3_IND"},
52 {{ 0x85, 0x01}, "GET_B3_PARAMS_CONF"},
53 {{ 0x01, 0x01}, "RESET_B3_CONF"},
54 {{ 0x01, 0x02}, "RESET_B3_IND"},
55 /* {{ 0x87, 0x02, "HANDSET_IND"}, not implemented */
56 {{ 0xff, 0x01}, "MANUFACTURER_CONF"},
57 {{ 0xff, 0x02}, "MANUFACTURER_IND"},
60 {{ 0x01, 0x00}, "RESET_B3_REQ"},
61 {{ 0x02, 0x00}, "CONNECT_REQ"},
62 {{ 0x04, 0x00}, "DISCONNECT_REQ"},
63 {{ 0x05, 0x00}, "LISTEN_REQ"},
64 {{ 0x06, 0x00}, "GET_PARAMS_REQ"},
65 {{ 0x07, 0x00}, "INFO_REQ"},
66 {{ 0x08, 0x00}, "DATA_REQ"},
67 {{ 0x09, 0x00}, "CONNECT_INFO_REQ"},
68 {{ 0x40, 0x00}, "SELECT_B2_PROTOCOL_REQ"},
69 {{ 0x80, 0x00}, "SELECT_B3_PROTOCOL_REQ"},
70 {{ 0x81, 0x00}, "LISTEN_B3_REQ"},
71 {{ 0x82, 0x00}, "CONNECT_B3_REQ"},
72 {{ 0x84, 0x00}, "DISCONNECT_B3_REQ"},
73 {{ 0x85, 0x00}, "GET_B3_PARAMS_REQ"},
74 {{ 0x86, 0x00}, "DATA_B3_REQ"},
75 {{ 0xff, 0x00}, "MANUFACTURER_REQ"},
77 {{ 0x01, 0x03}, "RESET_B3_RESP"},
78 {{ 0x02, 0x03}, "CONNECT_RESP"},
79 {{ 0x03, 0x03}, "CONNECT_ACTIVE_RESP"},
80 {{ 0x04, 0x03}, "DISCONNECT_RESP"},
81 {{ 0x07, 0x03}, "INFO_RESP"},
82 {{ 0x08, 0x03}, "DATA_RESP"},
83 {{ 0x82, 0x03}, "CONNECT_B3_RESP"},
84 {{ 0x83, 0x03}, "CONNECT_B3_ACTIVE_RESP"},
85 {{ 0x84, 0x03}, "DISCONNECT_B3_RESP"},
86 {{ 0x86, 0x03}, "DATA_B3_RESP"},
87 {{ 0xff, 0x03}, "MANUFACTURER_RESP"},
89 {{ 0x00, 0x00}, NULL
},
91 #define num_valid_msg (sizeof(valid_msg)/sizeof(actcapi_msgdsc))
92 #define num_valid_imsg 27 /* MANUFACTURER_IND */
95 * Check for a valid incoming CAPI message.
98 * 1 = Valid message, no B-Channel-data
99 * 2 = Valid message, B-Channel-data
102 actcapi_chkhdr(act2000_card
* card
, actcapi_msghdr
*hdr
)
106 if (hdr
->applicationID
!= 1)
110 for (i
= 0; i
< num_valid_imsg
; i
++)
111 if ((hdr
->cmd
.cmd
== valid_msg
[i
].cmd
.cmd
) &&
112 (hdr
->cmd
.subcmd
== valid_msg
[i
].cmd
.subcmd
)) {
118 #define ACTCAPI_MKHDR(l, c, s) { \
119 skb = alloc_skb(l + 8, GFP_ATOMIC); \
121 m = (actcapi_msg *)skb_put(skb, l + 8); \
122 m->hdr.len = l + 8; \
123 m->hdr.applicationID = 1; \
124 m->hdr.cmd.cmd = c; \
125 m->hdr.cmd.subcmd = s; \
126 m->hdr.msgnum = actcapi_nextsmsg(card); \
130 #define ACTCAPI_CHKSKB if (!skb) { \
131 printk(KERN_WARNING "actcapi: alloc_skb failed\n"); \
135 #define ACTCAPI_QUEUE_TX { \
136 actcapi_debug_msg(skb, 1); \
137 skb_queue_tail(&card->sndq, skb); \
138 act2000_schedule_tx(card); \
142 actcapi_listen_req(act2000_card
*card
)
149 for (i
= 0; i
< ACT2000_BCH
; i
++)
150 eazmask
|= card
->bch
[i
].eazmask
;
151 ACTCAPI_MKHDR(9, 0x05, 0x00);
153 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
156 m
->msg
.listen_req
.controller
= 0;
157 m
->msg
.listen_req
.infomask
= 0x3f; /* All information */
158 m
->msg
.listen_req
.eazmask
= eazmask
;
159 m
->msg
.listen_req
.simask
= (eazmask
)?0x86:0; /* All SI's */
165 actcapi_connect_req(act2000_card
*card
, act2000_chan
*chan
, char *phone
,
166 char eaz
, int si1
, int si2
)
171 ACTCAPI_MKHDR((11 + strlen(phone
)), 0x02, 0x00);
173 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
174 chan
->fsm_state
= ACT2000_STATE_NULL
;
177 m
->msg
.connect_req
.controller
= 0;
178 m
->msg
.connect_req
.bchan
= 0x83;
179 m
->msg
.connect_req
.infomask
= 0x3f;
180 m
->msg
.connect_req
.si1
= si1
;
181 m
->msg
.connect_req
.si2
= si2
;
182 m
->msg
.connect_req
.eaz
= eaz
?eaz
:'0';
183 m
->msg
.connect_req
.addr
.len
= strlen(phone
) + 1;
184 m
->msg
.connect_req
.addr
.tnp
= 0x81;
185 memcpy(m
->msg
.connect_req
.addr
.num
, phone
, strlen(phone
));
186 chan
->callref
= m
->hdr
.msgnum
;
192 actcapi_connect_b3_req(act2000_card
*card
, act2000_chan
*chan
)
197 ACTCAPI_MKHDR(17, 0x82, 0x00);
199 m
->msg
.connect_b3_req
.plci
= chan
->plci
;
200 memset(&m
->msg
.connect_b3_req
.ncpi
, 0,
201 sizeof(m
->msg
.connect_b3_req
.ncpi
));
202 m
->msg
.connect_b3_req
.ncpi
.len
= 13;
203 m
->msg
.connect_b3_req
.ncpi
.modulo
= 8;
208 * Set net type (1TR6) or (EDSS1)
211 actcapi_manufacturer_req_net(act2000_card
*card
)
216 ACTCAPI_MKHDR(5, 0xff, 0x00);
218 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
221 m
->msg
.manufacturer_req_net
.manuf_msg
= 0x11;
222 m
->msg
.manufacturer_req_net
.controller
= 1;
223 m
->msg
.manufacturer_req_net
.nettype
= (card
->ptype
== ISDN_PTYPE_EURO
)?1:0;
225 printk(KERN_INFO
"act2000 %s: D-channel protocol now %s\n",
226 card
->interface
.id
, (card
->ptype
== ISDN_PTYPE_EURO
)?"euro":"1tr6");
227 card
->interface
.features
&=
228 ~(ISDN_FEATURE_P_UNKNOWN
| ISDN_FEATURE_P_EURO
| ISDN_FEATURE_P_1TR6
);
229 card
->interface
.features
|=
230 ((card
->ptype
== ISDN_PTYPE_EURO
)?ISDN_FEATURE_P_EURO
:ISDN_FEATURE_P_1TR6
);
235 * Switch V.42 on or off
238 actcapi_manufacturer_req_v42(act2000_card
*card
, ulong arg
)
243 ACTCAPI_MKHDR(8, 0xff, 0x00);
246 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
249 m
->msg
.manufacturer_req_v42
.manuf_msg
= 0x10;
250 m
->msg
.manufacturer_req_v42
.controller
= 0;
251 m
->msg
.manufacturer_req_v42
.v42control
= (arg
?1:0);
260 actcapi_manufacturer_req_errh(act2000_card
*card
)
265 ACTCAPI_MKHDR(4, 0xff, 0x00);
268 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
271 m
->msg
.manufacturer_req_err
.manuf_msg
= 0x03;
272 m
->msg
.manufacturer_req_err
.controller
= 0;
281 actcapi_manufacturer_req_msn(act2000_card
*card
)
283 msn_entry
*p
= card
->msn_list
;
291 len
= strlen(p
->msn
);
292 for (i
= 0; i
< 2; i
++) {
293 ACTCAPI_MKHDR(6 + len
, 0xff, 0x00);
295 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
298 m
->msg
.manufacturer_req_msn
.manuf_msg
= 0x13 + i
;
299 m
->msg
.manufacturer_req_msn
.controller
= 0;
300 m
->msg
.manufacturer_req_msn
.msnmap
.eaz
= p
->eaz
;
301 m
->msg
.manufacturer_req_msn
.msnmap
.len
= len
;
302 memcpy(m
->msg
.manufacturer_req_msn
.msnmap
.msn
, p
->msn
, len
);
311 actcapi_select_b2_protocol_req(act2000_card
*card
, act2000_chan
*chan
)
316 ACTCAPI_MKHDR(10, 0x40, 0x00);
318 m
->msg
.select_b2_protocol_req
.plci
= chan
->plci
;
319 memset(&m
->msg
.select_b2_protocol_req
.dlpd
, 0,
320 sizeof(m
->msg
.select_b2_protocol_req
.dlpd
));
321 m
->msg
.select_b2_protocol_req
.dlpd
.len
= 6;
322 switch (chan
->l2prot
) {
323 case ISDN_PROTO_L2_TRANS
:
324 m
->msg
.select_b2_protocol_req
.protocol
= 0x03;
325 m
->msg
.select_b2_protocol_req
.dlpd
.dlen
= 4000;
327 case ISDN_PROTO_L2_HDLC
:
328 m
->msg
.select_b2_protocol_req
.protocol
= 0x02;
329 m
->msg
.select_b2_protocol_req
.dlpd
.dlen
= 4000;
331 case ISDN_PROTO_L2_X75I
:
332 case ISDN_PROTO_L2_X75UI
:
333 case ISDN_PROTO_L2_X75BUI
:
334 m
->msg
.select_b2_protocol_req
.protocol
= 0x01;
335 m
->msg
.select_b2_protocol_req
.dlpd
.dlen
= 4000;
336 m
->msg
.select_b2_protocol_req
.dlpd
.laa
= 3;
337 m
->msg
.select_b2_protocol_req
.dlpd
.lab
= 1;
338 m
->msg
.select_b2_protocol_req
.dlpd
.win
= 7;
339 m
->msg
.select_b2_protocol_req
.dlpd
.modulo
= 8;
346 actcapi_select_b3_protocol_req(act2000_card
*card
, act2000_chan
*chan
)
351 ACTCAPI_MKHDR(17, 0x80, 0x00);
353 m
->msg
.select_b3_protocol_req
.plci
= chan
->plci
;
354 memset(&m
->msg
.select_b3_protocol_req
.ncpd
, 0,
355 sizeof(m
->msg
.select_b3_protocol_req
.ncpd
));
356 switch (chan
->l3prot
) {
357 case ISDN_PROTO_L3_TRANS
:
358 m
->msg
.select_b3_protocol_req
.protocol
= 0x04;
359 m
->msg
.select_b3_protocol_req
.ncpd
.len
= 13;
360 m
->msg
.select_b3_protocol_req
.ncpd
.modulo
= 8;
367 actcapi_listen_b3_req(act2000_card
*card
, act2000_chan
*chan
)
372 ACTCAPI_MKHDR(2, 0x81, 0x00);
374 m
->msg
.listen_b3_req
.plci
= chan
->plci
;
379 actcapi_disconnect_req(act2000_card
*card
, act2000_chan
*chan
)
384 ACTCAPI_MKHDR(3, 0x04, 0x00);
386 m
->msg
.disconnect_req
.plci
= chan
->plci
;
387 m
->msg
.disconnect_req
.cause
= 0;
392 actcapi_disconnect_b3_req(act2000_card
*card
, act2000_chan
*chan
)
397 ACTCAPI_MKHDR(17, 0x84, 0x00);
399 m
->msg
.disconnect_b3_req
.ncci
= chan
->ncci
;
400 memset(&m
->msg
.disconnect_b3_req
.ncpi
, 0,
401 sizeof(m
->msg
.disconnect_b3_req
.ncpi
));
402 m
->msg
.disconnect_b3_req
.ncpi
.len
= 13;
403 m
->msg
.disconnect_b3_req
.ncpi
.modulo
= 8;
404 chan
->fsm_state
= ACT2000_STATE_BHWAIT
;
409 actcapi_connect_resp(act2000_card
*card
, act2000_chan
*chan
, __u8 cause
)
414 ACTCAPI_MKHDR(3, 0x02, 0x03);
416 m
->msg
.connect_resp
.plci
= chan
->plci
;
417 m
->msg
.connect_resp
.rejectcause
= cause
;
419 chan
->fsm_state
= ACT2000_STATE_NULL
;
422 chan
->fsm_state
= ACT2000_STATE_IWAIT
;
427 actcapi_connect_active_resp(act2000_card
*card
, act2000_chan
*chan
)
432 ACTCAPI_MKHDR(2, 0x03, 0x03);
434 m
->msg
.connect_resp
.plci
= chan
->plci
;
435 if (chan
->fsm_state
== ACT2000_STATE_IWAIT
)
436 chan
->fsm_state
= ACT2000_STATE_IBWAIT
;
441 actcapi_connect_b3_resp(act2000_card
*card
, act2000_chan
*chan
, __u8 rejectcause
)
446 ACTCAPI_MKHDR((rejectcause
?3:17), 0x82, 0x03);
448 m
->msg
.connect_b3_resp
.ncci
= chan
->ncci
;
449 m
->msg
.connect_b3_resp
.rejectcause
= rejectcause
;
451 memset(&m
->msg
.connect_b3_resp
.ncpi
, 0,
452 sizeof(m
->msg
.connect_b3_resp
.ncpi
));
453 m
->msg
.connect_b3_resp
.ncpi
.len
= 13;
454 m
->msg
.connect_b3_resp
.ncpi
.modulo
= 8;
455 chan
->fsm_state
= ACT2000_STATE_BWAIT
;
461 actcapi_connect_b3_active_resp(act2000_card
*card
, act2000_chan
*chan
)
466 ACTCAPI_MKHDR(2, 0x83, 0x03);
468 m
->msg
.connect_b3_active_resp
.ncci
= chan
->ncci
;
469 chan
->fsm_state
= ACT2000_STATE_ACTIVE
;
474 actcapi_info_resp(act2000_card
*card
, act2000_chan
*chan
)
479 ACTCAPI_MKHDR(2, 0x07, 0x03);
481 m
->msg
.info_resp
.plci
= chan
->plci
;
486 actcapi_disconnect_b3_resp(act2000_card
*card
, act2000_chan
*chan
)
491 ACTCAPI_MKHDR(2, 0x84, 0x03);
493 m
->msg
.disconnect_b3_resp
.ncci
= chan
->ncci
;
500 actcapi_disconnect_resp(act2000_card
*card
, act2000_chan
*chan
)
505 ACTCAPI_MKHDR(2, 0x04, 0x03);
507 m
->msg
.disconnect_resp
.plci
= chan
->plci
;
513 new_plci(act2000_card
*card
, __u16 plci
)
516 for (i
= 0; i
< ACT2000_BCH
; i
++)
517 if (card
->bch
[i
].plci
== 0x8000) {
518 card
->bch
[i
].plci
= plci
;
525 find_plci(act2000_card
*card
, __u16 plci
)
528 for (i
= 0; i
< ACT2000_BCH
; i
++)
529 if (card
->bch
[i
].plci
== plci
)
535 find_ncci(act2000_card
*card
, __u16 ncci
)
538 for (i
= 0; i
< ACT2000_BCH
; i
++)
539 if (card
->bch
[i
].ncci
== ncci
)
545 find_dialing(act2000_card
*card
, __u16 callref
)
548 for (i
= 0; i
< ACT2000_BCH
; i
++)
549 if ((card
->bch
[i
].callref
== callref
) &&
550 (card
->bch
[i
].fsm_state
== ACT2000_STATE_OCALL
))
556 actcapi_data_b3_ind(act2000_card
*card
, struct sk_buff
*skb
) {
562 actcapi_msg
*msg
= (actcapi_msg
*)skb
->data
;
564 EVAL_NCCI(msg
->msg
.data_b3_ind
.fakencci
, plci
, controller
, ncci
);
565 chan
= find_ncci(card
, ncci
);
568 if (card
->bch
[chan
].fsm_state
!= ACT2000_STATE_ACTIVE
)
570 if (card
->bch
[chan
].plci
!= plci
)
572 blocknr
= msg
->msg
.data_b3_ind
.blocknr
;
574 card
->interface
.rcvcallb_skb(card
->myid
, chan
, skb
);
575 if (!(skb
= alloc_skb(11, GFP_ATOMIC
))) {
576 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
579 msg
= (actcapi_msg
*)skb_put(skb
, 11);
581 msg
->hdr
.applicationID
= 1;
582 msg
->hdr
.cmd
.cmd
= 0x86;
583 msg
->hdr
.cmd
.subcmd
= 0x03;
584 msg
->hdr
.msgnum
= actcapi_nextsmsg(card
);
585 msg
->msg
.data_b3_resp
.ncci
= ncci
;
586 msg
->msg
.data_b3_resp
.blocknr
= blocknr
;
592 * Walk over ackq, unlink DATA_B3_REQ from it, if
593 * ncci and blocknr are matching.
594 * Decrement queued-bytes counter.
597 handle_ack(act2000_card
*card
, act2000_chan
*chan
, __u8 blocknr
) {
601 struct actcapi_msg
*m
;
606 skb
= skb_peek(&card
->ackq
);
607 restore_flags(flags
);
609 printk(KERN_WARNING
"act2000: handle_ack nothing found!\n");
614 m
= (actcapi_msg
*)tmp
->data
;
615 if ((((m
->msg
.data_b3_req
.fakencci
>> 8) & 0xff) == chan
->ncci
) &&
616 (m
->msg
.data_b3_req
.blocknr
== blocknr
)) {
617 /* found corresponding DATA_B3_REQ */
619 chan
->queued
-= m
->msg
.data_b3_req
.datalen
;
620 if (m
->msg
.data_b3_req
.flags
)
621 ret
= m
->msg
.data_b3_req
.datalen
;
623 if (chan
->queued
< 0)
629 tmp
= skb_peek((struct sk_buff_head
*)tmp
);
630 restore_flags(flags
);
631 if ((tmp
== skb
) || (tmp
== NULL
)) {
632 /* reached end of queue */
633 printk(KERN_WARNING
"act2000: handle_ack nothing found!\n");
640 actcapi_dispatch(act2000_card
*card
)
651 while ((skb
= skb_dequeue(&card
->rcvq
))) {
652 actcapi_debug_msg(skb
, 0);
653 msg
= (actcapi_msg
*)skb
->data
;
654 ccmd
= ((msg
->hdr
.cmd
.cmd
<< 8) | msg
->hdr
.cmd
.subcmd
);
658 if (actcapi_data_b3_ind(card
, skb
))
663 chan
= find_ncci(card
, msg
->msg
.data_b3_conf
.ncci
);
664 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_ACTIVE
)) {
665 if (msg
->msg
.data_b3_conf
.info
!= 0)
666 printk(KERN_WARNING
"act2000: DATA_B3_CONF: %04x\n",
667 msg
->msg
.data_b3_conf
.info
);
668 len
= handle_ack(card
, &card
->bch
[chan
],
669 msg
->msg
.data_b3_conf
.blocknr
);
671 cmd
.driver
= card
->myid
;
672 cmd
.command
= ISDN_STAT_BSENT
;
674 cmd
.parm
.length
= len
;
675 card
->interface
.statcallb(&cmd
);
681 chan
= find_dialing(card
, msg
->hdr
.msgnum
);
683 if (msg
->msg
.connect_conf
.info
) {
684 card
->bch
[chan
].fsm_state
= ACT2000_STATE_NULL
;
685 cmd
.driver
= card
->myid
;
686 cmd
.command
= ISDN_STAT_DHUP
;
688 card
->interface
.statcallb(&cmd
);
690 card
->bch
[chan
].fsm_state
= ACT2000_STATE_OWAIT
;
691 card
->bch
[chan
].plci
= msg
->msg
.connect_conf
.plci
;
697 chan
= new_plci(card
, msg
->msg
.connect_ind
.plci
);
699 ctmp
= (act2000_chan
*)tmp
;
700 ctmp
->plci
= msg
->msg
.connect_ind
.plci
;
701 actcapi_connect_resp(card
, ctmp
, 0x11); /* All Card-Cannels busy */
703 card
->bch
[chan
].fsm_state
= ACT2000_STATE_ICALL
;
704 cmd
.driver
= card
->myid
;
705 cmd
.command
= ISDN_STAT_ICALL
;
707 cmd
.parm
.setup
.si1
= msg
->msg
.connect_ind
.si1
;
708 cmd
.parm
.setup
.si2
= msg
->msg
.connect_ind
.si2
;
709 if (card
->ptype
== ISDN_PTYPE_EURO
)
710 strcpy(cmd
.parm
.setup
.eazmsn
,
711 act2000_find_eaz(card
, msg
->msg
.connect_ind
.eaz
));
713 cmd
.parm
.setup
.eazmsn
[0] = msg
->msg
.connect_ind
.eaz
;
714 cmd
.parm
.setup
.eazmsn
[1] = 0;
716 memset(cmd
.parm
.setup
.phone
, 0, sizeof(cmd
.parm
.setup
.phone
));
717 memcpy(cmd
.parm
.setup
.phone
, msg
->msg
.connect_ind
.addr
.num
,
718 msg
->msg
.connect_ind
.addr
.len
- 1);
719 cmd
.parm
.setup
.plan
= msg
->msg
.connect_ind
.addr
.tnp
;
720 cmd
.parm
.setup
.screen
= 0;
721 if (card
->interface
.statcallb(&cmd
) == 2)
722 actcapi_connect_resp(card
, &card
->bch
[chan
], 0x15); /* Reject Call */
726 /* CONNECT_ACTIVE_IND */
727 chan
= find_plci(card
, msg
->msg
.connect_active_ind
.plci
);
729 switch (card
->bch
[chan
].fsm_state
) {
730 case ACT2000_STATE_IWAIT
:
731 actcapi_connect_active_resp(card
, &card
->bch
[chan
]);
733 case ACT2000_STATE_OWAIT
:
734 actcapi_connect_active_resp(card
, &card
->bch
[chan
]);
735 actcapi_select_b2_protocol_req(card
, &card
->bch
[chan
]);
741 chan
= find_plci(card
, msg
->msg
.connect_b3_ind
.plci
);
742 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_IBWAIT
)) {
743 card
->bch
[chan
].ncci
= msg
->msg
.connect_b3_ind
.ncci
;
744 actcapi_connect_b3_resp(card
, &card
->bch
[chan
], 0);
746 ctmp
= (act2000_chan
*)tmp
;
747 ctmp
->ncci
= msg
->msg
.connect_b3_ind
.ncci
;
748 actcapi_connect_b3_resp(card
, ctmp
, 0x11); /* All Card-Cannels busy */
752 /* CONNECT_B3_ACTIVE_IND */
753 chan
= find_ncci(card
, msg
->msg
.connect_b3_active_ind
.ncci
);
754 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_BWAIT
)) {
755 actcapi_connect_b3_active_resp(card
, &card
->bch
[chan
]);
756 cmd
.driver
= card
->myid
;
757 cmd
.command
= ISDN_STAT_BCONN
;
759 card
->interface
.statcallb(&cmd
);
763 /* DISCONNECT_B3_IND */
764 chan
= find_ncci(card
, msg
->msg
.disconnect_b3_ind
.ncci
);
766 ctmp
= &card
->bch
[chan
];
767 actcapi_disconnect_b3_resp(card
, ctmp
);
768 switch (ctmp
->fsm_state
) {
769 case ACT2000_STATE_ACTIVE
:
770 ctmp
->fsm_state
= ACT2000_STATE_DHWAIT2
;
771 cmd
.driver
= card
->myid
;
772 cmd
.command
= ISDN_STAT_BHUP
;
774 card
->interface
.statcallb(&cmd
);
776 case ACT2000_STATE_BHWAIT2
:
777 actcapi_disconnect_req(card
, ctmp
);
778 ctmp
->fsm_state
= ACT2000_STATE_DHWAIT
;
779 cmd
.driver
= card
->myid
;
780 cmd
.command
= ISDN_STAT_BHUP
;
782 card
->interface
.statcallb(&cmd
);
789 chan
= find_plci(card
, msg
->msg
.disconnect_ind
.plci
);
791 ctmp
= &card
->bch
[chan
];
792 actcapi_disconnect_resp(card
, ctmp
);
793 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
794 cmd
.driver
= card
->myid
;
795 cmd
.command
= ISDN_STAT_DHUP
;
797 card
->interface
.statcallb(&cmd
);
799 ctmp
= (act2000_chan
*)tmp
;
800 ctmp
->plci
= msg
->msg
.disconnect_ind
.plci
;
801 actcapi_disconnect_resp(card
, ctmp
);
805 /* SELECT_B2_PROTOCOL_CONF */
806 chan
= find_plci(card
, msg
->msg
.select_b2_protocol_conf
.plci
);
808 switch (card
->bch
[chan
].fsm_state
) {
809 case ACT2000_STATE_ICALL
:
810 case ACT2000_STATE_OWAIT
:
811 ctmp
= &card
->bch
[chan
];
812 if (msg
->msg
.select_b2_protocol_conf
.info
== 0)
813 actcapi_select_b3_protocol_req(card
, ctmp
);
815 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
816 cmd
.driver
= card
->myid
;
817 cmd
.command
= ISDN_STAT_DHUP
;
819 card
->interface
.statcallb(&cmd
);
825 /* SELECT_B3_PROTOCOL_CONF */
826 chan
= find_plci(card
, msg
->msg
.select_b3_protocol_conf
.plci
);
828 switch (card
->bch
[chan
].fsm_state
) {
829 case ACT2000_STATE_ICALL
:
830 case ACT2000_STATE_OWAIT
:
831 ctmp
= &card
->bch
[chan
];
832 if (msg
->msg
.select_b3_protocol_conf
.info
== 0)
833 actcapi_listen_b3_req(card
, ctmp
);
835 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
836 cmd
.driver
= card
->myid
;
837 cmd
.command
= ISDN_STAT_DHUP
;
839 card
->interface
.statcallb(&cmd
);
845 chan
= find_plci(card
, msg
->msg
.listen_b3_conf
.plci
);
847 switch (card
->bch
[chan
].fsm_state
) {
848 case ACT2000_STATE_ICALL
:
849 ctmp
= &card
->bch
[chan
];
850 if (msg
->msg
.listen_b3_conf
.info
== 0)
851 actcapi_connect_resp(card
, ctmp
, 0);
853 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
854 cmd
.driver
= card
->myid
;
855 cmd
.command
= ISDN_STAT_DHUP
;
857 card
->interface
.statcallb(&cmd
);
860 case ACT2000_STATE_OWAIT
:
861 ctmp
= &card
->bch
[chan
];
862 if (msg
->msg
.listen_b3_conf
.info
== 0) {
863 actcapi_connect_b3_req(card
, ctmp
);
864 ctmp
->fsm_state
= ACT2000_STATE_OBWAIT
;
865 cmd
.driver
= card
->myid
;
866 cmd
.command
= ISDN_STAT_DCONN
;
868 card
->interface
.statcallb(&cmd
);
870 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
871 cmd
.driver
= card
->myid
;
872 cmd
.command
= ISDN_STAT_DHUP
;
874 card
->interface
.statcallb(&cmd
);
880 /* CONNECT_B3_CONF */
881 chan
= find_plci(card
, msg
->msg
.connect_b3_conf
.plci
);
882 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_OBWAIT
)) {
883 ctmp
= &card
->bch
[chan
];
884 if (msg
->msg
.connect_b3_conf
.info
) {
885 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
886 cmd
.driver
= card
->myid
;
887 cmd
.command
= ISDN_STAT_DHUP
;
889 card
->interface
.statcallb(&cmd
);
891 ctmp
->ncci
= msg
->msg
.connect_b3_conf
.ncci
;
892 ctmp
->fsm_state
= ACT2000_STATE_BWAIT
;
897 /* DISCONNECT_B3_CONF */
898 chan
= find_ncci(card
, msg
->msg
.disconnect_b3_conf
.ncci
);
899 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_BHWAIT
))
900 card
->bch
[chan
].fsm_state
= ACT2000_STATE_BHWAIT2
;
904 chan
= find_plci(card
, msg
->msg
.info_ind
.plci
);
906 /* TODO: Eval Charging info / cause */
907 actcapi_info_resp(card
, &card
->bch
[chan
]);
914 /* MANUFACTURER_CONF */
917 /* MANUFACTURER_IND */
918 if (msg
->msg
.manuf_msg
== 3) {
919 memset(tmp
, 0, sizeof(tmp
));
921 &msg
->msg
.manufacturer_ind_err
.errstring
,
923 if (msg
->msg
.manufacturer_ind_err
.errcode
)
924 printk(KERN_WARNING
"act2000: %s\n", tmp
);
926 printk(KERN_DEBUG
"act2000: %s\n", tmp
);
927 if ((!strncmp(tmp
, "INFO: Trace buffer con", 22)) ||
928 (!strncmp(tmp
, "INFO: Compile Date/Tim", 22))) {
929 card
->flags
|= ACT2000_FLAGS_RUNNING
;
930 cmd
.command
= ISDN_STAT_RUN
;
931 cmd
.driver
= card
->myid
;
933 actcapi_manufacturer_req_net(card
);
934 actcapi_manufacturer_req_msn(card
);
935 actcapi_listen_req(card
);
936 card
->interface
.statcallb(&cmd
);
942 printk(KERN_WARNING
"act2000: UNHANDLED Message %04x\n", ccmd
);
951 actcapi_debug_caddr(actcapi_addr
*addr
)
955 printk(KERN_DEBUG
" Alen = %d\n", addr
->len
);
957 printk(KERN_DEBUG
" Atnp = 0x%02x\n", addr
->tnp
);
960 memcpy(tmp
, addr
->num
, addr
->len
- 1);
961 printk(KERN_DEBUG
" Anum = '%s'\n", tmp
);
966 actcapi_debug_ncpi(actcapi_ncpi
*ncpi
)
968 printk(KERN_DEBUG
" ncpi.len = %d\n", ncpi
->len
);
970 printk(KERN_DEBUG
" ncpi.lic = 0x%04x\n", ncpi
->lic
);
972 printk(KERN_DEBUG
" ncpi.hic = 0x%04x\n", ncpi
->hic
);
974 printk(KERN_DEBUG
" ncpi.ltc = 0x%04x\n", ncpi
->ltc
);
976 printk(KERN_DEBUG
" ncpi.htc = 0x%04x\n", ncpi
->htc
);
978 printk(KERN_DEBUG
" ncpi.loc = 0x%04x\n", ncpi
->loc
);
980 printk(KERN_DEBUG
" ncpi.hoc = 0x%04x\n", ncpi
->hoc
);
982 printk(KERN_DEBUG
" ncpi.mod = %d\n", ncpi
->modulo
);
986 actcapi_debug_dlpd(actcapi_dlpd
*dlpd
)
988 printk(KERN_DEBUG
" dlpd.len = %d\n", dlpd
->len
);
990 printk(KERN_DEBUG
" dlpd.dlen = 0x%04x\n", dlpd
->dlen
);
992 printk(KERN_DEBUG
" dlpd.laa = 0x%02x\n", dlpd
->laa
);
994 printk(KERN_DEBUG
" dlpd.lab = 0x%02x\n", dlpd
->lab
);
996 printk(KERN_DEBUG
" dlpd.modulo = %d\n", dlpd
->modulo
);
998 printk(KERN_DEBUG
" dlpd.win = %d\n", dlpd
->win
);
1001 #ifdef DEBUG_DUMP_SKB
1002 static void dump_skb(struct sk_buff
*skb
) {
1004 char *p
= skb
->data
;
1008 for (i
= 0; i
< skb
->len
; i
++) {
1009 t
+= sprintf(t
, "%02x ", *p
++ & 0xff);
1010 if ((i
& 0x0f) == 8) {
1011 printk(KERN_DEBUG
"dump: %s\n", tmp
);
1016 printk(KERN_DEBUG
"dump: %s\n", tmp
);
1021 actcapi_debug_msg(struct sk_buff
*skb
, int direction
)
1023 actcapi_msg
*msg
= (actcapi_msg
*)skb
->data
;
1028 #ifndef DEBUG_DATA_MSG
1029 if (msg
->hdr
.cmd
.cmd
== 0x86)
1033 #ifdef DEBUG_DUMP_SKB
1036 for (i
= 0; i
< num_valid_msg
; i
++)
1037 if ((msg
->hdr
.cmd
.cmd
== valid_msg
[i
].cmd
.cmd
) &&
1038 (msg
->hdr
.cmd
.subcmd
== valid_msg
[i
].cmd
.subcmd
)) {
1039 descr
= valid_msg
[i
].description
;
1042 printk(KERN_DEBUG
"%s %s msg\n", direction
?"Outgoing":"Incoming", descr
);
1043 printk(KERN_DEBUG
" ApplID = %d\n", msg
->hdr
.applicationID
);
1044 printk(KERN_DEBUG
" Len = %d\n", msg
->hdr
.len
);
1045 printk(KERN_DEBUG
" MsgNum = 0x%04x\n", msg
->hdr
.msgnum
);
1046 printk(KERN_DEBUG
" Cmd = 0x%02x\n", msg
->hdr
.cmd
.cmd
);
1047 printk(KERN_DEBUG
" SubCmd = 0x%02x\n", msg
->hdr
.cmd
.subcmd
);
1051 printk(KERN_DEBUG
" BLOCK = 0x%02x\n",
1052 msg
->msg
.data_b3_ind
.blocknr
);
1056 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1057 msg
->msg
.connect_conf
.plci
);
1058 printk(KERN_DEBUG
" Info = 0x%04x\n",
1059 msg
->msg
.connect_conf
.info
);
1063 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1064 msg
->msg
.connect_ind
.plci
);
1065 printk(KERN_DEBUG
" Contr = %d\n",
1066 msg
->msg
.connect_ind
.controller
);
1067 printk(KERN_DEBUG
" SI1 = %d\n",
1068 msg
->msg
.connect_ind
.si1
);
1069 printk(KERN_DEBUG
" SI2 = %d\n",
1070 msg
->msg
.connect_ind
.si2
);
1071 printk(KERN_DEBUG
" EAZ = '%c'\n",
1072 msg
->msg
.connect_ind
.eaz
);
1073 actcapi_debug_caddr(&msg
->msg
.connect_ind
.addr
);
1076 /* CONNECT ACTIVE IND */
1077 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1078 msg
->msg
.connect_active_ind
.plci
);
1079 actcapi_debug_caddr(&msg
->msg
.connect_active_ind
.addr
);
1083 printk(KERN_DEBUG
" Contr = %d\n",
1084 msg
->msg
.listen_conf
.controller
);
1085 printk(KERN_DEBUG
" Info = 0x%04x\n",
1086 msg
->msg
.listen_conf
.info
);
1090 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1091 msg
->msg
.info_ind
.plci
);
1092 printk(KERN_DEBUG
" Imsk = 0x%04x\n",
1093 msg
->msg
.info_ind
.nr
.mask
);
1094 if (msg
->hdr
.len
> 12) {
1095 int l
= msg
->hdr
.len
- 12;
1098 for (j
= 0; j
< l
; j
++)
1099 p
+= sprintf(p
, "%02x ", msg
->msg
.info_ind
.el
.display
[j
]);
1100 printk(KERN_DEBUG
" D = '%s'\n", tmp
);
1104 /* SELECT B2 PROTOCOL CONF */
1105 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1106 msg
->msg
.select_b2_protocol_conf
.plci
);
1107 printk(KERN_DEBUG
" Info = 0x%04x\n",
1108 msg
->msg
.select_b2_protocol_conf
.info
);
1111 /* SELECT B3 PROTOCOL CONF */
1112 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1113 msg
->msg
.select_b3_protocol_conf
.plci
);
1114 printk(KERN_DEBUG
" Info = 0x%04x\n",
1115 msg
->msg
.select_b3_protocol_conf
.info
);
1118 /* LISTEN B3 CONF */
1119 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1120 msg
->msg
.listen_b3_conf
.plci
);
1121 printk(KERN_DEBUG
" Info = 0x%04x\n",
1122 msg
->msg
.listen_b3_conf
.info
);
1125 /* CONNECT B3 IND */
1126 printk(KERN_DEBUG
" NCCI = 0x%04x\n",
1127 msg
->msg
.connect_b3_ind
.ncci
);
1128 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1129 msg
->msg
.connect_b3_ind
.plci
);
1130 actcapi_debug_ncpi(&msg
->msg
.connect_b3_ind
.ncpi
);
1133 /* CONNECT B3 ACTIVE IND */
1134 printk(KERN_DEBUG
" NCCI = 0x%04x\n",
1135 msg
->msg
.connect_b3_active_ind
.ncci
);
1136 actcapi_debug_ncpi(&msg
->msg
.connect_b3_active_ind
.ncpi
);
1139 /* MANUFACTURER IND */
1140 printk(KERN_DEBUG
" Mmsg = 0x%02x\n",
1141 msg
->msg
.manufacturer_ind_err
.manuf_msg
);
1142 switch (msg
->msg
.manufacturer_ind_err
.manuf_msg
) {
1144 printk(KERN_DEBUG
" Contr = %d\n",
1145 msg
->msg
.manufacturer_ind_err
.controller
);
1146 printk(KERN_DEBUG
" Code = 0x%08x\n",
1147 msg
->msg
.manufacturer_ind_err
.errcode
);
1148 memset(tmp
, 0, sizeof(tmp
));
1149 strncpy(tmp
, &msg
->msg
.manufacturer_ind_err
.errstring
,
1151 printk(KERN_DEBUG
" Emsg = '%s'\n", tmp
);
1157 printk(KERN_DEBUG
" Imsk = 0x%08x\n",
1158 msg
->msg
.listen_req
.infomask
);
1159 printk(KERN_DEBUG
" Emsk = 0x%04x\n",
1160 msg
->msg
.listen_req
.eazmask
);
1161 printk(KERN_DEBUG
" Smsk = 0x%04x\n",
1162 msg
->msg
.listen_req
.simask
);
1165 /* SELECT_B2_PROTOCOL_REQ */
1166 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1167 msg
->msg
.select_b2_protocol_req
.plci
);
1168 printk(KERN_DEBUG
" prot = 0x%02x\n",
1169 msg
->msg
.select_b2_protocol_req
.protocol
);
1170 if (msg
->hdr
.len
>= 11)
1171 printk(KERN_DEBUG
"No dlpd\n");
1173 actcapi_debug_dlpd(&msg
->msg
.select_b2_protocol_req
.dlpd
);
1177 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1178 msg
->msg
.connect_resp
.plci
);
1179 printk(KERN_DEBUG
" CAUSE = 0x%02x\n",
1180 msg
->msg
.connect_resp
.rejectcause
);
1183 /* CONNECT ACTIVE RESP */
1184 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1185 msg
->msg
.connect_active_resp
.plci
);