1 /* $Id: capi.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
2 *
3 * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
4 * CAPI encoder/decoder
5 *
6 * Author Fritz Elfert
7 * Copyright by Fritz Elfert <fritz@isdn4linux.de>
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 *
12 * Thanks to Friedemann Baitinger and IBM Germany
13 *
14 */
15
16 #define __NO_VERSION__
17 #include "act2000.h"
18 #include "capi.h"
19
20 static actcapi_msgdsc valid_msg[] = {
21 {{ 0x86, 0x02}, "DATA_B3_IND"}, /* DATA_B3_IND/CONF must be first because of speed!!! */
22 {{ 0x86, 0x01}, "DATA_B3_CONF"},
23 {{ 0x02, 0x01}, "CONNECT_CONF"},
24 {{ 0x02, 0x02}, "CONNECT_IND"},
25 {{ 0x09, 0x01}, "CONNECT_INFO_CONF"},
26 {{ 0x03, 0x02}, "CONNECT_ACTIVE_IND"},
27 {{ 0x04, 0x01}, "DISCONNECT_CONF"},
28 {{ 0x04, 0x02}, "DISCONNECT_IND"},
29 {{ 0x05, 0x01}, "LISTEN_CONF"},
30 {{ 0x06, 0x01}, "GET_PARAMS_CONF"},
31 {{ 0x07, 0x01}, "INFO_CONF"},
32 {{ 0x07, 0x02}, "INFO_IND"},
33 {{ 0x08, 0x01}, "DATA_CONF"},
34 {{ 0x08, 0x02}, "DATA_IND"},
35 {{ 0x40, 0x01}, "SELECT_B2_PROTOCOL_CONF"},
36 {{ 0x80, 0x01}, "SELECT_B3_PROTOCOL_CONF"},
37 {{ 0x81, 0x01}, "LISTEN_B3_CONF"},
38 {{ 0x82, 0x01}, "CONNECT_B3_CONF"},
39 {{ 0x82, 0x02}, "CONNECT_B3_IND"},
40 {{ 0x83, 0x02}, "CONNECT_B3_ACTIVE_IND"},
41 {{ 0x84, 0x01}, "DISCONNECT_B3_CONF"},
42 {{ 0x84, 0x02}, "DISCONNECT_B3_IND"},
43 {{ 0x85, 0x01}, "GET_B3_PARAMS_CONF"},
44 {{ 0x01, 0x01}, "RESET_B3_CONF"},
45 {{ 0x01, 0x02}, "RESET_B3_IND"},
46 /* {{ 0x87, 0x02, "HANDSET_IND"}, not implemented */
47 {{ 0xff, 0x01}, "MANUFACTURER_CONF"},
48 {{ 0xff, 0x02}, "MANUFACTURER_IND"},
49 #ifdef DEBUG_MSG
50 /* Requests */
51 {{ 0x01, 0x00}, "RESET_B3_REQ"},
52 {{ 0x02, 0x00}, "CONNECT_REQ"},
53 {{ 0x04, 0x00}, "DISCONNECT_REQ"},
54 {{ 0x05, 0x00}, "LISTEN_REQ"},
55 {{ 0x06, 0x00}, "GET_PARAMS_REQ"},
56 {{ 0x07, 0x00}, "INFO_REQ"},
57 {{ 0x08, 0x00}, "DATA_REQ"},
58 {{ 0x09, 0x00}, "CONNECT_INFO_REQ"},
59 {{ 0x40, 0x00}, "SELECT_B2_PROTOCOL_REQ"},
60 {{ 0x80, 0x00}, "SELECT_B3_PROTOCOL_REQ"},
61 {{ 0x81, 0x00}, "LISTEN_B3_REQ"},
62 {{ 0x82, 0x00}, "CONNECT_B3_REQ"},
63 {{ 0x84, 0x00}, "DISCONNECT_B3_REQ"},
64 {{ 0x85, 0x00}, "GET_B3_PARAMS_REQ"},
65 {{ 0x86, 0x00}, "DATA_B3_REQ"},
66 {{ 0xff, 0x00}, "MANUFACTURER_REQ"},
67 /* Responses */
68 {{ 0x01, 0x03}, "RESET_B3_RESP"},
69 {{ 0x02, 0x03}, "CONNECT_RESP"},
70 {{ 0x03, 0x03}, "CONNECT_ACTIVE_RESP"},
71 {{ 0x04, 0x03}, "DISCONNECT_RESP"},
72 {{ 0x07, 0x03}, "INFO_RESP"},
73 {{ 0x08, 0x03}, "DATA_RESP"},
74 {{ 0x82, 0x03}, "CONNECT_B3_RESP"},
75 {{ 0x83, 0x03}, "CONNECT_B3_ACTIVE_RESP"},
76 {{ 0x84, 0x03}, "DISCONNECT_B3_RESP"},
77 {{ 0x86, 0x03}, "DATA_B3_RESP"},
78 {{ 0xff, 0x03}, "MANUFACTURER_RESP"},
79 #endif
80 {{ 0x00, 0x00}, NULL},
81 };
82 #define num_valid_msg (sizeof(valid_msg)/sizeof(actcapi_msgdsc))
83 #define num_valid_imsg 27 /* MANUFACTURER_IND */
84
85 /*
86 * Check for a valid incoming CAPI message.
87 * Return:
88 * 0 = Invalid message
89 * 1 = Valid message, no B-Channel-data
90 * 2 = Valid message, B-Channel-data
91 */
92 int
actcapi_chkhdr(act2000_card * card,actcapi_msghdr * hdr)93 actcapi_chkhdr(act2000_card * card, actcapi_msghdr *hdr)
94 {
95 int i;
96
97 if (hdr->applicationID != 1)
98 return 0;
99 if (hdr->len < 9)
100 return 0;
101 for (i = 0; i < num_valid_imsg; i++)
102 if ((hdr->cmd.cmd == valid_msg[i].cmd.cmd) &&
103 (hdr->cmd.subcmd == valid_msg[i].cmd.subcmd)) {
104 return (i?1:2);
105 }
106 return 0;
107 }
108
109 #define ACTCAPI_MKHDR(l, c, s) { \
110 skb = alloc_skb(l + 8, GFP_ATOMIC); \
111 if (skb) { \
112 m = (actcapi_msg *)skb_put(skb, l + 8); \
113 m->hdr.len = l + 8; \
114 m->hdr.applicationID = 1; \
115 m->hdr.cmd.cmd = c; \
116 m->hdr.cmd.subcmd = s; \
117 m->hdr.msgnum = actcapi_nextsmsg(card); \
118 } else m = NULL;\
119 }
120
121 #define ACTCAPI_CHKSKB if (!skb) { \
122 printk(KERN_WARNING "actcapi: alloc_skb failed\n"); \
123 return; \
124 }
125
126 #define ACTCAPI_QUEUE_TX { \
127 actcapi_debug_msg(skb, 1); \
128 skb_queue_tail(&card->sndq, skb); \
129 act2000_schedule_tx(card); \
130 }
131
132 int
actcapi_listen_req(act2000_card * card)133 actcapi_listen_req(act2000_card *card)
134 {
135 __u16 eazmask = 0;
136 int i;
137 actcapi_msg *m;
138 struct sk_buff *skb;
139
140 for (i = 0; i < ACT2000_BCH; i++)
141 eazmask |= card->bch[i].eazmask;
142 ACTCAPI_MKHDR(9, 0x05, 0x00);
143 if (!skb) {
144 printk(KERN_WARNING "actcapi: alloc_skb failed\n");
145 return -ENOMEM;
146 }
147 m->msg.listen_req.controller = 0;
148 m->msg.listen_req.infomask = 0x3f; /* All information */
149 m->msg.listen_req.eazmask = eazmask;
150 m->msg.listen_req.simask = (eazmask)?0x86:0; /* All SI's */
151 ACTCAPI_QUEUE_TX;
152 return 0;
153 }
154
155 int
actcapi_connect_req(act2000_card * card,act2000_chan * chan,char * phone,char eaz,int si1,int si2)156 actcapi_connect_req(act2000_card *card, act2000_chan *chan, char *phone,
157 char eaz, int si1, int si2)
158 {
159 actcapi_msg *m;
160 struct sk_buff *skb;
161
162 ACTCAPI_MKHDR((11 + strlen(phone)), 0x02, 0x00);
163 if (!skb) {
164 printk(KERN_WARNING "actcapi: alloc_skb failed\n");
165 chan->fsm_state = ACT2000_STATE_NULL;
166 return -ENOMEM;
167 }
168 m->msg.connect_req.controller = 0;
169 m->msg.connect_req.bchan = 0x83;
170 m->msg.connect_req.infomask = 0x3f;
171 m->msg.connect_req.si1 = si1;
172 m->msg.connect_req.si2 = si2;
173 m->msg.connect_req.eaz = eaz?eaz:'0';
174 m->msg.connect_req.addr.len = strlen(phone) + 1;
175 m->msg.connect_req.addr.tnp = 0x81;
176 memcpy(m->msg.connect_req.addr.num, phone, strlen(phone));
177 chan->callref = m->hdr.msgnum;
178 ACTCAPI_QUEUE_TX;
179 return 0;
180 }
181
182 static void
actcapi_connect_b3_req(act2000_card * card,act2000_chan * chan)183 actcapi_connect_b3_req(act2000_card *card, act2000_chan *chan)
184 {
185 actcapi_msg *m;
186 struct sk_buff *skb;
187
188 ACTCAPI_MKHDR(17, 0x82, 0x00);
189 ACTCAPI_CHKSKB;
190 m->msg.connect_b3_req.plci = chan->plci;
191 memset(&m->msg.connect_b3_req.ncpi, 0,
192 sizeof(m->msg.connect_b3_req.ncpi));
193 m->msg.connect_b3_req.ncpi.len = 13;
194 m->msg.connect_b3_req.ncpi.modulo = 8;
195 ACTCAPI_QUEUE_TX;
196 }
197
198 /*
199 * Set net type (1TR6) or (EDSS1)
200 */
201 int
actcapi_manufacturer_req_net(act2000_card * card)202 actcapi_manufacturer_req_net(act2000_card *card)
203 {
204 actcapi_msg *m;
205 struct sk_buff *skb;
206
207 ACTCAPI_MKHDR(5, 0xff, 0x00);
208 if (!skb) {
209 printk(KERN_WARNING "actcapi: alloc_skb failed\n");
210 return -ENOMEM;
211 }
212 m->msg.manufacturer_req_net.manuf_msg = 0x11;
213 m->msg.manufacturer_req_net.controller = 1;
214 m->msg.manufacturer_req_net.nettype = (card->ptype == ISDN_PTYPE_EURO)?1:0;
215 ACTCAPI_QUEUE_TX;
216 printk(KERN_INFO "act2000 %s: D-channel protocol now %s\n",
217 card->interface.id, (card->ptype == ISDN_PTYPE_EURO)?"euro":"1tr6");
218 card->interface.features &=
219 ~(ISDN_FEATURE_P_UNKNOWN | ISDN_FEATURE_P_EURO | ISDN_FEATURE_P_1TR6);
220 card->interface.features |=
221 ((card->ptype == ISDN_PTYPE_EURO)?ISDN_FEATURE_P_EURO:ISDN_FEATURE_P_1TR6);
222 return 0;
223 }
224
225 /*
226 * Switch V.42 on or off
227 */
228 int
actcapi_manufacturer_req_v42(act2000_card * card,ulong arg)229 actcapi_manufacturer_req_v42(act2000_card *card, ulong arg)
230 {
231 actcapi_msg *m;
232 struct sk_buff *skb;
233
234 ACTCAPI_MKHDR(8, 0xff, 0x00);
235 if (!skb) {
236
237 printk(KERN_WARNING "actcapi: alloc_skb failed\n");
238 return -ENOMEM;
239 }
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);
243 ACTCAPI_QUEUE_TX;
244 return 0;
245 }
246
247 /*
248 * Set error-handler
249 */
250 int
actcapi_manufacturer_req_errh(act2000_card * card)251 actcapi_manufacturer_req_errh(act2000_card *card)
252 {
253 actcapi_msg *m;
254 struct sk_buff *skb;
255
256 ACTCAPI_MKHDR(4, 0xff, 0x00);
257 if (!skb) {
258
259 printk(KERN_WARNING "actcapi: alloc_skb failed\n");
260 return -ENOMEM;
261 }
262 m->msg.manufacturer_req_err.manuf_msg = 0x03;
263 m->msg.manufacturer_req_err.controller = 0;
264 ACTCAPI_QUEUE_TX;
265 return 0;
266 }
267
268 /*
269 * Set MSN-Mapping.
270 */
271 int
actcapi_manufacturer_req_msn(act2000_card * card)272 actcapi_manufacturer_req_msn(act2000_card *card)
273 {
274 msn_entry *p = card->msn_list;
275 actcapi_msg *m;
276 struct sk_buff *skb;
277 int len;
278
279 while (p) {
280 int i;
281
282 len = strlen(p->msn);
283 for (i = 0; i < 2; i++) {
284 ACTCAPI_MKHDR(6 + len, 0xff, 0x00);
285 if (!skb) {
286 printk(KERN_WARNING "actcapi: alloc_skb failed\n");
287 return -ENOMEM;
288 }
289 m->msg.manufacturer_req_msn.manuf_msg = 0x13 + i;
290 m->msg.manufacturer_req_msn.controller = 0;
291 m->msg.manufacturer_req_msn.msnmap.eaz = p->eaz;
292 m->msg.manufacturer_req_msn.msnmap.len = len;
293 memcpy(m->msg.manufacturer_req_msn.msnmap.msn, p->msn, len);
294 ACTCAPI_QUEUE_TX;
295 }
296 p = p->next;
297 }
298 return 0;
299 }
300
301 void
actcapi_select_b2_protocol_req(act2000_card * card,act2000_chan * chan)302 actcapi_select_b2_protocol_req(act2000_card *card, act2000_chan *chan)
303 {
304 actcapi_msg *m;
305 struct sk_buff *skb;
306
307 ACTCAPI_MKHDR(10, 0x40, 0x00);
308 ACTCAPI_CHKSKB;
309 m->msg.select_b2_protocol_req.plci = chan->plci;
310 memset(&m->msg.select_b2_protocol_req.dlpd, 0,
311 sizeof(m->msg.select_b2_protocol_req.dlpd));
312 m->msg.select_b2_protocol_req.dlpd.len = 6;
313 switch (chan->l2prot) {
314 case ISDN_PROTO_L2_TRANS:
315 m->msg.select_b2_protocol_req.protocol = 0x03;
316 m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
317 break;
318 case ISDN_PROTO_L2_HDLC:
319 m->msg.select_b2_protocol_req.protocol = 0x02;
320 m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
321 break;
322 case ISDN_PROTO_L2_X75I:
323 case ISDN_PROTO_L2_X75UI:
324 case ISDN_PROTO_L2_X75BUI:
325 m->msg.select_b2_protocol_req.protocol = 0x01;
326 m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
327 m->msg.select_b2_protocol_req.dlpd.laa = 3;
328 m->msg.select_b2_protocol_req.dlpd.lab = 1;
329 m->msg.select_b2_protocol_req.dlpd.win = 7;
330 m->msg.select_b2_protocol_req.dlpd.modulo = 8;
331 break;
332 }
333 ACTCAPI_QUEUE_TX;
334 }
335
336 static void
actcapi_select_b3_protocol_req(act2000_card * card,act2000_chan * chan)337 actcapi_select_b3_protocol_req(act2000_card *card, act2000_chan *chan)
338 {
339 actcapi_msg *m;
340 struct sk_buff *skb;
341
342 ACTCAPI_MKHDR(17, 0x80, 0x00);
343 ACTCAPI_CHKSKB;
344 m->msg.select_b3_protocol_req.plci = chan->plci;
345 memset(&m->msg.select_b3_protocol_req.ncpd, 0,
346 sizeof(m->msg.select_b3_protocol_req.ncpd));
347 switch (chan->l3prot) {
348 case ISDN_PROTO_L3_TRANS:
349 m->msg.select_b3_protocol_req.protocol = 0x04;
350 m->msg.select_b3_protocol_req.ncpd.len = 13;
351 m->msg.select_b3_protocol_req.ncpd.modulo = 8;
352 break;
353 }
354 ACTCAPI_QUEUE_TX;
355 }
356
357 static void
actcapi_listen_b3_req(act2000_card * card,act2000_chan * chan)358 actcapi_listen_b3_req(act2000_card *card, act2000_chan *chan)
359 {
360 actcapi_msg *m;
361 struct sk_buff *skb;
362
363 ACTCAPI_MKHDR(2, 0x81, 0x00);
364 ACTCAPI_CHKSKB;
365 m->msg.listen_b3_req.plci = chan->plci;
366 ACTCAPI_QUEUE_TX;
367 }
368
369 static void
actcapi_disconnect_req(act2000_card * card,act2000_chan * chan)370 actcapi_disconnect_req(act2000_card *card, act2000_chan *chan)
371 {
372 actcapi_msg *m;
373 struct sk_buff *skb;
374
375 ACTCAPI_MKHDR(3, 0x04, 0x00);
376 ACTCAPI_CHKSKB;
377 m->msg.disconnect_req.plci = chan->plci;
378 m->msg.disconnect_req.cause = 0;
379 ACTCAPI_QUEUE_TX;
380 }
381
382 void
actcapi_disconnect_b3_req(act2000_card * card,act2000_chan * chan)383 actcapi_disconnect_b3_req(act2000_card *card, act2000_chan *chan)
384 {
385 actcapi_msg *m;
386 struct sk_buff *skb;
387
388 ACTCAPI_MKHDR(17, 0x84, 0x00);
389 ACTCAPI_CHKSKB;
390 m->msg.disconnect_b3_req.ncci = chan->ncci;
391 memset(&m->msg.disconnect_b3_req.ncpi, 0,
392 sizeof(m->msg.disconnect_b3_req.ncpi));
393 m->msg.disconnect_b3_req.ncpi.len = 13;
394 m->msg.disconnect_b3_req.ncpi.modulo = 8;
395 chan->fsm_state = ACT2000_STATE_BHWAIT;
396 ACTCAPI_QUEUE_TX;
397 }
398
399 void
actcapi_connect_resp(act2000_card * card,act2000_chan * chan,__u8 cause)400 actcapi_connect_resp(act2000_card *card, act2000_chan *chan, __u8 cause)
401 {
402 actcapi_msg *m;
403 struct sk_buff *skb;
404
405 ACTCAPI_MKHDR(3, 0x02, 0x03);
406 ACTCAPI_CHKSKB;
407 m->msg.connect_resp.plci = chan->plci;
408 m->msg.connect_resp.rejectcause = cause;
409 if (cause) {
410 chan->fsm_state = ACT2000_STATE_NULL;
411 chan->plci = 0x8000;
412 } else
413 chan->fsm_state = ACT2000_STATE_IWAIT;
414 ACTCAPI_QUEUE_TX;
415 }
416
417 static void
actcapi_connect_active_resp(act2000_card * card,act2000_chan * chan)418 actcapi_connect_active_resp(act2000_card *card, act2000_chan *chan)
419 {
420 actcapi_msg *m;
421 struct sk_buff *skb;
422
423 ACTCAPI_MKHDR(2, 0x03, 0x03);
424 ACTCAPI_CHKSKB;
425 m->msg.connect_resp.plci = chan->plci;
426 if (chan->fsm_state == ACT2000_STATE_IWAIT)
427 chan->fsm_state = ACT2000_STATE_IBWAIT;
428 ACTCAPI_QUEUE_TX;
429 }
430
431 static void
actcapi_connect_b3_resp(act2000_card * card,act2000_chan * chan,__u8 rejectcause)432 actcapi_connect_b3_resp(act2000_card *card, act2000_chan *chan, __u8 rejectcause)
433 {
434 actcapi_msg *m;
435 struct sk_buff *skb;
436
437 ACTCAPI_MKHDR((rejectcause?3:17), 0x82, 0x03);
438 ACTCAPI_CHKSKB;
439 m->msg.connect_b3_resp.ncci = chan->ncci;
440 m->msg.connect_b3_resp.rejectcause = rejectcause;
441 if (!rejectcause) {
442 memset(&m->msg.connect_b3_resp.ncpi, 0,
443 sizeof(m->msg.connect_b3_resp.ncpi));
444 m->msg.connect_b3_resp.ncpi.len = 13;
445 m->msg.connect_b3_resp.ncpi.modulo = 8;
446 chan->fsm_state = ACT2000_STATE_BWAIT;
447 }
448 ACTCAPI_QUEUE_TX;
449 }
450
451 static void
actcapi_connect_b3_active_resp(act2000_card * card,act2000_chan * chan)452 actcapi_connect_b3_active_resp(act2000_card *card, act2000_chan *chan)
453 {
454 actcapi_msg *m;
455 struct sk_buff *skb;
456
457 ACTCAPI_MKHDR(2, 0x83, 0x03);
458 ACTCAPI_CHKSKB;
459 m->msg.connect_b3_active_resp.ncci = chan->ncci;
460 chan->fsm_state = ACT2000_STATE_ACTIVE;
461 ACTCAPI_QUEUE_TX;
462 }
463
464 static void
actcapi_info_resp(act2000_card * card,act2000_chan * chan)465 actcapi_info_resp(act2000_card *card, act2000_chan *chan)
466 {
467 actcapi_msg *m;
468 struct sk_buff *skb;
469
470 ACTCAPI_MKHDR(2, 0x07, 0x03);
471 ACTCAPI_CHKSKB;
472 m->msg.info_resp.plci = chan->plci;
473 ACTCAPI_QUEUE_TX;
474 }
475
476 static void
actcapi_disconnect_b3_resp(act2000_card * card,act2000_chan * chan)477 actcapi_disconnect_b3_resp(act2000_card *card, act2000_chan *chan)
478 {
479 actcapi_msg *m;
480 struct sk_buff *skb;
481
482 ACTCAPI_MKHDR(2, 0x84, 0x03);
483 ACTCAPI_CHKSKB;
484 m->msg.disconnect_b3_resp.ncci = chan->ncci;
485 chan->ncci = 0x8000;
486 chan->queued = 0;
487 ACTCAPI_QUEUE_TX;
488 }
489
490 static void
actcapi_disconnect_resp(act2000_card * card,act2000_chan * chan)491 actcapi_disconnect_resp(act2000_card *card, act2000_chan *chan)
492 {
493 actcapi_msg *m;
494 struct sk_buff *skb;
495
496 ACTCAPI_MKHDR(2, 0x04, 0x03);
497 ACTCAPI_CHKSKB;
498 m->msg.disconnect_resp.plci = chan->plci;
499 chan->plci = 0x8000;
500 ACTCAPI_QUEUE_TX;
501 }
502
503 static int
new_plci(act2000_card * card,__u16 plci)504 new_plci(act2000_card *card, __u16 plci)
505 {
506 int i;
507 for (i = 0; i < ACT2000_BCH; i++)
508 if (card->bch[i].plci == 0x8000) {
509 card->bch[i].plci = plci;
510 return i;
511 }
512 return -1;
513 }
514
515 static int
find_plci(act2000_card * card,__u16 plci)516 find_plci(act2000_card *card, __u16 plci)
517 {
518 int i;
519 for (i = 0; i < ACT2000_BCH; i++)
520 if (card->bch[i].plci == plci)
521 return i;
522 return -1;
523 }
524
525 static int
find_ncci(act2000_card * card,__u16 ncci)526 find_ncci(act2000_card *card, __u16 ncci)
527 {
528 int i;
529 for (i = 0; i < ACT2000_BCH; i++)
530 if (card->bch[i].ncci == ncci)
531 return i;
532 return -1;
533 }
534
535 static int
find_dialing(act2000_card * card,__u16 callref)536 find_dialing(act2000_card *card, __u16 callref)
537 {
538 int i;
539 for (i = 0; i < ACT2000_BCH; i++)
540 if ((card->bch[i].callref == callref) &&
541 (card->bch[i].fsm_state == ACT2000_STATE_OCALL))
542 return i;
543 return -1;
544 }
545
546 static int
actcapi_data_b3_ind(act2000_card * card,struct sk_buff * skb)547 actcapi_data_b3_ind(act2000_card *card, struct sk_buff *skb) {
548 __u16 plci;
549 __u16 ncci;
550 __u16 controller;
551 __u8 blocknr;
552 int chan;
553 actcapi_msg *msg = (actcapi_msg *)skb->data;
554
555 EVAL_NCCI(msg->msg.data_b3_ind.fakencci, plci, controller, ncci);
556 chan = find_ncci(card, ncci);
557 if (chan < 0)
558 return 0;
559 if (card->bch[chan].fsm_state != ACT2000_STATE_ACTIVE)
560 return 0;
561 if (card->bch[chan].plci != plci)
562 return 0;
563 blocknr = msg->msg.data_b3_ind.blocknr;
564 skb_pull(skb, 19);
565 card->interface.rcvcallb_skb(card->myid, chan, skb);
566 if (!(skb = alloc_skb(11, GFP_ATOMIC))) {
567 printk(KERN_WARNING "actcapi: alloc_skb failed\n");
568 return 1;
569 }
570 msg = (actcapi_msg *)skb_put(skb, 11);
571 msg->hdr.len = 11;
572 msg->hdr.applicationID = 1;
573 msg->hdr.cmd.cmd = 0x86;
574 msg->hdr.cmd.subcmd = 0x03;
575 msg->hdr.msgnum = actcapi_nextsmsg(card);
576 msg->msg.data_b3_resp.ncci = ncci;
577 msg->msg.data_b3_resp.blocknr = blocknr;
578 ACTCAPI_QUEUE_TX;
579 return 1;
580 }
581
582 /*
583 * Walk over ackq, unlink DATA_B3_REQ from it, if
584 * ncci and blocknr are matching.
585 * Decrement queued-bytes counter.
586 */
587 static int
handle_ack(act2000_card * card,act2000_chan * chan,__u8 blocknr)588 handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) {
589 unsigned long flags;
590 struct sk_buff *skb;
591 struct sk_buff *tmp;
592 struct actcapi_msg *m;
593 int ret = 0;
594
595 save_flags(flags);
596 cli();
597 skb = skb_peek(&card->ackq);
598 restore_flags(flags);
599 if (!skb) {
600 printk(KERN_WARNING "act2000: handle_ack nothing found!\n");
601 return 0;
602 }
603 tmp = skb;
604 while (1) {
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);
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;
613 dev_kfree_skb(tmp);
614 if (chan->queued < 0)
615 chan->queued = 0;
616 return ret;
617 }
618 save_flags(flags);
619 cli();
620 tmp = skb_peek((struct sk_buff_head *)tmp);
621 restore_flags(flags);
622 if ((tmp == skb) || (tmp == NULL)) {
623 /* reached end of queue */
624 printk(KERN_WARNING "act2000: handle_ack nothing found!\n");
625 return 0;
626 }
627 }
628 }
629
630 void
actcapi_dispatch(act2000_card * card)631 actcapi_dispatch(act2000_card *card)
632 {
633 struct sk_buff *skb;
634 actcapi_msg *msg;
635 __u16 ccmd;
636 int chan;
637 int len;
638 act2000_chan *ctmp;
639 isdn_ctrl cmd;
640 char tmp[170];
641
642 while ((skb = skb_dequeue(&card->rcvq))) {
643 actcapi_debug_msg(skb, 0);
644 msg = (actcapi_msg *)skb->data;
645 ccmd = ((msg->hdr.cmd.cmd << 8) | msg->hdr.cmd.subcmd);
646 switch (ccmd) {
647 case 0x8602:
648 /* DATA_B3_IND */
649 if (actcapi_data_b3_ind(card, skb))
650 return;
651 break;
652 case 0x8601:
653 /* DATA_B3_CONF */
654 chan = find_ncci(card, msg->msg.data_b3_conf.ncci);
655 if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_ACTIVE)) {
656 if (msg->msg.data_b3_conf.info != 0)
657 printk(KERN_WARNING "act2000: DATA_B3_CONF: %04x\n",
658 msg->msg.data_b3_conf.info);
659 len = handle_ack(card, &card->bch[chan],
660 msg->msg.data_b3_conf.blocknr);
661 if (len) {
662 cmd.driver = card->myid;
663 cmd.command = ISDN_STAT_BSENT;
664 cmd.arg = chan;
665 cmd.parm.length = len;
666 card->interface.statcallb(&cmd);
667 }
668 }
669 break;
670 case 0x0201:
671 /* CONNECT_CONF */
672 chan = find_dialing(card, msg->hdr.msgnum);
673 if (chan >= 0) {
674 if (msg->msg.connect_conf.info) {
675 card->bch[chan].fsm_state = ACT2000_STATE_NULL;
676 cmd.driver = card->myid;
677 cmd.command = ISDN_STAT_DHUP;
678 cmd.arg = chan;
679 card->interface.statcallb(&cmd);
680 } else {
681 card->bch[chan].fsm_state = ACT2000_STATE_OWAIT;
682 card->bch[chan].plci = msg->msg.connect_conf.plci;
683 }
684 }
685 break;
686 case 0x0202:
687 /* CONNECT_IND */
688 chan = new_plci(card, msg->msg.connect_ind.plci);
689 if (chan < 0) {
690 ctmp = (act2000_chan *)tmp;
691 ctmp->plci = msg->msg.connect_ind.plci;
692 actcapi_connect_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
693 } else {
694 card->bch[chan].fsm_state = ACT2000_STATE_ICALL;
695 cmd.driver = card->myid;
696 cmd.command = ISDN_STAT_ICALL;
697 cmd.arg = chan;
698 cmd.parm.setup.si1 = msg->msg.connect_ind.si1;
699 cmd.parm.setup.si2 = msg->msg.connect_ind.si2;
700 if (card->ptype == ISDN_PTYPE_EURO)
701 strcpy(cmd.parm.setup.eazmsn,
702 act2000_find_eaz(card, msg->msg.connect_ind.eaz));
703 else {
704 cmd.parm.setup.eazmsn[0] = msg->msg.connect_ind.eaz;
705 cmd.parm.setup.eazmsn[1] = 0;
706 }
707 memset(cmd.parm.setup.phone, 0, sizeof(cmd.parm.setup.phone));
708 memcpy(cmd.parm.setup.phone, msg->msg.connect_ind.addr.num,
709 msg->msg.connect_ind.addr.len - 1);
710 cmd.parm.setup.plan = msg->msg.connect_ind.addr.tnp;
711 cmd.parm.setup.screen = 0;
712 if (card->interface.statcallb(&cmd) == 2)
713 actcapi_connect_resp(card, &card->bch[chan], 0x15); /* Reject Call */
714 }
715 break;
716 case 0x0302:
717 /* CONNECT_ACTIVE_IND */
718 chan = find_plci(card, msg->msg.connect_active_ind.plci);
719 if (chan >= 0)
720 switch (card->bch[chan].fsm_state) {
721 case ACT2000_STATE_IWAIT:
722 actcapi_connect_active_resp(card, &card->bch[chan]);
723 break;
724 case ACT2000_STATE_OWAIT:
725 actcapi_connect_active_resp(card, &card->bch[chan]);
726 actcapi_select_b2_protocol_req(card, &card->bch[chan]);
727 break;
728 }
729 break;
730 case 0x8202:
731 /* CONNECT_B3_IND */
732 chan = find_plci(card, msg->msg.connect_b3_ind.plci);
733 if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_IBWAIT)) {
734 card->bch[chan].ncci = msg->msg.connect_b3_ind.ncci;
735 actcapi_connect_b3_resp(card, &card->bch[chan], 0);
736 } else {
737 ctmp = (act2000_chan *)tmp;
738 ctmp->ncci = msg->msg.connect_b3_ind.ncci;
739 actcapi_connect_b3_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
740 }
741 break;
742 case 0x8302:
743 /* CONNECT_B3_ACTIVE_IND */
744 chan = find_ncci(card, msg->msg.connect_b3_active_ind.ncci);
745 if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BWAIT)) {
746 actcapi_connect_b3_active_resp(card, &card->bch[chan]);
747 cmd.driver = card->myid;
748 cmd.command = ISDN_STAT_BCONN;
749 cmd.arg = chan;
750 card->interface.statcallb(&cmd);
751 }
752 break;
753 case 0x8402:
754 /* DISCONNECT_B3_IND */
755 chan = find_ncci(card, msg->msg.disconnect_b3_ind.ncci);
756 if (chan >= 0) {
757 ctmp = &card->bch[chan];
758 actcapi_disconnect_b3_resp(card, ctmp);
759 switch (ctmp->fsm_state) {
760 case ACT2000_STATE_ACTIVE:
761 ctmp->fsm_state = ACT2000_STATE_DHWAIT2;
762 cmd.driver = card->myid;
763 cmd.command = ISDN_STAT_BHUP;
764 cmd.arg = chan;
765 card->interface.statcallb(&cmd);
766 break;
767 case ACT2000_STATE_BHWAIT2:
768 actcapi_disconnect_req(card, ctmp);
769 ctmp->fsm_state = ACT2000_STATE_DHWAIT;
770 cmd.driver = card->myid;
771 cmd.command = ISDN_STAT_BHUP;
772 cmd.arg = chan;
773 card->interface.statcallb(&cmd);
774 break;
775 }
776 }
777 break;
778 case 0x0402:
779 /* DISCONNECT_IND */
780 chan = find_plci(card, msg->msg.disconnect_ind.plci);
781 if (chan >= 0) {
782 ctmp = &card->bch[chan];
783 actcapi_disconnect_resp(card, ctmp);
784 ctmp->fsm_state = ACT2000_STATE_NULL;
785 cmd.driver = card->myid;
786 cmd.command = ISDN_STAT_DHUP;
787 cmd.arg = chan;
788 card->interface.statcallb(&cmd);
789 } else {
790 ctmp = (act2000_chan *)tmp;
791 ctmp->plci = msg->msg.disconnect_ind.plci;
792 actcapi_disconnect_resp(card, ctmp);
793 }
794 break;
795 case 0x4001:
796 /* SELECT_B2_PROTOCOL_CONF */
797 chan = find_plci(card, msg->msg.select_b2_protocol_conf.plci);
798 if (chan >= 0)
799 switch (card->bch[chan].fsm_state) {
800 case ACT2000_STATE_ICALL:
801 case ACT2000_STATE_OWAIT:
802 ctmp = &card->bch[chan];
803 if (msg->msg.select_b2_protocol_conf.info == 0)
804 actcapi_select_b3_protocol_req(card, ctmp);
805 else {
806 ctmp->fsm_state = ACT2000_STATE_NULL;
807 cmd.driver = card->myid;
808 cmd.command = ISDN_STAT_DHUP;
809 cmd.arg = chan;
810 card->interface.statcallb(&cmd);
811 }
812 break;
813 }
814 break;
815 case 0x8001:
816 /* SELECT_B3_PROTOCOL_CONF */
817 chan = find_plci(card, msg->msg.select_b3_protocol_conf.plci);
818 if (chan >= 0)
819 switch (card->bch[chan].fsm_state) {
820 case ACT2000_STATE_ICALL:
821 case ACT2000_STATE_OWAIT:
822 ctmp = &card->bch[chan];
823 if (msg->msg.select_b3_protocol_conf.info == 0)
824 actcapi_listen_b3_req(card, ctmp);
825 else {
826 ctmp->fsm_state = ACT2000_STATE_NULL;
827 cmd.driver = card->myid;
828 cmd.command = ISDN_STAT_DHUP;
829 cmd.arg = chan;
830 card->interface.statcallb(&cmd);
831 }
832 }
833 break;
834 case 0x8101:
835 /* LISTEN_B3_CONF */
836 chan = find_plci(card, msg->msg.listen_b3_conf.plci);
837 if (chan >= 0)
838 switch (card->bch[chan].fsm_state) {
839 case ACT2000_STATE_ICALL:
840 ctmp = &card->bch[chan];
841 if (msg->msg.listen_b3_conf.info == 0)
842 actcapi_connect_resp(card, ctmp, 0);
843 else {
844 ctmp->fsm_state = ACT2000_STATE_NULL;
845 cmd.driver = card->myid;
846 cmd.command = ISDN_STAT_DHUP;
847 cmd.arg = chan;
848 card->interface.statcallb(&cmd);
849 }
850 break;
851 case ACT2000_STATE_OWAIT:
852 ctmp = &card->bch[chan];
853 if (msg->msg.listen_b3_conf.info == 0) {
854 actcapi_connect_b3_req(card, ctmp);
855 ctmp->fsm_state = ACT2000_STATE_OBWAIT;
856 cmd.driver = card->myid;
857 cmd.command = ISDN_STAT_DCONN;
858 cmd.arg = chan;
859 card->interface.statcallb(&cmd);
860 } else {
861 ctmp->fsm_state = ACT2000_STATE_NULL;
862 cmd.driver = card->myid;
863 cmd.command = ISDN_STAT_DHUP;
864 cmd.arg = chan;
865 card->interface.statcallb(&cmd);
866 }
867 break;
868 }
869 break;
870 case 0x8201:
871 /* CONNECT_B3_CONF */
872 chan = find_plci(card, msg->msg.connect_b3_conf.plci);
873 if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_OBWAIT)) {
874 ctmp = &card->bch[chan];
875 if (msg->msg.connect_b3_conf.info) {
876 ctmp->fsm_state = ACT2000_STATE_NULL;
877 cmd.driver = card->myid;
878 cmd.command = ISDN_STAT_DHUP;
879 cmd.arg = chan;
880 card->interface.statcallb(&cmd);
881 } else {
882 ctmp->ncci = msg->msg.connect_b3_conf.ncci;
883 ctmp->fsm_state = ACT2000_STATE_BWAIT;
884 }
885 }
886 break;
887 case 0x8401:
888 /* DISCONNECT_B3_CONF */
889 chan = find_ncci(card, msg->msg.disconnect_b3_conf.ncci);
890 if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BHWAIT))
891 card->bch[chan].fsm_state = ACT2000_STATE_BHWAIT2;
892 break;
893 case 0x0702:
894 /* INFO_IND */
895 chan = find_plci(card, msg->msg.info_ind.plci);
896 if (chan >= 0)
897 /* TODO: Eval Charging info / cause */
898 actcapi_info_resp(card, &card->bch[chan]);
899 break;
900 case 0x0401:
901 /* LISTEN_CONF */
902 case 0x0501:
903 /* LISTEN_CONF */
904 case 0xff01:
905 /* MANUFACTURER_CONF */
906 break;
907 case 0xff02:
908 /* MANUFACTURER_IND */
909 if (msg->msg.manuf_msg == 3) {
910 memset(tmp, 0, sizeof(tmp));
911 strncpy(tmp,
912 &msg->msg.manufacturer_ind_err.errstring,
913 msg->hdr.len - 16);
914 if (msg->msg.manufacturer_ind_err.errcode)
915 printk(KERN_WARNING "act2000: %s\n", tmp);
916 else {
917 printk(KERN_DEBUG "act2000: %s\n", tmp);
918 if ((!strncmp(tmp, "INFO: Trace buffer con", 22)) ||
919 (!strncmp(tmp, "INFO: Compile Date/Tim", 22))) {
920 card->flags |= ACT2000_FLAGS_RUNNING;
921 cmd.command = ISDN_STAT_RUN;
922 cmd.driver = card->myid;
923 cmd.arg = 0;
924 actcapi_manufacturer_req_net(card);
925 actcapi_manufacturer_req_msn(card);
926 actcapi_listen_req(card);
927 card->interface.statcallb(&cmd);
928 }
929 }
930 }
931 break;
932 default:
933 printk(KERN_WARNING "act2000: UNHANDLED Message %04x\n", ccmd);
934 break;
935 }
936 dev_kfree_skb(skb);
937 }
938 }
939
940 #ifdef DEBUG_MSG
941 static void
actcapi_debug_caddr(actcapi_addr * addr)942 actcapi_debug_caddr(actcapi_addr *addr)
943 {
944 char tmp[30];
945
946 printk(KERN_DEBUG " Alen = %d\n", addr->len);
947 if (addr->len > 0)
948 printk(KERN_DEBUG " Atnp = 0x%02x\n", addr->tnp);
949 if (addr->len > 1) {
950 memset(tmp, 0, 30);
951 memcpy(tmp, addr->num, addr->len - 1);
952 printk(KERN_DEBUG " Anum = '%s'\n", tmp);
953 }
954 }
955
956 static void
actcapi_debug_ncpi(actcapi_ncpi * ncpi)957 actcapi_debug_ncpi(actcapi_ncpi *ncpi)
958 {
959 printk(KERN_DEBUG " ncpi.len = %d\n", ncpi->len);
960 if (ncpi->len >= 2)
961 printk(KERN_DEBUG " ncpi.lic = 0x%04x\n", ncpi->lic);
962 if (ncpi->len >= 4)
963 printk(KERN_DEBUG " ncpi.hic = 0x%04x\n", ncpi->hic);
964 if (ncpi->len >= 6)
965 printk(KERN_DEBUG " ncpi.ltc = 0x%04x\n", ncpi->ltc);
966 if (ncpi->len >= 8)
967 printk(KERN_DEBUG " ncpi.htc = 0x%04x\n", ncpi->htc);
968 if (ncpi->len >= 10)
969 printk(KERN_DEBUG " ncpi.loc = 0x%04x\n", ncpi->loc);
970 if (ncpi->len >= 12)
971 printk(KERN_DEBUG " ncpi.hoc = 0x%04x\n", ncpi->hoc);
972 if (ncpi->len >= 13)
973 printk(KERN_DEBUG " ncpi.mod = %d\n", ncpi->modulo);
974 }
975
976 static void
actcapi_debug_dlpd(actcapi_dlpd * dlpd)977 actcapi_debug_dlpd(actcapi_dlpd *dlpd)
978 {
979 printk(KERN_DEBUG " dlpd.len = %d\n", dlpd->len);
980 if (dlpd->len >= 2)
981 printk(KERN_DEBUG " dlpd.dlen = 0x%04x\n", dlpd->dlen);
982 if (dlpd->len >= 3)
983 printk(KERN_DEBUG " dlpd.laa = 0x%02x\n", dlpd->laa);
984 if (dlpd->len >= 4)
985 printk(KERN_DEBUG " dlpd.lab = 0x%02x\n", dlpd->lab);
986 if (dlpd->len >= 5)
987 printk(KERN_DEBUG " dlpd.modulo = %d\n", dlpd->modulo);
988 if (dlpd->len >= 6)
989 printk(KERN_DEBUG " dlpd.win = %d\n", dlpd->win);
990 }
991
992 #ifdef DEBUG_DUMP_SKB
dump_skb(struct sk_buff * skb)993 static void dump_skb(struct sk_buff *skb) {
994 char tmp[80];
995 char *p = skb->data;
996 char *t = tmp;
997 int i;
998
999 for (i = 0; i < skb->len; i++) {
1000 t += sprintf(t, "%02x ", *p++ & 0xff);
1001 if ((i & 0x0f) == 8) {
1002 printk(KERN_DEBUG "dump: %s\n", tmp);
1003 t = tmp;
1004 }
1005 }
1006 if (i & 0x07)
1007 printk(KERN_DEBUG "dump: %s\n", tmp);
1008 }
1009 #endif
1010
1011 void
actcapi_debug_msg(struct sk_buff * skb,int direction)1012 actcapi_debug_msg(struct sk_buff *skb, int direction)
1013 {
1014 actcapi_msg *msg = (actcapi_msg *)skb->data;
1015 char *descr;
1016 int i;
1017 char tmp[170];
1018
1019 #ifndef DEBUG_DATA_MSG
1020 if (msg->hdr.cmd.cmd == 0x86)
1021 return;
1022 #endif
1023 descr = "INVALID";
1024 #ifdef DEBUG_DUMP_SKB
1025 dump_skb(skb);
1026 #endif
1027 for (i = 0; i < num_valid_msg; i++)
1028 if ((msg->hdr.cmd.cmd == valid_msg[i].cmd.cmd) &&
1029 (msg->hdr.cmd.subcmd == valid_msg[i].cmd.subcmd)) {
1030 descr = valid_msg[i].description;
1031 break;
1032 }
1033 printk(KERN_DEBUG "%s %s msg\n", direction?"Outgoing":"Incoming", descr);
1034 printk(KERN_DEBUG " ApplID = %d\n", msg->hdr.applicationID);
1035 printk(KERN_DEBUG " Len = %d\n", msg->hdr.len);
1036 printk(KERN_DEBUG " MsgNum = 0x%04x\n", msg->hdr.msgnum);
1037 printk(KERN_DEBUG " Cmd = 0x%02x\n", msg->hdr.cmd.cmd);
1038 printk(KERN_DEBUG " SubCmd = 0x%02x\n", msg->hdr.cmd.subcmd);
1039 switch (i) {
1040 case 0:
1041 /* DATA B3 IND */
1042 printk(KERN_DEBUG " BLOCK = 0x%02x\n",
1043 msg->msg.data_b3_ind.blocknr);
1044 break;
1045 case 2:
1046 /* CONNECT CONF */
1047 printk(KERN_DEBUG " PLCI = 0x%04x\n",
1048 msg->msg.connect_conf.plci);
1049 printk(KERN_DEBUG " Info = 0x%04x\n",
1050 msg->msg.connect_conf.info);
1051 break;
1052 case 3:
1053 /* CONNECT IND */
1054 printk(KERN_DEBUG " PLCI = 0x%04x\n",
1055 msg->msg.connect_ind.plci);
1056 printk(KERN_DEBUG " Contr = %d\n",
1057 msg->msg.connect_ind.controller);
1058 printk(KERN_DEBUG " SI1 = %d\n",
1059 msg->msg.connect_ind.si1);
1060 printk(KERN_DEBUG " SI2 = %d\n",
1061 msg->msg.connect_ind.si2);
1062 printk(KERN_DEBUG " EAZ = '%c'\n",
1063 msg->msg.connect_ind.eaz);
1064 actcapi_debug_caddr(&msg->msg.connect_ind.addr);
1065 break;
1066 case 5:
1067 /* CONNECT ACTIVE IND */
1068 printk(KERN_DEBUG " PLCI = 0x%04x\n",
1069 msg->msg.connect_active_ind.plci);
1070 actcapi_debug_caddr(&msg->msg.connect_active_ind.addr);
1071 break;
1072 case 8:
1073 /* LISTEN CONF */
1074 printk(KERN_DEBUG " Contr = %d\n",
1075 msg->msg.listen_conf.controller);
1076 printk(KERN_DEBUG " Info = 0x%04x\n",
1077 msg->msg.listen_conf.info);
1078 break;
1079 case 11:
1080 /* INFO IND */
1081 printk(KERN_DEBUG " PLCI = 0x%04x\n",
1082 msg->msg.info_ind.plci);
1083 printk(KERN_DEBUG " Imsk = 0x%04x\n",
1084 msg->msg.info_ind.nr.mask);
1085 if (msg->hdr.len > 12) {
1086 int l = msg->hdr.len - 12;
1087 int j;
1088 char *p = tmp;
1089 for (j = 0; j < l ; j++)
1090 p += sprintf(p, "%02x ", msg->msg.info_ind.el.display[j]);
1091 printk(KERN_DEBUG " D = '%s'\n", tmp);
1092 }
1093 break;
1094 case 14:
1095 /* SELECT B2 PROTOCOL CONF */
1096 printk(KERN_DEBUG " PLCI = 0x%04x\n",
1097 msg->msg.select_b2_protocol_conf.plci);
1098 printk(KERN_DEBUG " Info = 0x%04x\n",
1099 msg->msg.select_b2_protocol_conf.info);
1100 break;
1101 case 15:
1102 /* SELECT B3 PROTOCOL CONF */
1103 printk(KERN_DEBUG " PLCI = 0x%04x\n",
1104 msg->msg.select_b3_protocol_conf.plci);
1105 printk(KERN_DEBUG " Info = 0x%04x\n",
1106 msg->msg.select_b3_protocol_conf.info);
1107 break;
1108 case 16:
1109 /* LISTEN B3 CONF */
1110 printk(KERN_DEBUG " PLCI = 0x%04x\n",
1111 msg->msg.listen_b3_conf.plci);
1112 printk(KERN_DEBUG " Info = 0x%04x\n",
1113 msg->msg.listen_b3_conf.info);
1114 break;
1115 case 18:
1116 /* CONNECT B3 IND */
1117 printk(KERN_DEBUG " NCCI = 0x%04x\n",
1118 msg->msg.connect_b3_ind.ncci);
1119 printk(KERN_DEBUG " PLCI = 0x%04x\n",
1120 msg->msg.connect_b3_ind.plci);
1121 actcapi_debug_ncpi(&msg->msg.connect_b3_ind.ncpi);
1122 break;
1123 case 19:
1124 /* CONNECT B3 ACTIVE IND */
1125 printk(KERN_DEBUG " NCCI = 0x%04x\n",
1126 msg->msg.connect_b3_active_ind.ncci);
1127 actcapi_debug_ncpi(&msg->msg.connect_b3_active_ind.ncpi);
1128 break;
1129 case 26:
1130 /* MANUFACTURER IND */
1131 printk(KERN_DEBUG " Mmsg = 0x%02x\n",
1132 msg->msg.manufacturer_ind_err.manuf_msg);
1133 switch (msg->msg.manufacturer_ind_err.manuf_msg) {
1134 case 3:
1135 printk(KERN_DEBUG " Contr = %d\n",
1136 msg->msg.manufacturer_ind_err.controller);
1137 printk(KERN_DEBUG " Code = 0x%08x\n",
1138 msg->msg.manufacturer_ind_err.errcode);
1139 memset(tmp, 0, sizeof(tmp));
1140 strncpy(tmp, &msg->msg.manufacturer_ind_err.errstring,
1141 msg->hdr.len - 16);
1142 printk(KERN_DEBUG " Emsg = '%s'\n", tmp);
1143 break;
1144 }
1145 break;
1146 case 30:
1147 /* LISTEN REQ */
1148 printk(KERN_DEBUG " Imsk = 0x%08x\n",
1149 msg->msg.listen_req.infomask);
1150 printk(KERN_DEBUG " Emsk = 0x%04x\n",
1151 msg->msg.listen_req.eazmask);
1152 printk(KERN_DEBUG " Smsk = 0x%04x\n",
1153 msg->msg.listen_req.simask);
1154 break;
1155 case 35:
1156 /* SELECT_B2_PROTOCOL_REQ */
1157 printk(KERN_DEBUG " PLCI = 0x%04x\n",
1158 msg->msg.select_b2_protocol_req.plci);
1159 printk(KERN_DEBUG " prot = 0x%02x\n",
1160 msg->msg.select_b2_protocol_req.protocol);
1161 if (msg->hdr.len >= 11)
1162 printk(KERN_DEBUG "No dlpd\n");
1163 else
1164 actcapi_debug_dlpd(&msg->msg.select_b2_protocol_req.dlpd);
1165 break;
1166 case 44:
1167 /* CONNECT RESP */
1168 printk(KERN_DEBUG " PLCI = 0x%04x\n",
1169 msg->msg.connect_resp.plci);
1170 printk(KERN_DEBUG " CAUSE = 0x%02x\n",
1171 msg->msg.connect_resp.rejectcause);
1172 break;
1173 case 45:
1174 /* CONNECT ACTIVE RESP */
1175 printk(KERN_DEBUG " PLCI = 0x%04x\n",
1176 msg->msg.connect_active_resp.plci);
1177 break;
1178 }
1179 }
1180 #endif
1181