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