Import 2.3.48
[davej-history.git] / drivers / isdn / eicon / eicon_idi.c
blobeb3590069da90a47baaf4d88a0739a5b86db982c
1 /* $Id: eicon_idi.c,v 1.31 2000/02/22 16:26:40 armin Exp $
3 * ISDN lowlevel-module for Eicon active cards.
4 * IDI interface
6 * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
7 * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
9 * Thanks to Deutsche Mailbox Saar-Lor-Lux GmbH
10 * for sponsoring and testing fax
11 * capabilities with Diva Server cards.
12 * (dor@deutschemailbox.de)
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 * $Log: eicon_idi.c,v $
29 * Revision 1.31 2000/02/22 16:26:40 armin
30 * Fixed membase error message.
31 * Fixed missing log buffer struct.
33 * Revision 1.30 2000/02/16 16:08:46 armin
34 * Fixed virtual channel handling of IDI.
36 * Revision 1.29 2000/01/23 21:21:23 armin
37 * Added new trace capability and some updates.
38 * DIVA Server BRI now supports data for ISDNLOG.
40 * Revision 1.28 2000/01/20 19:55:34 keil
41 * Add FAX Class 1 support
43 * Revision 1.27 1999/11/29 13:12:03 armin
44 * Autoconnect on L2_TRANS doesn't work with link_level correctly,
45 * changed back to former mode.
47 * Revision 1.26 1999/11/25 11:43:27 armin
48 * Fixed statectrl and connect message.
49 * X.75 fix and HDLC/transparent with autoconnect.
50 * Minor cleanup.
52 * Revision 1.25 1999/11/18 20:30:55 armin
53 * removed old workaround for ISA cards.
55 * Revision 1.24 1999/10/26 21:15:33 armin
56 * using define for checking phone number len to avoid buffer overflow.
58 * Revision 1.23 1999/10/11 18:13:25 armin
59 * Added fax capabilities for Eicon Diva Server cards.
61 * Revision 1.22 1999/10/08 22:09:33 armin
62 * Some fixes of cards interface handling.
63 * Bugfix of NULL pointer occurence.
64 * Changed a few log outputs.
66 * Revision 1.21 1999/09/26 14:17:53 armin
67 * Improved debug and log via readstat()
69 * Revision 1.20 1999/09/21 20:35:43 armin
70 * added more error checking.
72 * Revision 1.19 1999/09/21 20:06:40 armin
73 * Added pointer checks.
75 * Revision 1.18 1999/09/07 12:48:05 armin
76 * Prepared for sub-address usage.
78 * Revision 1.17 1999/09/07 12:35:39 armin
79 * Better checking and channel Id handling.
81 * Revision 1.16 1999/09/04 13:44:19 armin
82 * Fix of V.42 analog Modem negotiation handling.
84 * Revision 1.15 1999/08/28 21:32:50 armin
85 * Prepared for fax related functions.
86 * Now compilable without errors/warnings.
88 * Revision 1.14 1999/08/28 20:24:40 armin
89 * Corrected octet 3/3a in CPN/OAD information element.
90 * Thanks to John Simpson <xfl23@dial.pipex.com>
92 * Revision 1.13 1999/08/22 20:26:44 calle
93 * backported changes from kernel 2.3.14:
94 * - several #include "config.h" gone, others come.
95 * - "struct device" changed to "struct net_device" in 2.3.14, added a
96 * define in isdn_compat.h for older kernel versions.
98 * Revision 1.12 1999/08/18 20:16:59 armin
99 * Added XLOG function for all cards.
100 * Bugfix of alloc_skb NULL pointer.
102 * Revision 1.11 1999/07/25 15:12:03 armin
103 * fix of some debug logs.
104 * enabled ISA-cards option.
106 * Revision 1.10 1999/07/11 17:16:24 armin
107 * Bugfixes in queue handling.
108 * Added DSP-DTMF decoder functions.
109 * Reorganized ack_handler.
111 * Revision 1.9 1999/03/29 11:19:42 armin
112 * I/O stuff now in seperate file (eicon_io.c)
113 * Old ISA type cards (S,SX,SCOM,Quadro,S2M) implemented.
115 * Revision 1.8 1999/03/02 12:37:43 armin
116 * Added some important checks.
117 * Analog Modem with DSP.
118 * Channels will be added to Link-Level after loading firmware.
120 * Revision 1.7 1999/02/03 18:34:35 armin
121 * Channel selection for outgoing calls w/o CHI.
122 * Added channel # in debug messages.
123 * L2 Transparent should work with 800 byte/packet now.
125 * Revision 1.6 1999/01/26 07:18:59 armin
126 * Bug with wrong added CPN fixed.
128 * Revision 1.5 1999/01/24 20:14:11 armin
129 * Changed and added debug stuff.
130 * Better data sending. (still problems with tty's flip buffer)
132 * Revision 1.4 1999/01/10 18:46:05 armin
133 * Bug with wrong values in HLC fixed.
134 * Bytes to send are counted and limited now.
136 * Revision 1.3 1999/01/05 14:49:34 armin
137 * Added experimental usage of full BC and HLC for
138 * speech, 3.1kHz audio, fax gr.2/3
140 * Revision 1.2 1999/01/04 13:19:29 armin
141 * Channel status with listen-request wrong - fixed.
143 * Revision 1.1 1999/01/01 18:09:41 armin
144 * First checkin of new eicon driver.
145 * DIVA-Server BRI/PCI and PRI/PCI are supported.
146 * Old diehl code is obsolete.
151 #include <linux/config.h>
152 #define __NO_VERSION__
153 #include "eicon.h"
154 #include "eicon_idi.h"
155 #include "eicon_dsp.h"
157 #undef EICON_FULL_SERVICE_OKTETT
159 char *eicon_idi_revision = "$Revision: 1.31 $";
161 eicon_manifbuf *manbuf;
163 static char BC_Speech[3] = { 0x80, 0x90, 0xa3 };
164 static char BC_31khz[3] = { 0x90, 0x90, 0xa3 };
165 static char BC_64k[2] = { 0x88, 0x90 };
166 static char BC_video[3] = { 0x91, 0x90, 0xa5 };
168 #ifdef EICON_FULL_SERVICE_OKTETT
170 static char HLC_telephony[2] = { 0x91, 0x81 };
172 static char HLC_faxg3[2] = { 0x91, 0x84 };
173 #endif
175 int eicon_idi_manage_assign(eicon_card *card);
176 int eicon_idi_manage_remove(eicon_card *card);
177 int idi_fill_in_T30(eicon_chan *chan, unsigned char *buffer);
180 idi_assign_req(eicon_REQ *reqbuf, int signet, eicon_chan *chan)
182 int l = 0;
183 int tmp;
185 tmp = 0;
186 if (!signet) {
187 /* Signal Layer */
188 reqbuf->XBuffer.P[l++] = CAI;
189 reqbuf->XBuffer.P[l++] = 1;
190 reqbuf->XBuffer.P[l++] = 0;
191 reqbuf->XBuffer.P[l++] = KEY;
192 reqbuf->XBuffer.P[l++] = 3;
193 reqbuf->XBuffer.P[l++] = 'I';
194 reqbuf->XBuffer.P[l++] = '4';
195 reqbuf->XBuffer.P[l++] = 'L';
196 reqbuf->XBuffer.P[l++] = SHIFT|6;
197 reqbuf->XBuffer.P[l++] = SIN;
198 reqbuf->XBuffer.P[l++] = 2;
199 reqbuf->XBuffer.P[l++] = 0;
200 reqbuf->XBuffer.P[l++] = 0;
201 reqbuf->XBuffer.P[l++] = 0; /* end */
202 reqbuf->Req = ASSIGN;
203 reqbuf->ReqCh = 0;
204 reqbuf->ReqId = 0;
205 reqbuf->XBuffer.length = l;
206 reqbuf->Reference = 0; /* Sig Entity */
208 else {
209 /* Network Layer */
210 reqbuf->XBuffer.P[l++] = CAI;
211 reqbuf->XBuffer.P[l++] = 1;
212 reqbuf->XBuffer.P[l++] = chan->e.D3Id;
213 reqbuf->XBuffer.P[l++] = LLC;
214 reqbuf->XBuffer.P[l++] = 2;
215 switch(chan->l2prot) {
216 case ISDN_PROTO_L2_TRANS:
217 reqbuf->XBuffer.P[l++] = 2; /* transparent */
218 break;
219 case ISDN_PROTO_L2_X75I:
220 case ISDN_PROTO_L2_X75UI:
221 case ISDN_PROTO_L2_X75BUI:
222 reqbuf->XBuffer.P[l++] = 5; /* X.75 */
223 break;
224 case ISDN_PROTO_L2_MODEM:
225 if (chan->fsm_state == EICON_STATE_IWAIT)
226 reqbuf->XBuffer.P[l++] = 9; /* V.42 incoming */
227 else
228 reqbuf->XBuffer.P[l++] = 10; /* V.42 */
229 break;
230 case ISDN_PROTO_L2_HDLC:
231 case ISDN_PROTO_L2_FAX:
232 if (chan->fsm_state == EICON_STATE_IWAIT)
233 reqbuf->XBuffer.P[l++] = 3; /* autoconnect on incoming */
234 else
235 reqbuf->XBuffer.P[l++] = 2; /* transparent */
236 break;
237 default:
238 reqbuf->XBuffer.P[l++] = 1;
240 switch(chan->l3prot) {
241 case ISDN_PROTO_L3_FCLASS2:
242 #ifdef CONFIG_ISDN_TTY_FAX
243 reqbuf->XBuffer.P[l++] = 6;
244 reqbuf->XBuffer.P[l++] = NLC;
245 tmp = idi_fill_in_T30(chan, &reqbuf->XBuffer.P[l+1]);
246 reqbuf->XBuffer.P[l++] = tmp;
247 l += tmp;
248 break;
249 #endif
250 case ISDN_PROTO_L3_TRANS:
251 default:
252 reqbuf->XBuffer.P[l++] = 4;
254 reqbuf->XBuffer.P[l++] = 0; /* end */
255 reqbuf->Req = ASSIGN;
256 reqbuf->ReqCh = 0;
257 reqbuf->ReqId = 0x20;
258 reqbuf->XBuffer.length = l;
259 reqbuf->Reference = 1; /* Net Entity */
261 return(0);
265 idi_put_req(eicon_REQ *reqbuf, int rq, int signet, int Ch)
267 reqbuf->Req = rq;
268 reqbuf->ReqCh = Ch;
269 reqbuf->ReqId = 1;
270 reqbuf->XBuffer.length = 1;
271 reqbuf->XBuffer.P[0] = 0;
272 reqbuf->Reference = signet;
273 return(0);
277 idi_call_res_req(eicon_REQ *reqbuf, eicon_chan *chan)
279 int l = 9;
280 reqbuf->Req = CALL_RES;
281 reqbuf->ReqCh = 0;
282 reqbuf->ReqId = 1;
283 reqbuf->XBuffer.P[0] = CAI;
284 reqbuf->XBuffer.P[1] = 6;
285 reqbuf->XBuffer.P[2] = 9;
286 reqbuf->XBuffer.P[3] = 0;
287 reqbuf->XBuffer.P[4] = 0;
288 reqbuf->XBuffer.P[5] = 0;
289 reqbuf->XBuffer.P[6] = 32;
290 reqbuf->XBuffer.P[7] = 3;
291 switch(chan->l2prot) {
292 case ISDN_PROTO_L2_X75I:
293 case ISDN_PROTO_L2_X75UI:
294 case ISDN_PROTO_L2_X75BUI:
295 case ISDN_PROTO_L2_HDLC:
296 reqbuf->XBuffer.P[1] = 1;
297 reqbuf->XBuffer.P[2] = 0x05;
298 l = 4;
299 break;
300 case ISDN_PROTO_L2_V11096:
301 reqbuf->XBuffer.P[2] = 0x0d;
302 reqbuf->XBuffer.P[3] = 5;
303 reqbuf->XBuffer.P[4] = 0;
304 break;
305 case ISDN_PROTO_L2_V11019:
306 reqbuf->XBuffer.P[2] = 0x0d;
307 reqbuf->XBuffer.P[3] = 6;
308 reqbuf->XBuffer.P[4] = 0;
309 break;
310 case ISDN_PROTO_L2_V11038:
311 reqbuf->XBuffer.P[2] = 0x0d;
312 reqbuf->XBuffer.P[3] = 7;
313 reqbuf->XBuffer.P[4] = 0;
314 break;
315 case ISDN_PROTO_L2_MODEM:
316 reqbuf->XBuffer.P[2] = 0x11;
317 reqbuf->XBuffer.P[3] = 7;
318 reqbuf->XBuffer.P[4] = 0;
319 reqbuf->XBuffer.P[5] = 0;
320 reqbuf->XBuffer.P[6] = 128;
321 reqbuf->XBuffer.P[7] = 0;
322 break;
323 case ISDN_PROTO_L2_FAX:
324 reqbuf->XBuffer.P[2] = 0x10;
325 reqbuf->XBuffer.P[3] = 0;
326 reqbuf->XBuffer.P[4] = 0;
327 reqbuf->XBuffer.P[5] = 0;
328 reqbuf->XBuffer.P[6] = 128;
329 reqbuf->XBuffer.P[7] = 0;
330 break;
331 case ISDN_PROTO_L2_TRANS:
332 switch(chan->l3prot) {
333 case ISDN_PROTO_L3_TRANSDSP:
334 reqbuf->XBuffer.P[2] = 22; /* DTMF, audio events on */
336 break;
338 reqbuf->XBuffer.P[8] = 0;
339 reqbuf->XBuffer.length = l;
340 reqbuf->Reference = 0; /* Sig Entity */
341 eicon_log(NULL, 8, "idi_req: Ch%d: Call_Res\n", chan->No);
342 return(0);
346 idi_do_req(eicon_card *card, eicon_chan *chan, int cmd, int layer)
348 struct sk_buff *skb;
349 struct sk_buff *skb2;
350 eicon_REQ *reqbuf;
351 eicon_chan_ptr *chan2;
353 skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
354 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
356 if ((!skb) || (!skb2)) {
357 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in do_req()\n", chan->No);
358 if (skb)
359 dev_kfree_skb(skb);
360 if (skb2)
361 dev_kfree_skb(skb2);
362 return -ENOMEM;
365 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
366 chan2->ptr = chan;
368 reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
369 eicon_log(card, 8, "idi_req: Ch%d: req %x (%s)\n", chan->No, cmd, (layer)?"Net":"Sig");
370 if (layer) cmd |= 0x700;
371 switch(cmd) {
372 case ASSIGN:
373 case ASSIGN|0x700:
374 idi_assign_req(reqbuf, layer, chan);
375 break;
376 case REMOVE:
377 case REMOVE|0x700:
378 idi_put_req(reqbuf, REMOVE, layer, 0);
379 break;
380 case INDICATE_REQ:
381 idi_put_req(reqbuf, INDICATE_REQ, 0, 0);
382 break;
383 case HANGUP:
384 idi_put_req(reqbuf, HANGUP, 0, 0);
385 break;
386 case REJECT:
387 idi_put_req(reqbuf, REJECT, 0 ,0);
388 break;
389 case CALL_ALERT:
390 idi_put_req(reqbuf, CALL_ALERT, 0, 0);
391 break;
392 case CALL_RES:
393 idi_call_res_req(reqbuf, chan);
394 break;
395 case IDI_N_CONNECT|0x700:
396 idi_put_req(reqbuf, IDI_N_CONNECT, 1, 0);
397 break;
398 case IDI_N_CONNECT_ACK|0x700:
399 idi_put_req(reqbuf, IDI_N_CONNECT_ACK, 1, 0);
400 break;
401 case IDI_N_DISC|0x700:
402 idi_put_req(reqbuf, IDI_N_DISC, 1, chan->e.IndCh);
403 break;
404 case IDI_N_DISC_ACK|0x700:
405 idi_put_req(reqbuf, IDI_N_DISC_ACK, 1, chan->e.IndCh);
406 break;
407 default:
408 eicon_log(card, 1, "idi_req: Ch%d: Unknown request\n", chan->No);
409 dev_kfree_skb(skb);
410 dev_kfree_skb(skb2);
411 return(-1);
414 skb_queue_tail(&chan->e.X, skb);
415 skb_queue_tail(&card->sndq, skb2);
416 eicon_schedule_tx(card);
417 return(0);
421 eicon_idi_listen_req(eicon_card *card, eicon_chan *chan)
423 if ((!card) || (!chan))
424 return 1;
426 eicon_log(card, 16, "idi_req: Ch%d: Listen_Req eazmask=0x%x\n",chan->No, chan->eazmask);
427 if (!chan->e.D3Id) {
428 idi_do_req(card, chan, ASSIGN, 0);
430 if (chan->fsm_state == EICON_STATE_NULL) {
431 if (!(chan->statectrl & HAVE_CONN_REQ)) {
432 idi_do_req(card, chan, INDICATE_REQ, 0);
433 chan->fsm_state = EICON_STATE_LISTEN;
436 return(0);
439 unsigned char
440 idi_si2bc(int si1, int si2, char *bc, char *hlc)
442 hlc[0] = 0;
443 switch(si1) {
444 case 1:
445 bc[0] = 0x90; /* 3,1 kHz audio */
446 bc[1] = 0x90; /* 64 kbit/s */
447 bc[2] = 0xa3; /* G.711 A-law */
448 #ifdef EICON_FULL_SERVICE_OKTETT
449 if (si2 == 1) {
450 bc[0] = 0x80; /* Speech */
451 hlc[0] = 0x02; /* hlc len */
452 hlc[1] = 0x91; /* first hic */
453 hlc[2] = 0x81; /* Telephony */
455 #endif
456 return(3);
457 case 2:
458 bc[0] = 0x90; /* 3,1 kHz audio */
459 bc[1] = 0x90; /* 64 kbit/s */
460 bc[2] = 0xa3; /* G.711 A-law */
461 #ifdef EICON_FULL_SERVICE_OKTETT
462 if (si2 == 2) {
463 hlc[0] = 0x02; /* hlc len */
464 hlc[1] = 0x91; /* first hic */
465 hlc[2] = 0x84; /* Fax Gr.2/3 */
467 #endif
468 return(3);
469 case 5:
470 case 7:
471 default:
472 bc[0] = 0x88;
473 bc[1] = 0x90;
474 return(2);
476 return (0);
480 idi_hangup(eicon_card *card, eicon_chan *chan)
482 if ((!card) || (!chan))
483 return 1;
485 if ((chan->fsm_state == EICON_STATE_ACTIVE) ||
486 (chan->fsm_state == EICON_STATE_WMCONN)) {
487 if (chan->e.B2Id) idi_do_req(card, chan, IDI_N_DISC, 1);
489 if (chan->e.B2Id) idi_do_req(card, chan, REMOVE, 1);
490 if (chan->fsm_state != EICON_STATE_NULL) {
491 chan->statectrl |= WAITING_FOR_HANGUP;
492 idi_do_req(card, chan, HANGUP, 0);
493 chan->fsm_state = EICON_STATE_NULL;
495 eicon_log(card, 8, "idi_req: Ch%d: Hangup\n", chan->No);
496 #ifdef CONFIG_ISDN_TTY_FAX
497 chan->fax = 0;
498 #endif
499 return(0);
503 idi_connect_res(eicon_card *card, eicon_chan *chan)
505 if ((!card) || (!chan))
506 return 1;
508 chan->fsm_state = EICON_STATE_IWAIT;
510 /* check if old NetID has been removed */
511 if (chan->e.B2Id) {
512 eicon_log(card, 1, "eicon: Ch%d: old net_id %x still exist, removing.\n",
513 chan->No, chan->e.B2Id);
514 idi_do_req(card, chan, REMOVE, 1);
517 idi_do_req(card, chan, ASSIGN, 1);
518 idi_do_req(card, chan, CALL_RES, 0);
519 return(0);
523 idi_connect_req(eicon_card *card, eicon_chan *chan, char *phone,
524 char *eazmsn, int si1, int si2)
526 int l = 0;
527 int i;
528 unsigned char tmp;
529 unsigned char *sub, *sp;
530 unsigned char bc[5];
531 unsigned char hlc[5];
532 struct sk_buff *skb;
533 struct sk_buff *skb2;
534 eicon_REQ *reqbuf;
535 eicon_chan_ptr *chan2;
537 if ((!card) || (!chan))
538 return 1;
540 skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
541 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
543 if ((!skb) || (!skb2)) {
544 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in connect_req()\n", chan->No);
545 if (skb)
546 dev_kfree_skb(skb);
547 if (skb2)
548 dev_kfree_skb(skb2);
549 return -ENOMEM;
552 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
553 chan2->ptr = chan;
555 reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
556 reqbuf->Req = CALL_REQ;
557 reqbuf->ReqCh = 0;
558 reqbuf->ReqId = 1;
560 sub = NULL;
561 sp = phone;
562 while (*sp) {
563 if (*sp == '.') {
564 sub = sp + 1;
565 *sp = 0;
566 } else
567 sp++;
569 reqbuf->XBuffer.P[l++] = CPN;
570 reqbuf->XBuffer.P[l++] = strlen(phone) + 1;
571 reqbuf->XBuffer.P[l++] = 0x81;
572 for(i=0; i<strlen(phone);i++)
573 reqbuf->XBuffer.P[l++] = phone[i] & 0x7f;
574 if (sub) {
575 reqbuf->XBuffer.P[l++] = DSA;
576 reqbuf->XBuffer.P[l++] = strlen(sub) + 2;
577 reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */
578 reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */
579 while (*sub)
580 reqbuf->XBuffer.P[l++] = *sub++ & 0x7f;
583 sub = NULL;
584 sp = eazmsn;
585 while (*sp) {
586 if (*sp == '.') {
587 sub = sp + 1;
588 *sp = 0;
589 } else
590 sp++;
592 reqbuf->XBuffer.P[l++] = OAD;
593 reqbuf->XBuffer.P[l++] = strlen(eazmsn) + 2;
594 reqbuf->XBuffer.P[l++] = 0x01;
595 reqbuf->XBuffer.P[l++] = 0x80;
596 for(i=0; i<strlen(eazmsn);i++)
597 reqbuf->XBuffer.P[l++] = eazmsn[i] & 0x7f;
598 if (sub) {
599 reqbuf->XBuffer.P[l++] = OSA;
600 reqbuf->XBuffer.P[l++] = strlen(sub) + 2;
601 reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */
602 reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */
603 while (*sub)
604 reqbuf->XBuffer.P[l++] = *sub++ & 0x7f;
607 if ((tmp = idi_si2bc(si1, si2, bc, hlc)) > 0) {
608 reqbuf->XBuffer.P[l++] = BC;
609 reqbuf->XBuffer.P[l++] = tmp;
610 for(i=0; i<tmp;i++)
611 reqbuf->XBuffer.P[l++] = bc[i];
612 if ((tmp=hlc[0])) {
613 reqbuf->XBuffer.P[l++] = HLC;
614 reqbuf->XBuffer.P[l++] = tmp;
615 for(i=1; i<=tmp;i++)
616 reqbuf->XBuffer.P[l++] = hlc[i];
620 reqbuf->XBuffer.P[l++] = CAI;
621 reqbuf->XBuffer.P[l++] = 6;
622 reqbuf->XBuffer.P[l++] = 0x09;
623 reqbuf->XBuffer.P[l++] = 0;
624 reqbuf->XBuffer.P[l++] = 0;
625 reqbuf->XBuffer.P[l++] = 0;
626 reqbuf->XBuffer.P[l++] = 32;
627 reqbuf->XBuffer.P[l++] = 3;
628 switch(chan->l2prot) {
629 case ISDN_PROTO_L2_X75I:
630 case ISDN_PROTO_L2_X75UI:
631 case ISDN_PROTO_L2_X75BUI:
632 case ISDN_PROTO_L2_HDLC:
633 reqbuf->XBuffer.P[l-6] = 5;
634 reqbuf->XBuffer.P[l-7] = 1;
635 l -= 5;
636 break;
637 case ISDN_PROTO_L2_V11096:
638 reqbuf->XBuffer.P[l-7] = 3;
639 reqbuf->XBuffer.P[l-6] = 0x0d;
640 reqbuf->XBuffer.P[l-5] = 5;
641 reqbuf->XBuffer.P[l-4] = 0;
642 l -= 3;
643 break;
644 case ISDN_PROTO_L2_V11019:
645 reqbuf->XBuffer.P[l-7] = 3;
646 reqbuf->XBuffer.P[l-6] = 0x0d;
647 reqbuf->XBuffer.P[l-5] = 6;
648 reqbuf->XBuffer.P[l-4] = 0;
649 l -= 3;
650 break;
651 case ISDN_PROTO_L2_V11038:
652 reqbuf->XBuffer.P[l-7] = 3;
653 reqbuf->XBuffer.P[l-6] = 0x0d;
654 reqbuf->XBuffer.P[l-5] = 7;
655 reqbuf->XBuffer.P[l-4] = 0;
656 l -= 3;
657 break;
658 case ISDN_PROTO_L2_MODEM:
659 reqbuf->XBuffer.P[l-6] = 0x11;
660 reqbuf->XBuffer.P[l-5] = 7;
661 reqbuf->XBuffer.P[l-4] = 0;
662 reqbuf->XBuffer.P[l-3] = 0;
663 reqbuf->XBuffer.P[l-2] = 128;
664 reqbuf->XBuffer.P[l-1] = 0;
665 break;
666 case ISDN_PROTO_L2_FAX:
667 reqbuf->XBuffer.P[l-6] = 0x10;
668 reqbuf->XBuffer.P[l-5] = 0;
669 reqbuf->XBuffer.P[l-4] = 0;
670 reqbuf->XBuffer.P[l-3] = 0;
671 reqbuf->XBuffer.P[l-2] = 128;
672 reqbuf->XBuffer.P[l-1] = 0;
673 break;
674 case ISDN_PROTO_L2_TRANS:
675 switch(chan->l3prot) {
676 case ISDN_PROTO_L3_TRANSDSP:
677 reqbuf->XBuffer.P[l-6] = 22; /* DTMF, audio events on */
679 break;
682 reqbuf->XBuffer.P[l++] = 0; /* end */
683 reqbuf->XBuffer.length = l;
684 reqbuf->Reference = 0; /* Sig Entity */
686 if (chan->statectrl & WAITING_FOR_HANGUP) {
687 /* If the line did not disconnect yet,
688 we have to delay this command */
689 eicon_log(card, 32, "idi_req: Ch%d: delaying conn_req\n", chan->No);
690 chan->statectrl |= HAVE_CONN_REQ;
691 chan->tskb1 = skb;
692 chan->tskb2 = skb2;
693 } else {
694 skb_queue_tail(&chan->e.X, skb);
695 skb_queue_tail(&card->sndq, skb2);
696 eicon_schedule_tx(card);
699 eicon_log(card, 8, "idi_req: Ch%d: Conn_Req %s -> %s\n",chan->No, eazmsn, phone);
700 return(0);
704 void
705 idi_IndParse(eicon_card *ccard, eicon_chan *chan, idi_ind_message *message, unsigned char *buffer, int len)
707 int i,j;
708 int pos = 0;
709 int codeset = 0;
710 int wlen = 0;
711 int lock = 0;
712 __u8 w;
713 __u16 code;
714 isdn_ctrl cmd;
716 memset(message, 0, sizeof(idi_ind_message));
718 if ((!len) || (!buffer[pos])) return;
720 while(pos <= len) {
721 w = buffer[pos++];
722 if (!w) return;
723 if (w & 0x80) {
724 wlen = 0;
726 else {
727 wlen = buffer[pos++];
730 if (pos > len) return;
732 if (lock & 0x80) lock &= 0x7f;
733 else codeset = lock;
735 if((w&0xf0) == SHIFT) {
736 codeset = w;
737 if(!(codeset & 0x08)) lock = codeset & 7;
738 codeset &= 7;
739 lock |= 0x80;
741 else {
742 if (w==ESC && wlen >=2) {
743 code = buffer[pos++]|0x800;
744 wlen--;
746 else code = w;
747 code |= (codeset<<8);
749 if (pos + wlen > len) {
750 eicon_log(ccard, 1, "idi_err: Ch%d: IElen %d of %x exceeds Ind_Length (+%d)\n", chan->No,
751 wlen, code, (pos + wlen) - len);
752 return;
755 switch(code) {
756 case OAD:
757 if (wlen > sizeof(message->oad)) {
758 pos += wlen;
759 break;
761 j = 1;
762 if (wlen) {
763 message->plan = buffer[pos++];
764 if (message->plan &0x80)
765 message->screen = 0;
766 else {
767 message->screen = buffer[pos++];
768 j = 2;
771 for(i=0; i < wlen-j; i++)
772 message->oad[i] = buffer[pos++];
773 eicon_log(ccard, 2, "idi_inf: Ch%d: OAD=(0x%02x,0x%02x) %s\n", chan->No,
774 message->plan, message->screen, message->oad);
775 break;
776 case RDN:
777 if (wlen > sizeof(message->rdn)) {
778 pos += wlen;
779 break;
781 j = 1;
782 if (wlen) {
783 if (!(buffer[pos++] & 0x80)) {
784 pos++;
785 j = 2;
788 for(i=0; i < wlen-j; i++)
789 message->rdn[i] = buffer[pos++];
790 eicon_log(ccard, 2, "idi_inf: Ch%d: RDN= %s\n", chan->No,
791 message->rdn);
792 break;
793 case CPN:
794 if (wlen > sizeof(message->cpn)) {
795 pos += wlen;
796 break;
798 for(i=0; i < wlen; i++)
799 message->cpn[i] = buffer[pos++];
800 eicon_log(ccard, 2, "idi_inf: Ch%d: CPN=(0x%02x) %s\n", chan->No,
801 (__u8)message->cpn[0], message->cpn + 1);
802 break;
803 case DSA:
804 if (wlen > sizeof(message->dsa)) {
805 pos += wlen;
806 break;
808 pos += 2;
809 for(i=0; i < wlen-2; i++)
810 message->dsa[i] = buffer[pos++];
811 eicon_log(ccard, 2, "idi_inf: Ch%d: DSA=%s\n", chan->No, message->dsa);
812 break;
813 case OSA:
814 if (wlen > sizeof(message->osa)) {
815 pos += wlen;
816 break;
818 pos += 2;
819 for(i=0; i < wlen-2; i++)
820 message->osa[i] = buffer[pos++];
821 eicon_log(ccard, 2, "idi_inf: Ch%d: OSA=%s\n", chan->No, message->osa);
822 break;
823 case CAD:
824 pos += wlen;
825 eicon_log(ccard, 2, "idi_inf: Ch%d: Connected Address in ind, len:%x\n",
826 chan->No, wlen);
827 break;
828 case BC:
829 if (wlen > sizeof(message->bc)) {
830 pos += wlen;
831 break;
833 for(i=0; i < wlen; i++)
834 message->bc[i] = buffer[pos++];
835 eicon_log(ccard, 4, "idi_inf: Ch%d: BC = 0x%02x 0x%02x 0x%02x\n", chan->No,
836 message->bc[0],message->bc[1],message->bc[2]);
837 break;
838 case 0x800|BC:
839 if (wlen > sizeof(message->e_bc)) {
840 pos += wlen;
841 break;
843 for(i=0; i < wlen; i++)
844 message->e_bc[i] = buffer[pos++];
845 eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/BC=%d\n", chan->No, message->bc[0]);
846 break;
847 case LLC:
848 if (wlen > sizeof(message->llc)) {
849 pos += wlen;
850 break;
852 for(i=0; i < wlen; i++)
853 message->llc[i] = buffer[pos++];
854 eicon_log(ccard, 4, "idi_inf: Ch%d: LLC=%d %d %d %d\n", chan->No, message->llc[0],
855 message->llc[1],message->llc[2],message->llc[3]);
856 break;
857 case HLC:
858 if (wlen > sizeof(message->hlc)) {
859 pos += wlen;
860 break;
862 for(i=0; i < wlen; i++)
863 message->hlc[i] = buffer[pos++];
864 eicon_log(ccard, 4, "idi_inf: Ch%d: HLC=%x %x %x %x %x\n", chan->No,
865 message->hlc[0], message->hlc[1],
866 message->hlc[2], message->hlc[3], message->hlc[4]);
867 break;
868 case DSP:
869 case 0x600|DSP:
870 if (wlen > sizeof(message->display)) {
871 pos += wlen;
872 break;
874 for(i=0; i < wlen; i++)
875 message->display[i] = buffer[pos++];
876 eicon_log(ccard, 4, "idi_inf: Ch%d: Display: %s\n", chan->No,
877 message->display);
878 break;
879 case 0x600|KEY:
880 if (wlen > sizeof(message->keypad)) {
881 pos += wlen;
882 break;
884 for(i=0; i < wlen; i++)
885 message->keypad[i] = buffer[pos++];
886 eicon_log(ccard, 4, "idi_inf: Ch%d: Keypad: %s\n", chan->No,
887 message->keypad);
888 break;
889 case NI:
890 case 0x600|NI:
891 if (wlen) {
892 switch(buffer[pos] & 127) {
893 case 0:
894 eicon_log(ccard, 4, "idi_inf: Ch%d: User suspended.\n", chan->No);
895 break;
896 case 1:
897 eicon_log(ccard, 4, "idi_inf: Ch%d: User resumed.\n", chan->No);
898 break;
899 case 2:
900 eicon_log(ccard, 4, "idi_inf: Ch%d: Bearer service change.\n", chan->No);
901 break;
902 default:
903 eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Notification %x.\n",
904 chan->No, buffer[pos] & 127);
906 pos += wlen;
908 break;
909 case PI:
910 case 0x600|PI:
911 if (wlen > 1) {
912 switch(buffer[pos+1] & 127) {
913 case 1:
914 eicon_log(ccard, 4, "idi_inf: Ch%d: Call is not end-to-end ISDN.\n", chan->No);
915 break;
916 case 2:
917 eicon_log(ccard, 4, "idi_inf: Ch%d: Destination address is non ISDN.\n", chan->No);
918 break;
919 case 3:
920 eicon_log(ccard, 4, "idi_inf: Ch%d: Origination address is non ISDN.\n", chan->No);
921 break;
922 case 4:
923 eicon_log(ccard, 4, "idi_inf: Ch%d: Call has returned to the ISDN.\n", chan->No);
924 break;
925 case 5:
926 eicon_log(ccard, 4, "idi_inf: Ch%d: Interworking has occurred.\n", chan->No);
927 break;
928 case 8:
929 eicon_log(ccard, 4, "idi_inf: Ch%d: In-band information available.\n", chan->No);
930 break;
931 default:
932 eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Progress %x.\n",
933 chan->No, buffer[pos+1] & 127);
936 pos += wlen;
937 break;
938 case CAU:
939 if (wlen > sizeof(message->cau)) {
940 pos += wlen;
941 break;
943 for(i=0; i < wlen; i++)
944 message->cau[i] = buffer[pos++];
945 memcpy(&chan->cause, &message->cau, 2);
946 eicon_log(ccard, 4, "idi_inf: Ch%d: CAU=%d %d\n", chan->No,
947 message->cau[0],message->cau[1]);
948 break;
949 case 0x800|CAU:
950 if (wlen > sizeof(message->e_cau)) {
951 pos += wlen;
952 break;
954 for(i=0; i < wlen; i++)
955 message->e_cau[i] = buffer[pos++];
956 eicon_log(ccard, 4, "idi_inf: Ch%d: ECAU=%d %d\n", chan->No,
957 message->e_cau[0],message->e_cau[1]);
958 break;
959 case 0x800|CHI:
960 if (wlen > sizeof(message->e_chi)) {
961 pos += wlen;
962 break;
964 for(i=0; i < wlen; i++)
965 message->e_chi[i] = buffer[pos++];
966 eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/CHI=%d\n", chan->No,
967 message->e_cau[0]);
968 break;
969 case 0x800|0x7a:
970 pos ++;
971 message->e_mt=buffer[pos++];
972 eicon_log(ccard, 4, "idi_inf: Ch%d: EMT=0x%x\n", chan->No, message->e_mt);
973 break;
974 case DT:
975 if (wlen > sizeof(message->dt)) {
976 pos += wlen;
977 break;
979 for(i=0; i < wlen; i++)
980 message->dt[i] = buffer[pos++];
981 eicon_log(ccard, 4, "idi_inf: Ch%d: DT: %02d.%02d.%02d %02d:%02d:%02d\n", chan->No,
982 message->dt[2], message->dt[1], message->dt[0],
983 message->dt[3], message->dt[4], message->dt[5]);
984 break;
985 case 0x600|SIN:
986 if (wlen > sizeof(message->sin)) {
987 pos += wlen;
988 break;
990 for(i=0; i < wlen; i++)
991 message->sin[i] = buffer[pos++];
992 eicon_log(ccard, 2, "idi_inf: Ch%d: SIN=%d %d\n", chan->No,
993 message->sin[0],message->sin[1]);
994 break;
995 case 0x600|CPS:
996 eicon_log(ccard, 2, "idi_inf: Ch%d: Called Party Status in ind\n", chan->No);
997 pos += wlen;
998 break;
999 case 0x600|CIF:
1000 for (i = 0; i < wlen; i++)
1001 if (buffer[pos + i] != '0') break;
1002 memcpy(&cmd.parm.num, &buffer[pos + i], wlen - i);
1003 cmd.parm.num[wlen - i] = 0;
1004 eicon_log(ccard, 2, "idi_inf: Ch%d: CIF=%s\n", chan->No, cmd.parm.num);
1005 pos += wlen;
1006 cmd.driver = ccard->myid;
1007 cmd.command = ISDN_STAT_CINF;
1008 cmd.arg = chan->No;
1009 ccard->interface.statcallb(&cmd);
1010 break;
1011 case 0x600|DATE:
1012 eicon_log(ccard, 2, "idi_inf: Ch%d: Date in ind\n", chan->No);
1013 pos += wlen;
1014 break;
1015 case 0xa1:
1016 eicon_log(ccard, 2, "idi_inf: Ch%d: Sending Complete in ind.\n", chan->No);
1017 pos += wlen;
1018 break;
1019 case 0xe08:
1020 case 0xe7a:
1021 case 0xe04:
1022 case 0xe00:
1023 /* *** TODO *** */
1024 case CHA:
1025 /* Charge advice */
1026 case FTY:
1027 case 0x600|FTY:
1028 case CHI:
1029 case 0x800:
1030 /* Not yet interested in this */
1031 pos += wlen;
1032 break;
1033 case 0x880:
1034 /* Managment Information Element */
1035 if (!manbuf) {
1036 eicon_log(ccard, 1, "idi_err: manbuf not allocated\n");
1038 else {
1039 memcpy(&manbuf->data[manbuf->pos], &buffer[pos], wlen);
1040 manbuf->length[manbuf->count] = wlen;
1041 manbuf->count++;
1042 manbuf->pos += wlen;
1044 pos += wlen;
1045 break;
1046 default:
1047 pos += wlen;
1048 eicon_log(ccard, 6, "idi_inf: Ch%d: unknown information element 0x%x in ind, len:%x\n",
1049 chan->No, code, wlen);
1055 void
1056 idi_bc2si(unsigned char *bc, unsigned char *hlc, unsigned char *si1, unsigned char *si2)
1058 si1[0] = 0;
1059 si2[0] = 0;
1060 if (memcmp(bc, BC_Speech, 3) == 0) { /* Speech */
1061 si1[0] = 1;
1062 #ifdef EICON_FULL_SERVICE_OKTETT
1063 si2[0] = 1;
1064 #endif
1066 if (memcmp(bc, BC_31khz, 3) == 0) { /* 3.1kHz audio */
1067 si1[0] = 1;
1068 #ifdef EICON_FULL_SERVICE_OKTETT
1069 si2[0] = 2;
1070 if (memcmp(hlc, HLC_faxg3, 2) == 0) { /* Fax Gr.2/3 */
1071 si1[0] = 2;
1073 #endif
1075 if (memcmp(bc, BC_64k, 2) == 0) { /* unrestricted 64 kbits */
1076 si1[0] = 7;
1078 if (memcmp(bc, BC_video, 3) == 0) { /* video */
1079 si1[0] = 4;
1083 /********************* FAX stuff ***************************/
1085 #ifdef CONFIG_ISDN_TTY_FAX
1088 idi_fill_in_T30(eicon_chan *chan, unsigned char *buffer)
1090 eicon_t30_s *t30 = (eicon_t30_s *) buffer;
1092 if (!chan->fax) {
1093 eicon_log(NULL, 1,"idi_T30: fill_in with NULL fax struct, ERROR\n");
1094 return 0;
1096 memset(t30, 0, sizeof(eicon_t30_s));
1097 t30->station_id_len = EICON_FAXID_LEN;
1098 memcpy(&t30->station_id[0], &chan->fax->id[0], EICON_FAXID_LEN);
1099 t30->resolution = chan->fax->resolution;
1100 t30->rate = chan->fax->rate + 1; /* eicon rate starts with 1 */
1101 t30->format = T30_FORMAT_SFF;
1102 t30->pages_low = 0;
1103 t30->pages_high = 0;
1104 t30->atf = 1; /* optimised for AT+F command set */
1105 t30->code = 0;
1106 t30->feature_bits_low = 0;
1107 t30->feature_bits_high = 0;
1108 t30->control_bits_low = 0;
1109 t30->control_bits_high = 0;
1111 if (chan->fax->nbc) {
1112 /* set compression by DCC value */
1113 switch(chan->fax->compression) {
1114 case (0): /* 1-D modified */
1115 break;
1116 case (1): /* 2-D modified Read */
1117 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
1118 t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
1119 break;
1120 case (2): /* 2-D uncompressed */
1121 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
1122 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
1123 t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
1124 t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
1125 break;
1126 case (3): /* 2-D modified Read */
1127 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING;
1128 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
1129 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
1130 t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
1131 t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING;
1132 t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
1133 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
1134 t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
1135 break;
1137 } else {
1138 /* set compression to best */
1139 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING;
1140 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
1141 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
1142 t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
1143 t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING;
1144 t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
1145 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
1146 t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
1148 switch(chan->fax->ecm) {
1149 case (0): /* disable ECM */
1150 break;
1151 case (1):
1152 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
1153 t30->control_bits_low |= T30_CONTROL_BIT_ECM_64_BYTES;
1154 t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
1155 t30->feature_bits_low |= T30_FEATURE_BIT_ECM_64_BYTES;
1156 break;
1157 case (2):
1158 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
1159 t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
1160 break;
1163 if (DebugVar & 128) {
1164 char st[40];
1165 eicon_log(NULL, 128, "sT30:code = %x\n", t30->code);
1166 eicon_log(NULL, 128, "sT30:rate = %x\n", t30->rate);
1167 eicon_log(NULL, 128, "sT30:res = %x\n", t30->resolution);
1168 eicon_log(NULL, 128, "sT30:format = %x\n", t30->format);
1169 eicon_log(NULL, 128, "sT30:pages_low = %x\n", t30->pages_low);
1170 eicon_log(NULL, 128, "sT30:pages_high = %x\n", t30->pages_high);
1171 eicon_log(NULL, 128, "sT30:atf = %x\n", t30->atf);
1172 eicon_log(NULL, 128, "sT30:control_bits_low = %x\n", t30->control_bits_low);
1173 eicon_log(NULL, 128, "sT30:control_bits_high = %x\n", t30->control_bits_high);
1174 eicon_log(NULL, 128, "sT30:feature_bits_low = %x\n", t30->feature_bits_low);
1175 eicon_log(NULL, 128, "sT30:feature_bits_high = %x\n", t30->feature_bits_high);
1176 //eicon_log(NULL, 128, "sT30:universal_5 = %x\n", t30->universal_5);
1177 //eicon_log(NULL, 128, "sT30:universal_6 = %x\n", t30->universal_6);
1178 //eicon_log(NULL, 128, "sT30:universal_7 = %x\n", t30->universal_7);
1179 eicon_log(NULL, 128, "sT30:station_id_len = %x\n", t30->station_id_len);
1180 eicon_log(NULL, 128, "sT30:head_line_len = %x\n", t30->head_line_len);
1181 strncpy(st, t30->station_id, t30->station_id_len);
1182 st[t30->station_id_len] = 0;
1183 eicon_log(NULL, 128, "sT30:station_id = <%s>\n", st);
1185 return(sizeof(eicon_t30_s));
1188 /* send fax struct */
1190 idi_send_edata(eicon_card *card, eicon_chan *chan)
1192 struct sk_buff *skb;
1193 struct sk_buff *skb2;
1194 eicon_REQ *reqbuf;
1195 eicon_chan_ptr *chan2;
1197 if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) {
1198 eicon_log(card, 1, "idi_snd: Ch%d: send edata on state %d !\n", chan->No, chan->fsm_state);
1199 return -ENODEV;
1201 eicon_log(card, 128, "idi_snd: Ch%d: edata (fax)\n", chan->No);
1203 skb = alloc_skb(sizeof(eicon_REQ) + sizeof(eicon_t30_s), GFP_ATOMIC);
1204 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
1206 if ((!skb) || (!skb2)) {
1207 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_edata()\n", chan->No);
1208 if (skb)
1209 dev_kfree_skb(skb);
1210 if (skb2)
1211 dev_kfree_skb(skb2);
1212 return -ENOMEM;
1215 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
1216 chan2->ptr = chan;
1218 reqbuf = (eicon_REQ *)skb_put(skb, sizeof(eicon_t30_s) + sizeof(eicon_REQ));
1220 reqbuf->Req = IDI_N_EDATA;
1221 reqbuf->ReqCh = chan->e.IndCh;
1222 reqbuf->ReqId = 1;
1224 reqbuf->XBuffer.length = idi_fill_in_T30(chan, reqbuf->XBuffer.P);
1225 reqbuf->Reference = 1; /* Net Entity */
1227 skb_queue_tail(&chan->e.X, skb);
1228 skb_queue_tail(&card->sndq, skb2);
1229 eicon_schedule_tx(card);
1230 return (0);
1233 void
1234 idi_parse_edata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len)
1236 eicon_t30_s *p = (eicon_t30_s *)buffer;
1237 int i;
1239 if (DebugVar & 128) {
1240 char st[40];
1241 eicon_log(ccard, 128, "rT30:len %d , size %d\n", len, sizeof(eicon_t30_s));
1242 eicon_log(ccard, 128, "rT30:code = %x\n", p->code);
1243 eicon_log(ccard, 128, "rT30:rate = %x\n", p->rate);
1244 eicon_log(ccard, 128, "rT30:res = %x\n", p->resolution);
1245 eicon_log(ccard, 128, "rT30:format = %x\n", p->format);
1246 eicon_log(ccard, 128, "rT30:pages_low = %x\n", p->pages_low);
1247 eicon_log(ccard, 128, "rT30:pages_high = %x\n", p->pages_high);
1248 eicon_log(ccard, 128, "rT30:atf = %x\n", p->atf);
1249 eicon_log(ccard, 128, "rT30:control_bits_low = %x\n", p->control_bits_low);
1250 eicon_log(ccard, 128, "rT30:control_bits_high = %x\n", p->control_bits_high);
1251 eicon_log(ccard, 128, "rT30:feature_bits_low = %x\n", p->feature_bits_low);
1252 eicon_log(ccard, 128, "rT30:feature_bits_high = %x\n", p->feature_bits_high);
1253 //eicon_log(ccard, 128, "rT30:universal_5 = %x\n", p->universal_5);
1254 //eicon_log(ccard, 128, "rT30:universal_6 = %x\n", p->universal_6);
1255 //eicon_log(ccard, 128, "rT30:universal_7 = %x\n", p->universal_7);
1256 eicon_log(ccard, 128, "rT30:station_id_len = %x\n", p->station_id_len);
1257 eicon_log(ccard, 128, "rT30:head_line_len = %x\n", p->head_line_len);
1258 strncpy(st, p->station_id, p->station_id_len);
1259 st[p->station_id_len] = 0;
1260 eicon_log(ccard, 128, "rT30:station_id = <%s>\n", st);
1262 if (!chan->fax) {
1263 eicon_log(ccard, 1, "idi_edata: parse to NULL fax struct, ERROR\n");
1264 return;
1266 chan->fax->code = p->code;
1267 i = (p->station_id_len < FAXIDLEN) ? p->station_id_len : (FAXIDLEN - 1);
1268 memcpy(chan->fax->r_id, p->station_id, i);
1269 chan->fax->r_id[i] = 0;
1270 chan->fax->r_resolution = p->resolution;
1271 chan->fax->r_rate = p->rate - 1;
1272 chan->fax->r_binary = 0; /* no binary support */
1273 chan->fax->r_width = 0;
1274 chan->fax->r_length = 2;
1275 chan->fax->r_scantime = 0;
1276 chan->fax->r_compression = 0;
1277 chan->fax->r_ecm = 0;
1278 if (p->feature_bits_low & T30_FEATURE_BIT_2D_CODING) {
1279 chan->fax->r_compression = 1;
1280 if (p->feature_bits_low & T30_FEATURE_BIT_UNCOMPR_ENABLED) {
1281 chan->fax->r_compression = 2;
1284 if (p->feature_bits_low & T30_FEATURE_BIT_T6_CODING) {
1285 chan->fax->r_compression = 3;
1288 if (p->feature_bits_low & T30_FEATURE_BIT_ECM) {
1289 chan->fax->r_ecm = 2;
1290 if (p->feature_bits_low & T30_FEATURE_BIT_ECM_64_BYTES)
1291 chan->fax->r_ecm = 1;
1295 void
1296 idi_fax_send_header(eicon_card *card, eicon_chan *chan, int header)
1298 static __u16 wd2sff[] = {
1299 1728, 2048, 2432, 1216, 864
1301 static __u16 ln2sff[2][3] = {
1302 { 1143, 1401, 0 } , { 2287, 2802, 0 }
1304 struct sk_buff *skb;
1305 eicon_sff_dochead *doc;
1306 eicon_sff_pagehead *page;
1307 u_char *docp;
1309 if (!chan->fax) {
1310 eicon_log(card, 1, "idi_fax: send head with NULL fax struct, ERROR\n");
1311 return;
1313 if (header == 2) { /* DocHeader + PageHeader */
1314 skb = alloc_skb(sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead), GFP_ATOMIC);
1315 } else {
1316 skb = alloc_skb(sizeof(eicon_sff_pagehead), GFP_ATOMIC);
1318 if (!skb) {
1319 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_header()\n", chan->No);
1320 return;
1323 if (header == 2) { /* DocHeader + PageHeader */
1324 docp = skb_put(skb, sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead));
1325 doc = (eicon_sff_dochead *) docp;
1326 page = (eicon_sff_pagehead *) (docp + sizeof(eicon_sff_dochead));
1327 memset(docp, 0,sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead));
1328 doc->id = 0x66666653;
1329 doc->version = 0x01;
1330 doc->off1pagehead = sizeof(eicon_sff_dochead);
1331 } else {
1332 page = (eicon_sff_pagehead *)skb_put(skb, sizeof(eicon_sff_pagehead));
1333 memset(page, 0, sizeof(eicon_sff_pagehead));
1336 switch(header) {
1337 case 1: /* PageHeaderEnd */
1338 page->pageheadid = 254;
1339 page->pageheadlen = 0;
1340 break;
1341 case 0: /* PageHeader */
1342 case 2: /* DocHeader + PageHeader */
1343 page->pageheadid = 254;
1344 page->pageheadlen = sizeof(eicon_sff_pagehead) - 2;
1345 page->resvert = chan->fax->resolution;
1346 page->reshoriz = 0; /* always 203 dpi */
1347 page->coding = 0; /* always 1D */
1348 page->linelength = wd2sff[chan->fax->width];
1349 page->pagelength = ln2sff[chan->fax->resolution][chan->fax->length];
1350 eicon_log(card, 128, "sSFF-Head: linelength = %d\n", page->linelength);
1351 eicon_log(card, 128, "sSFF-Head: pagelength = %d\n", page->pagelength);
1352 break;
1354 idi_send_data(card, chan, 0, skb, 0);
1357 void
1358 idi_fax_cmd(eicon_card *card, eicon_chan *chan)
1360 isdn_ctrl cmd;
1362 if ((!card) || (!chan))
1363 return;
1365 if (!chan->fax) {
1366 eicon_log(card, 1, "idi_fax: cmd with NULL fax struct, ERROR\n");
1367 return;
1369 switch (chan->fax->code) {
1370 case ISDN_TTY_FAX_DT:
1371 if (chan->fax->phase == ISDN_FAX_PHASE_B) {
1372 idi_send_edata(card, chan);
1373 break;
1375 if (chan->fax->phase == ISDN_FAX_PHASE_D) {
1376 idi_send_edata(card, chan);
1377 break;
1379 break;
1381 case ISDN_TTY_FAX_DR:
1382 if (chan->fax->phase == ISDN_FAX_PHASE_B) {
1383 idi_send_edata(card, chan);
1385 cmd.driver = card->myid;
1386 cmd.command = ISDN_STAT_FAXIND;
1387 cmd.arg = chan->No;
1388 chan->fax->r_code = ISDN_TTY_FAX_CFR;
1389 card->interface.statcallb(&cmd);
1391 cmd.driver = card->myid;
1392 cmd.command = ISDN_STAT_FAXIND;
1393 cmd.arg = chan->No;
1394 chan->fax->r_code = ISDN_TTY_FAX_RID;
1395 card->interface.statcallb(&cmd);
1397 /* telling 1-D compression */
1398 chan->fax->r_compression = 0;
1399 cmd.driver = card->myid;
1400 cmd.command = ISDN_STAT_FAXIND;
1401 cmd.arg = chan->No;
1402 chan->fax->r_code = ISDN_TTY_FAX_DCS;
1403 card->interface.statcallb(&cmd);
1405 chan->fax2.NextObject = FAX_OBJECT_DOCU;
1406 chan->fax2.PrevObject = FAX_OBJECT_DOCU;
1408 break;
1410 if (chan->fax->phase == ISDN_FAX_PHASE_D) {
1411 idi_send_edata(card, chan);
1412 break;
1414 break;
1416 case ISDN_TTY_FAX_ET:
1417 switch(chan->fax->fet) {
1418 case 0:
1419 case 1:
1420 idi_fax_send_header(card, chan, 0);
1421 break;
1422 case 2:
1423 idi_fax_send_header(card, chan, 1);
1424 break;
1426 break;
1430 void
1431 idi_edata_rcveop(eicon_card *card, eicon_chan *chan)
1433 isdn_ctrl cmd;
1435 if (!chan->fax) {
1436 eicon_log(card, 1, "idi_edata: rcveop with NULL fax struct, ERROR\n");
1437 return;
1439 cmd.driver = card->myid;
1440 cmd.command = ISDN_STAT_FAXIND;
1441 cmd.arg = chan->No;
1442 chan->fax->r_code = ISDN_TTY_FAX_ET;
1443 card->interface.statcallb(&cmd);
1446 void
1447 idi_reset_fax_stat(eicon_chan *chan)
1449 chan->fax2.LineLen = 0;
1450 chan->fax2.LineData = 0;
1451 chan->fax2.LineDataLen = 0;
1452 chan->fax2.NullByteExist = 0;
1453 chan->fax2.Dle = 0;
1454 chan->fax2.PageCount = 0;
1455 chan->fax2.Eop = 0;
1458 void
1459 idi_edata_action(eicon_card *ccard, eicon_chan *chan, char *buffer, int len)
1461 isdn_ctrl cmd;
1463 if (!chan->fax) {
1464 eicon_log(ccard, 1, "idi_edata: action with NULL fax struct, ERROR\n");
1465 return;
1467 if (chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) {
1468 idi_parse_edata(ccard, chan, buffer, len);
1470 if (chan->fax->phase == ISDN_FAX_PHASE_A) {
1471 idi_reset_fax_stat(chan);
1473 chan->fsm_state = EICON_STATE_ACTIVE;
1474 cmd.driver = ccard->myid;
1475 cmd.command = ISDN_STAT_BCONN;
1476 cmd.arg = chan->No;
1477 strcpy(cmd.parm.num, "");
1478 ccard->interface.statcallb(&cmd);
1480 cmd.driver = ccard->myid;
1481 cmd.command = ISDN_STAT_FAXIND;
1482 cmd.arg = chan->No;
1483 chan->fax->r_code = ISDN_TTY_FAX_FCON;
1484 ccard->interface.statcallb(&cmd);
1486 cmd.driver = ccard->myid;
1487 cmd.command = ISDN_STAT_FAXIND;
1488 cmd.arg = chan->No;
1489 chan->fax->r_code = ISDN_TTY_FAX_RID;
1490 ccard->interface.statcallb(&cmd);
1492 cmd.driver = ccard->myid;
1493 cmd.command = ISDN_STAT_FAXIND;
1494 cmd.arg = chan->No;
1495 chan->fax->r_code = ISDN_TTY_FAX_DIS;
1496 ccard->interface.statcallb(&cmd);
1498 if (chan->fax->r_compression != 0) {
1499 /* telling fake compression in second DIS message */
1500 chan->fax->r_compression = 0;
1501 cmd.driver = ccard->myid;
1502 cmd.command = ISDN_STAT_FAXIND;
1503 cmd.arg = chan->No;
1504 chan->fax->r_code = ISDN_TTY_FAX_DIS;
1505 ccard->interface.statcallb(&cmd);
1508 cmd.driver = ccard->myid;
1509 cmd.command = ISDN_STAT_FAXIND;
1510 cmd.arg = chan->No;
1511 chan->fax->r_code = ISDN_TTY_FAX_SENT; /* OK message */
1512 ccard->interface.statcallb(&cmd);
1513 } else
1514 if (chan->fax->phase == ISDN_FAX_PHASE_D) {
1516 if ((chan->fax->code == EDATA_T30_MCF) &&
1517 (chan->fax->fet != 2)) {
1518 cmd.driver = ccard->myid;
1519 cmd.command = ISDN_STAT_FAXIND;
1520 cmd.arg = chan->No;
1521 chan->fax->r_code = ISDN_TTY_FAX_PTS;
1522 ccard->interface.statcallb(&cmd);
1525 switch(chan->fax->fet) {
1526 case 0: /* new page */
1527 /* stay in phase D , wait on cmd +FDT */
1528 break;
1529 case 1: /* new document */
1530 /* link-level switch to phase B */
1531 break;
1532 case 2: /* session end */
1533 default:
1534 /* send_edata produces error on some */
1535 /* fax-machines here, so we don't */
1536 /* idi_send_edata(ccard, chan); */
1537 break;
1542 if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
1543 idi_parse_edata(ccard, chan, buffer, len);
1545 if ((chan->fax->code == EDATA_T30_DCS) &&
1546 (chan->fax->phase == ISDN_FAX_PHASE_A)) {
1547 idi_reset_fax_stat(chan);
1549 cmd.driver = ccard->myid;
1550 cmd.command = ISDN_STAT_BCONN;
1551 cmd.arg = chan->No;
1552 strcpy(cmd.parm.num, "");
1553 ccard->interface.statcallb(&cmd);
1555 cmd.driver = ccard->myid;
1556 cmd.command = ISDN_STAT_FAXIND;
1557 cmd.arg = chan->No;
1558 chan->fax->r_code = ISDN_TTY_FAX_FCON_I;
1559 ccard->interface.statcallb(&cmd);
1560 } else
1561 if ((chan->fax->code == EDATA_T30_TRAIN_OK) &&
1562 (chan->fax->phase == ISDN_FAX_PHASE_A)) {
1563 cmd.driver = ccard->myid;
1564 cmd.command = ISDN_STAT_FAXIND;
1565 cmd.arg = chan->No;
1566 chan->fax->r_code = ISDN_TTY_FAX_RID;
1567 ccard->interface.statcallb(&cmd);
1569 cmd.driver = ccard->myid;
1570 cmd.command = ISDN_STAT_FAXIND;
1571 cmd.arg = chan->No;
1572 chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;
1573 ccard->interface.statcallb(&cmd);
1574 } else
1575 if ((chan->fax->code == EDATA_T30_TRAIN_OK) &&
1576 (chan->fax->phase == ISDN_FAX_PHASE_B)) {
1577 cmd.driver = ccard->myid;
1578 cmd.command = ISDN_STAT_FAXIND;
1579 cmd.arg = chan->No;
1580 chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;
1581 ccard->interface.statcallb(&cmd);
1582 } else
1583 if (chan->fax->phase == ISDN_FAX_PHASE_C) {
1584 switch(chan->fax->code) {
1585 case EDATA_T30_TRAIN_OK:
1586 idi_send_edata(ccard, chan);
1587 break;
1588 case EDATA_T30_MPS:
1589 chan->fax->fet = 0;
1590 idi_edata_rcveop(ccard, chan);
1591 break;
1592 case EDATA_T30_EOM:
1593 chan->fax->fet = 1;
1594 idi_edata_rcveop(ccard, chan);
1595 break;
1596 case EDATA_T30_EOP:
1597 chan->fax->fet = 2;
1598 idi_edata_rcveop(ccard, chan);
1599 break;
1605 void
1606 fax_put_rcv(eicon_card *ccard, eicon_chan *chan, u_char *Data, int len)
1608 struct sk_buff *skb;
1610 skb = alloc_skb(len + MAX_HEADER_LEN, GFP_ATOMIC);
1611 if (!skb) {
1612 eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_put_rcv()\n", chan->No);
1613 return;
1615 skb_reserve(skb, MAX_HEADER_LEN);
1616 memcpy(skb_put(skb, len), Data, len);
1617 ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb);
1620 void
1621 idi_faxdata_rcv(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb)
1623 eicon_OBJBUFFER InBuf;
1624 eicon_OBJBUFFER LineBuf;
1625 unsigned int Length = 0;
1626 unsigned int aLength = 0;
1627 unsigned int ObjectSize = 0;
1628 unsigned int ObjHeadLen = 0;
1629 unsigned int ObjDataLen = 0;
1630 __u8 Recordtype;
1631 __u8 PageHeaderLen;
1632 __u8 Event;
1633 eicon_sff_pagehead *ob_page;
1635 __u16 Cl2Eol = 0x8000;
1637 # define EVENT_NONE 0
1638 # define EVENT_NEEDDATA 1
1640 if (!chan->fax) {
1641 eicon_log(ccard, 1, "idi_fax: rcvdata with NULL fax struct, ERROR\n");
1642 return;
1647 if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
1648 InBuf.Data = skb->data;
1649 InBuf.Size = skb->len;
1650 InBuf.Len = 0;
1651 InBuf.Next = InBuf.Data;
1652 LineBuf.Data = chan->fax2.abLine;
1653 LineBuf.Size = sizeof(chan->fax2.abLine);
1654 LineBuf.Len = chan->fax2.LineLen;
1655 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1657 Event = EVENT_NONE;
1658 while (Event == EVENT_NONE) {
1659 switch(chan->fax2.NextObject) {
1660 case FAX_OBJECT_DOCU:
1661 Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
1662 if (Length < sizeof(eicon_sff_dochead)) {
1663 Event = EVENT_NEEDDATA;
1664 break;
1666 ObjectSize = sizeof(eicon_sff_dochead);
1667 Length = ObjectSize;
1668 if (LineBuf.Len < Length) {
1669 Length -= LineBuf.Len;
1670 LineBuf.Len = 0;
1671 LineBuf.Next = LineBuf.Data;
1672 InBuf.Len += Length;
1673 InBuf.Next += Length;
1674 } else {
1675 LineBuf.Len -= Length;
1676 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1677 memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
1679 chan->fax2.PrevObject = FAX_OBJECT_DOCU;
1680 chan->fax2.NextObject = FAX_OBJECT_PAGE;
1681 break;
1683 case FAX_OBJECT_PAGE:
1684 Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
1685 if (Length < 2) {
1686 Event = EVENT_NEEDDATA;
1687 break;
1689 if (LineBuf.Len == 0) {
1690 *LineBuf.Next++ = *InBuf.Next++;
1691 LineBuf.Len++;
1692 InBuf.Len++;
1694 if (LineBuf.Len == 1) {
1695 *LineBuf.Next++ = *InBuf.Next++;
1696 LineBuf.Len++;
1697 InBuf.Len++;
1699 PageHeaderLen = *(LineBuf.Data + 1);
1700 ObjectSize = (PageHeaderLen == 0) ? 2 : sizeof(eicon_sff_pagehead);
1701 if (Length < ObjectSize) {
1702 Event = EVENT_NEEDDATA;
1703 break;
1705 Length = ObjectSize;
1706 /* extract page dimensions */
1707 if (LineBuf.Len < Length) {
1708 aLength = Length - LineBuf.Len;
1709 memcpy(LineBuf.Next, InBuf.Next, aLength);
1710 LineBuf.Next += aLength;
1711 InBuf.Next += aLength;
1712 LineBuf.Len += aLength;
1713 InBuf.Len += aLength;
1715 if (Length > 2) {
1716 ob_page = (eicon_sff_pagehead *)LineBuf.Data;
1717 switch(ob_page->linelength) {
1718 case 2048:
1719 chan->fax->r_width = 1;
1720 break;
1721 case 2432:
1722 chan->fax->r_width = 2;
1723 break;
1724 case 1216:
1725 chan->fax->r_width = 3;
1726 break;
1727 case 864:
1728 chan->fax->r_width = 4;
1729 break;
1730 case 1728:
1731 default:
1732 chan->fax->r_width = 0;
1734 switch(ob_page->pagelength) {
1735 case 1143:
1736 case 2287:
1737 chan->fax->r_length = 0;
1738 break;
1739 case 1401:
1740 case 2802:
1741 chan->fax->r_length = 1;
1742 break;
1743 default:
1744 chan->fax->r_length = 2;
1746 eicon_log(ccard, 128, "rSFF-Head: linelength = %d\n", ob_page->linelength);
1747 eicon_log(ccard, 128, "rSFF-Head: pagelength = %d\n", ob_page->pagelength);
1749 LineBuf.Len -= Length;
1750 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1751 memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
1753 chan->fax2.PrevObject = FAX_OBJECT_PAGE;
1754 chan->fax2.NextObject = FAX_OBJECT_LINE;
1755 break;
1757 case FAX_OBJECT_LINE:
1758 Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
1759 if (Length < 1) {
1760 Event = EVENT_NEEDDATA;
1761 break;
1763 if (LineBuf.Len == 0) {
1764 *LineBuf.Next++ = *InBuf.Next++;
1765 LineBuf.Len++;
1766 InBuf.Len++;
1768 Recordtype = *LineBuf.Data;
1769 if (Recordtype == 0) {
1770 /* recordtype pixel row (2 byte length) */
1771 ObjHeadLen = 3;
1772 if (Length < ObjHeadLen) {
1773 Event = EVENT_NEEDDATA;
1774 break;
1776 while (LineBuf.Len < ObjHeadLen) {
1777 *LineBuf.Next++ = *InBuf.Next++;
1778 LineBuf.Len++;
1779 InBuf.Len++;
1781 ObjDataLen = *((__u16*) (LineBuf.Data + 1));
1782 ObjectSize = ObjHeadLen + ObjDataLen;
1783 if (Length < ObjectSize) {
1784 Event = EVENT_NEEDDATA;
1785 break;
1787 } else
1788 if ((Recordtype >= 1) && (Recordtype <= 216)) {
1789 /* recordtype pixel row (1 byte length) */
1790 ObjHeadLen = 1;
1791 ObjDataLen = Recordtype;
1792 ObjectSize = ObjHeadLen + ObjDataLen;
1793 if (Length < ObjectSize) {
1794 Event = EVENT_NEEDDATA;
1795 break;
1797 } else
1798 if ((Recordtype >= 217) && (Recordtype <= 253)) {
1799 /* recordtype empty lines */
1800 ObjHeadLen = 1;
1801 ObjDataLen = 0;
1802 ObjectSize = ObjHeadLen + ObjDataLen;
1803 LineBuf.Len--;
1804 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1805 memmove(LineBuf.Data, LineBuf.Data + 1, LineBuf.Len);
1806 break;
1807 } else
1808 if (Recordtype == 254) {
1809 /* recordtype page header */
1810 chan->fax2.PrevObject = FAX_OBJECT_LINE;
1811 chan->fax2.NextObject = FAX_OBJECT_PAGE;
1812 break;
1813 } else {
1814 /* recordtype user information */
1815 ObjHeadLen = 2;
1816 if (Length < ObjHeadLen) {
1817 Event = EVENT_NEEDDATA;
1818 break;
1820 while (LineBuf.Len < ObjHeadLen) {
1821 *LineBuf.Next++ = *InBuf.Next++;
1822 LineBuf.Len++;
1823 InBuf.Len++;
1825 ObjDataLen = *(LineBuf.Data + 1);
1826 ObjectSize = ObjHeadLen + ObjDataLen;
1827 if (ObjDataLen == 0) {
1828 /* illegal line coding */
1829 LineBuf.Len -= ObjHeadLen;
1830 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1831 memmove(LineBuf.Data, LineBuf.Data + ObjHeadLen, LineBuf.Len);
1832 break;
1833 } else {
1834 /* user information */
1835 if (Length < ObjectSize) {
1836 Event = EVENT_NEEDDATA;
1837 break;
1839 Length = ObjectSize;
1840 if (LineBuf.Len < Length) {
1841 Length -= LineBuf.Len;
1842 LineBuf.Len = 0;
1843 LineBuf.Next = LineBuf.Data;
1844 InBuf.Len += Length;
1845 InBuf.Next += Length;
1846 } else {
1847 LineBuf.Len -= Length;
1848 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1849 memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
1852 break;
1854 Length = ObjectSize;
1855 if (LineBuf.Len > ObjHeadLen) {
1856 fax_put_rcv(ccard, chan, LineBuf.Data + ObjHeadLen,
1857 (LineBuf.Len - ObjHeadLen));
1859 Length -= LineBuf.Len;
1860 LineBuf.Len = 0;
1861 LineBuf.Next = LineBuf.Data;
1862 if (Length > 0) {
1863 fax_put_rcv(ccard, chan, InBuf.Next, Length);
1864 InBuf.Len += Length;
1865 InBuf.Next += Length;
1867 fax_put_rcv(ccard, chan, (__u8 *)&Cl2Eol, sizeof(Cl2Eol));
1868 break;
1869 } /* end of switch (chan->fax2.NextObject) */
1870 } /* end of while (Event==EVENT_NONE) */
1871 if (InBuf.Len < InBuf.Size) {
1872 Length = InBuf.Size - InBuf.Len;
1873 if ((LineBuf.Len + Length) > LineBuf.Size) {
1874 eicon_log(ccard, 1, "idi_fax: Ch%d: %d bytes dropping, small buffer\n", chan->No,
1875 Length);
1876 } else {
1877 memcpy(LineBuf.Next, InBuf.Next, Length);
1878 LineBuf.Len += Length;
1881 chan->fax2.LineLen = LineBuf.Len;
1882 } else { /* CONN_OUT */
1883 /* On CONN_OUT we do not need incoming data, drop it */
1884 /* maybe later for polling */
1887 # undef EVENT_NONE
1888 # undef EVENT_NEEDDATA
1890 return;
1894 idi_fax_send_outbuf(eicon_card *ccard, eicon_chan *chan, eicon_OBJBUFFER *OutBuf)
1896 struct sk_buff *skb;
1898 skb = alloc_skb(OutBuf->Len, GFP_ATOMIC);
1899 if (!skb) {
1900 eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_outbuf()\n", chan->No);
1901 return(-1);
1903 memcpy(skb_put(skb, OutBuf->Len), OutBuf->Data, OutBuf->Len);
1905 OutBuf->Len = 0;
1906 OutBuf->Next = OutBuf->Data;
1908 return(idi_send_data(ccard, chan, 0, skb, 1));
1912 idi_faxdata_send(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb)
1914 isdn_ctrl cmd;
1915 eicon_OBJBUFFER InBuf;
1916 __u8 InData;
1917 __u8 InMask;
1918 eicon_OBJBUFFER OutBuf;
1919 eicon_OBJBUFFER LineBuf;
1920 __u32 LineData;
1921 unsigned int LineDataLen;
1922 __u8 Byte;
1923 __u8 Event;
1924 int ret = 1;
1926 # define EVENT_NONE 0
1927 # define EVENT_EOD 1
1928 # define EVENT_EOL 2
1929 # define EVENT_EOP 3
1931 if ((!ccard) || (!chan))
1932 return -1;
1934 if (!chan->fax) {
1935 eicon_log(ccard, 1, "idi_fax: senddata with NULL fax struct, ERROR\n");
1936 return -1;
1939 if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
1940 /* Simply ignore any data written in data mode when receiving a fax. */
1941 /* This is not completely correct because only XON's should come here. */
1942 dev_kfree_skb(skb);
1943 return 1;
1946 if (chan->fax->phase != ISDN_FAX_PHASE_C) {
1947 dev_kfree_skb(skb);
1948 return 1;
1951 if (chan->queued + skb->len > 1200)
1952 return 0;
1954 InBuf.Data = skb->data;
1955 InBuf.Size = skb->len;
1956 InBuf.Len = 0;
1957 InBuf.Next = InBuf.Data;
1958 InData = 0;
1959 InMask = 0;
1961 LineBuf.Data = chan->fax2.abLine;
1962 LineBuf.Size = sizeof(chan->fax2.abLine);
1963 LineBuf.Len = chan->fax2.LineLen;
1964 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1965 LineData = chan->fax2.LineData;
1966 LineDataLen = chan->fax2.LineDataLen;
1968 OutBuf.Data = chan->fax2.abFrame;
1969 OutBuf.Size = sizeof(chan->fax2.abFrame);
1970 OutBuf.Len = 0;
1971 OutBuf.Next = OutBuf.Data;
1973 Event = EVENT_NONE;
1975 chan->fax2.Eop = 0;
1977 for (;;) {
1978 for (;;) {
1979 if (InMask == 0) {
1980 if (InBuf.Len >= InBuf.Size) {
1981 Event = EVENT_EOD;
1982 break;
1984 if ((chan->fax2.Dle != _DLE_) && *InBuf.Next == _DLE_) {
1985 chan->fax2.Dle = _DLE_;
1986 InBuf.Next++;
1987 InBuf.Len++;
1988 if (InBuf.Len >= InBuf.Size) {
1989 Event = EVENT_EOD;
1990 break;
1993 if (chan->fax2.Dle == _DLE_) {
1994 chan->fax2.Dle = 0;
1995 if (*InBuf.Next == _ETX_) {
1996 Event = EVENT_EOP;
1997 break;
1998 } else
1999 if (*InBuf.Next == _DLE_) {
2000 /* do nothing */
2001 } else {
2002 eicon_log(ccard, 1,
2003 "idi_err: Ch%d: unknown DLE escape %02x found\n",
2004 chan->No, *InBuf.Next);
2005 InBuf.Next++;
2006 InBuf.Len++;
2007 if (InBuf.Len >= InBuf.Size) {
2008 Event = EVENT_EOD;
2009 break;
2013 InBuf.Len++;
2014 InData = *InBuf.Next++;
2015 InMask = (chan->fax->bor) ? 0x80 : 0x01;
2017 while (InMask) {
2018 LineData >>= 1;
2019 LineDataLen++;
2020 if (InData & InMask)
2021 LineData |= 0x80000000;
2022 if (chan->fax->bor)
2023 InMask >>= 1;
2024 else
2025 InMask <<= 1;
2027 if ((LineDataLen >= T4_EOL_BITSIZE) &&
2028 ((LineData & T4_EOL_MASK_DWORD) == T4_EOL_DWORD)) {
2029 Event = EVENT_EOL;
2030 if (LineDataLen > T4_EOL_BITSIZE) {
2031 Byte = (__u8)
2032 ((LineData & ~T4_EOL_MASK_DWORD) >>
2033 (32 - LineDataLen));
2034 if (Byte == 0) {
2035 if (! chan->fax2.NullByteExist) {
2036 chan->fax2.NullBytesPos = LineBuf.Len;
2037 chan->fax2.NullByteExist = 1;
2039 } else {
2040 chan->fax2.NullByteExist = 0;
2042 if (LineBuf.Len < LineBuf.Size) {
2043 *LineBuf.Next++ = Byte;
2044 LineBuf.Len++;
2047 LineDataLen = 0;
2048 break;
2050 if (LineDataLen >= T4_EOL_BITSIZE + 8) {
2051 Byte = (__u8)
2052 ((LineData & ~T4_EOL_MASK_DWORD) >>
2053 (32 - T4_EOL_BITSIZE - 8));
2054 LineData &= T4_EOL_MASK_DWORD;
2055 LineDataLen = T4_EOL_BITSIZE;
2056 if (Byte == 0) {
2057 if (! chan->fax2.NullByteExist) {
2058 chan->fax2.NullBytesPos = LineBuf.Len;
2059 chan->fax2.NullByteExist = 1;
2061 } else {
2062 chan->fax2.NullByteExist = 0;
2064 if (LineBuf.Len < LineBuf.Size) {
2065 *LineBuf.Next++ = Byte;
2066 LineBuf.Len++;
2070 if (Event != EVENT_NONE)
2071 break;
2074 if ((Event != EVENT_EOL) && (Event != EVENT_EOP))
2075 break;
2077 if ((Event == EVENT_EOP) && (LineDataLen > 0)) {
2078 LineData >>= 32 - LineDataLen;
2079 LineDataLen = 0;
2080 while (LineData != 0) {
2081 Byte = (__u8) LineData;
2082 LineData >>= 8;
2083 if (Byte == 0) {
2084 if (! chan->fax2.NullByteExist) {
2085 chan->fax2.NullBytesPos = LineBuf.Len;
2086 chan->fax2.NullByteExist = 1;
2088 } else {
2089 chan->fax2.NullByteExist = 0;
2091 if (LineBuf.Len < LineBuf.Size) {
2092 *LineBuf.Next++ = Byte;
2093 LineBuf.Len++;
2098 if (chan->fax2.NullByteExist) {
2099 if (chan->fax2.NullBytesPos == 0) {
2100 LineBuf.Len = 0;
2101 } else {
2102 LineBuf.Len = chan->fax2.NullBytesPos + 1;
2105 if (LineBuf.Len > 0) {
2106 if (OutBuf.Len + LineBuf.Len + SFF_LEN_FLD_SIZE > OutBuf.Size) {
2107 ret = idi_fax_send_outbuf(ccard, chan, &OutBuf);
2109 if (LineBuf.Len <= 216) {
2110 *OutBuf.Next++ = (__u8) LineBuf.Len;
2111 OutBuf.Len++;
2112 } else {
2113 *OutBuf.Next++ = 0;
2114 *((__u16 *) OutBuf.Next)++ = (__u16) LineBuf.Len;
2115 OutBuf.Len += 3;
2117 memcpy(OutBuf.Next, LineBuf.Data, LineBuf.Len);
2118 OutBuf.Next += LineBuf.Len;
2119 OutBuf.Len += LineBuf.Len;
2121 LineBuf.Len = 0;
2122 LineBuf.Next = LineBuf.Data;
2123 chan->fax2.NullByteExist = 0;
2124 if (Event == EVENT_EOP)
2125 break;
2127 Event = EVENT_NONE;
2130 if (Event == EVENT_EOP) {
2131 chan->fax2.Eop = 1;
2132 chan->fax2.PageCount++;
2133 cmd.driver = ccard->myid;
2134 cmd.command = ISDN_STAT_FAXIND;
2135 cmd.arg = chan->No;
2136 chan->fax->r_code = ISDN_TTY_FAX_EOP;
2137 ccard->interface.statcallb(&cmd);
2139 if (OutBuf.Len > 0) {
2140 ret = idi_fax_send_outbuf(ccard, chan, &OutBuf);
2143 chan->fax2.LineLen = LineBuf.Len;
2144 chan->fax2.LineData = LineData;
2145 chan->fax2.LineDataLen = LineDataLen;
2147 # undef EVENT_NONE
2148 # undef EVENT_EOD
2149 # undef EVENT_EOL
2150 # undef EVENT_EOP
2152 if (ret >= 0)
2153 dev_kfree_skb(skb);
2154 if (ret == 0)
2155 ret = 1;
2156 return(ret);
2159 void
2160 idi_fax_hangup(eicon_card *ccard, eicon_chan *chan)
2162 isdn_ctrl cmd;
2164 if (!chan->fax) {
2165 eicon_log(ccard, 1, "idi_fax: hangup with NULL fax struct, ERROR\n");
2166 return;
2168 if ((chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) &&
2169 (chan->fax->code == 0)) {
2170 cmd.driver = ccard->myid;
2171 cmd.command = ISDN_STAT_FAXIND;
2172 cmd.arg = chan->No;
2173 chan->fax->r_code = ISDN_TTY_FAX_PTS;
2174 ccard->interface.statcallb(&cmd);
2176 if ((chan->fax->code > 1) && (chan->fax->code < 120))
2177 chan->fax->code += 120;
2178 chan->fax->r_code = ISDN_TTY_FAX_HNG;
2179 cmd.driver = ccard->myid;
2180 cmd.command = ISDN_STAT_FAXIND;
2181 cmd.arg = chan->No;
2182 ccard->interface.statcallb(&cmd);
2185 #endif /******** FAX ********/
2188 idi_send_udata(eicon_card *card, eicon_chan *chan, int UReq, u_char *buffer, int len)
2190 struct sk_buff *skb;
2191 struct sk_buff *skb2;
2192 eicon_REQ *reqbuf;
2193 eicon_chan_ptr *chan2;
2195 if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) {
2196 eicon_log(card, 1, "idi_snd: Ch%d: send udata on state %d !\n", chan->No, chan->fsm_state);
2197 return -ENODEV;
2199 eicon_log(card, 8, "idi_snd: Ch%d: udata 0x%x: %d %d %d %d\n", chan->No,
2200 UReq, buffer[0], buffer[1], buffer[2], buffer[3]);
2202 skb = alloc_skb(sizeof(eicon_REQ) + len + 1, GFP_ATOMIC);
2203 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
2205 if ((!skb) || (!skb2)) {
2206 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_udata()\n", chan->No);
2207 if (skb)
2208 dev_kfree_skb(skb);
2209 if (skb2)
2210 dev_kfree_skb(skb2);
2211 return -ENOMEM;
2214 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
2215 chan2->ptr = chan;
2217 reqbuf = (eicon_REQ *)skb_put(skb, 1 + len + sizeof(eicon_REQ));
2219 reqbuf->Req = IDI_N_UDATA;
2220 reqbuf->ReqCh = chan->e.IndCh;
2221 reqbuf->ReqId = 1;
2223 reqbuf->XBuffer.length = len + 1;
2224 reqbuf->XBuffer.P[0] = UReq;
2225 memcpy(&reqbuf->XBuffer.P[1], buffer, len);
2226 reqbuf->Reference = 1; /* Net Entity */
2228 skb_queue_tail(&chan->e.X, skb);
2229 skb_queue_tail(&card->sndq, skb2);
2230 eicon_schedule_tx(card);
2231 return (0);
2234 void
2235 idi_audio_cmd(eicon_card *ccard, eicon_chan *chan, int cmd, u_char *value)
2237 u_char buf[6];
2238 struct enable_dtmf_s *dtmf_buf = (struct enable_dtmf_s *)buf;
2240 if ((!ccard) || (!chan))
2241 return;
2243 memset(buf, 0, 6);
2244 switch(cmd) {
2245 case ISDN_AUDIO_SETDD:
2246 if (value[0]) {
2247 dtmf_buf->tone = (__u16) (value[1] * 5);
2248 dtmf_buf->gap = (__u16) (value[1] * 5);
2249 idi_send_udata(ccard, chan,
2250 DSP_UDATA_REQUEST_ENABLE_DTMF_RECEIVER,
2251 buf, 4);
2252 } else {
2253 idi_send_udata(ccard, chan,
2254 DSP_UDATA_REQUEST_DISABLE_DTMF_RECEIVER,
2255 buf, 0);
2257 break;
2261 void
2262 idi_parse_udata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len)
2264 isdn_ctrl cmd;
2265 eicon_dsp_ind *p = (eicon_dsp_ind *) (&buffer[1]);
2266 static char *connmsg[] =
2267 {"", "V.21", "V.23", "V.22", "V.22bis", "V.32bis", "V.34",
2268 "V.8", "Bell 212A", "Bell 103", "V.29 Leased", "V.33 Leased", "V.90",
2269 "V.21 CH2", "V.27ter", "V.29", "V.33", "V.17"};
2270 static u_char dtmf_code[] = {
2271 '1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D'
2274 if ((!ccard) || (!chan))
2275 return;
2277 switch (buffer[0]) {
2278 case DSP_UDATA_INDICATION_SYNC:
2279 eicon_log(ccard, 16, "idi_ind: Ch%d: UDATA_SYNC time %d\n", chan->No, p->time);
2280 break;
2281 case DSP_UDATA_INDICATION_DCD_OFF:
2282 eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_OFF time %d\n", chan->No, p->time);
2283 break;
2284 case DSP_UDATA_INDICATION_DCD_ON:
2285 if ((chan->l2prot == ISDN_PROTO_L2_MODEM) &&
2286 (chan->fsm_state == EICON_STATE_WMCONN)) {
2287 chan->fsm_state = EICON_STATE_ACTIVE;
2288 cmd.driver = ccard->myid;
2289 cmd.command = ISDN_STAT_BCONN;
2290 cmd.arg = chan->No;
2291 sprintf(cmd.parm.num, "%d/%s", p->speed, connmsg[p->norm]);
2292 ccard->interface.statcallb(&cmd);
2294 eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_ON time %d\n", chan->No, p->time);
2295 eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No,
2296 p->norm, p->options, p->speed, p->delay);
2297 break;
2298 case DSP_UDATA_INDICATION_CTS_OFF:
2299 eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_OFF time %d\n", chan->No, p->time);
2300 break;
2301 case DSP_UDATA_INDICATION_CTS_ON:
2302 eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_ON time %d\n", chan->No, p->time);
2303 eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No,
2304 p->norm, p->options, p->speed, p->delay);
2305 break;
2306 case DSP_UDATA_INDICATION_DISCONNECT:
2307 eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DISCONNECT cause %d\n", chan->No, buffer[1]);
2308 break;
2309 case DSP_UDATA_INDICATION_DTMF_DIGITS_RECEIVED:
2310 eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DTMF_REC '%c'\n", chan->No,
2311 dtmf_code[buffer[1]]);
2312 cmd.driver = ccard->myid;
2313 cmd.command = ISDN_STAT_AUDIO;
2314 cmd.parm.num[0] = ISDN_AUDIO_DTMF;
2315 cmd.parm.num[1] = dtmf_code[buffer[1]];
2316 cmd.arg = chan->No;
2317 ccard->interface.statcallb(&cmd);
2318 break;
2319 default:
2320 eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED UDATA Indication 0x%02x\n", chan->No, buffer[0]);
2324 void
2325 eicon_parse_trace(eicon_card *ccard, unsigned char *buffer, int len)
2327 int i,j,n;
2328 int buflen = len * 3 + 30;
2329 char *p;
2330 struct trace_s {
2331 unsigned long time;
2332 unsigned short size;
2333 unsigned short code;
2334 unsigned char data[1];
2335 } *q;
2337 if (!(p = kmalloc(buflen, GFP_ATOMIC))) {
2338 eicon_log(ccard, 1, "idi_err: Ch??: could not allocate trace buffer\n");
2339 return;
2341 memset(p, 0, buflen);
2342 q = (struct trace_s *)buffer;
2344 if (DebugVar & 512) {
2345 if ((q->code == 3) || (q->code == 4)) {
2346 n = (short) *(q->data);
2347 if (n) {
2348 j = sprintf(p, "DTRC:");
2349 for (i = 0; i < n; i++) {
2350 j += sprintf(p + j, "%02x ", q->data[i+2]);
2352 j += sprintf(p + j, "\n");
2355 } else {
2356 j = sprintf(p, "XLOG: %lx %04x %04x ",
2357 q->time, q->size, q->code);
2359 for (i = 0; i < q->size; i++) {
2360 j += sprintf(p + j, "%02x ", q->data[i]);
2362 j += sprintf(p + j, "\n");
2364 if (strlen(p))
2365 eicon_putstatus(ccard, p);
2366 kfree(p);
2369 void
2370 idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
2372 int tmp;
2373 char tnum[64];
2374 int dlev;
2375 int free_buff;
2376 ulong flags;
2377 struct sk_buff *skb2;
2378 eicon_IND *ind = (eicon_IND *)skb->data;
2379 eicon_chan *chan;
2380 idi_ind_message message;
2381 isdn_ctrl cmd;
2383 if (!ccard) {
2384 eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ind\n");
2385 dev_kfree_skb(skb);
2386 return;
2389 if ((chan = ccard->IdTable[ind->IndId]) == NULL) {
2390 eicon_log(ccard, 1, "idi_err: Ch??: null chan in handle_ind\n");
2391 dev_kfree_skb(skb);
2392 return;
2395 if ((ind->Ind != 8) && (ind->Ind != 0xc))
2396 dlev = 144;
2397 else
2398 dlev = 128;
2400 eicon_log(ccard, dlev, "idi_hdl: Ch%d: Ind=%x Id=%x Ch=%x MInd=%x MLen=%x Len=%x\n", chan->No,
2401 ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
2403 free_buff = 1;
2404 /* Signal Layer */
2405 if (chan->e.D3Id == ind->IndId) {
2406 idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
2407 switch(ind->Ind) {
2408 case HANGUP:
2409 eicon_log(ccard, 8, "idi_ind: Ch%d: Hangup\n", chan->No);
2410 while((skb2 = skb_dequeue(&chan->e.X))) {
2411 dev_kfree_skb(skb2);
2413 save_flags(flags);
2414 cli();
2415 chan->queued = 0;
2416 chan->waitq = 0;
2417 chan->waitpq = 0;
2418 restore_flags(flags);
2419 if (message.e_cau[0] & 0x7f) {
2420 cmd.driver = ccard->myid;
2421 cmd.arg = chan->No;
2422 sprintf(cmd.parm.num,"E%02x%02x",
2423 chan->cause[0]&0x7f, message.e_cau[0]&0x7f);
2424 cmd.command = ISDN_STAT_CAUSE;
2425 ccard->interface.statcallb(&cmd);
2427 chan->cause[0] = 0;
2428 #ifdef CONFIG_ISDN_TTY_FAX
2429 if (!chan->e.B2Id)
2430 chan->fax = 0;
2431 #endif
2432 if (((chan->fsm_state == EICON_STATE_ACTIVE) ||
2433 (chan->fsm_state == EICON_STATE_WMCONN)) ||
2434 ((chan->l2prot == ISDN_PROTO_L2_FAX) &&
2435 (chan->fsm_state == EICON_STATE_OBWAIT))) {
2436 chan->fsm_state = EICON_STATE_NULL;
2437 } else {
2438 if (chan->e.B2Id)
2439 idi_do_req(ccard, chan, REMOVE, 1);
2440 chan->statectrl &= ~WAITING_FOR_HANGUP;
2441 if (chan->statectrl & HAVE_CONN_REQ) {
2442 eicon_log(ccard, 32, "idi_req: Ch%d: queueing delayed conn_req\n", chan->No);
2443 chan->statectrl &= ~HAVE_CONN_REQ;
2444 if ((chan->tskb1) && (chan->tskb2)) {
2445 skb_queue_tail(&chan->e.X, chan->tskb1);
2446 skb_queue_tail(&ccard->sndq, chan->tskb2);
2447 eicon_schedule_tx(ccard);
2449 chan->tskb1 = NULL;
2450 chan->tskb2 = NULL;
2451 } else {
2452 chan->fsm_state = EICON_STATE_NULL;
2453 cmd.driver = ccard->myid;
2454 cmd.arg = chan->No;
2455 cmd.command = ISDN_STAT_DHUP;
2456 ccard->interface.statcallb(&cmd);
2457 eicon_idi_listen_req(ccard, chan);
2460 break;
2461 case INDICATE_IND:
2462 eicon_log(ccard, 8, "idi_ind: Ch%d: Indicate_Ind\n", chan->No);
2463 if (chan->fsm_state != EICON_STATE_LISTEN) {
2464 eicon_log(ccard, 1, "idi_err: Ch%d: Incoming call on wrong state (%d).\n",
2465 chan->No, chan->fsm_state);
2466 idi_do_req(ccard, chan, HANGUP, 0);
2467 break;
2469 chan->fsm_state = EICON_STATE_ICALL;
2470 idi_bc2si(message.bc, message.hlc, &chan->si1, &chan->si2);
2471 strcpy(chan->cpn, message.cpn + 1);
2472 strcpy(chan->oad, message.oad);
2473 strcpy(chan->dsa, message.dsa);
2474 strcpy(chan->osa, message.osa);
2475 chan->plan = message.plan;
2476 chan->screen = message.screen;
2477 try_stat_icall_again:
2478 cmd.driver = ccard->myid;
2479 cmd.command = ISDN_STAT_ICALL;
2480 cmd.arg = chan->No;
2481 cmd.parm.setup.si1 = chan->si1;
2482 cmd.parm.setup.si2 = chan->si2;
2483 strcpy(tnum, chan->cpn);
2484 if (strlen(chan->dsa)) {
2485 strcat(tnum, ".");
2486 strcat(tnum, chan->dsa);
2488 tnum[ISDN_MSNLEN - 1] = 0;
2489 strcpy(cmd.parm.setup.eazmsn, tnum);
2490 strcpy(tnum, chan->oad);
2491 if (strlen(chan->osa)) {
2492 strcat(tnum, ".");
2493 strcat(tnum, chan->osa);
2495 tnum[ISDN_MSNLEN - 1] = 0;
2496 strcpy(cmd.parm.setup.phone, tnum);
2497 cmd.parm.setup.plan = chan->plan;
2498 cmd.parm.setup.screen = chan->screen;
2499 tmp = ccard->interface.statcallb(&cmd);
2500 switch(tmp) {
2501 case 0: /* no user responding */
2502 idi_do_req(ccard, chan, HANGUP, 0);
2503 chan->fsm_state = EICON_STATE_NULL;
2504 break;
2505 case 1: /* alert */
2506 eicon_log(ccard, 8, "idi_req: Ch%d: Call Alert\n", chan->No);
2507 if ((chan->fsm_state == EICON_STATE_ICALL) || (chan->fsm_state == EICON_STATE_ICALLW)) {
2508 chan->fsm_state = EICON_STATE_ICALL;
2509 idi_do_req(ccard, chan, CALL_ALERT, 0);
2511 break;
2512 case 2: /* reject */
2513 eicon_log(ccard, 8, "idi_req: Ch%d: Call Reject\n", chan->No);
2514 idi_do_req(ccard, chan, REJECT, 0);
2515 break;
2516 case 3: /* incomplete number */
2517 eicon_log(ccard, 8, "idi_req: Ch%d: Incomplete Number\n", chan->No);
2518 switch(ccard->type) {
2519 case EICON_CTYPE_MAESTRAP:
2520 case EICON_CTYPE_S2M:
2521 /* TODO (other protocols) */
2522 chan->fsm_state = EICON_STATE_ICALLW;
2523 break;
2524 default:
2525 idi_do_req(ccard, chan, HANGUP, 0);
2527 break;
2529 break;
2530 case INFO_IND:
2531 eicon_log(ccard, 8, "idi_ind: Ch%d: Info_Ind\n", chan->No);
2532 if ((chan->fsm_state == EICON_STATE_ICALLW) &&
2533 (message.cpn[0])) {
2534 strcat(chan->cpn, message.cpn + 1);
2535 goto try_stat_icall_again;
2537 break;
2538 case CALL_IND:
2539 eicon_log(ccard, 8, "idi_ind: Ch%d: Call_Ind\n", chan->No);
2540 if ((chan->fsm_state == EICON_STATE_ICALL) || (chan->fsm_state == EICON_STATE_IWAIT)) {
2541 chan->fsm_state = EICON_STATE_IBWAIT;
2542 cmd.driver = ccard->myid;
2543 cmd.command = ISDN_STAT_DCONN;
2544 cmd.arg = chan->No;
2545 ccard->interface.statcallb(&cmd);
2546 switch(chan->l2prot) {
2547 case ISDN_PROTO_L2_FAX:
2548 #ifdef CONFIG_ISDN_TTY_FAX
2549 if (chan->fax)
2550 chan->fax->phase = ISDN_FAX_PHASE_A;
2551 #endif
2552 break;
2553 case ISDN_PROTO_L2_MODEM:
2554 /* do nothing, wait for connect */
2555 break;
2556 case ISDN_PROTO_L2_TRANS:
2557 idi_do_req(ccard, chan, IDI_N_CONNECT, 1);
2558 break;
2559 default:
2560 /* On most incoming calls we use automatic connect */
2561 /* idi_do_req(ccard, chan, IDI_N_CONNECT, 1); */
2563 } else
2564 idi_hangup(ccard, chan);
2565 break;
2566 case CALL_CON:
2567 eicon_log(ccard, 8, "idi_ind: Ch%d: Call_Con\n", chan->No);
2568 if (chan->fsm_state == EICON_STATE_OCALL) {
2569 chan->fsm_state = EICON_STATE_OBWAIT;
2570 cmd.driver = ccard->myid;
2571 cmd.command = ISDN_STAT_DCONN;
2572 cmd.arg = chan->No;
2573 ccard->interface.statcallb(&cmd);
2575 /* check if old NetID has been removed */
2576 if (chan->e.B2Id) {
2577 eicon_log(ccard, 1, "eicon: Ch%d: old net_id %x still exist, removing.\n",
2578 chan->No, chan->e.B2Id);
2579 idi_do_req(ccard, chan, REMOVE, 1);
2582 idi_do_req(ccard, chan, ASSIGN, 1);
2583 idi_do_req(ccard, chan, IDI_N_CONNECT, 1);
2584 #ifdef CONFIG_ISDN_TTY_FAX
2585 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2586 if (chan->fax)
2587 chan->fax->phase = ISDN_FAX_PHASE_A;
2589 #endif
2590 } else
2591 idi_hangup(ccard, chan);
2592 break;
2593 case AOC_IND:
2594 eicon_log(ccard, 8, "idi_ind: Ch%d: Advice of Charge\n", chan->No);
2595 break;
2596 default:
2597 eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED SigIndication 0x%02x\n", chan->No, ind->Ind);
2600 /* Network Layer */
2601 else if (chan->e.B2Id == ind->IndId) {
2603 if (chan->No == ccard->nchannels) {
2604 /* Management Indication */
2605 if (ind->Ind == 0x04) { /* Trace_Ind */
2606 eicon_parse_trace(ccard, ind->RBuffer.P, ind->RBuffer.length);
2607 } else {
2608 idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
2609 chan->fsm_state = 1;
2612 else
2613 switch(ind->Ind) {
2614 case IDI_N_CONNECT_ACK:
2615 eicon_log(ccard, 16, "idi_ind: Ch%d: N_Connect_Ack\n", chan->No);
2616 if (chan->l2prot == ISDN_PROTO_L2_MODEM) {
2617 chan->fsm_state = EICON_STATE_WMCONN;
2618 break;
2620 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2621 #ifdef CONFIG_ISDN_TTY_FAX
2622 chan->fsm_state = EICON_STATE_ACTIVE;
2623 idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2624 if (chan->fax) {
2625 if (chan->fax->phase == ISDN_FAX_PHASE_B) {
2626 idi_fax_send_header(ccard, chan, 2);
2627 cmd.driver = ccard->myid;
2628 cmd.command = ISDN_STAT_FAXIND;
2629 cmd.arg = chan->No;
2630 chan->fax->r_code = ISDN_TTY_FAX_DCS;
2631 ccard->interface.statcallb(&cmd);
2634 else {
2635 eicon_log(ccard, 1, "idi_ind: N_CONNECT_ACK with NULL fax struct, ERROR\n");
2637 #endif
2638 break;
2640 chan->fsm_state = EICON_STATE_ACTIVE;
2641 cmd.driver = ccard->myid;
2642 cmd.command = ISDN_STAT_BCONN;
2643 cmd.arg = chan->No;
2644 strcpy(cmd.parm.num, "64000");
2645 ccard->interface.statcallb(&cmd);
2646 break;
2647 case IDI_N_CONNECT:
2648 eicon_log(ccard, 16,"idi_ind: Ch%d: N_Connect\n", chan->No);
2649 chan->e.IndCh = ind->IndCh;
2650 if (chan->e.B2Id) idi_do_req(ccard, chan, IDI_N_CONNECT_ACK, 1);
2651 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2652 break;
2654 if (chan->l2prot == ISDN_PROTO_L2_MODEM) {
2655 chan->fsm_state = EICON_STATE_WMCONN;
2656 break;
2658 chan->fsm_state = EICON_STATE_ACTIVE;
2659 cmd.driver = ccard->myid;
2660 cmd.command = ISDN_STAT_BCONN;
2661 cmd.arg = chan->No;
2662 strcpy(cmd.parm.num, "64000");
2663 ccard->interface.statcallb(&cmd);
2664 break;
2665 case IDI_N_DISC:
2666 eicon_log(ccard, 16, "idi_ind: Ch%d: N_DISC\n", chan->No);
2667 if (chan->e.B2Id) {
2668 while((skb2 = skb_dequeue(&chan->e.X))) {
2669 dev_kfree_skb(skb2);
2671 idi_do_req(ccard, chan, IDI_N_DISC_ACK, 1);
2672 idi_do_req(ccard, chan, REMOVE, 1);
2674 #ifdef CONFIG_ISDN_TTY_FAX
2675 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2676 idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2677 idi_fax_hangup(ccard, chan);
2679 #endif
2680 chan->e.IndCh = 0;
2681 save_flags(flags);
2682 cli();
2683 chan->queued = 0;
2684 chan->waitq = 0;
2685 chan->waitpq = 0;
2686 restore_flags(flags);
2687 idi_do_req(ccard, chan, HANGUP, 0);
2688 if (chan->fsm_state == EICON_STATE_ACTIVE) {
2689 cmd.driver = ccard->myid;
2690 cmd.command = ISDN_STAT_BHUP;
2691 cmd.arg = chan->No;
2692 ccard->interface.statcallb(&cmd);
2693 chan->fsm_state = EICON_STATE_NULL;
2694 chan->statectrl |= WAITING_FOR_HANGUP;
2696 #ifdef CONFIG_ISDN_TTY_FAX
2697 chan->fax = 0;
2698 #endif
2699 break;
2700 case IDI_N_DISC_ACK:
2701 eicon_log(ccard, 16, "idi_ind: Ch%d: N_DISC_ACK\n", chan->No);
2702 #ifdef CONFIG_ISDN_TTY_FAX
2703 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2704 idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2705 idi_fax_hangup(ccard, chan);
2707 #endif
2708 break;
2709 case IDI_N_DATA_ACK:
2710 eicon_log(ccard, 128, "idi_ind: Ch%d: N_DATA_ACK\n", chan->No);
2711 break;
2712 case IDI_N_DATA:
2713 skb_pull(skb, sizeof(eicon_IND) - 1);
2714 eicon_log(ccard, 128, "idi_rcv: Ch%d: %d bytes\n", chan->No, skb->len);
2715 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2716 #ifdef CONFIG_ISDN_TTY_FAX
2717 idi_faxdata_rcv(ccard, chan, skb);
2718 #endif
2719 } else {
2720 ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb);
2721 free_buff = 0;
2723 break;
2724 case IDI_N_UDATA:
2725 idi_parse_udata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2726 break;
2727 #ifdef CONFIG_ISDN_TTY_FAX
2728 case IDI_N_EDATA:
2729 idi_edata_action(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2730 break;
2731 #endif
2732 default:
2733 eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED NetIndication 0x%02x\n", chan->No, ind->Ind);
2736 else {
2737 eicon_log(ccard, 1, "idi_ind: Ch%d: Ind is neither SIG nor NET !\n", chan->No);
2739 if (free_buff)
2740 dev_kfree_skb(skb);
2744 idi_handle_ack_ok(eicon_card *ccard, eicon_chan *chan, eicon_RC *ack)
2746 ulong flags;
2747 isdn_ctrl cmd;
2749 if (ack->RcId != ((chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id)) {
2750 /* I dont know why this happens, should not ! */
2751 /* just ignoring this RC */
2752 eicon_log(ccard, 16, "idi_ack: Ch%d: RcId %d not equal to last %d\n", chan->No,
2753 ack->RcId, (chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id);
2754 return 1;
2757 /* Management Interface */
2758 if (chan->No == ccard->nchannels) {
2759 /* Managementinterface: changing state */
2760 if (chan->e.Req != 0x02)
2761 chan->fsm_state = 1;
2764 /* Remove an Id */
2765 if (chan->e.Req == REMOVE) {
2766 if (ack->Reference != chan->e.ref) {
2767 /* This should not happen anymore */
2768 eicon_log(ccard, 16, "idi_ack: Ch%d: Rc-Ref %d not equal to stored %d\n", chan->No,
2769 ack->Reference, chan->e.ref);
2771 save_flags(flags);
2772 cli();
2773 ccard->IdTable[ack->RcId] = NULL;
2774 eicon_log(ccard, 16, "idi_ack: Ch%d: Removed : Id=%x Ch=%d (%s)\n", chan->No,
2775 ack->RcId, ack->RcCh, (chan->e.ReqCh)? "Net":"Sig");
2776 if (!chan->e.ReqCh)
2777 chan->e.D3Id = 0;
2778 else
2779 chan->e.B2Id = 0;
2780 restore_flags(flags);
2781 return 1;
2784 /* Signal layer */
2785 if (!chan->e.ReqCh) {
2786 eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
2787 ack->RcId, ack->RcCh, ack->Reference);
2788 } else {
2789 /* Network layer */
2790 switch(chan->e.Req & 0x0f) {
2791 case IDI_N_CONNECT:
2792 chan->e.IndCh = ack->RcCh;
2793 eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
2794 ack->RcId, ack->RcCh, ack->Reference);
2795 break;
2796 case IDI_N_MDATA:
2797 case IDI_N_DATA:
2798 if ((chan->e.Req & 0x0f) == IDI_N_DATA) {
2799 if (chan->queued) {
2800 cmd.driver = ccard->myid;
2801 cmd.command = ISDN_STAT_BSENT;
2802 cmd.arg = chan->No;
2803 cmd.parm.length = chan->waitpq;
2804 ccard->interface.statcallb(&cmd);
2806 save_flags(flags);
2807 cli();
2808 chan->waitpq = 0;
2809 restore_flags(flags);
2810 #ifdef CONFIG_ISDN_TTY_FAX
2811 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2812 if (((chan->queued - chan->waitq) < 1) &&
2813 (chan->fax2.Eop)) {
2814 chan->fax2.Eop = 0;
2815 if (chan->fax) {
2816 cmd.driver = ccard->myid;
2817 cmd.command = ISDN_STAT_FAXIND;
2818 cmd.arg = chan->No;
2819 chan->fax->r_code = ISDN_TTY_FAX_SENT;
2820 ccard->interface.statcallb(&cmd);
2822 else {
2823 eicon_log(ccard, 1, "idi_ack: Sent with NULL fax struct, ERROR\n");
2827 #endif
2829 save_flags(flags);
2830 cli();
2831 chan->queued -= chan->waitq;
2832 if (chan->queued < 0) chan->queued = 0;
2833 restore_flags(flags);
2834 break;
2835 default:
2836 eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
2837 ack->RcId, ack->RcCh, ack->Reference);
2840 return 1;
2843 void
2844 idi_handle_ack(eicon_card *ccard, struct sk_buff *skb)
2846 int j;
2847 ulong flags;
2848 eicon_RC *ack = (eicon_RC *)skb->data;
2849 eicon_chan *chan;
2850 isdn_ctrl cmd;
2851 int dCh = -1;
2853 if (!ccard) {
2854 eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ack\n");
2855 dev_kfree_skb(skb);
2856 return;
2859 save_flags(flags);
2860 cli();
2861 if ((chan = ccard->IdTable[ack->RcId]) != NULL)
2862 dCh = chan->No;
2863 restore_flags(flags);
2865 switch (ack->Rc) {
2866 case OK_FC:
2867 case N_FLOW_CONTROL:
2868 case ASSIGN_RC:
2869 eicon_log(ccard, 1, "idi_ack: Ch%d: unhandled RC 0x%x\n",
2870 dCh, ack->Rc);
2871 break;
2872 case READY_INT:
2873 case TIMER_INT:
2874 /* we do nothing here */
2875 break;
2877 case OK:
2878 if (!chan) {
2879 eicon_log(ccard, 1, "idi_ack: Ch%d: OK on chan without Id\n", dCh);
2880 break;
2882 if (!idi_handle_ack_ok(ccard, chan, ack))
2883 chan = NULL;
2884 break;
2886 case ASSIGN_OK:
2887 if (chan) {
2888 eicon_log(ccard, 1, "idi_ack: Ch%d: ASSIGN-OK on chan already assigned (%x,%x)\n",
2889 chan->No, chan->e.D3Id, chan->e.B2Id);
2891 save_flags(flags);
2892 cli();
2893 for(j = 0; j < ccard->nchannels + 1; j++) {
2894 if ((ccard->bch[j].e.ref == ack->Reference) &&
2895 (ccard->bch[j].e.Req == ASSIGN)) {
2896 if (!ccard->bch[j].e.ReqCh)
2897 ccard->bch[j].e.D3Id = ack->RcId;
2898 else
2899 ccard->bch[j].e.B2Id = ack->RcId;
2900 ccard->IdTable[ack->RcId] = &ccard->bch[j];
2901 chan = &ccard->bch[j];
2902 eicon_log(ccard, 16, "idi_ack: Ch%d: Id %x assigned (%s)\n", j,
2903 ack->RcId, (ccard->bch[j].e.ReqCh)? "Net":"Sig");
2904 break;
2907 restore_flags(flags);
2908 if (j > ccard->nchannels) {
2909 eicon_log(ccard, 24, "idi_ack: Ch??: ref %d not found for Id %d\n",
2910 ack->Reference, ack->RcId);
2912 break;
2914 case OUT_OF_RESOURCES:
2915 case UNKNOWN_COMMAND:
2916 case WRONG_COMMAND:
2917 case WRONG_ID:
2918 case WRONG_CH:
2919 case UNKNOWN_IE:
2920 case WRONG_IE:
2921 default:
2922 if (!chan) {
2923 eicon_log(ccard, 1, "idi_ack: Ch%d: Not OK !! on chan without Id\n", dCh);
2924 break;
2925 } else
2926 switch (chan->e.Req) {
2927 case 12: /* Alert */
2928 eicon_log(ccard, 2, "eicon_err: Ch%d: Alert Not OK : Rc=%d Id=%x Ch=%d\n",
2929 dCh, ack->Rc, ack->RcId, ack->RcCh);
2930 break;
2931 default:
2932 if (dCh != ccard->nchannels)
2933 eicon_log(ccard, 1, "eicon_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n",
2934 dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req);
2936 if (dCh == ccard->nchannels) { /* Management */
2937 chan->fsm_state = 2;
2938 eicon_log(ccard, 8, "eicon_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n",
2939 dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req);
2940 } else if (dCh >= 0) {
2941 /* any other channel */
2942 /* card reports error: we hangup */
2943 idi_hangup(ccard, chan);
2944 cmd.driver = ccard->myid;
2945 cmd.command = ISDN_STAT_DHUP;
2946 cmd.arg = chan->No;
2947 ccard->interface.statcallb(&cmd);
2950 save_flags(flags);
2951 cli();
2952 if (chan) {
2953 chan->e.ref = 0;
2954 chan->e.busy = 0;
2956 restore_flags(flags);
2957 dev_kfree_skb(skb);
2958 eicon_schedule_tx(ccard);
2962 idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb, int que)
2964 struct sk_buff *xmit_skb;
2965 struct sk_buff *skb2;
2966 eicon_REQ *reqbuf;
2967 eicon_chan_ptr *chan2;
2968 int len, plen = 0, offset = 0;
2969 unsigned long flags;
2971 if ((!card) || (!chan)) {
2972 eicon_log(card, 1, "idi_err: Ch??: null card/chan in send_data\n");
2973 return -1;
2976 if (chan->fsm_state != EICON_STATE_ACTIVE) {
2977 eicon_log(card, 1, "idi_snd: Ch%d: send bytes on state %d !\n", chan->No, chan->fsm_state);
2978 return -ENODEV;
2981 len = skb->len;
2982 if (len > EICON_MAX_QUEUE) /* too much for the shared memory */
2983 return -1;
2984 if (!len)
2985 return 0;
2986 if (chan->queued + len > EICON_MAX_QUEUE)
2987 return 0;
2989 eicon_log(card, 128, "idi_snd: Ch%d: %d bytes\n", chan->No, len);
2991 save_flags(flags);
2992 cli();
2993 while(offset < len) {
2995 plen = ((len - offset) > 270) ? 270 : len - offset;
2997 xmit_skb = alloc_skb(plen + sizeof(eicon_REQ), GFP_ATOMIC);
2998 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
3000 if ((!xmit_skb) || (!skb2)) {
3001 restore_flags(flags);
3002 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_data()\n", chan->No);
3003 if (xmit_skb)
3004 dev_kfree_skb(skb);
3005 if (skb2)
3006 dev_kfree_skb(skb2);
3007 return -ENOMEM;
3010 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
3011 chan2->ptr = chan;
3013 reqbuf = (eicon_REQ *)skb_put(xmit_skb, plen + sizeof(eicon_REQ));
3014 if (((len - offset) > 270) &&
3015 (chan->l2prot != ISDN_PROTO_L2_TRANS)) {
3016 reqbuf->Req = IDI_N_MDATA;
3017 } else {
3018 reqbuf->Req = IDI_N_DATA;
3019 if (ack) reqbuf->Req |= N_D_BIT;
3021 reqbuf->ReqCh = chan->e.IndCh;
3022 reqbuf->ReqId = 1;
3023 memcpy(&reqbuf->XBuffer.P, skb->data + offset, plen);
3024 reqbuf->XBuffer.length = plen;
3025 reqbuf->Reference = 1; /* Net Entity */
3027 skb_queue_tail(&chan->e.X, xmit_skb);
3028 skb_queue_tail(&card->sndq, skb2);
3030 offset += plen;
3032 if (que)
3033 chan->queued += len;
3034 restore_flags(flags);
3035 eicon_schedule_tx(card);
3036 dev_kfree_skb(skb);
3037 return len;
3042 eicon_idi_manage_assign(eicon_card *card)
3044 struct sk_buff *skb;
3045 struct sk_buff *skb2;
3046 eicon_REQ *reqbuf;
3047 eicon_chan *chan;
3048 eicon_chan_ptr *chan2;
3050 chan = &(card->bch[card->nchannels]);
3052 skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
3053 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
3055 if ((!skb) || (!skb2)) {
3056 eicon_log(card, 1, "idi_err: alloc_skb failed in manage_assign()\n");
3057 if (skb)
3058 dev_kfree_skb(skb);
3059 if (skb2)
3060 dev_kfree_skb(skb2);
3061 return -ENOMEM;
3064 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
3065 chan2->ptr = chan;
3067 reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
3069 reqbuf->XBuffer.P[0] = 0;
3070 reqbuf->Req = ASSIGN;
3071 reqbuf->ReqCh = 0;
3072 reqbuf->ReqId = 0xe0;
3073 reqbuf->XBuffer.length = 1;
3074 reqbuf->Reference = 2; /* Man Entity */
3076 skb_queue_tail(&chan->e.X, skb);
3077 skb_queue_tail(&card->sndq, skb2);
3078 eicon_schedule_tx(card);
3079 return(0);
3084 eicon_idi_manage_remove(eicon_card *card)
3086 struct sk_buff *skb;
3087 struct sk_buff *skb2;
3088 eicon_REQ *reqbuf;
3089 eicon_chan *chan;
3090 eicon_chan_ptr *chan2;
3092 chan = &(card->bch[card->nchannels]);
3094 skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
3095 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
3097 if ((!skb) || (!skb2)) {
3098 eicon_log(card, 1, "idi_err: alloc_skb failed in manage_remove()\n");
3099 if (skb)
3100 dev_kfree_skb(skb);
3101 if (skb2)
3102 dev_kfree_skb(skb2);
3103 return -ENOMEM;
3106 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
3107 chan2->ptr = chan;
3109 reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
3111 reqbuf->Req = REMOVE;
3112 reqbuf->ReqCh = 0;
3113 reqbuf->ReqId = 1;
3114 reqbuf->XBuffer.length = 0;
3115 reqbuf->Reference = 2; /* Man Entity */
3117 skb_queue_tail(&chan->e.X, skb);
3118 skb_queue_tail(&card->sndq, skb2);
3119 eicon_schedule_tx(card);
3120 return(0);
3125 eicon_idi_manage(eicon_card *card, eicon_manifbuf *mb)
3127 int l = 0;
3128 int ret = 0;
3129 int timeout;
3130 int i;
3131 struct sk_buff *skb;
3132 struct sk_buff *skb2;
3133 eicon_REQ *reqbuf;
3134 eicon_chan *chan;
3135 eicon_chan_ptr *chan2;
3137 chan = &(card->bch[card->nchannels]);
3139 if (!(chan->e.D3Id)) {
3140 chan->e.D3Id = 1;
3141 while((skb2 = skb_dequeue(&chan->e.X)))
3142 dev_kfree_skb(skb2);
3143 chan->e.busy = 0;
3145 if ((ret = eicon_idi_manage_assign(card))) {
3146 chan->e.D3Id = 0;
3147 return(ret);
3150 timeout = jiffies + 50;
3151 while (timeout > jiffies) {
3152 if (chan->e.B2Id) break;
3153 SLEEP(10);
3155 if (!chan->e.B2Id) {
3156 chan->e.D3Id = 0;
3157 return -EIO;
3161 chan->fsm_state = 0;
3163 if (!(manbuf = kmalloc(sizeof(eicon_manifbuf), GFP_KERNEL))) {
3164 eicon_log(card, 1, "idi_err: alloc_manifbuf failed\n");
3165 return -ENOMEM;
3167 if (copy_from_user(manbuf, mb, sizeof(eicon_manifbuf))) {
3168 kfree(manbuf);
3169 return -EFAULT;
3172 skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
3173 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
3175 if ((!skb) || (!skb2)) {
3176 eicon_log(card, 1, "idi_err_manif: alloc_skb failed in manage()\n");
3177 if (skb)
3178 dev_kfree_skb(skb);
3179 if (skb2)
3180 dev_kfree_skb(skb2);
3181 kfree(manbuf);
3182 return -ENOMEM;
3185 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
3186 chan2->ptr = chan;
3188 reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
3190 reqbuf->XBuffer.P[l++] = ESC;
3191 reqbuf->XBuffer.P[l++] = 6;
3192 reqbuf->XBuffer.P[l++] = 0x80;
3193 for (i = 0; i < manbuf->length[0]; i++)
3194 reqbuf->XBuffer.P[l++] = manbuf->data[i];
3195 reqbuf->XBuffer.P[1] = manbuf->length[0] + 1;
3197 reqbuf->XBuffer.P[l++] = 0;
3198 reqbuf->Req = (manbuf->count) ? manbuf->count : 0x02; /* Request */
3199 reqbuf->ReqCh = 0;
3200 reqbuf->ReqId = 1;
3201 reqbuf->XBuffer.length = l;
3202 reqbuf->Reference = 2; /* Man Entity */
3204 skb_queue_tail(&chan->e.X, skb);
3205 skb_queue_tail(&card->sndq, skb2);
3207 manbuf->count = 0;
3208 manbuf->pos = 0;
3210 eicon_schedule_tx(card);
3212 timeout = jiffies + 50;
3213 while (timeout > jiffies) {
3214 if (chan->fsm_state) break;
3215 SLEEP(10);
3217 if ((!chan->fsm_state) || (chan->fsm_state == 2)) {
3218 kfree(manbuf);
3219 return -EIO;
3221 if (copy_to_user(mb, manbuf, sizeof(eicon_manifbuf))) {
3222 kfree(manbuf);
3223 return -EFAULT;
3226 kfree(manbuf);
3227 return(0);