1 /* $Id: capi.c,v 1.9.6.2 2001/09/23 22:24:32 kai Exp $
3 * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
7 * Copyright by Fritz Elfert <fritz@isdn4linux.de>
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
12 * Thanks to Friedemann Baitinger and IBM Germany
19 static actcapi_msgdsc valid_msg
[] = {
20 {{ 0x86, 0x02}, "DATA_B3_IND"}, /* DATA_B3_IND/CONF must be first because of speed!!! */
21 {{ 0x86, 0x01}, "DATA_B3_CONF"},
22 {{ 0x02, 0x01}, "CONNECT_CONF"},
23 {{ 0x02, 0x02}, "CONNECT_IND"},
24 {{ 0x09, 0x01}, "CONNECT_INFO_CONF"},
25 {{ 0x03, 0x02}, "CONNECT_ACTIVE_IND"},
26 {{ 0x04, 0x01}, "DISCONNECT_CONF"},
27 {{ 0x04, 0x02}, "DISCONNECT_IND"},
28 {{ 0x05, 0x01}, "LISTEN_CONF"},
29 {{ 0x06, 0x01}, "GET_PARAMS_CONF"},
30 {{ 0x07, 0x01}, "INFO_CONF"},
31 {{ 0x07, 0x02}, "INFO_IND"},
32 {{ 0x08, 0x01}, "DATA_CONF"},
33 {{ 0x08, 0x02}, "DATA_IND"},
34 {{ 0x40, 0x01}, "SELECT_B2_PROTOCOL_CONF"},
35 {{ 0x80, 0x01}, "SELECT_B3_PROTOCOL_CONF"},
36 {{ 0x81, 0x01}, "LISTEN_B3_CONF"},
37 {{ 0x82, 0x01}, "CONNECT_B3_CONF"},
38 {{ 0x82, 0x02}, "CONNECT_B3_IND"},
39 {{ 0x83, 0x02}, "CONNECT_B3_ACTIVE_IND"},
40 {{ 0x84, 0x01}, "DISCONNECT_B3_CONF"},
41 {{ 0x84, 0x02}, "DISCONNECT_B3_IND"},
42 {{ 0x85, 0x01}, "GET_B3_PARAMS_CONF"},
43 {{ 0x01, 0x01}, "RESET_B3_CONF"},
44 {{ 0x01, 0x02}, "RESET_B3_IND"},
45 /* {{ 0x87, 0x02, "HANDSET_IND"}, not implemented */
46 {{ 0xff, 0x01}, "MANUFACTURER_CONF"},
47 {{ 0xff, 0x02}, "MANUFACTURER_IND"},
50 {{ 0x01, 0x00}, "RESET_B3_REQ"},
51 {{ 0x02, 0x00}, "CONNECT_REQ"},
52 {{ 0x04, 0x00}, "DISCONNECT_REQ"},
53 {{ 0x05, 0x00}, "LISTEN_REQ"},
54 {{ 0x06, 0x00}, "GET_PARAMS_REQ"},
55 {{ 0x07, 0x00}, "INFO_REQ"},
56 {{ 0x08, 0x00}, "DATA_REQ"},
57 {{ 0x09, 0x00}, "CONNECT_INFO_REQ"},
58 {{ 0x40, 0x00}, "SELECT_B2_PROTOCOL_REQ"},
59 {{ 0x80, 0x00}, "SELECT_B3_PROTOCOL_REQ"},
60 {{ 0x81, 0x00}, "LISTEN_B3_REQ"},
61 {{ 0x82, 0x00}, "CONNECT_B3_REQ"},
62 {{ 0x84, 0x00}, "DISCONNECT_B3_REQ"},
63 {{ 0x85, 0x00}, "GET_B3_PARAMS_REQ"},
64 {{ 0x86, 0x00}, "DATA_B3_REQ"},
65 {{ 0xff, 0x00}, "MANUFACTURER_REQ"},
67 {{ 0x01, 0x03}, "RESET_B3_RESP"},
68 {{ 0x02, 0x03}, "CONNECT_RESP"},
69 {{ 0x03, 0x03}, "CONNECT_ACTIVE_RESP"},
70 {{ 0x04, 0x03}, "DISCONNECT_RESP"},
71 {{ 0x07, 0x03}, "INFO_RESP"},
72 {{ 0x08, 0x03}, "DATA_RESP"},
73 {{ 0x82, 0x03}, "CONNECT_B3_RESP"},
74 {{ 0x83, 0x03}, "CONNECT_B3_ACTIVE_RESP"},
75 {{ 0x84, 0x03}, "DISCONNECT_B3_RESP"},
76 {{ 0x86, 0x03}, "DATA_B3_RESP"},
77 {{ 0xff, 0x03}, "MANUFACTURER_RESP"},
79 {{ 0x00, 0x00}, NULL
},
81 #define num_valid_msg (sizeof(valid_msg)/sizeof(actcapi_msgdsc))
82 #define num_valid_imsg 27 /* MANUFACTURER_IND */
85 * Check for a valid incoming CAPI message.
88 * 1 = Valid message, no B-Channel-data
89 * 2 = Valid message, B-Channel-data
92 actcapi_chkhdr(act2000_card
* card
, actcapi_msghdr
*hdr
)
96 if (hdr
->applicationID
!= 1)
100 for (i
= 0; i
< num_valid_imsg
; i
++)
101 if ((hdr
->cmd
.cmd
== valid_msg
[i
].cmd
.cmd
) &&
102 (hdr
->cmd
.subcmd
== valid_msg
[i
].cmd
.subcmd
)) {
108 #define ACTCAPI_MKHDR(l, c, s) { \
109 skb = alloc_skb(l + 8, GFP_ATOMIC); \
111 m = (actcapi_msg *)skb_put(skb, l + 8); \
112 m->hdr.len = l + 8; \
113 m->hdr.applicationID = 1; \
114 m->hdr.cmd.cmd = c; \
115 m->hdr.cmd.subcmd = s; \
116 m->hdr.msgnum = actcapi_nextsmsg(card); \
120 #define ACTCAPI_CHKSKB if (!skb) { \
121 printk(KERN_WARNING "actcapi: alloc_skb failed\n"); \
125 #define ACTCAPI_QUEUE_TX { \
126 actcapi_debug_msg(skb, 1); \
127 skb_queue_tail(&card->sndq, skb); \
128 act2000_schedule_tx(card); \
132 actcapi_listen_req(act2000_card
*card
)
139 for (i
= 0; i
< ACT2000_BCH
; i
++)
140 eazmask
|= card
->bch
[i
].eazmask
;
141 ACTCAPI_MKHDR(9, 0x05, 0x00);
143 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
146 m
->msg
.listen_req
.controller
= 0;
147 m
->msg
.listen_req
.infomask
= 0x3f; /* All information */
148 m
->msg
.listen_req
.eazmask
= eazmask
;
149 m
->msg
.listen_req
.simask
= (eazmask
)?0x86:0; /* All SI's */
155 actcapi_connect_req(act2000_card
*card
, act2000_chan
*chan
, char *phone
,
156 char eaz
, int si1
, int si2
)
161 ACTCAPI_MKHDR((11 + strlen(phone
)), 0x02, 0x00);
163 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
164 chan
->fsm_state
= ACT2000_STATE_NULL
;
167 m
->msg
.connect_req
.controller
= 0;
168 m
->msg
.connect_req
.bchan
= 0x83;
169 m
->msg
.connect_req
.infomask
= 0x3f;
170 m
->msg
.connect_req
.si1
= si1
;
171 m
->msg
.connect_req
.si2
= si2
;
172 m
->msg
.connect_req
.eaz
= eaz
?eaz
:'0';
173 m
->msg
.connect_req
.addr
.len
= strlen(phone
) + 1;
174 m
->msg
.connect_req
.addr
.tnp
= 0x81;
175 memcpy(m
->msg
.connect_req
.addr
.num
, phone
, strlen(phone
));
176 chan
->callref
= m
->hdr
.msgnum
;
182 actcapi_connect_b3_req(act2000_card
*card
, act2000_chan
*chan
)
187 ACTCAPI_MKHDR(17, 0x82, 0x00);
189 m
->msg
.connect_b3_req
.plci
= chan
->plci
;
190 memset(&m
->msg
.connect_b3_req
.ncpi
, 0,
191 sizeof(m
->msg
.connect_b3_req
.ncpi
));
192 m
->msg
.connect_b3_req
.ncpi
.len
= 13;
193 m
->msg
.connect_b3_req
.ncpi
.modulo
= 8;
198 * Set net type (1TR6) or (EDSS1)
201 actcapi_manufacturer_req_net(act2000_card
*card
)
206 ACTCAPI_MKHDR(5, 0xff, 0x00);
208 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
211 m
->msg
.manufacturer_req_net
.manuf_msg
= 0x11;
212 m
->msg
.manufacturer_req_net
.controller
= 1;
213 m
->msg
.manufacturer_req_net
.nettype
= (card
->ptype
== ISDN_PTYPE_EURO
)?1:0;
215 printk(KERN_INFO
"act2000 %s: D-channel protocol now %s\n",
216 card
->interface
.id
, (card
->ptype
== ISDN_PTYPE_EURO
)?"euro":"1tr6");
217 card
->interface
.features
&=
218 ~(ISDN_FEATURE_P_UNKNOWN
| ISDN_FEATURE_P_EURO
| ISDN_FEATURE_P_1TR6
);
219 card
->interface
.features
|=
220 ((card
->ptype
== ISDN_PTYPE_EURO
)?ISDN_FEATURE_P_EURO
:ISDN_FEATURE_P_1TR6
);
225 * Switch V.42 on or off
229 actcapi_manufacturer_req_v42(act2000_card
*card
, ulong arg
)
234 ACTCAPI_MKHDR(8, 0xff, 0x00);
237 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
240 m
->msg
.manufacturer_req_v42
.manuf_msg
= 0x10;
241 m
->msg
.manufacturer_req_v42
.controller
= 0;
242 m
->msg
.manufacturer_req_v42
.v42control
= (arg
?1:0);
252 actcapi_manufacturer_req_errh(act2000_card
*card
)
257 ACTCAPI_MKHDR(4, 0xff, 0x00);
260 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
263 m
->msg
.manufacturer_req_err
.manuf_msg
= 0x03;
264 m
->msg
.manufacturer_req_err
.controller
= 0;
273 actcapi_manufacturer_req_msn(act2000_card
*card
)
275 msn_entry
*p
= card
->msn_list
;
283 len
= strlen(p
->msn
);
284 for (i
= 0; i
< 2; i
++) {
285 ACTCAPI_MKHDR(6 + len
, 0xff, 0x00);
287 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
290 m
->msg
.manufacturer_req_msn
.manuf_msg
= 0x13 + i
;
291 m
->msg
.manufacturer_req_msn
.controller
= 0;
292 m
->msg
.manufacturer_req_msn
.msnmap
.eaz
= p
->eaz
;
293 m
->msg
.manufacturer_req_msn
.msnmap
.len
= len
;
294 memcpy(m
->msg
.manufacturer_req_msn
.msnmap
.msn
, p
->msn
, len
);
303 actcapi_select_b2_protocol_req(act2000_card
*card
, act2000_chan
*chan
)
308 ACTCAPI_MKHDR(10, 0x40, 0x00);
310 m
->msg
.select_b2_protocol_req
.plci
= chan
->plci
;
311 memset(&m
->msg
.select_b2_protocol_req
.dlpd
, 0,
312 sizeof(m
->msg
.select_b2_protocol_req
.dlpd
));
313 m
->msg
.select_b2_protocol_req
.dlpd
.len
= 6;
314 switch (chan
->l2prot
) {
315 case ISDN_PROTO_L2_TRANS
:
316 m
->msg
.select_b2_protocol_req
.protocol
= 0x03;
317 m
->msg
.select_b2_protocol_req
.dlpd
.dlen
= 4000;
319 case ISDN_PROTO_L2_HDLC
:
320 m
->msg
.select_b2_protocol_req
.protocol
= 0x02;
321 m
->msg
.select_b2_protocol_req
.dlpd
.dlen
= 4000;
323 case ISDN_PROTO_L2_X75I
:
324 case ISDN_PROTO_L2_X75UI
:
325 case ISDN_PROTO_L2_X75BUI
:
326 m
->msg
.select_b2_protocol_req
.protocol
= 0x01;
327 m
->msg
.select_b2_protocol_req
.dlpd
.dlen
= 4000;
328 m
->msg
.select_b2_protocol_req
.dlpd
.laa
= 3;
329 m
->msg
.select_b2_protocol_req
.dlpd
.lab
= 1;
330 m
->msg
.select_b2_protocol_req
.dlpd
.win
= 7;
331 m
->msg
.select_b2_protocol_req
.dlpd
.modulo
= 8;
338 actcapi_select_b3_protocol_req(act2000_card
*card
, act2000_chan
*chan
)
343 ACTCAPI_MKHDR(17, 0x80, 0x00);
345 m
->msg
.select_b3_protocol_req
.plci
= chan
->plci
;
346 memset(&m
->msg
.select_b3_protocol_req
.ncpd
, 0,
347 sizeof(m
->msg
.select_b3_protocol_req
.ncpd
));
348 switch (chan
->l3prot
) {
349 case ISDN_PROTO_L3_TRANS
:
350 m
->msg
.select_b3_protocol_req
.protocol
= 0x04;
351 m
->msg
.select_b3_protocol_req
.ncpd
.len
= 13;
352 m
->msg
.select_b3_protocol_req
.ncpd
.modulo
= 8;
359 actcapi_listen_b3_req(act2000_card
*card
, act2000_chan
*chan
)
364 ACTCAPI_MKHDR(2, 0x81, 0x00);
366 m
->msg
.listen_b3_req
.plci
= chan
->plci
;
371 actcapi_disconnect_req(act2000_card
*card
, act2000_chan
*chan
)
376 ACTCAPI_MKHDR(3, 0x04, 0x00);
378 m
->msg
.disconnect_req
.plci
= chan
->plci
;
379 m
->msg
.disconnect_req
.cause
= 0;
384 actcapi_disconnect_b3_req(act2000_card
*card
, act2000_chan
*chan
)
389 ACTCAPI_MKHDR(17, 0x84, 0x00);
391 m
->msg
.disconnect_b3_req
.ncci
= chan
->ncci
;
392 memset(&m
->msg
.disconnect_b3_req
.ncpi
, 0,
393 sizeof(m
->msg
.disconnect_b3_req
.ncpi
));
394 m
->msg
.disconnect_b3_req
.ncpi
.len
= 13;
395 m
->msg
.disconnect_b3_req
.ncpi
.modulo
= 8;
396 chan
->fsm_state
= ACT2000_STATE_BHWAIT
;
401 actcapi_connect_resp(act2000_card
*card
, act2000_chan
*chan
, __u8 cause
)
406 ACTCAPI_MKHDR(3, 0x02, 0x03);
408 m
->msg
.connect_resp
.plci
= chan
->plci
;
409 m
->msg
.connect_resp
.rejectcause
= cause
;
411 chan
->fsm_state
= ACT2000_STATE_NULL
;
414 chan
->fsm_state
= ACT2000_STATE_IWAIT
;
419 actcapi_connect_active_resp(act2000_card
*card
, act2000_chan
*chan
)
424 ACTCAPI_MKHDR(2, 0x03, 0x03);
426 m
->msg
.connect_resp
.plci
= chan
->plci
;
427 if (chan
->fsm_state
== ACT2000_STATE_IWAIT
)
428 chan
->fsm_state
= ACT2000_STATE_IBWAIT
;
433 actcapi_connect_b3_resp(act2000_card
*card
, act2000_chan
*chan
, __u8 rejectcause
)
438 ACTCAPI_MKHDR((rejectcause
?3:17), 0x82, 0x03);
440 m
->msg
.connect_b3_resp
.ncci
= chan
->ncci
;
441 m
->msg
.connect_b3_resp
.rejectcause
= rejectcause
;
443 memset(&m
->msg
.connect_b3_resp
.ncpi
, 0,
444 sizeof(m
->msg
.connect_b3_resp
.ncpi
));
445 m
->msg
.connect_b3_resp
.ncpi
.len
= 13;
446 m
->msg
.connect_b3_resp
.ncpi
.modulo
= 8;
447 chan
->fsm_state
= ACT2000_STATE_BWAIT
;
453 actcapi_connect_b3_active_resp(act2000_card
*card
, act2000_chan
*chan
)
458 ACTCAPI_MKHDR(2, 0x83, 0x03);
460 m
->msg
.connect_b3_active_resp
.ncci
= chan
->ncci
;
461 chan
->fsm_state
= ACT2000_STATE_ACTIVE
;
466 actcapi_info_resp(act2000_card
*card
, act2000_chan
*chan
)
471 ACTCAPI_MKHDR(2, 0x07, 0x03);
473 m
->msg
.info_resp
.plci
= chan
->plci
;
478 actcapi_disconnect_b3_resp(act2000_card
*card
, act2000_chan
*chan
)
483 ACTCAPI_MKHDR(2, 0x84, 0x03);
485 m
->msg
.disconnect_b3_resp
.ncci
= chan
->ncci
;
492 actcapi_disconnect_resp(act2000_card
*card
, act2000_chan
*chan
)
497 ACTCAPI_MKHDR(2, 0x04, 0x03);
499 m
->msg
.disconnect_resp
.plci
= chan
->plci
;
505 new_plci(act2000_card
*card
, __u16 plci
)
508 for (i
= 0; i
< ACT2000_BCH
; i
++)
509 if (card
->bch
[i
].plci
== 0x8000) {
510 card
->bch
[i
].plci
= plci
;
517 find_plci(act2000_card
*card
, __u16 plci
)
520 for (i
= 0; i
< ACT2000_BCH
; i
++)
521 if (card
->bch
[i
].plci
== plci
)
527 find_ncci(act2000_card
*card
, __u16 ncci
)
530 for (i
= 0; i
< ACT2000_BCH
; i
++)
531 if (card
->bch
[i
].ncci
== ncci
)
537 find_dialing(act2000_card
*card
, __u16 callref
)
540 for (i
= 0; i
< ACT2000_BCH
; i
++)
541 if ((card
->bch
[i
].callref
== callref
) &&
542 (card
->bch
[i
].fsm_state
== ACT2000_STATE_OCALL
))
548 actcapi_data_b3_ind(act2000_card
*card
, struct sk_buff
*skb
) {
554 actcapi_msg
*msg
= (actcapi_msg
*)skb
->data
;
556 EVAL_NCCI(msg
->msg
.data_b3_ind
.fakencci
, plci
, controller
, ncci
);
557 chan
= find_ncci(card
, ncci
);
560 if (card
->bch
[chan
].fsm_state
!= ACT2000_STATE_ACTIVE
)
562 if (card
->bch
[chan
].plci
!= plci
)
564 blocknr
= msg
->msg
.data_b3_ind
.blocknr
;
566 card
->interface
.rcvcallb_skb(card
->myid
, chan
, skb
);
567 if (!(skb
= alloc_skb(11, GFP_ATOMIC
))) {
568 printk(KERN_WARNING
"actcapi: alloc_skb failed\n");
571 msg
= (actcapi_msg
*)skb_put(skb
, 11);
573 msg
->hdr
.applicationID
= 1;
574 msg
->hdr
.cmd
.cmd
= 0x86;
575 msg
->hdr
.cmd
.subcmd
= 0x03;
576 msg
->hdr
.msgnum
= actcapi_nextsmsg(card
);
577 msg
->msg
.data_b3_resp
.ncci
= ncci
;
578 msg
->msg
.data_b3_resp
.blocknr
= blocknr
;
584 * Walk over ackq, unlink DATA_B3_REQ from it, if
585 * ncci and blocknr are matching.
586 * Decrement queued-bytes counter.
589 handle_ack(act2000_card
*card
, act2000_chan
*chan
, __u8 blocknr
) {
593 struct actcapi_msg
*m
;
596 spin_lock_irqsave(&card
->lock
, flags
);
597 skb
= skb_peek(&card
->ackq
);
598 spin_unlock_irqrestore(&card
->lock
, flags
);
600 printk(KERN_WARNING
"act2000: handle_ack nothing found!\n");
605 m
= (actcapi_msg
*)tmp
->data
;
606 if ((((m
->msg
.data_b3_req
.fakencci
>> 8) & 0xff) == chan
->ncci
) &&
607 (m
->msg
.data_b3_req
.blocknr
== blocknr
)) {
608 /* found corresponding DATA_B3_REQ */
609 skb_unlink(tmp
, &card
->ackq
);
610 chan
->queued
-= m
->msg
.data_b3_req
.datalen
;
611 if (m
->msg
.data_b3_req
.flags
)
612 ret
= m
->msg
.data_b3_req
.datalen
;
614 if (chan
->queued
< 0)
618 spin_lock_irqsave(&card
->lock
, flags
);
619 tmp
= skb_peek((struct sk_buff_head
*)tmp
);
620 spin_unlock_irqrestore(&card
->lock
, flags
);
621 if ((tmp
== skb
) || (tmp
== NULL
)) {
622 /* reached end of queue */
623 printk(KERN_WARNING
"act2000: handle_ack nothing found!\n");
630 actcapi_dispatch(struct work_struct
*work
)
632 struct act2000_card
*card
=
633 container_of(work
, struct act2000_card
, rcv_tq
);
643 while ((skb
= skb_dequeue(&card
->rcvq
))) {
644 actcapi_debug_msg(skb
, 0);
645 msg
= (actcapi_msg
*)skb
->data
;
646 ccmd
= ((msg
->hdr
.cmd
.cmd
<< 8) | msg
->hdr
.cmd
.subcmd
);
650 if (actcapi_data_b3_ind(card
, skb
))
655 chan
= find_ncci(card
, msg
->msg
.data_b3_conf
.ncci
);
656 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_ACTIVE
)) {
657 if (msg
->msg
.data_b3_conf
.info
!= 0)
658 printk(KERN_WARNING
"act2000: DATA_B3_CONF: %04x\n",
659 msg
->msg
.data_b3_conf
.info
);
660 len
= handle_ack(card
, &card
->bch
[chan
],
661 msg
->msg
.data_b3_conf
.blocknr
);
663 cmd
.driver
= card
->myid
;
664 cmd
.command
= ISDN_STAT_BSENT
;
666 cmd
.parm
.length
= len
;
667 card
->interface
.statcallb(&cmd
);
673 chan
= find_dialing(card
, msg
->hdr
.msgnum
);
675 if (msg
->msg
.connect_conf
.info
) {
676 card
->bch
[chan
].fsm_state
= ACT2000_STATE_NULL
;
677 cmd
.driver
= card
->myid
;
678 cmd
.command
= ISDN_STAT_DHUP
;
680 card
->interface
.statcallb(&cmd
);
682 card
->bch
[chan
].fsm_state
= ACT2000_STATE_OWAIT
;
683 card
->bch
[chan
].plci
= msg
->msg
.connect_conf
.plci
;
689 chan
= new_plci(card
, msg
->msg
.connect_ind
.plci
);
691 ctmp
= (act2000_chan
*)tmp
;
692 ctmp
->plci
= msg
->msg
.connect_ind
.plci
;
693 actcapi_connect_resp(card
, ctmp
, 0x11); /* All Card-Cannels busy */
695 card
->bch
[chan
].fsm_state
= ACT2000_STATE_ICALL
;
696 cmd
.driver
= card
->myid
;
697 cmd
.command
= ISDN_STAT_ICALL
;
699 cmd
.parm
.setup
.si1
= msg
->msg
.connect_ind
.si1
;
700 cmd
.parm
.setup
.si2
= msg
->msg
.connect_ind
.si2
;
701 if (card
->ptype
== ISDN_PTYPE_EURO
)
702 strcpy(cmd
.parm
.setup
.eazmsn
,
703 act2000_find_eaz(card
, msg
->msg
.connect_ind
.eaz
));
705 cmd
.parm
.setup
.eazmsn
[0] = msg
->msg
.connect_ind
.eaz
;
706 cmd
.parm
.setup
.eazmsn
[1] = 0;
708 memset(cmd
.parm
.setup
.phone
, 0, sizeof(cmd
.parm
.setup
.phone
));
709 memcpy(cmd
.parm
.setup
.phone
, msg
->msg
.connect_ind
.addr
.num
,
710 msg
->msg
.connect_ind
.addr
.len
- 1);
711 cmd
.parm
.setup
.plan
= msg
->msg
.connect_ind
.addr
.tnp
;
712 cmd
.parm
.setup
.screen
= 0;
713 if (card
->interface
.statcallb(&cmd
) == 2)
714 actcapi_connect_resp(card
, &card
->bch
[chan
], 0x15); /* Reject Call */
718 /* CONNECT_ACTIVE_IND */
719 chan
= find_plci(card
, msg
->msg
.connect_active_ind
.plci
);
721 switch (card
->bch
[chan
].fsm_state
) {
722 case ACT2000_STATE_IWAIT
:
723 actcapi_connect_active_resp(card
, &card
->bch
[chan
]);
725 case ACT2000_STATE_OWAIT
:
726 actcapi_connect_active_resp(card
, &card
->bch
[chan
]);
727 actcapi_select_b2_protocol_req(card
, &card
->bch
[chan
]);
733 chan
= find_plci(card
, msg
->msg
.connect_b3_ind
.plci
);
734 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_IBWAIT
)) {
735 card
->bch
[chan
].ncci
= msg
->msg
.connect_b3_ind
.ncci
;
736 actcapi_connect_b3_resp(card
, &card
->bch
[chan
], 0);
738 ctmp
= (act2000_chan
*)tmp
;
739 ctmp
->ncci
= msg
->msg
.connect_b3_ind
.ncci
;
740 actcapi_connect_b3_resp(card
, ctmp
, 0x11); /* All Card-Cannels busy */
744 /* CONNECT_B3_ACTIVE_IND */
745 chan
= find_ncci(card
, msg
->msg
.connect_b3_active_ind
.ncci
);
746 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_BWAIT
)) {
747 actcapi_connect_b3_active_resp(card
, &card
->bch
[chan
]);
748 cmd
.driver
= card
->myid
;
749 cmd
.command
= ISDN_STAT_BCONN
;
751 card
->interface
.statcallb(&cmd
);
755 /* DISCONNECT_B3_IND */
756 chan
= find_ncci(card
, msg
->msg
.disconnect_b3_ind
.ncci
);
758 ctmp
= &card
->bch
[chan
];
759 actcapi_disconnect_b3_resp(card
, ctmp
);
760 switch (ctmp
->fsm_state
) {
761 case ACT2000_STATE_ACTIVE
:
762 ctmp
->fsm_state
= ACT2000_STATE_DHWAIT2
;
763 cmd
.driver
= card
->myid
;
764 cmd
.command
= ISDN_STAT_BHUP
;
766 card
->interface
.statcallb(&cmd
);
768 case ACT2000_STATE_BHWAIT2
:
769 actcapi_disconnect_req(card
, ctmp
);
770 ctmp
->fsm_state
= ACT2000_STATE_DHWAIT
;
771 cmd
.driver
= card
->myid
;
772 cmd
.command
= ISDN_STAT_BHUP
;
774 card
->interface
.statcallb(&cmd
);
781 chan
= find_plci(card
, msg
->msg
.disconnect_ind
.plci
);
783 ctmp
= &card
->bch
[chan
];
784 actcapi_disconnect_resp(card
, ctmp
);
785 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
786 cmd
.driver
= card
->myid
;
787 cmd
.command
= ISDN_STAT_DHUP
;
789 card
->interface
.statcallb(&cmd
);
791 ctmp
= (act2000_chan
*)tmp
;
792 ctmp
->plci
= msg
->msg
.disconnect_ind
.plci
;
793 actcapi_disconnect_resp(card
, ctmp
);
797 /* SELECT_B2_PROTOCOL_CONF */
798 chan
= find_plci(card
, msg
->msg
.select_b2_protocol_conf
.plci
);
800 switch (card
->bch
[chan
].fsm_state
) {
801 case ACT2000_STATE_ICALL
:
802 case ACT2000_STATE_OWAIT
:
803 ctmp
= &card
->bch
[chan
];
804 if (msg
->msg
.select_b2_protocol_conf
.info
== 0)
805 actcapi_select_b3_protocol_req(card
, ctmp
);
807 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
808 cmd
.driver
= card
->myid
;
809 cmd
.command
= ISDN_STAT_DHUP
;
811 card
->interface
.statcallb(&cmd
);
817 /* SELECT_B3_PROTOCOL_CONF */
818 chan
= find_plci(card
, msg
->msg
.select_b3_protocol_conf
.plci
);
820 switch (card
->bch
[chan
].fsm_state
) {
821 case ACT2000_STATE_ICALL
:
822 case ACT2000_STATE_OWAIT
:
823 ctmp
= &card
->bch
[chan
];
824 if (msg
->msg
.select_b3_protocol_conf
.info
== 0)
825 actcapi_listen_b3_req(card
, ctmp
);
827 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
828 cmd
.driver
= card
->myid
;
829 cmd
.command
= ISDN_STAT_DHUP
;
831 card
->interface
.statcallb(&cmd
);
837 chan
= find_plci(card
, msg
->msg
.listen_b3_conf
.plci
);
839 switch (card
->bch
[chan
].fsm_state
) {
840 case ACT2000_STATE_ICALL
:
841 ctmp
= &card
->bch
[chan
];
842 if (msg
->msg
.listen_b3_conf
.info
== 0)
843 actcapi_connect_resp(card
, ctmp
, 0);
845 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
846 cmd
.driver
= card
->myid
;
847 cmd
.command
= ISDN_STAT_DHUP
;
849 card
->interface
.statcallb(&cmd
);
852 case ACT2000_STATE_OWAIT
:
853 ctmp
= &card
->bch
[chan
];
854 if (msg
->msg
.listen_b3_conf
.info
== 0) {
855 actcapi_connect_b3_req(card
, ctmp
);
856 ctmp
->fsm_state
= ACT2000_STATE_OBWAIT
;
857 cmd
.driver
= card
->myid
;
858 cmd
.command
= ISDN_STAT_DCONN
;
860 card
->interface
.statcallb(&cmd
);
862 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
863 cmd
.driver
= card
->myid
;
864 cmd
.command
= ISDN_STAT_DHUP
;
866 card
->interface
.statcallb(&cmd
);
872 /* CONNECT_B3_CONF */
873 chan
= find_plci(card
, msg
->msg
.connect_b3_conf
.plci
);
874 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_OBWAIT
)) {
875 ctmp
= &card
->bch
[chan
];
876 if (msg
->msg
.connect_b3_conf
.info
) {
877 ctmp
->fsm_state
= ACT2000_STATE_NULL
;
878 cmd
.driver
= card
->myid
;
879 cmd
.command
= ISDN_STAT_DHUP
;
881 card
->interface
.statcallb(&cmd
);
883 ctmp
->ncci
= msg
->msg
.connect_b3_conf
.ncci
;
884 ctmp
->fsm_state
= ACT2000_STATE_BWAIT
;
889 /* DISCONNECT_B3_CONF */
890 chan
= find_ncci(card
, msg
->msg
.disconnect_b3_conf
.ncci
);
891 if ((chan
>= 0) && (card
->bch
[chan
].fsm_state
== ACT2000_STATE_BHWAIT
))
892 card
->bch
[chan
].fsm_state
= ACT2000_STATE_BHWAIT2
;
896 chan
= find_plci(card
, msg
->msg
.info_ind
.plci
);
898 /* TODO: Eval Charging info / cause */
899 actcapi_info_resp(card
, &card
->bch
[chan
]);
906 /* MANUFACTURER_CONF */
909 /* MANUFACTURER_IND */
910 if (msg
->msg
.manuf_msg
== 3) {
911 memset(tmp
, 0, sizeof(tmp
));
913 &msg
->msg
.manufacturer_ind_err
.errstring
,
915 if (msg
->msg
.manufacturer_ind_err
.errcode
)
916 printk(KERN_WARNING
"act2000: %s\n", tmp
);
918 printk(KERN_DEBUG
"act2000: %s\n", tmp
);
919 if ((!strncmp(tmp
, "INFO: Trace buffer con", 22)) ||
920 (!strncmp(tmp
, "INFO: Compile Date/Tim", 22))) {
921 card
->flags
|= ACT2000_FLAGS_RUNNING
;
922 cmd
.command
= ISDN_STAT_RUN
;
923 cmd
.driver
= card
->myid
;
925 actcapi_manufacturer_req_net(card
);
926 actcapi_manufacturer_req_msn(card
);
927 actcapi_listen_req(card
);
928 card
->interface
.statcallb(&cmd
);
934 printk(KERN_WARNING
"act2000: UNHANDLED Message %04x\n", ccmd
);
943 actcapi_debug_caddr(actcapi_addr
*addr
)
947 printk(KERN_DEBUG
" Alen = %d\n", addr
->len
);
949 printk(KERN_DEBUG
" Atnp = 0x%02x\n", addr
->tnp
);
952 memcpy(tmp
, addr
->num
, addr
->len
- 1);
953 printk(KERN_DEBUG
" Anum = '%s'\n", tmp
);
958 actcapi_debug_ncpi(actcapi_ncpi
*ncpi
)
960 printk(KERN_DEBUG
" ncpi.len = %d\n", ncpi
->len
);
962 printk(KERN_DEBUG
" ncpi.lic = 0x%04x\n", ncpi
->lic
);
964 printk(KERN_DEBUG
" ncpi.hic = 0x%04x\n", ncpi
->hic
);
966 printk(KERN_DEBUG
" ncpi.ltc = 0x%04x\n", ncpi
->ltc
);
968 printk(KERN_DEBUG
" ncpi.htc = 0x%04x\n", ncpi
->htc
);
970 printk(KERN_DEBUG
" ncpi.loc = 0x%04x\n", ncpi
->loc
);
972 printk(KERN_DEBUG
" ncpi.hoc = 0x%04x\n", ncpi
->hoc
);
974 printk(KERN_DEBUG
" ncpi.mod = %d\n", ncpi
->modulo
);
978 actcapi_debug_dlpd(actcapi_dlpd
*dlpd
)
980 printk(KERN_DEBUG
" dlpd.len = %d\n", dlpd
->len
);
982 printk(KERN_DEBUG
" dlpd.dlen = 0x%04x\n", dlpd
->dlen
);
984 printk(KERN_DEBUG
" dlpd.laa = 0x%02x\n", dlpd
->laa
);
986 printk(KERN_DEBUG
" dlpd.lab = 0x%02x\n", dlpd
->lab
);
988 printk(KERN_DEBUG
" dlpd.modulo = %d\n", dlpd
->modulo
);
990 printk(KERN_DEBUG
" dlpd.win = %d\n", dlpd
->win
);
993 #ifdef DEBUG_DUMP_SKB
994 static void dump_skb(struct sk_buff
*skb
) {
1000 for (i
= 0; i
< skb
->len
; i
++) {
1001 t
+= sprintf(t
, "%02x ", *p
++ & 0xff);
1002 if ((i
& 0x0f) == 8) {
1003 printk(KERN_DEBUG
"dump: %s\n", tmp
);
1008 printk(KERN_DEBUG
"dump: %s\n", tmp
);
1013 actcapi_debug_msg(struct sk_buff
*skb
, int direction
)
1015 actcapi_msg
*msg
= (actcapi_msg
*)skb
->data
;
1020 #ifndef DEBUG_DATA_MSG
1021 if (msg
->hdr
.cmd
.cmd
== 0x86)
1025 #ifdef DEBUG_DUMP_SKB
1028 for (i
= 0; i
< num_valid_msg
; i
++)
1029 if ((msg
->hdr
.cmd
.cmd
== valid_msg
[i
].cmd
.cmd
) &&
1030 (msg
->hdr
.cmd
.subcmd
== valid_msg
[i
].cmd
.subcmd
)) {
1031 descr
= valid_msg
[i
].description
;
1034 printk(KERN_DEBUG
"%s %s msg\n", direction
?"Outgoing":"Incoming", descr
);
1035 printk(KERN_DEBUG
" ApplID = %d\n", msg
->hdr
.applicationID
);
1036 printk(KERN_DEBUG
" Len = %d\n", msg
->hdr
.len
);
1037 printk(KERN_DEBUG
" MsgNum = 0x%04x\n", msg
->hdr
.msgnum
);
1038 printk(KERN_DEBUG
" Cmd = 0x%02x\n", msg
->hdr
.cmd
.cmd
);
1039 printk(KERN_DEBUG
" SubCmd = 0x%02x\n", msg
->hdr
.cmd
.subcmd
);
1043 printk(KERN_DEBUG
" BLOCK = 0x%02x\n",
1044 msg
->msg
.data_b3_ind
.blocknr
);
1048 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1049 msg
->msg
.connect_conf
.plci
);
1050 printk(KERN_DEBUG
" Info = 0x%04x\n",
1051 msg
->msg
.connect_conf
.info
);
1055 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1056 msg
->msg
.connect_ind
.plci
);
1057 printk(KERN_DEBUG
" Contr = %d\n",
1058 msg
->msg
.connect_ind
.controller
);
1059 printk(KERN_DEBUG
" SI1 = %d\n",
1060 msg
->msg
.connect_ind
.si1
);
1061 printk(KERN_DEBUG
" SI2 = %d\n",
1062 msg
->msg
.connect_ind
.si2
);
1063 printk(KERN_DEBUG
" EAZ = '%c'\n",
1064 msg
->msg
.connect_ind
.eaz
);
1065 actcapi_debug_caddr(&msg
->msg
.connect_ind
.addr
);
1068 /* CONNECT ACTIVE IND */
1069 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1070 msg
->msg
.connect_active_ind
.plci
);
1071 actcapi_debug_caddr(&msg
->msg
.connect_active_ind
.addr
);
1075 printk(KERN_DEBUG
" Contr = %d\n",
1076 msg
->msg
.listen_conf
.controller
);
1077 printk(KERN_DEBUG
" Info = 0x%04x\n",
1078 msg
->msg
.listen_conf
.info
);
1082 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1083 msg
->msg
.info_ind
.plci
);
1084 printk(KERN_DEBUG
" Imsk = 0x%04x\n",
1085 msg
->msg
.info_ind
.nr
.mask
);
1086 if (msg
->hdr
.len
> 12) {
1087 int l
= msg
->hdr
.len
- 12;
1090 for (j
= 0; j
< l
; j
++)
1091 p
+= sprintf(p
, "%02x ", msg
->msg
.info_ind
.el
.display
[j
]);
1092 printk(KERN_DEBUG
" D = '%s'\n", tmp
);
1096 /* SELECT B2 PROTOCOL CONF */
1097 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1098 msg
->msg
.select_b2_protocol_conf
.plci
);
1099 printk(KERN_DEBUG
" Info = 0x%04x\n",
1100 msg
->msg
.select_b2_protocol_conf
.info
);
1103 /* SELECT B3 PROTOCOL CONF */
1104 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1105 msg
->msg
.select_b3_protocol_conf
.plci
);
1106 printk(KERN_DEBUG
" Info = 0x%04x\n",
1107 msg
->msg
.select_b3_protocol_conf
.info
);
1110 /* LISTEN B3 CONF */
1111 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1112 msg
->msg
.listen_b3_conf
.plci
);
1113 printk(KERN_DEBUG
" Info = 0x%04x\n",
1114 msg
->msg
.listen_b3_conf
.info
);
1117 /* CONNECT B3 IND */
1118 printk(KERN_DEBUG
" NCCI = 0x%04x\n",
1119 msg
->msg
.connect_b3_ind
.ncci
);
1120 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1121 msg
->msg
.connect_b3_ind
.plci
);
1122 actcapi_debug_ncpi(&msg
->msg
.connect_b3_ind
.ncpi
);
1125 /* CONNECT B3 ACTIVE IND */
1126 printk(KERN_DEBUG
" NCCI = 0x%04x\n",
1127 msg
->msg
.connect_b3_active_ind
.ncci
);
1128 actcapi_debug_ncpi(&msg
->msg
.connect_b3_active_ind
.ncpi
);
1131 /* MANUFACTURER IND */
1132 printk(KERN_DEBUG
" Mmsg = 0x%02x\n",
1133 msg
->msg
.manufacturer_ind_err
.manuf_msg
);
1134 switch (msg
->msg
.manufacturer_ind_err
.manuf_msg
) {
1136 printk(KERN_DEBUG
" Contr = %d\n",
1137 msg
->msg
.manufacturer_ind_err
.controller
);
1138 printk(KERN_DEBUG
" Code = 0x%08x\n",
1139 msg
->msg
.manufacturer_ind_err
.errcode
);
1140 memset(tmp
, 0, sizeof(tmp
));
1141 strncpy(tmp
, &msg
->msg
.manufacturer_ind_err
.errstring
,
1143 printk(KERN_DEBUG
" Emsg = '%s'\n", tmp
);
1149 printk(KERN_DEBUG
" Imsk = 0x%08x\n",
1150 msg
->msg
.listen_req
.infomask
);
1151 printk(KERN_DEBUG
" Emsk = 0x%04x\n",
1152 msg
->msg
.listen_req
.eazmask
);
1153 printk(KERN_DEBUG
" Smsk = 0x%04x\n",
1154 msg
->msg
.listen_req
.simask
);
1157 /* SELECT_B2_PROTOCOL_REQ */
1158 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1159 msg
->msg
.select_b2_protocol_req
.plci
);
1160 printk(KERN_DEBUG
" prot = 0x%02x\n",
1161 msg
->msg
.select_b2_protocol_req
.protocol
);
1162 if (msg
->hdr
.len
>= 11)
1163 printk(KERN_DEBUG
"No dlpd\n");
1165 actcapi_debug_dlpd(&msg
->msg
.select_b2_protocol_req
.dlpd
);
1169 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1170 msg
->msg
.connect_resp
.plci
);
1171 printk(KERN_DEBUG
" CAUSE = 0x%02x\n",
1172 msg
->msg
.connect_resp
.rejectcause
);
1175 /* CONNECT ACTIVE RESP */
1176 printk(KERN_DEBUG
" PLCI = 0x%04x\n",
1177 msg
->msg
.connect_active_resp
.plci
);