update atp870u driver to 0.78 from D-Link source
[linux-2.4.git] / drivers / isdn / eicon / eicon_idi.c
1 /* $Id: eicon_idi.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
2  *
3  * ISDN lowlevel-module for Eicon active cards.
4  * IDI interface 
5  *
6  * Copyright 1998-2000  by Armin Schindler (mac@melware.de)
7  * Copyright 1999,2000  Cytronics & Melware (info@melware.de)
8  *
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)
13  *
14  * This software may be used and distributed according to the terms
15  * of the GNU General Public License, incorporated herein by reference.
16  *
17  */
18
19 #include <linux/config.h>
20 #define __NO_VERSION__
21 #include "eicon.h"
22 #include "eicon_idi.h"
23 #include "eicon_dsp.h"
24 #include "uxio.h"
25
26 #undef EICON_FULL_SERVICE_OKTETT
27
28 char *eicon_idi_revision = "$Revision: 1.1.4.1 $";
29
30 eicon_manifbuf *manbuf;
31
32 int eicon_idi_manage_assign(eicon_card *card);
33 int eicon_idi_manage_remove(eicon_card *card);
34 int idi_fill_in_T30(eicon_chan *chan, unsigned char *buffer);
35
36 int
37 idi_assign_req(eicon_REQ *reqbuf, int signet, eicon_chan *chan)
38 {
39         int l = 0;
40         int tmp;
41
42         tmp = 0;
43   if (!signet) {
44         /* Signal Layer */
45         reqbuf->XBuffer.P[l++] = CAI;
46         reqbuf->XBuffer.P[l++] = 1;
47         reqbuf->XBuffer.P[l++] = 0;
48         reqbuf->XBuffer.P[l++] = KEY;
49         reqbuf->XBuffer.P[l++] = 3;
50         reqbuf->XBuffer.P[l++] = 'I';
51         reqbuf->XBuffer.P[l++] = '4';
52         reqbuf->XBuffer.P[l++] = 'L';
53         reqbuf->XBuffer.P[l++] = SHIFT|6;
54         reqbuf->XBuffer.P[l++] = SIN;
55         reqbuf->XBuffer.P[l++] = 2;
56         reqbuf->XBuffer.P[l++] = 0;
57         reqbuf->XBuffer.P[l++] = 0;
58         reqbuf->XBuffer.P[l++] = 0; /* end */
59         reqbuf->Req = ASSIGN;
60         reqbuf->ReqCh = 0;
61         reqbuf->ReqId = DSIG_ID;
62         reqbuf->XBuffer.length = l;
63         reqbuf->Reference = 0; /* Sig Entity */
64   }
65   else {
66         /* Network Layer */
67         reqbuf->XBuffer.P[l++] = CAI;
68         reqbuf->XBuffer.P[l++] = 1;
69         reqbuf->XBuffer.P[l++] = chan->e.D3Id;
70         reqbuf->XBuffer.P[l++] = LLC;
71         reqbuf->XBuffer.P[l++] = 2;
72         switch(chan->l2prot) {
73                 case ISDN_PROTO_L2_V11096:
74                 case ISDN_PROTO_L2_V11019:
75                 case ISDN_PROTO_L2_V11038:
76                 case ISDN_PROTO_L2_TRANS:
77                         reqbuf->XBuffer.P[l++] = 2; /* transparent */
78                         break;
79                 case ISDN_PROTO_L2_X75I:
80                 case ISDN_PROTO_L2_X75UI:
81                 case ISDN_PROTO_L2_X75BUI:
82                         reqbuf->XBuffer.P[l++] = 5; /* X.75 */ 
83                         break;
84                 case ISDN_PROTO_L2_MODEM:
85                         if (chan->fsm_state == EICON_STATE_IWAIT)
86                                 reqbuf->XBuffer.P[l++] = 9; /* V.42 incoming */
87                         else
88                                 reqbuf->XBuffer.P[l++] = 10; /* V.42 */
89                         break;
90                 case ISDN_PROTO_L2_HDLC:
91                 case ISDN_PROTO_L2_FAX:
92                         if (chan->fsm_state == EICON_STATE_IWAIT)
93                                 reqbuf->XBuffer.P[l++] = 3; /* autoconnect on incoming */
94                         else
95                                 reqbuf->XBuffer.P[l++] = 2; /* transparent */
96                         break;
97                 default:
98                         reqbuf->XBuffer.P[l++] = 1;
99         }
100         switch(chan->l3prot) {
101                 case ISDN_PROTO_L3_FCLASS2:
102 #ifdef CONFIG_ISDN_TTY_FAX
103                         reqbuf->XBuffer.P[l++] = 6;
104                         reqbuf->XBuffer.P[l++] = NLC;
105                         tmp = idi_fill_in_T30(chan, &reqbuf->XBuffer.P[l+1]);
106                         reqbuf->XBuffer.P[l++] = tmp; 
107                         l += tmp;
108                         break;
109 #endif
110                 case ISDN_PROTO_L3_TRANS:
111                 default:
112                         reqbuf->XBuffer.P[l++] = 4;
113         }
114         reqbuf->XBuffer.P[l++] = 0; /* end */
115         reqbuf->Req = ASSIGN;
116         reqbuf->ReqCh = 0;
117         reqbuf->ReqId = NL_ID;
118         reqbuf->XBuffer.length = l;
119         reqbuf->Reference = 1; /* Net Entity */
120   }
121    return(0);
122 }
123
124 int
125 idi_put_req(eicon_REQ *reqbuf, int rq, int signet, int Ch)
126 {
127         reqbuf->Req = rq;
128         reqbuf->ReqCh = Ch;
129         reqbuf->ReqId = 1;
130         reqbuf->XBuffer.length = 1;
131         reqbuf->XBuffer.P[0] = 0;
132         reqbuf->Reference = signet;
133    return(0);
134 }
135
136 int
137 idi_put_suspend_req(eicon_REQ *reqbuf, eicon_chan *chan)
138 {
139         reqbuf->Req = SUSPEND;
140         reqbuf->ReqCh = 0;
141         reqbuf->ReqId = 1;
142         reqbuf->XBuffer.P[0] = CAI;
143         reqbuf->XBuffer.P[1] = 1;
144         reqbuf->XBuffer.P[2] = chan->No;
145         reqbuf->XBuffer.P[3] = 0;
146         reqbuf->XBuffer.length = 4;
147         reqbuf->Reference = 0; /* Sig Entity */
148    return(0);
149 }
150
151 int
152 idi_call_res_req(eicon_REQ *reqbuf, eicon_chan *chan)
153 {
154         int l = 9;
155         reqbuf->Req = CALL_RES;
156         reqbuf->ReqCh = 0;
157         reqbuf->ReqId = 1;
158         reqbuf->XBuffer.P[0] = CAI;
159         reqbuf->XBuffer.P[1] = 6;
160         reqbuf->XBuffer.P[2] = 9;
161         reqbuf->XBuffer.P[3] = 0;
162         reqbuf->XBuffer.P[4] = 0;
163         reqbuf->XBuffer.P[5] = 0;
164         reqbuf->XBuffer.P[6] = 32;
165         reqbuf->XBuffer.P[7] = 0;
166         switch(chan->l2prot) {
167                 case ISDN_PROTO_L2_X75I:
168                 case ISDN_PROTO_L2_X75UI:
169                 case ISDN_PROTO_L2_X75BUI:
170                 case ISDN_PROTO_L2_HDLC:
171                         reqbuf->XBuffer.P[1] = 1;
172                         reqbuf->XBuffer.P[2] = 0x05;
173                         l = 4;
174                         break;
175                 case ISDN_PROTO_L2_V11096:
176                         reqbuf->XBuffer.P[2] = 0x0d;
177                         reqbuf->XBuffer.P[3] = 5;
178                         reqbuf->XBuffer.P[4] = 0;
179                         break;
180                 case ISDN_PROTO_L2_V11019:
181                         reqbuf->XBuffer.P[2] = 0x0d;
182                         reqbuf->XBuffer.P[3] = 6;
183                         reqbuf->XBuffer.P[4] = 0;
184                         break;
185                 case ISDN_PROTO_L2_V11038:
186                         reqbuf->XBuffer.P[2] = 0x0d;
187                         reqbuf->XBuffer.P[3] = 7;
188                         reqbuf->XBuffer.P[4] = 0;
189                         break;
190                 case ISDN_PROTO_L2_MODEM:
191                         reqbuf->XBuffer.P[2] = 0x11;
192                         reqbuf->XBuffer.P[3] = 7;
193                         reqbuf->XBuffer.P[4] = 0;
194                         reqbuf->XBuffer.P[5] = 0;
195                         reqbuf->XBuffer.P[6] = 128;
196                         reqbuf->XBuffer.P[7] = 0;
197                         break;
198                 case ISDN_PROTO_L2_FAX:
199                         reqbuf->XBuffer.P[2] = 0x10;
200                         reqbuf->XBuffer.P[3] = 0;
201                         reqbuf->XBuffer.P[4] = 0;
202                         reqbuf->XBuffer.P[5] = 0;
203                         reqbuf->XBuffer.P[6] = 128;
204                         reqbuf->XBuffer.P[7] = 0;
205                         break;
206                 case ISDN_PROTO_L2_TRANS:
207                         switch(chan->l3prot) {
208                                 case ISDN_PROTO_L3_TRANSDSP:
209                                         reqbuf->XBuffer.P[2] = 22; /* DTMF, audio events on */
210                         }
211                         break;
212         }
213         reqbuf->XBuffer.P[8] = 0;
214         reqbuf->XBuffer.length = l;
215         reqbuf->Reference = 0; /* Sig Entity */
216         eicon_log(NULL, 8, "idi_req: Ch%d: Call_Res\n", chan->No);
217    return(0);
218 }
219
220 int
221 idi_do_req(eicon_card *card, eicon_chan *chan, int cmd, int layer)
222 {
223         struct sk_buff *skb;
224         struct sk_buff *skb2;
225         eicon_REQ *reqbuf;
226         eicon_chan_ptr *chan2;
227
228         skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
229         skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
230
231         if ((!skb) || (!skb2)) {
232                 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in do_req()\n", chan->No);
233                 if (skb) 
234                         dev_kfree_skb(skb);
235                 if (skb2) 
236                         dev_kfree_skb(skb2);
237                 return -ENOMEM; 
238         }
239
240         chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
241         chan2->ptr = chan;
242
243         reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
244         eicon_log(card, 8, "idi_req: Ch%d: req %x (%s)\n", chan->No, cmd, (layer)?"Net":"Sig");
245         if (layer) cmd |= 0x700;
246         switch(cmd) {
247                 case ASSIGN:
248                 case ASSIGN|0x700:
249                         idi_assign_req(reqbuf, layer, chan);
250                         break;
251                 case REMOVE:
252                 case REMOVE|0x700:
253                         idi_put_req(reqbuf, REMOVE, layer, 0);
254                         break;
255                 case INDICATE_REQ:
256                         idi_put_req(reqbuf, INDICATE_REQ, 0, 0);
257                         break;
258                 case HANGUP:
259                         idi_put_req(reqbuf, HANGUP, 0, 0);
260                         break;
261                 case SUSPEND:
262                         idi_put_suspend_req(reqbuf, chan);
263                         break;
264                 case RESUME:
265                         idi_put_req(reqbuf, RESUME, 0 ,0);
266                         break;
267                 case REJECT:
268                         idi_put_req(reqbuf, REJECT, 0 ,0);
269                         break;
270                 case CALL_ALERT:
271                         idi_put_req(reqbuf, CALL_ALERT, 0, 0);
272                         break;
273                 case CALL_RES:
274                         idi_call_res_req(reqbuf, chan);
275                         break;
276                 case CALL_HOLD:
277                         idi_put_req(reqbuf, CALL_HOLD, 0, 0);
278                         break;
279                 case N_CONNECT|0x700:
280                         idi_put_req(reqbuf, N_CONNECT, 1, 0);
281                         break;
282                 case N_CONNECT_ACK|0x700:
283                         idi_put_req(reqbuf, N_CONNECT_ACK, 1, 0);
284                         break;
285                 case N_DISC|0x700:
286                         idi_put_req(reqbuf, N_DISC, 1, chan->e.IndCh);
287                         break;
288                 case N_DISC_ACK|0x700:
289                         idi_put_req(reqbuf, N_DISC_ACK, 1, chan->e.IndCh);
290                         break;
291                 default:
292                         eicon_log(card, 1, "idi_req: Ch%d: Unknown request\n", chan->No);
293                         dev_kfree_skb(skb);
294                         dev_kfree_skb(skb2);
295                         return(-1);
296         }
297
298         skb_queue_tail(&chan->e.X, skb);
299         skb_queue_tail(&card->sndq, skb2); 
300         eicon_schedule_tx(card);
301         return(0);
302 }
303
304 int
305 eicon_idi_listen_req(eicon_card *card, eicon_chan *chan)
306 {
307         if ((!card) || (!chan))
308                 return 1;
309
310         eicon_log(card, 16, "idi_req: Ch%d: Listen_Req eazmask=0x%x\n",chan->No, chan->eazmask);
311         if (!chan->e.D3Id) {
312                 idi_do_req(card, chan, ASSIGN, 0); 
313         }
314         if (chan->fsm_state == EICON_STATE_NULL) {
315                 if (!(chan->statectrl & HAVE_CONN_REQ)) {
316                         idi_do_req(card, chan, INDICATE_REQ, 0);
317                         chan->fsm_state = EICON_STATE_LISTEN;
318                 }
319         }
320   return(0);
321 }
322
323 unsigned char
324 idi_si2bc(int si1, int si2, char *bc, char *hlc)
325 {
326   hlc[0] = 0;
327   switch(si1) {
328         case 1:
329                 bc[0] = 0x90;           /* 3,1 kHz audio */
330                 bc[1] = 0x90;           /* 64 kbit/s */
331                 bc[2] = 0xa3;           /* G.711 A-law */
332 #ifdef EICON_FULL_SERVICE_OKTETT
333                 if (si2 == 1) {
334                         bc[0] = 0x80;   /* Speech */
335                         hlc[0] = 0x02;  /* hlc len */
336                         hlc[1] = 0x91;  /* first hic */
337                         hlc[2] = 0x81;  /* Telephony */
338                 }
339 #endif
340                 return(3);
341         case 2:
342                 bc[0] = 0x90;           /* 3,1 kHz audio */
343                 bc[1] = 0x90;           /* 64 kbit/s */
344                 bc[2] = 0xa3;           /* G.711 A-law */
345 #ifdef EICON_FULL_SERVICE_OKTETT
346                 if (si2 == 2) {
347                         hlc[0] = 0x02;  /* hlc len */
348                         hlc[1] = 0x91;  /* first hic */
349                         hlc[2] = 0x84;  /* Fax Gr.2/3 */
350                 }
351 #endif
352                 return(3);
353         case 5:
354         case 7:
355         default:
356                 bc[0] = 0x88;
357                 bc[1] = 0x90;
358                 return(2);
359   }
360  return (0);
361 }
362
363 int
364 idi_hangup(eicon_card *card, eicon_chan *chan)
365 {
366         if ((!card) || (!chan))
367                 return 1;
368
369         if ((chan->fsm_state == EICON_STATE_ACTIVE) ||
370             (chan->fsm_state == EICON_STATE_WMCONN)) {
371                 if (chan->e.B2Id) idi_do_req(card, chan, N_DISC, 1);
372         }
373         if (chan->e.B2Id) idi_do_req(card, chan, REMOVE, 1);
374         if (chan->fsm_state != EICON_STATE_NULL) {
375                 chan->statectrl |= WAITING_FOR_HANGUP;
376                 idi_do_req(card, chan, HANGUP, 0);
377                 chan->fsm_state = EICON_STATE_NULL;
378         }
379         eicon_log(card, 8, "idi_req: Ch%d: Hangup\n", chan->No);
380 #ifdef CONFIG_ISDN_TTY_FAX
381         chan->fax = 0;
382 #endif
383   return(0);
384 }
385
386 int
387 capipmsg(eicon_card *card, eicon_chan *chan, capi_msg *cm)
388 {
389         if ((cm->para[0] != 3) || (cm->para[1] != 0))
390                 return -1;
391         if (cm->para[2] < 3)
392                 return -1;
393         if (cm->para[4] != 0)
394                 return -1;
395         switch(cm->para[3]) {
396                 case 4: /* Suspend */
397                         eicon_log(card, 8, "idi_req: Ch%d: Call Suspend\n", chan->No);
398                         if (cm->para[5]) {
399                                 idi_do_req(card, chan, SUSPEND, 0);
400                         } else {
401                                 idi_do_req(card, chan, CALL_HOLD, 0);
402                         }
403                         break;
404                 case 5: /* Resume */
405                         eicon_log(card, 8, "idi_req: Ch%d: Call Resume\n", chan->No);
406                         idi_do_req(card, chan, RESUME, 0);
407                         break;
408         }
409         return 0;
410 }
411
412 int
413 idi_connect_res(eicon_card *card, eicon_chan *chan)
414 {
415         if ((!card) || (!chan))
416                 return 1;
417
418         chan->fsm_state = EICON_STATE_IWAIT;
419         
420         /* check if old NetID has been removed */
421         if (chan->e.B2Id) {
422                 eicon_log(card, 1, "eicon: Ch%d: old net_id %x still exist, removing.\n",
423                         chan->No, chan->e.B2Id);
424                 idi_do_req(card, chan, REMOVE, 1);
425         }
426
427         idi_do_req(card, chan, ASSIGN, 1);
428         idi_do_req(card, chan, CALL_RES, 0);
429         return(0);
430 }
431
432 int
433 idi_connect_req(eicon_card *card, eicon_chan *chan, char *phone,
434                     char *eazmsn, int si1, int si2)
435 {
436         int l = 0;
437         int i;
438         unsigned char tmp;
439         unsigned char *sub, *sp;
440         unsigned char bc[5];
441         unsigned char hlc[5];
442         struct sk_buff *skb;
443         struct sk_buff *skb2;
444         eicon_REQ *reqbuf;
445         eicon_chan_ptr *chan2;
446
447         if ((!card) || (!chan))
448                 return 1;
449
450         skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
451         skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
452
453         if ((!skb) || (!skb2)) {
454                 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in connect_req()\n", chan->No);
455                 if (skb) 
456                         dev_kfree_skb(skb);
457                 if (skb2) 
458                         dev_kfree_skb(skb2);
459                 return -ENOMEM; 
460         }
461
462         chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
463         chan2->ptr = chan;
464
465         reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
466         reqbuf->Req = CALL_REQ;
467         reqbuf->ReqCh = 0;
468         reqbuf->ReqId = 1;
469
470         sub = NULL;
471         sp = phone;
472         while (*sp) {
473                 if (*sp == '.') {
474                         sub = sp + 1;
475                         *sp = 0;
476                 } else
477                         sp++;
478         }
479         reqbuf->XBuffer.P[l++] = CPN;
480         reqbuf->XBuffer.P[l++] = strlen(phone) + 1;
481         reqbuf->XBuffer.P[l++] = 0x81;
482         for(i=0; i<strlen(phone);i++) 
483                 reqbuf->XBuffer.P[l++] = phone[i] & 0x7f;
484         if (sub) {
485                 reqbuf->XBuffer.P[l++] = DSA;
486                 reqbuf->XBuffer.P[l++] = strlen(sub) + 2;
487                 reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */
488                 reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */
489                 while (*sub)
490                         reqbuf->XBuffer.P[l++] = *sub++ & 0x7f;
491         }
492
493         sub = NULL;
494         sp = eazmsn;
495         while (*sp) {
496                 if (*sp == '.') {
497                         sub = sp + 1;
498                         *sp = 0;
499                 } else
500                         sp++;
501         }
502         reqbuf->XBuffer.P[l++] = OAD;
503         reqbuf->XBuffer.P[l++] = strlen(eazmsn) + 2;
504         reqbuf->XBuffer.P[l++] = 0x01;
505         reqbuf->XBuffer.P[l++] = 0x80;
506         for(i=0; i<strlen(eazmsn);i++) 
507                 reqbuf->XBuffer.P[l++] = eazmsn[i] & 0x7f;
508         if (sub) {
509                 reqbuf->XBuffer.P[l++] = OSA;
510                 reqbuf->XBuffer.P[l++] = strlen(sub) + 2;
511                 reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */
512                 reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */
513                 while (*sub)
514                         reqbuf->XBuffer.P[l++] = *sub++ & 0x7f;
515         }
516
517         if (si2 > 2) {
518                 reqbuf->XBuffer.P[l++] = SHIFT|6;
519                 reqbuf->XBuffer.P[l++] = SIN;
520                 reqbuf->XBuffer.P[l++] = 2;
521                 reqbuf->XBuffer.P[l++] = si1;
522                 reqbuf->XBuffer.P[l++] = si2;
523         }
524         else if ((tmp = idi_si2bc(si1, si2, bc, hlc)) > 0) {
525                 reqbuf->XBuffer.P[l++] = BC;
526                 reqbuf->XBuffer.P[l++] = tmp;
527                 for(i=0; i<tmp;i++) 
528                         reqbuf->XBuffer.P[l++] = bc[i];
529                 if ((tmp=hlc[0])) {
530                         reqbuf->XBuffer.P[l++] = HLC;
531                         reqbuf->XBuffer.P[l++] = tmp;
532                         for(i=1; i<=tmp;i++) 
533                                 reqbuf->XBuffer.P[l++] = hlc[i];
534                 }
535         }
536
537         reqbuf->XBuffer.P[l++] = CAI;
538         reqbuf->XBuffer.P[l++] = 6;
539         reqbuf->XBuffer.P[l++] = 0x09;
540         reqbuf->XBuffer.P[l++] = 0;
541         reqbuf->XBuffer.P[l++] = 0;
542         reqbuf->XBuffer.P[l++] = 0;
543         reqbuf->XBuffer.P[l++] = 32;
544         reqbuf->XBuffer.P[l++] = 0;
545         switch(chan->l2prot) {
546                 case ISDN_PROTO_L2_X75I:
547                 case ISDN_PROTO_L2_X75UI:
548                 case ISDN_PROTO_L2_X75BUI:
549                 case ISDN_PROTO_L2_HDLC:
550                         reqbuf->XBuffer.P[l-6] = 5;
551                         reqbuf->XBuffer.P[l-7] = 1;
552                         l -= 5; 
553                         break;
554                 case ISDN_PROTO_L2_V11096:
555                         reqbuf->XBuffer.P[l-7] = 3;
556                         reqbuf->XBuffer.P[l-6] = 0x0d;
557                         reqbuf->XBuffer.P[l-5] = 5;
558                         reqbuf->XBuffer.P[l-4] = 0;
559                         l -= 3;
560                         break;
561                 case ISDN_PROTO_L2_V11019:
562                         reqbuf->XBuffer.P[l-7] = 3;
563                         reqbuf->XBuffer.P[l-6] = 0x0d;
564                         reqbuf->XBuffer.P[l-5] = 6;
565                         reqbuf->XBuffer.P[l-4] = 0;
566                         l -= 3;
567                         break;
568                 case ISDN_PROTO_L2_V11038:
569                         reqbuf->XBuffer.P[l-7] = 3;
570                         reqbuf->XBuffer.P[l-6] = 0x0d;
571                         reqbuf->XBuffer.P[l-5] = 7;
572                         reqbuf->XBuffer.P[l-4] = 0;
573                         l -= 3;
574                         break;
575                 case ISDN_PROTO_L2_MODEM:
576                         reqbuf->XBuffer.P[l-6] = 0x11;
577                         reqbuf->XBuffer.P[l-5] = 7;
578                         reqbuf->XBuffer.P[l-4] = 0;
579                         reqbuf->XBuffer.P[l-3] = 0;
580                         reqbuf->XBuffer.P[l-2] = 128;
581                         reqbuf->XBuffer.P[l-1] = 0;
582                         break;
583                 case ISDN_PROTO_L2_FAX:
584                         reqbuf->XBuffer.P[l-6] = 0x10;
585                         reqbuf->XBuffer.P[l-5] = 0;
586                         reqbuf->XBuffer.P[l-4] = 0;
587                         reqbuf->XBuffer.P[l-3] = 0;
588                         reqbuf->XBuffer.P[l-2] = 128;
589                         reqbuf->XBuffer.P[l-1] = 0;
590                         break;
591                 case ISDN_PROTO_L2_TRANS:
592                         switch(chan->l3prot) {
593                                 case ISDN_PROTO_L3_TRANSDSP:
594                                         reqbuf->XBuffer.P[l-6] = 22; /* DTMF, audio events on */
595                         }
596                         break;
597         }
598         
599         reqbuf->XBuffer.P[l++] = 0; /* end */
600         reqbuf->XBuffer.length = l;
601         reqbuf->Reference = 0; /* Sig Entity */
602
603         if (chan->statectrl & WAITING_FOR_HANGUP) {
604                 /*      If the line did not disconnect yet,
605                         we have to delay this command           */
606                 eicon_log(card, 32, "idi_req: Ch%d: delaying conn_req\n", chan->No);
607                 chan->statectrl |= HAVE_CONN_REQ;
608                 chan->tskb1 = skb;
609                 chan->tskb2 = skb2;
610         } else {
611                 skb_queue_tail(&chan->e.X, skb);
612                 skb_queue_tail(&card->sndq, skb2); 
613                 eicon_schedule_tx(card);
614         }
615
616         eicon_log(card, 8, "idi_req: Ch%d: Conn_Req %s -> %s\n",chan->No, eazmsn, phone);
617    return(0);
618 }
619
620
621 void
622 idi_IndParse(eicon_card *ccard, eicon_chan *chan, idi_ind_message *message, unsigned char *buffer, int len)
623 {
624         int i,j;
625         int pos = 0;
626         int codeset = 0;
627         int wlen = 0;
628         int lock = 0;
629         __u8 w;
630         __u16 code;
631         isdn_ctrl cmd;
632
633         memset(message, 0, sizeof(idi_ind_message));
634
635         if ((!len) || (!buffer[pos])) return;
636
637   while(pos <= len) {
638         w = buffer[pos++];
639         if (!w) return;
640         if (w & 0x80) {
641                 wlen = 0;
642         }
643         else {
644                 wlen = buffer[pos++];
645         }
646
647         if (pos > len) return;
648
649         if (lock & 0x80) lock &= 0x7f;
650         else codeset = lock;
651
652         if((w&0xf0) == SHIFT) {
653                 codeset = w;
654                 if(!(codeset & 0x08)) lock = codeset & 7;
655                 codeset &= 7;
656                 lock |= 0x80;
657         }
658         else {
659                 if (w==ESC && wlen >=2) {
660                         code = buffer[pos++]|0x800;
661                         wlen--;
662                 }
663                 else code = w;
664                 code |= (codeset<<8);
665
666                 if (pos + wlen > len) {
667                         eicon_log(ccard, 1, "idi_err: Ch%d: IElen %d of %x exceeds Ind_Length (+%d)\n", chan->No, 
668                                         wlen, code, (pos + wlen) - len);
669                         return;
670                 }
671
672                 switch(code) {
673                         case OAD:
674                                 if (wlen > sizeof(message->oad)) {
675                                         pos += wlen;
676                                         break;
677                                 }
678                                 j = 1;
679                                 if (wlen) {
680                                         message->plan = buffer[pos++];
681                                         if (message->plan &0x80) 
682                                                 message->screen = 0;
683                                         else {
684                                                 message->screen = buffer[pos++];
685                                                 j = 2;
686                                         }
687                                 }
688                                 for(i=0; i < wlen-j; i++) 
689                                         message->oad[i] = buffer[pos++];
690                                 eicon_log(ccard, 2, "idi_inf: Ch%d: OAD=(0x%02x,0x%02x) %s\n", chan->No, 
691                                         message->plan, message->screen, message->oad);
692                                 break;
693                         case RDN:
694                                 if (wlen > sizeof(message->rdn)) {
695                                         pos += wlen;
696                                         break;
697                                 }
698                                 j = 1;
699                                 if (wlen) {
700                                         if (!(buffer[pos++] & 0x80)) {
701                                                 pos++; 
702                                                 j = 2;
703                                         }
704                                 }
705                                 for(i=0; i < wlen-j; i++) 
706                                         message->rdn[i] = buffer[pos++];
707                                 eicon_log(ccard, 2, "idi_inf: Ch%d: RDN= %s\n", chan->No, 
708                                                 message->rdn);
709                                 break;
710                         case CPN:
711                                 if (wlen > sizeof(message->cpn)) {
712                                         pos += wlen;
713                                         break;
714                                 }
715                                 for(i=0; i < wlen; i++) 
716                                         message->cpn[i] = buffer[pos++];
717                                 eicon_log(ccard, 2, "idi_inf: Ch%d: CPN=(0x%02x) %s\n", chan->No,
718                                         (__u8)message->cpn[0], message->cpn + 1);
719                                 break;
720                         case DSA:
721                                 if (wlen > sizeof(message->dsa)) {
722                                         pos += wlen;
723                                         break;
724                                 }
725                                 pos += 2;
726                                 for(i=0; i < wlen-2; i++) 
727                                         message->dsa[i] = buffer[pos++];
728                                 eicon_log(ccard, 2, "idi_inf: Ch%d: DSA=%s\n", chan->No, message->dsa);
729                                 break;
730                         case OSA:
731                                 if (wlen > sizeof(message->osa)) {
732                                         pos += wlen;
733                                         break;
734                                 }
735                                 pos += 2;
736                                 for(i=0; i < wlen-2; i++) 
737                                         message->osa[i] = buffer[pos++];
738                                 eicon_log(ccard, 2, "idi_inf: Ch%d: OSA=%s\n", chan->No, message->osa);
739                                 break;
740                         case CAD:
741                                 pos += wlen;
742                                 eicon_log(ccard, 2, "idi_inf: Ch%d: Connected Address in ind, len:%x\n", 
743                                         chan->No, wlen);
744                                 break;
745                         case BC:
746                                 if (wlen > sizeof(message->bc)) {
747                                         pos += wlen;
748                                         break;
749                                 }
750                                 for(i=0; i < wlen; i++) 
751                                         message->bc[i] = buffer[pos++];
752                                 eicon_log(ccard, 4, "idi_inf: Ch%d: BC = 0x%02x 0x%02x 0x%02x\n", chan->No,
753                                         message->bc[0],message->bc[1],message->bc[2]);
754                                 break;
755                         case 0x800|BC:
756                                 if (wlen > sizeof(message->e_bc)) {
757                                         pos += wlen;
758                                         break;
759                                 }
760                                 for(i=0; i < wlen; i++) 
761                                         message->e_bc[i] = buffer[pos++];
762                                 eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/BC=%d\n", chan->No, message->bc[0]);
763                                 break;
764                         case LLC:
765                                 if (wlen > sizeof(message->llc)) {
766                                         pos += wlen;
767                                         break;
768                                 }
769                                 for(i=0; i < wlen; i++) 
770                                         message->llc[i] = buffer[pos++];
771                                 eicon_log(ccard, 4, "idi_inf: Ch%d: LLC=%d %d %d %d ...\n", chan->No, message->llc[0],
772                                         message->llc[1],message->llc[2],message->llc[3]);
773                                 break;
774                         case HLC:
775                                 if (wlen > sizeof(message->hlc)) {
776                                         pos += wlen;
777                                         break;
778                                 }
779                                 for(i=0; i < wlen; i++) 
780                                         message->hlc[i] = buffer[pos++];
781                                 eicon_log(ccard, 4, "idi_inf: Ch%d: HLC=%x %x %x %x %x ...\n", chan->No,
782                                         message->hlc[0], message->hlc[1],
783                                         message->hlc[2], message->hlc[3], message->hlc[4]);
784                                 break;
785                         case DSP:
786                         case 0x600|DSP:
787                                 if (wlen > sizeof(message->display)) {
788                                         pos += wlen;
789                                         break;
790                                 }
791                                 for(i=0; i < wlen; i++) 
792                                         message->display[i] = buffer[pos++];
793                                 eicon_log(ccard, 4, "idi_inf: Ch%d: Display: %s\n", chan->No,
794                                         message->display);
795                                 break;
796                         case 0x600|KEY:
797                                 if (wlen > sizeof(message->keypad)) {
798                                         pos += wlen;
799                                         break;
800                                 }
801                                 for(i=0; i < wlen; i++) 
802                                         message->keypad[i] = buffer[pos++];
803                                 eicon_log(ccard, 4, "idi_inf: Ch%d: Keypad: %s\n", chan->No,
804                                         message->keypad);
805                                 break;
806                         case NI:
807                         case 0x600|NI:
808                                 if (wlen) {
809                                         switch(buffer[pos] & 127) {
810                                                 case 0:
811                                                         eicon_log(ccard, 4, "idi_inf: Ch%d: User suspended.\n", chan->No);
812                                                         break;
813                                                 case 1:
814                                                         eicon_log(ccard, 4, "idi_inf: Ch%d: User resumed.\n", chan->No);
815                                                         break;
816                                                 case 2:
817                                                         eicon_log(ccard, 4, "idi_inf: Ch%d: Bearer service change.\n", chan->No);
818                                                         break;
819                                                 default:
820                                                         eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Notification %x.\n", 
821                                                                         chan->No, buffer[pos] & 127);
822                                         }
823                                         pos += wlen;
824                                 }
825                                 break;
826                         case PI:
827                         case 0x600|PI:
828                                 if (wlen > 1) {
829                                         switch(buffer[pos+1] & 127) {
830                                                 case 1:
831                                                         eicon_log(ccard, 4, "idi_inf: Ch%d: Call is not end-to-end ISDN.\n", chan->No);
832                                                         break;
833                                                 case 2:
834                                                         eicon_log(ccard, 4, "idi_inf: Ch%d: Destination address is non ISDN.\n", chan->No);
835                                                         break;
836                                                 case 3:
837                                                         eicon_log(ccard, 4, "idi_inf: Ch%d: Origination address is non ISDN.\n", chan->No);
838                                                         break;
839                                                 case 4:
840                                                         eicon_log(ccard, 4, "idi_inf: Ch%d: Call has returned to the ISDN.\n", chan->No);
841                                                         break;
842                                                 case 5:
843                                                         eicon_log(ccard, 4, "idi_inf: Ch%d: Interworking has occurred.\n", chan->No);
844                                                         break;
845                                                 case 8:
846                                                         eicon_log(ccard, 4, "idi_inf: Ch%d: In-band information available.\n", chan->No);
847                                                         break;
848                                                 default:
849                                                         eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Progress %x.\n", 
850                                                                         chan->No, buffer[pos+1] & 127);
851                                         }
852                                 }
853                                 pos += wlen;
854                                 break;
855                         case CAU:
856                                 if (wlen > sizeof(message->cau)) {
857                                         pos += wlen;
858                                         break;
859                                 }
860                                 for(i=0; i < wlen; i++) 
861                                         message->cau[i] = buffer[pos++];
862                                 memcpy(&chan->cause, &message->cau, 2);
863                                 eicon_log(ccard, 4, "idi_inf: Ch%d: CAU=%d %d\n", chan->No,
864                                         message->cau[0],message->cau[1]);
865                                 break;
866                         case 0x800|CAU:
867                                 if (wlen > sizeof(message->e_cau)) {
868                                         pos += wlen;
869                                         break;
870                                 }
871                                 for(i=0; i < wlen; i++) 
872                                         message->e_cau[i] = buffer[pos++];
873                                 eicon_log(ccard, 4, "idi_inf: Ch%d: ECAU=%d %d\n", chan->No,
874                                         message->e_cau[0],message->e_cau[1]);
875                                 break;
876                         case 0x800|CHI:
877                                 if (wlen > sizeof(message->e_chi)) {
878                                         pos += wlen;
879                                         break;
880                                 }
881                                 for(i=0; i < wlen; i++) 
882                                         message->e_chi[i] = buffer[pos++];
883                                 eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/CHI=%d\n", chan->No,
884                                         message->e_cau[0]);
885                                 break;
886                         case 0x800|0x7a:
887                                 pos ++;
888                                 message->e_mt=buffer[pos++];
889                                 eicon_log(ccard, 4, "idi_inf: Ch%d: EMT=0x%x\n", chan->No, message->e_mt);
890                                 break;
891                         case DT:
892                                 if (wlen > sizeof(message->dt)) {
893                                         pos += wlen;
894                                         break;
895                                 }
896                                 for(i=0; i < wlen; i++) 
897                                         message->dt[i] = buffer[pos++];
898                                 eicon_log(ccard, 4, "idi_inf: Ch%d: DT: %02d.%02d.%02d %02d:%02d:%02d\n", chan->No,
899                                         message->dt[2], message->dt[1], message->dt[0],
900                                         message->dt[3], message->dt[4], message->dt[5]);
901                                 break;
902                         case 0x600|SIN:
903                                 if (wlen > sizeof(message->sin)) {
904                                         pos += wlen;
905                                         break;
906                                 }
907                                 for(i=0; i < wlen; i++) 
908                                         message->sin[i] = buffer[pos++];
909                                 eicon_log(ccard, 2, "idi_inf: Ch%d: SIN=%d %d\n", chan->No,
910                                         message->sin[0],message->sin[1]);
911                                 break;
912                         case 0x600|CPS:
913                                 eicon_log(ccard, 2, "idi_inf: Ch%d: Called Party Status in ind\n", chan->No);
914                                 pos += wlen;
915                                 break;
916                         case 0x600|CIF:
917                                 for (i = 0; i < wlen; i++)
918                                         if (buffer[pos + i] != '0') break;
919                                 memcpy(&cmd.parm.num, &buffer[pos + i], wlen - i);
920                                 cmd.parm.num[wlen - i] = 0;
921                                 eicon_log(ccard, 2, "idi_inf: Ch%d: CIF=%s\n", chan->No, cmd.parm.num);
922                                 pos += wlen;
923                                 cmd.driver = ccard->myid;
924                                 cmd.command = ISDN_STAT_CINF;
925                                 cmd.arg = chan->No;
926                                 ccard->interface.statcallb(&cmd);
927                                 break;
928                         case 0x600|DATE:
929                                 eicon_log(ccard, 2, "idi_inf: Ch%d: Date in ind\n", chan->No);
930                                 pos += wlen;
931                                 break;
932                         case 0xa1: 
933                                 eicon_log(ccard, 2, "idi_inf: Ch%d: Sending Complete in ind.\n", chan->No);
934                                 pos += wlen;
935                                 break;
936                         case 0xe08: 
937                         case 0xe7a: 
938                         case 0xe04: 
939                         case 0xe00: 
940                                 /* *** TODO *** */
941                         case CHA:
942                                 /* Charge advice */
943                         case FTY:
944                         case 0x600|FTY:
945                         case CHI:
946                         case 0x800:
947                                 /* Not yet interested in this */
948                                 pos += wlen;
949                                 break;
950                         case 0x880:
951                                 /* Managment Information Element */
952                                 if (!manbuf) {
953                                         eicon_log(ccard, 1, "idi_err: manbuf not allocated\n");
954                                 }
955                                 else {
956                                         memcpy(&manbuf->data[manbuf->pos], &buffer[pos], wlen);
957                                         manbuf->length[manbuf->count] = wlen;
958                                         manbuf->count++;
959                                         manbuf->pos += wlen;
960                                 }
961                                 pos += wlen;
962                                 break;
963                         default:
964                                 pos += wlen;
965                                 eicon_log(ccard, 6, "idi_inf: Ch%d: unknown information element 0x%x in ind, len:%x\n", 
966                                         chan->No, code, wlen);
967                 }
968         }
969   }
970 }
971
972 void
973 idi_bc2si(unsigned char *bc, unsigned char *hlc, unsigned char *sin, unsigned char *si1, unsigned char *si2)
974 {
975         si1[0] = 0;
976         si2[0] = 0;
977
978         switch (bc[0] & 0x7f) {
979                 case 0x00: /* Speech */
980                         si1[0] = 1;
981 #ifdef EICON_FULL_SERVICE_OKTETT
982                         si1[0] = sin[0];
983                         si2[0] = sin[1];
984 #endif
985                         break;
986                 case 0x10: /* 3.1 Khz audio */
987                         si1[0] = 1;
988 #ifdef EICON_FULL_SERVICE_OKTETT
989                         si1[0] = sin[0];
990                         si2[0] = sin[1];
991 #endif
992                         break;
993                 case 0x08: /* Unrestricted digital information */
994                         si1[0] = 7;
995                         si2[0] = sin[1];
996                         break;
997                 case 0x09: /* Restricted digital information */
998                         si1[0] = 2;
999                         break;
1000                 case 0x11:
1001                         /* Unrestr. digital information  with
1002                          * tones/announcements ( or 7 kHz audio
1003                          */
1004                         si1[0] = 3;
1005                         break;
1006                 case 0x18: /* Video */
1007                         si1[0] = 4;
1008                         break;
1009         }
1010         switch (bc[1] & 0x7f) {
1011                 case 0x40: /* packed mode */
1012                         si1[0] = 8;
1013                         break;
1014                 case 0x10: /* 64 kbit */
1015                 case 0x11: /* 2*64 kbit */
1016                 case 0x13: /* 384 kbit */
1017                 case 0x15: /* 1536 kbit */
1018                 case 0x17: /* 1920 kbit */
1019                         /* moderate = bc[1] & 0x7f; */
1020                         break;
1021         }
1022 }
1023
1024 /********************* FAX stuff ***************************/
1025
1026 #ifdef CONFIG_ISDN_TTY_FAX
1027
1028 int
1029 idi_fill_in_T30(eicon_chan *chan, unsigned char *buffer)
1030 {
1031         eicon_t30_s     *t30 = (eicon_t30_s *) buffer;
1032
1033         if (!chan->fax) {
1034                 eicon_log(NULL, 1,"idi_T30: fill_in with NULL fax struct, ERROR\n");
1035                 return 0;
1036         }
1037         memset(t30, 0, sizeof(eicon_t30_s));
1038         t30->station_id_len = EICON_FAXID_LEN;
1039         memcpy(&t30->station_id[0], &chan->fax->id[0], EICON_FAXID_LEN);
1040         t30->resolution = chan->fax->resolution;
1041         t30->rate = chan->fax->rate + 1;        /* eicon rate starts with 1 */
1042         t30->format = T30_FORMAT_SFF;
1043         t30->pages_low = 0;
1044         t30->pages_high = 0;
1045         t30->atf = 1;                           /* optimised for AT+F command set */
1046         t30->code = 0;
1047         t30->feature_bits_low = 0;
1048         t30->feature_bits_high = 0;
1049         t30->control_bits_low = 0;
1050         t30->control_bits_high = 0;
1051
1052         if (chan->fax->nbc) {
1053                 /* set compression by DCC value */
1054           switch(chan->fax->compression) {
1055                 case (0):       /* 1-D modified */
1056                         break;
1057                 case (1):       /* 2-D modified Read */
1058                         t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
1059                         t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
1060                         break;
1061                 case (2):       /* 2-D uncompressed */
1062                         t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
1063                         t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
1064                         t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
1065                         t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
1066                         break;
1067                 case (3):       /* 2-D modified Read */
1068                         t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING;
1069                         t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
1070                         t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
1071                         t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
1072                         t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING;
1073                         t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
1074                         t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
1075                         t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
1076                         break;
1077           }
1078         } else {
1079                 /* set compression to best */
1080                 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING;
1081                 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
1082                 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
1083                 t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
1084                 t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING;
1085                 t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
1086                 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
1087                 t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
1088         }
1089         switch(chan->fax->ecm) {
1090                 case (0):       /* disable ECM */
1091                         break;
1092                 case (1):
1093                         t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
1094                         t30->control_bits_low |= T30_CONTROL_BIT_ECM_64_BYTES;
1095                         t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
1096                         t30->feature_bits_low |= T30_FEATURE_BIT_ECM_64_BYTES;
1097                         break;
1098                 case (2):
1099                         t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
1100                         t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
1101                         break;
1102         }
1103
1104         if (DebugVar & 128) {
1105                 char st[40];
1106                 eicon_log(NULL, 128, "sT30:code = %x\n", t30->code);
1107                 eicon_log(NULL, 128, "sT30:rate = %x\n", t30->rate);
1108                 eicon_log(NULL, 128, "sT30:res  = %x\n", t30->resolution);
1109                 eicon_log(NULL, 128, "sT30:format = %x\n", t30->format);
1110                 eicon_log(NULL, 128, "sT30:pages_low = %x\n", t30->pages_low);
1111                 eicon_log(NULL, 128, "sT30:pages_high = %x\n", t30->pages_high);
1112                 eicon_log(NULL, 128, "sT30:atf  = %x\n", t30->atf);
1113                 eicon_log(NULL, 128, "sT30:control_bits_low = %x\n", t30->control_bits_low);
1114                 eicon_log(NULL, 128, "sT30:control_bits_high = %x\n", t30->control_bits_high);
1115                 eicon_log(NULL, 128, "sT30:feature_bits_low = %x\n", t30->feature_bits_low);
1116                 eicon_log(NULL, 128, "sT30:feature_bits_high = %x\n", t30->feature_bits_high);
1117                 //eicon_log(NULL, 128, "sT30:universal_5 = %x\n", t30->universal_5);
1118                 //eicon_log(NULL, 128, "sT30:universal_6 = %x\n", t30->universal_6);
1119                 //eicon_log(NULL, 128, "sT30:universal_7 = %x\n", t30->universal_7);
1120                 eicon_log(NULL, 128, "sT30:station_id_len = %x\n", t30->station_id_len);
1121                 eicon_log(NULL, 128, "sT30:head_line_len = %x\n", t30->head_line_len);
1122                 strncpy(st, t30->station_id, t30->station_id_len);
1123                 st[t30->station_id_len] = 0;
1124                 eicon_log(NULL, 128, "sT30:station_id = <%s>\n", st);
1125         }
1126         return(sizeof(eicon_t30_s));
1127 }
1128
1129 /* send fax struct */
1130 int
1131 idi_send_edata(eicon_card *card, eicon_chan *chan)
1132 {
1133         struct sk_buff *skb;
1134         struct sk_buff *skb2;
1135         eicon_REQ *reqbuf;
1136         eicon_chan_ptr *chan2;
1137
1138         if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) {
1139                 eicon_log(card, 1, "idi_snd: Ch%d: send edata on state %d !\n", chan->No, chan->fsm_state);
1140                 return -ENODEV;
1141         }
1142         eicon_log(card, 128, "idi_snd: Ch%d: edata (fax)\n", chan->No);
1143
1144         skb = alloc_skb(sizeof(eicon_REQ) + sizeof(eicon_t30_s), GFP_ATOMIC);
1145         skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
1146
1147         if ((!skb) || (!skb2)) {
1148                 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_edata()\n", chan->No);
1149                 if (skb) 
1150                         dev_kfree_skb(skb);
1151                 if (skb2) 
1152                         dev_kfree_skb(skb2);
1153                 return -ENOMEM;
1154         }
1155
1156         chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
1157         chan2->ptr = chan;
1158
1159         reqbuf = (eicon_REQ *)skb_put(skb, sizeof(eicon_t30_s) + sizeof(eicon_REQ));
1160
1161         reqbuf->Req = N_EDATA;
1162         reqbuf->ReqCh = chan->e.IndCh;
1163         reqbuf->ReqId = 1;
1164
1165         reqbuf->XBuffer.length = idi_fill_in_T30(chan, reqbuf->XBuffer.P);
1166         reqbuf->Reference = 1; /* Net Entity */
1167
1168         skb_queue_tail(&chan->e.X, skb);
1169         skb_queue_tail(&card->sndq, skb2);
1170         eicon_schedule_tx(card);
1171         return (0);
1172 }
1173
1174 void
1175 idi_parse_edata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len)
1176 {
1177         eicon_t30_s *p = (eicon_t30_s *)buffer;
1178         int i;
1179
1180         if (DebugVar & 128) {
1181                 char st[40];
1182                 eicon_log(ccard, 128, "rT30:len %d , size %d\n", len, sizeof(eicon_t30_s));
1183                 eicon_log(ccard, 128, "rT30:code = %x\n", p->code);
1184                 eicon_log(ccard, 128, "rT30:rate = %x\n", p->rate);
1185                 eicon_log(ccard, 128, "rT30:res  = %x\n", p->resolution);
1186                 eicon_log(ccard, 128, "rT30:format = %x\n", p->format);
1187                 eicon_log(ccard, 128, "rT30:pages_low = %x\n", p->pages_low);
1188                 eicon_log(ccard, 128, "rT30:pages_high = %x\n", p->pages_high);
1189                 eicon_log(ccard, 128, "rT30:atf  = %x\n", p->atf);
1190                 eicon_log(ccard, 128, "rT30:control_bits_low = %x\n", p->control_bits_low);
1191                 eicon_log(ccard, 128, "rT30:control_bits_high = %x\n", p->control_bits_high);
1192                 eicon_log(ccard, 128, "rT30:feature_bits_low = %x\n", p->feature_bits_low);
1193                 eicon_log(ccard, 128, "rT30:feature_bits_high = %x\n", p->feature_bits_high);
1194                 //eicon_log(ccard, 128, "rT30:universal_5 = %x\n", p->universal_5);
1195                 //eicon_log(ccard, 128, "rT30:universal_6 = %x\n", p->universal_6);
1196                 //eicon_log(ccard, 128, "rT30:universal_7 = %x\n", p->universal_7);
1197                 eicon_log(ccard, 128, "rT30:station_id_len = %x\n", p->station_id_len);
1198                 eicon_log(ccard, 128, "rT30:head_line_len = %x\n", p->head_line_len);
1199                 strncpy(st, p->station_id, p->station_id_len);
1200                 st[p->station_id_len] = 0;
1201                 eicon_log(ccard, 128, "rT30:station_id = <%s>\n", st);
1202         }
1203         if (!chan->fax) {
1204                 eicon_log(ccard, 1, "idi_edata: parse to NULL fax struct, ERROR\n");
1205                 return;
1206         }
1207         chan->fax->code = p->code;
1208         i = (p->station_id_len < FAXIDLEN) ? p->station_id_len : (FAXIDLEN - 1);
1209         memcpy(chan->fax->r_id, p->station_id, i);
1210         chan->fax->r_id[i] = 0;
1211         chan->fax->r_resolution = p->resolution;
1212         chan->fax->r_rate = p->rate - 1;
1213         chan->fax->r_binary = 0; /* no binary support */
1214         chan->fax->r_width = 0;
1215         chan->fax->r_length = 2;
1216         chan->fax->r_scantime = 0;
1217         chan->fax->r_compression = 0;
1218         chan->fax->r_ecm = 0;
1219         if (p->feature_bits_low & T30_FEATURE_BIT_2D_CODING) {
1220                 chan->fax->r_compression = 1;
1221                 if (p->feature_bits_low & T30_FEATURE_BIT_UNCOMPR_ENABLED) {
1222                         chan->fax->r_compression = 2;
1223                 }
1224         }
1225         if (p->feature_bits_low & T30_FEATURE_BIT_T6_CODING) {
1226                 chan->fax->r_compression = 3;
1227         }
1228
1229         if (p->feature_bits_low & T30_FEATURE_BIT_ECM) {
1230                 chan->fax->r_ecm = 2;
1231                 if (p->feature_bits_low & T30_FEATURE_BIT_ECM_64_BYTES)
1232                         chan->fax->r_ecm = 1;
1233         }
1234 }
1235
1236 void
1237 idi_fax_send_header(eicon_card *card, eicon_chan *chan, int header)
1238 {
1239         static __u16 wd2sff[] = {
1240                 1728, 2048, 2432, 1216, 864
1241         };
1242         static __u16 ln2sff[2][3] = {
1243                 { 1143, 1401, 0 } , { 2287, 2802, 0 }
1244         };
1245         struct sk_buff *skb;
1246         eicon_sff_dochead *doc;
1247         eicon_sff_pagehead *page;
1248         u_char *docp;
1249
1250         if (!chan->fax) {
1251                 eicon_log(card, 1, "idi_fax: send head with NULL fax struct, ERROR\n");
1252                 return;
1253         }
1254         if (header == 2) { /* DocHeader + PageHeader */
1255                 skb = alloc_skb(sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead), GFP_ATOMIC);
1256         } else {
1257                 skb = alloc_skb(sizeof(eicon_sff_pagehead), GFP_ATOMIC);
1258         }
1259         if (!skb) {
1260                 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_header()\n", chan->No);
1261                 return;
1262         }
1263
1264         if (header == 2) { /* DocHeader + PageHeader */
1265                 docp = skb_put(skb, sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead));
1266                 doc = (eicon_sff_dochead *) docp;
1267                 page = (eicon_sff_pagehead *) (docp + sizeof(eicon_sff_dochead));
1268                 memset(docp, 0,sizeof(eicon_sff_dochead)  + sizeof(eicon_sff_pagehead));
1269                 doc->id = 0x66666653;
1270                 doc->version = 0x01;
1271                 doc->off1pagehead = sizeof(eicon_sff_dochead);
1272         } else {
1273                 page = (eicon_sff_pagehead *)skb_put(skb, sizeof(eicon_sff_pagehead));
1274                 memset(page, 0, sizeof(eicon_sff_pagehead));
1275         }
1276
1277         switch(header) {
1278                 case 1: /* PageHeaderEnd */
1279                         page->pageheadid = 254;
1280                         page->pageheadlen = 0; 
1281                         break;
1282                 case 0: /* PageHeader */
1283                 case 2: /* DocHeader + PageHeader */
1284                         page->pageheadid = 254;
1285                         page->pageheadlen = sizeof(eicon_sff_pagehead) - 2;
1286                         page->resvert = chan->fax->resolution;
1287                         page->reshoriz = 0; /* always 203 dpi */
1288                         page->coding = 0; /* always 1D */
1289                         page->linelength = wd2sff[chan->fax->width];
1290                         page->pagelength = ln2sff[chan->fax->resolution][chan->fax->length]; 
1291                         eicon_log(card, 128, "sSFF-Head: linelength = %d\n", page->linelength);
1292                         eicon_log(card, 128, "sSFF-Head: pagelength = %d\n", page->pagelength);
1293                         break;
1294         }
1295         idi_send_data(card, chan, 0, skb, 0, 0);
1296 }
1297
1298 void
1299 idi_fax_cmd(eicon_card *card, eicon_chan *chan) 
1300 {
1301         isdn_ctrl cmd;
1302
1303         if ((!card) || (!chan))
1304                 return;
1305
1306         if (!chan->fax) {
1307                 eicon_log(card, 1, "idi_fax: cmd with NULL fax struct, ERROR\n");
1308                 return;
1309         }
1310         switch (chan->fax->code) {
1311                 case ISDN_TTY_FAX_DT:
1312                         if (chan->fax->phase == ISDN_FAX_PHASE_B) {
1313                                 idi_send_edata(card, chan);
1314                                 break;
1315                         }
1316                         if (chan->fax->phase == ISDN_FAX_PHASE_D) {
1317                                 idi_send_edata(card, chan);
1318                                 break;
1319                         }
1320                         break;
1321
1322                 case ISDN_TTY_FAX_DR:
1323                         if (chan->fax->phase == ISDN_FAX_PHASE_B) {
1324                                 idi_send_edata(card, chan);
1325
1326                                 cmd.driver = card->myid;
1327                                 cmd.command = ISDN_STAT_FAXIND;
1328                                 cmd.arg = chan->No;
1329                                 chan->fax->r_code = ISDN_TTY_FAX_CFR;
1330                                 card->interface.statcallb(&cmd);
1331
1332                                 cmd.driver = card->myid;
1333                                 cmd.command = ISDN_STAT_FAXIND;
1334                                 cmd.arg = chan->No;
1335                                 chan->fax->r_code = ISDN_TTY_FAX_RID;
1336                                 card->interface.statcallb(&cmd);
1337
1338                                 /* telling 1-D compression */
1339                                 chan->fax->r_compression = 0;
1340                                 cmd.driver = card->myid;
1341                                 cmd.command = ISDN_STAT_FAXIND;
1342                                 cmd.arg = chan->No;
1343                                 chan->fax->r_code = ISDN_TTY_FAX_DCS;
1344                                 card->interface.statcallb(&cmd);
1345
1346                                 chan->fax2.NextObject = FAX_OBJECT_DOCU;
1347                                 chan->fax2.PrevObject = FAX_OBJECT_DOCU;
1348
1349                                 break;
1350                         }
1351                         if (chan->fax->phase == ISDN_FAX_PHASE_D) {
1352                                 idi_send_edata(card, chan);
1353                                 break;
1354                         }
1355                         break;
1356
1357                 case ISDN_TTY_FAX_ET:
1358                                 switch(chan->fax->fet) {
1359                                         case 0:
1360                                         case 1:
1361                                                 idi_fax_send_header(card, chan, 0);
1362                                                 break;
1363                                         case 2:
1364                                                 idi_fax_send_header(card, chan, 1);
1365                                                 break;
1366                                 }
1367                         break;
1368         }
1369 }
1370
1371 void
1372 idi_edata_rcveop(eicon_card *card, eicon_chan *chan)
1373 {
1374         isdn_ctrl cmd;
1375
1376         if (!chan->fax) {
1377                 eicon_log(card, 1, "idi_edata: rcveop with NULL fax struct, ERROR\n");
1378                 return;
1379         }
1380         cmd.driver = card->myid;
1381         cmd.command = ISDN_STAT_FAXIND;
1382         cmd.arg = chan->No;
1383         chan->fax->r_code = ISDN_TTY_FAX_ET;
1384         card->interface.statcallb(&cmd);
1385 }
1386
1387 void
1388 idi_reset_fax_stat(eicon_chan *chan)
1389 {
1390         chan->fax2.LineLen = 0;
1391         chan->fax2.LineData = 0;
1392         chan->fax2.LineDataLen = 0;
1393         chan->fax2.NullByteExist = 0;
1394         chan->fax2.Dle = 0;
1395         chan->fax2.PageCount = 0;
1396         chan->fax2.Eop = 0;
1397 }
1398
1399 void
1400 idi_edata_action(eicon_card *ccard, eicon_chan *chan, char *buffer, int len)
1401 {
1402         isdn_ctrl cmd;
1403
1404         if (!chan->fax) {
1405                 eicon_log(ccard, 1, "idi_edata: action with NULL fax struct, ERROR\n");
1406                 return;
1407         }
1408         if (chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) {
1409                 idi_parse_edata(ccard, chan, buffer, len);
1410
1411                 if (chan->fax->phase == ISDN_FAX_PHASE_A) {
1412                         idi_reset_fax_stat(chan);
1413
1414                         chan->fsm_state = EICON_STATE_ACTIVE;
1415                         cmd.driver = ccard->myid;
1416                         cmd.command = ISDN_STAT_BCONN;
1417                         cmd.arg = chan->No;
1418                         strcpy(cmd.parm.num, "");
1419                         ccard->interface.statcallb(&cmd);
1420
1421                         cmd.driver = ccard->myid;
1422                         cmd.command = ISDN_STAT_FAXIND;
1423                         cmd.arg = chan->No;
1424                         chan->fax->r_code = ISDN_TTY_FAX_FCON;
1425                         ccard->interface.statcallb(&cmd);
1426
1427                         cmd.driver = ccard->myid;
1428                         cmd.command = ISDN_STAT_FAXIND;
1429                         cmd.arg = chan->No;
1430                         chan->fax->r_code = ISDN_TTY_FAX_RID;
1431                         ccard->interface.statcallb(&cmd);
1432
1433                         cmd.driver = ccard->myid;
1434                         cmd.command = ISDN_STAT_FAXIND;
1435                         cmd.arg = chan->No;
1436                         chan->fax->r_code = ISDN_TTY_FAX_DIS;
1437                         ccard->interface.statcallb(&cmd);
1438
1439                         if (chan->fax->r_compression != 0) {
1440                         /* telling fake compression in second DIS message */
1441                                 chan->fax->r_compression = 0;
1442                                 cmd.driver = ccard->myid;
1443                                 cmd.command = ISDN_STAT_FAXIND;
1444                                 cmd.arg = chan->No;
1445                                 chan->fax->r_code = ISDN_TTY_FAX_DIS;
1446                                 ccard->interface.statcallb(&cmd);
1447                         }
1448
1449                         cmd.driver = ccard->myid;
1450                         cmd.command = ISDN_STAT_FAXIND;
1451                         cmd.arg = chan->No;
1452                         chan->fax->r_code = ISDN_TTY_FAX_SENT; /* OK message */
1453                         ccard->interface.statcallb(&cmd);
1454                 } else
1455                 if (chan->fax->phase == ISDN_FAX_PHASE_D) {
1456
1457                         if ((chan->fax->code == EDATA_T30_MCF) &&
1458                             (chan->fax->fet != 2)) {
1459                                 cmd.driver = ccard->myid;
1460                                 cmd.command = ISDN_STAT_FAXIND;
1461                                 cmd.arg = chan->No;
1462                                 chan->fax->r_code = ISDN_TTY_FAX_PTS;
1463                                 ccard->interface.statcallb(&cmd);
1464                         }
1465
1466                         switch(chan->fax->fet) {
1467                                 case 0: /* new page */
1468                                         /* stay in phase D , wait on cmd +FDT */
1469                                         break;
1470                                 case 1: /* new document */
1471                                         /* link-level switch to phase B */
1472                                         break;
1473                                 case 2: /* session end */
1474                                 default:
1475                                         /* send_edata produces error on some */
1476                                         /* fax-machines here, so we don't */
1477                                         /* idi_send_edata(ccard, chan); */
1478                                         break;
1479                         }
1480                 }
1481         }
1482
1483         if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
1484                 idi_parse_edata(ccard, chan, buffer, len);
1485
1486                 if ((chan->fax->code == EDATA_T30_DCS) &&
1487                     (chan->fax->phase == ISDN_FAX_PHASE_A)) {
1488                         idi_reset_fax_stat(chan);
1489
1490                         cmd.driver = ccard->myid;
1491                         cmd.command = ISDN_STAT_BCONN;
1492                         cmd.arg = chan->No;
1493                         strcpy(cmd.parm.num, "");
1494                         ccard->interface.statcallb(&cmd);
1495
1496                         cmd.driver = ccard->myid;
1497                         cmd.command = ISDN_STAT_FAXIND;
1498                         cmd.arg = chan->No;
1499                         chan->fax->r_code = ISDN_TTY_FAX_FCON_I;
1500                         ccard->interface.statcallb(&cmd);
1501                 } else
1502                 if ((chan->fax->code == EDATA_T30_TRAIN_OK) &&
1503                     (chan->fax->phase == ISDN_FAX_PHASE_A)) {
1504                         cmd.driver = ccard->myid;
1505                         cmd.command = ISDN_STAT_FAXIND;
1506                         cmd.arg = chan->No;
1507                         chan->fax->r_code = ISDN_TTY_FAX_RID;
1508                         ccard->interface.statcallb(&cmd);
1509
1510                         cmd.driver = ccard->myid;
1511                         cmd.command = ISDN_STAT_FAXIND;
1512                         cmd.arg = chan->No;
1513                         chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;
1514                         ccard->interface.statcallb(&cmd);
1515                 } else
1516                 if ((chan->fax->code == EDATA_T30_TRAIN_OK) &&
1517                     (chan->fax->phase == ISDN_FAX_PHASE_B)) {
1518                         cmd.driver = ccard->myid;
1519                         cmd.command = ISDN_STAT_FAXIND;
1520                         cmd.arg = chan->No;
1521                         chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;
1522                         ccard->interface.statcallb(&cmd);
1523                 } else
1524                 if (chan->fax->phase == ISDN_FAX_PHASE_C) {
1525                         switch(chan->fax->code) {
1526                                 case EDATA_T30_TRAIN_OK:
1527                                         idi_send_edata(ccard, chan);
1528                                         break;
1529                                 case EDATA_T30_MPS:
1530                                         chan->fax->fet = 0;
1531                                         idi_edata_rcveop(ccard, chan);
1532                                         break;
1533                                 case EDATA_T30_EOM:
1534                                         chan->fax->fet = 1;
1535                                         idi_edata_rcveop(ccard, chan);
1536                                         break;
1537                                 case EDATA_T30_EOP:
1538                                         chan->fax->fet = 2;
1539                                         idi_edata_rcveop(ccard, chan);
1540                                         break;
1541                         }
1542                 }
1543         }
1544 }
1545
1546 void
1547 fax_put_rcv(eicon_card *ccard, eicon_chan *chan, u_char *Data, int len)
1548 {
1549         struct sk_buff *skb;
1550         
1551         skb = alloc_skb(len + MAX_HEADER_LEN, GFP_ATOMIC);
1552         if (!skb) {
1553                 eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_put_rcv()\n", chan->No);
1554                 return;
1555         }
1556         skb_reserve(skb, MAX_HEADER_LEN);
1557         memcpy(skb_put(skb, len), Data, len);
1558         ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb);
1559 }
1560
1561 void
1562 idi_faxdata_rcv(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb)
1563 {
1564         eicon_OBJBUFFER InBuf;
1565         eicon_OBJBUFFER LineBuf;
1566         unsigned int Length = 0;
1567         unsigned int aLength = 0;
1568         unsigned int ObjectSize = 0;
1569         unsigned int ObjHeadLen = 0;
1570         unsigned int ObjDataLen = 0;
1571         __u8 Recordtype;
1572         __u8 PageHeaderLen;     
1573         __u8 Event;
1574         eicon_sff_pagehead *ob_page;
1575
1576         __u16 Cl2Eol = 0x8000;
1577
1578 #       define EVENT_NONE       0
1579 #       define EVENT_NEEDDATA   1
1580
1581         if (!chan->fax) {
1582                 eicon_log(ccard, 1, "idi_fax: rcvdata with NULL fax struct, ERROR\n");
1583                 return;
1584         }
1585
1586
1587         
1588         if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
1589                 InBuf.Data = skb->data;
1590                 InBuf.Size = skb->len;
1591                 InBuf.Len  = 0;
1592                 InBuf.Next = InBuf.Data;
1593                 LineBuf.Data = chan->fax2.abLine;
1594                 LineBuf.Size = sizeof(chan->fax2.abLine);
1595                 LineBuf.Len  = chan->fax2.LineLen;
1596                 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1597
1598                 Event = EVENT_NONE;
1599                 while (Event == EVENT_NONE) {
1600                         switch(chan->fax2.NextObject) {
1601                                 case FAX_OBJECT_DOCU:
1602                                                 Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
1603                                                 if (Length < sizeof(eicon_sff_dochead)) {
1604                                                         Event = EVENT_NEEDDATA;
1605                                                         break;
1606                                                 }
1607                                                 ObjectSize = sizeof(eicon_sff_dochead);
1608                                                 Length = ObjectSize;
1609                                                 if (LineBuf.Len < Length) {
1610                                                         Length -= LineBuf.Len;
1611                                                         LineBuf.Len = 0;
1612                                                         LineBuf.Next = LineBuf.Data;
1613                                                         InBuf.Len += Length;
1614                                                         InBuf.Next += Length;
1615                                                 } else {
1616                                                         LineBuf.Len -= Length;
1617                                                         LineBuf.Next = LineBuf.Data + LineBuf.Len;
1618                                                         memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
1619                                                 }
1620                                                 chan->fax2.PrevObject = FAX_OBJECT_DOCU;
1621                                                 chan->fax2.NextObject = FAX_OBJECT_PAGE;
1622                                         break;
1623
1624                                 case FAX_OBJECT_PAGE:
1625                                                 Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
1626                                                 if (Length < 2) {
1627                                                         Event = EVENT_NEEDDATA;
1628                                                         break;
1629                                                 }
1630                                                 if (LineBuf.Len == 0) {
1631                                                         *LineBuf.Next++ = *InBuf.Next++;
1632                                                         LineBuf.Len++;
1633                                                         InBuf.Len++;
1634                                                 }
1635                                                 if (LineBuf.Len == 1) {
1636                                                         *LineBuf.Next++ = *InBuf.Next++;
1637                                                         LineBuf.Len++;
1638                                                         InBuf.Len++;
1639                                                 }
1640                                                 PageHeaderLen = *(LineBuf.Data + 1);
1641                                                 ObjectSize = (PageHeaderLen == 0) ? 2 : sizeof(eicon_sff_pagehead);
1642                                                 if (Length < ObjectSize) {
1643                                                         Event = EVENT_NEEDDATA;
1644                                                         break;
1645                                                 }
1646                                                 Length = ObjectSize;
1647                                                 /* extract page dimensions */
1648                                                 if (LineBuf.Len < Length) {
1649                                                         aLength = Length - LineBuf.Len;
1650                                                         memcpy(LineBuf.Next, InBuf.Next, aLength);
1651                                                         LineBuf.Next += aLength;
1652                                                         InBuf.Next += aLength;
1653                                                         LineBuf.Len += aLength;
1654                                                         InBuf.Len += aLength;
1655                                                 }
1656                                                 if (Length > 2) {
1657                                                         ob_page = (eicon_sff_pagehead *)LineBuf.Data;
1658                                                         switch(ob_page->linelength) {
1659                                                                 case 2048:
1660                                                                         chan->fax->r_width = 1;
1661                                                                         break;
1662                                                                 case 2432:
1663                                                                         chan->fax->r_width = 2;
1664                                                                         break;
1665                                                                 case 1216:
1666                                                                         chan->fax->r_width = 3;
1667                                                                         break;
1668                                                                 case 864:
1669                                                                         chan->fax->r_width = 4;
1670                                                                         break;
1671                                                                 case 1728:
1672                                                                 default:
1673                                                                         chan->fax->r_width = 0;
1674                                                         }
1675                                                         switch(ob_page->pagelength) {
1676                                                                 case 1143:
1677                                                                 case 2287:
1678                                                                         chan->fax->r_length = 0;
1679                                                                         break;
1680                                                                 case 1401:
1681                                                                 case 2802:
1682                                                                         chan->fax->r_length = 1;
1683                                                                         break;
1684                                                                 default:
1685                                                                         chan->fax->r_length = 2;
1686                                                         }
1687                                                         eicon_log(ccard, 128, "rSFF-Head: linelength = %d\n", ob_page->linelength);
1688                                                         eicon_log(ccard, 128, "rSFF-Head: pagelength = %d\n", ob_page->pagelength);
1689                                                 }
1690                                                 LineBuf.Len -= Length;
1691                                                 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1692                                                 memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
1693
1694                                                 chan->fax2.PrevObject = FAX_OBJECT_PAGE;
1695                                                 chan->fax2.NextObject = FAX_OBJECT_LINE;
1696                                         break;
1697
1698                                 case FAX_OBJECT_LINE:
1699                                                 Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
1700                                                 if (Length < 1) {
1701                                                         Event = EVENT_NEEDDATA;
1702                                                         break;
1703                                                 }
1704                                                 if (LineBuf.Len == 0) {
1705                                                         *LineBuf.Next++ = *InBuf.Next++;
1706                                                         LineBuf.Len++;
1707                                                         InBuf.Len++;
1708                                                 }
1709                                                 Recordtype = *LineBuf.Data;
1710                                                 if (Recordtype == 0) {
1711                                                         /* recordtype pixel row (2 byte length) */
1712                                                         ObjHeadLen = 3;
1713                                                         if (Length < ObjHeadLen) {
1714                                                                 Event = EVENT_NEEDDATA;
1715                                                                 break;
1716                                                         }
1717                                                         while (LineBuf.Len < ObjHeadLen) {
1718                                                                 *LineBuf.Next++ = *InBuf.Next++;
1719                                                                 LineBuf.Len++;
1720                                                                 InBuf.Len++;
1721                                                         }
1722                                                         ObjDataLen = *((__u16*) (LineBuf.Data + 1));
1723                                                         ObjectSize = ObjHeadLen + ObjDataLen;
1724                                                         if (Length < ObjectSize) {
1725                                                                 Event = EVENT_NEEDDATA;
1726                                                                 break;
1727                                                         }
1728                                                 } else
1729                                                 if ((Recordtype >= 1) && (Recordtype <= 216)) {
1730                                                         /* recordtype pixel row (1 byte length) */
1731                                                         ObjHeadLen = 1;
1732                                                         ObjDataLen = Recordtype;
1733                                                         ObjectSize = ObjHeadLen + ObjDataLen;
1734                                                         if (Length < ObjectSize) {
1735                                                                 Event = EVENT_NEEDDATA;
1736                                                                 break;
1737                                                         }
1738                                                 } else
1739                                                 if ((Recordtype >= 217) && (Recordtype <= 253)) {
1740                                                         /* recordtype empty lines */
1741                                                         ObjHeadLen = 1;
1742                                                         ObjDataLen = 0;
1743                                                         ObjectSize = ObjHeadLen + ObjDataLen;
1744                                                         LineBuf.Len--;
1745                                                         LineBuf.Next = LineBuf.Data + LineBuf.Len;
1746                                                         memmove(LineBuf.Data, LineBuf.Data + 1, LineBuf.Len);
1747                                                         break;
1748                                                 } else
1749                                                 if (Recordtype == 254) {
1750                                                         /* recordtype page header */
1751                                                         chan->fax2.PrevObject = FAX_OBJECT_LINE;
1752                                                         chan->fax2.NextObject = FAX_OBJECT_PAGE;
1753                                                         break;
1754                                                 } else {
1755                                                         /* recordtype user information */
1756                                                         ObjHeadLen = 2;
1757                                                         if (Length < ObjHeadLen) {
1758                                                                 Event = EVENT_NEEDDATA;
1759                                                                 break;
1760                                                         }
1761                                                         while (LineBuf.Len < ObjHeadLen) {
1762                                                                 *LineBuf.Next++ = *InBuf.Next++;
1763                                                                 LineBuf.Len++;
1764                                                                 InBuf.Len++;
1765                                                         }
1766                                                         ObjDataLen = *(LineBuf.Data + 1);
1767                                                         ObjectSize = ObjHeadLen + ObjDataLen;
1768                                                         if (ObjDataLen == 0) {
1769                                                                 /* illegal line coding */
1770                                                                 LineBuf.Len -= ObjHeadLen;
1771                                                                 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1772                                                                 memmove(LineBuf.Data, LineBuf.Data + ObjHeadLen, LineBuf.Len);
1773                                                                 break;
1774                                                         } else {
1775                                                                 /* user information */
1776                                                                 if (Length < ObjectSize) {
1777                                                                         Event = EVENT_NEEDDATA;
1778                                                                         break;
1779                                                                 }
1780                                                                 Length = ObjectSize;
1781                                                                 if (LineBuf.Len < Length) {
1782                                                                         Length -= LineBuf.Len;
1783                                                                         LineBuf.Len = 0;
1784                                                                         LineBuf.Next = LineBuf.Data;
1785                                                                         InBuf.Len += Length;
1786                                                                         InBuf.Next += Length;
1787                                                                 } else {
1788                                                                         LineBuf.Len -= Length;
1789                                                                         LineBuf.Next = LineBuf.Data + LineBuf.Len;
1790                                                                         memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
1791                                                                 }
1792                                                         }
1793                                                         break;  
1794                                                 }
1795                                                 Length = ObjectSize;
1796                                                 if (LineBuf.Len > ObjHeadLen) {
1797                                                         fax_put_rcv(ccard, chan, LineBuf.Data + ObjHeadLen,
1798                                                                         (LineBuf.Len - ObjHeadLen));
1799                                                 }
1800                                                 Length -= LineBuf.Len;
1801                                                 LineBuf.Len = 0;
1802                                                 LineBuf.Next = LineBuf.Data;
1803                                                 if (Length > 0) {
1804                                                         fax_put_rcv(ccard, chan, InBuf.Next, Length);
1805                                                         InBuf.Len += Length;
1806                                                         InBuf.Next += Length;
1807                                                 }
1808                                                 fax_put_rcv(ccard, chan, (__u8 *)&Cl2Eol, sizeof(Cl2Eol));
1809                                         break;
1810                         } /* end of switch (chan->fax2.NextObject) */
1811                 } /* end of while (Event==EVENT_NONE) */
1812                 if (InBuf.Len < InBuf.Size) {
1813                         Length = InBuf.Size - InBuf.Len;
1814                         if ((LineBuf.Len + Length) > LineBuf.Size) {
1815                                 eicon_log(ccard, 1, "idi_fax: Ch%d: %d bytes dropping, small buffer\n", chan->No,
1816                                         Length);
1817                                 } else {
1818                                         memcpy(LineBuf.Next, InBuf.Next, Length);
1819                                         LineBuf.Len += Length;
1820                                 }
1821                 }
1822                 chan->fax2.LineLen = LineBuf.Len;
1823         } else { /* CONN_OUT */
1824                 /* On CONN_OUT we do not need incoming data, drop it */
1825                 /* maybe later for polling */
1826         }
1827
1828 #       undef EVENT_NONE
1829 #       undef EVENT_NEEDDATA
1830
1831         return;
1832 }
1833
1834 int
1835 idi_fax_send_outbuf(eicon_card *ccard, eicon_chan *chan, eicon_OBJBUFFER *OutBuf)
1836 {
1837         struct sk_buff *skb;
1838
1839         skb = alloc_skb(OutBuf->Len, GFP_ATOMIC);
1840         if (!skb) {
1841                 eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_outbuf()\n", chan->No);
1842                 return(-1);
1843         }
1844         memcpy(skb_put(skb, OutBuf->Len), OutBuf->Data, OutBuf->Len);
1845
1846         OutBuf->Len = 0;
1847         OutBuf->Next = OutBuf->Data;
1848
1849         return(idi_send_data(ccard, chan, 0, skb, 1, 0));
1850 }
1851
1852 int
1853 idi_faxdata_send(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb)
1854 {
1855         isdn_ctrl cmd;
1856         eicon_OBJBUFFER InBuf;
1857         __u8 InData;
1858         __u8 InMask;
1859         eicon_OBJBUFFER OutBuf;
1860         eicon_OBJBUFFER LineBuf;
1861         __u32 LineData;
1862         unsigned int LineDataLen;
1863         __u8 Byte;
1864         __u8 Event;
1865         int ret = 1;
1866
1867 #       define EVENT_NONE       0
1868 #       define EVENT_EOD        1
1869 #       define EVENT_EOL        2
1870 #       define EVENT_EOP        3
1871
1872         if ((!ccard) || (!chan))
1873                 return -1;
1874
1875         if (!chan->fax) {
1876                 eicon_log(ccard, 1, "idi_fax: senddata with NULL fax struct, ERROR\n");
1877                 return -1;
1878         }
1879
1880         if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
1881                 /* Simply ignore any data written in data mode when receiving a fax.    */
1882                 /* This is not completely correct because only XON's should come here.  */
1883                 dev_kfree_skb(skb);
1884                 return 1;
1885         }
1886
1887         if (chan->fax->phase != ISDN_FAX_PHASE_C) {
1888                 dev_kfree_skb(skb);
1889                 return 1;
1890         }
1891
1892         if (chan->queued + skb->len > 1200)
1893                 return 0;
1894         if (chan->pqueued > 1)
1895                 return 0;
1896
1897         InBuf.Data = skb->data;
1898         InBuf.Size = skb->len;
1899         InBuf.Len  = 0;
1900         InBuf.Next = InBuf.Data;
1901         InData = 0;
1902         InMask = 0;
1903
1904         LineBuf.Data = chan->fax2.abLine;
1905         LineBuf.Size = sizeof(chan->fax2.abLine);
1906         LineBuf.Len  = chan->fax2.LineLen;
1907         LineBuf.Next = LineBuf.Data + LineBuf.Len;
1908         LineData = chan->fax2.LineData;
1909         LineDataLen = chan->fax2.LineDataLen;
1910
1911         OutBuf.Data = chan->fax2.abFrame;
1912         OutBuf.Size = sizeof(chan->fax2.abFrame);
1913         OutBuf.Len = 0;
1914         OutBuf.Next = OutBuf.Data;
1915
1916         Event = EVENT_NONE;
1917
1918         chan->fax2.Eop = 0;
1919
1920         for (;;) {
1921           for (;;) {
1922                 if (InMask == 0) {
1923                         if (InBuf.Len >= InBuf.Size) {
1924                                 Event = EVENT_EOD;
1925                                 break;
1926                         }
1927                         if ((chan->fax2.Dle != _DLE_) && *InBuf.Next == _DLE_) {
1928                                 chan->fax2.Dle = _DLE_;
1929                                 InBuf.Next++;
1930                                 InBuf.Len++;
1931                                 if (InBuf.Len >= InBuf.Size) {
1932                                         Event = EVENT_EOD;
1933                                         break;
1934                                 }
1935                         }
1936                         if (chan->fax2.Dle == _DLE_) {
1937                                 chan->fax2.Dle = 0;
1938                                 if (*InBuf.Next == _ETX_) {
1939                                         Event = EVENT_EOP;
1940                                         break;
1941                                 } else
1942                                 if (*InBuf.Next == _DLE_) {
1943                                         /* do nothing */
1944                                 } else {
1945                                         eicon_log(ccard, 1,
1946                                                 "idi_err: Ch%d: unknown DLE escape %02x found\n",
1947                                                         chan->No, *InBuf.Next);
1948                                         InBuf.Next++;
1949                                         InBuf.Len++;
1950                                         if (InBuf.Len >= InBuf.Size) {
1951                                                 Event = EVENT_EOD;
1952                                                 break;
1953                                         }
1954                                 }
1955                         }
1956                         InBuf.Len++;
1957                         InData = *InBuf.Next++;
1958                         InMask = (chan->fax->bor) ? 0x80 : 0x01;
1959                 }
1960                 while (InMask) {
1961                         LineData >>= 1;
1962                         LineDataLen++;
1963                         if (InData & InMask)
1964                                 LineData |= 0x80000000;
1965                         if (chan->fax->bor)
1966                                 InMask >>= 1;
1967                         else
1968                                 InMask <<= 1;
1969
1970                         if ((LineDataLen >= T4_EOL_BITSIZE) &&
1971                            ((LineData & T4_EOL_MASK_DWORD) == T4_EOL_DWORD)) {
1972                                 Event = EVENT_EOL;
1973                                 if (LineDataLen > T4_EOL_BITSIZE) {
1974                                         Byte = (__u8)
1975                                                 ((LineData & ~T4_EOL_MASK_DWORD) >>
1976                                                 (32 - LineDataLen));
1977                                         if (Byte == 0) {
1978                                                 if (! chan->fax2.NullByteExist) {
1979                                                         chan->fax2.NullBytesPos = LineBuf.Len;
1980                                                         chan->fax2.NullByteExist = 1;
1981                                                 }
1982                                         } else {
1983                                                 chan->fax2.NullByteExist = 0;
1984                                         }
1985                                         if (LineBuf.Len < LineBuf.Size) {
1986                                                 *LineBuf.Next++  = Byte;
1987                                                 LineBuf.Len++;
1988                                         }
1989                                 }
1990                                 LineDataLen = 0;
1991                                 break;
1992                         }
1993                         if (LineDataLen >= T4_EOL_BITSIZE + 8) {
1994                                 Byte = (__u8)
1995                                         ((LineData & ~T4_EOL_MASK_DWORD) >>
1996                                         (32 - T4_EOL_BITSIZE - 8));
1997                                 LineData &= T4_EOL_MASK_DWORD;
1998                                 LineDataLen = T4_EOL_BITSIZE;
1999                                 if (Byte == 0) {
2000                                         if (! chan->fax2.NullByteExist) {
2001                                                 chan->fax2.NullBytesPos = LineBuf.Len;
2002                                                 chan->fax2.NullByteExist = 1;
2003                                         }
2004                                 } else {
2005                                         chan->fax2.NullByteExist = 0;
2006                                 }
2007                                 if (LineBuf.Len < LineBuf.Size) {
2008                                         *LineBuf.Next++  = Byte; 
2009                                         LineBuf.Len++;
2010                                 }
2011                         }
2012                 }
2013                 if (Event != EVENT_NONE)
2014                         break;
2015           }
2016
2017                 if ((Event != EVENT_EOL) && (Event != EVENT_EOP))
2018                         break;
2019
2020                 if ((Event == EVENT_EOP) && (LineDataLen > 0)) {
2021                         LineData >>= 32 - LineDataLen;
2022                         LineDataLen = 0;
2023                         while (LineData != 0) {
2024                                 Byte = (__u8) LineData;
2025                                 LineData >>= 8;
2026                                 if (Byte == 0) {
2027                                         if (! chan->fax2.NullByteExist) {
2028                                                 chan->fax2.NullBytesPos = LineBuf.Len;
2029                                                 chan->fax2.NullByteExist = 1;
2030                                         }
2031                                 } else {
2032                                         chan->fax2.NullByteExist = 0;
2033                                 }
2034                                 if (LineBuf.Len < LineBuf.Size) {
2035                                         *LineBuf.Next++  = Byte;
2036                                         LineBuf.Len++;
2037                                 }
2038                                 
2039                         }
2040                 }
2041                 if (chan->fax2.NullByteExist) {
2042                         if (chan->fax2.NullBytesPos == 0) {
2043                                 LineBuf.Len = 0;
2044                         } else {
2045                                 LineBuf.Len = chan->fax2.NullBytesPos + 1;
2046                         }
2047                 }
2048                 if (LineBuf.Len > 0) {
2049                         if (OutBuf.Len + LineBuf.Len + SFF_LEN_FLD_SIZE > OutBuf.Size) {
2050                                 ret = idi_fax_send_outbuf(ccard, chan, &OutBuf);
2051                         }
2052                         if (LineBuf.Len <= 216) {
2053                                 *OutBuf.Next++ = (__u8) LineBuf.Len;
2054                                 OutBuf.Len++;
2055                         } else {
2056                                 *OutBuf.Next++ = 0;
2057                                 *(__u16 *) OutBuf.Next = (__u16) LineBuf.Len;
2058                                 OutBuf.Next += sizeof(__u16);
2059                                 OutBuf.Len += 3;
2060                         }
2061                         memcpy(OutBuf.Next, LineBuf.Data, LineBuf.Len);
2062                         OutBuf.Next += LineBuf.Len;
2063                         OutBuf.Len  += LineBuf.Len;
2064                 }
2065                 LineBuf.Len = 0;
2066                 LineBuf.Next = LineBuf.Data;
2067                 chan->fax2.NullByteExist = 0;
2068                 if (Event == EVENT_EOP)
2069                         break;
2070
2071                 Event = EVENT_NONE;
2072         }
2073
2074         if (Event == EVENT_EOP) {
2075                 chan->fax2.Eop = 1;
2076                 chan->fax2.PageCount++;
2077                 cmd.driver = ccard->myid;
2078                 cmd.command = ISDN_STAT_FAXIND;
2079                 cmd.arg = chan->No;
2080                 chan->fax->r_code = ISDN_TTY_FAX_EOP;
2081                 ccard->interface.statcallb(&cmd);
2082         }
2083         if (OutBuf.Len > 0) {
2084                 ret = idi_fax_send_outbuf(ccard, chan, &OutBuf);
2085         }
2086
2087         chan->fax2.LineLen = LineBuf.Len;
2088         chan->fax2.LineData = LineData;
2089         chan->fax2.LineDataLen = LineDataLen;
2090
2091 #       undef EVENT_NONE
2092 #       undef EVENT_EOD
2093 #       undef EVENT_EOL
2094 #       undef EVENT_EOP
2095
2096         if (ret >= 0)
2097                 dev_kfree_skb(skb);
2098         if (ret == 0)
2099                 ret = 1;
2100         return(ret);
2101 }
2102
2103 void
2104 idi_fax_hangup(eicon_card *ccard, eicon_chan *chan)
2105 {
2106         isdn_ctrl cmd;
2107
2108         if (!chan->fax) {
2109                 eicon_log(ccard, 1, "idi_fax: hangup with NULL fax struct, ERROR\n");
2110                 return;
2111         }
2112         if ((chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) &&
2113             (chan->fax->code == 0)) {
2114                 cmd.driver = ccard->myid;
2115                 cmd.command = ISDN_STAT_FAXIND;
2116                 cmd.arg = chan->No;
2117                 chan->fax->r_code = ISDN_TTY_FAX_PTS;
2118                 ccard->interface.statcallb(&cmd);
2119         }
2120         if ((chan->fax->code > 1) && (chan->fax->code < 120))
2121                 chan->fax->code += 120;
2122         eicon_log(ccard, 8, "idi_fax: Ch%d: Hangup (code=%d)\n", chan->No, chan->fax->code);
2123         chan->fax->r_code = ISDN_TTY_FAX_HNG;
2124         cmd.driver = ccard->myid;
2125         cmd.command = ISDN_STAT_FAXIND;
2126         cmd.arg = chan->No;
2127         ccard->interface.statcallb(&cmd);
2128 }
2129
2130 #endif  /******** FAX ********/
2131
2132 int
2133 idi_send_udata(eicon_card *card, eicon_chan *chan, int UReq, u_char *buffer, int len)
2134 {
2135         struct sk_buff *skb;
2136         struct sk_buff *skb2;
2137         eicon_REQ *reqbuf;
2138         eicon_chan_ptr *chan2;
2139
2140         if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) {
2141                 eicon_log(card, 1, "idi_snd: Ch%d: send udata on state %d !\n", chan->No, chan->fsm_state);
2142                 return -ENODEV;
2143         }
2144         eicon_log(card, 8, "idi_snd: Ch%d: udata 0x%x: %d %d %d %d\n", chan->No,
2145                         UReq, buffer[0], buffer[1], buffer[2], buffer[3]);
2146
2147         skb = alloc_skb(sizeof(eicon_REQ) + len + 1, GFP_ATOMIC);
2148         skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
2149
2150         if ((!skb) || (!skb2)) {
2151                 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_udata()\n", chan->No);
2152                 if (skb) 
2153                         dev_kfree_skb(skb);
2154                 if (skb2) 
2155                         dev_kfree_skb(skb2);
2156                 return -ENOMEM;
2157         }
2158
2159         chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
2160         chan2->ptr = chan;
2161
2162         reqbuf = (eicon_REQ *)skb_put(skb, 1 + len + sizeof(eicon_REQ));
2163
2164         reqbuf->Req = N_UDATA;
2165         reqbuf->ReqCh = chan->e.IndCh;
2166         reqbuf->ReqId = 1;
2167
2168         reqbuf->XBuffer.length = len + 1;
2169         reqbuf->XBuffer.P[0] = UReq;
2170         memcpy(&reqbuf->XBuffer.P[1], buffer, len);
2171         reqbuf->Reference = 1; /* Net Entity */
2172
2173         skb_queue_tail(&chan->e.X, skb);
2174         skb_queue_tail(&card->sndq, skb2);
2175         eicon_schedule_tx(card);
2176         return (0);
2177 }
2178
2179 void
2180 idi_audio_cmd(eicon_card *ccard, eicon_chan *chan, int cmd, u_char *value)
2181 {
2182         u_char buf[6];
2183         struct enable_dtmf_s *dtmf_buf = (struct enable_dtmf_s *)buf;
2184
2185         if ((!ccard) || (!chan))
2186                 return;
2187
2188         memset(buf, 0, 6);
2189         switch(cmd) {
2190                 case ISDN_AUDIO_SETDD:
2191                         if (value[0]) {
2192                                 dtmf_buf->tone = (__u16) (value[1] * 5);
2193                                 dtmf_buf->gap = (__u16) (value[1] * 5);
2194                                 idi_send_udata(ccard, chan,
2195                                         DSP_UDATA_REQUEST_ENABLE_DTMF_RECEIVER,
2196                                         buf, 4);
2197                         } else {
2198                                 idi_send_udata(ccard, chan,
2199                                         DSP_UDATA_REQUEST_DISABLE_DTMF_RECEIVER,
2200                                         buf, 0);
2201                         }
2202                         break;
2203         }
2204 }
2205
2206 void
2207 idi_parse_udata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len)
2208 {
2209         isdn_ctrl cmd;
2210         eicon_dsp_ind *p = (eicon_dsp_ind *) (&buffer[1]);
2211         static char *connmsg[] =
2212         {"", "V.21", "V.23", "V.22", "V.22bis", "V.32bis", "V.34",
2213          "V.8", "Bell 212A", "Bell 103", "V.29 Leased", "V.33 Leased", "V.90",
2214          "V.21 CH2", "V.27ter", "V.29", "V.33", "V.17", "V.32", "K56Flex",
2215          "X2", "V.18", "V.18LH", "V.18HL", "V.21LH", "V.21HL",
2216          "Bell 103LH", "Bell 103HL", "V.23", "V.23", "EDT 110",
2217          "Baudot45", "Baudot47", "Baudot50", "DTMF" };
2218         static u_char dtmf_code[] = {
2219         '1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D'
2220         };
2221
2222         if ((!ccard) || (!chan))
2223                 return;
2224
2225         switch (buffer[0]) {
2226                 case DSP_UDATA_INDICATION_SYNC:
2227                         eicon_log(ccard, 16, "idi_ind: Ch%d: UDATA_SYNC time %d\n", chan->No, p->time);
2228                         break;
2229                 case DSP_UDATA_INDICATION_DCD_OFF:
2230                         eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_OFF time %d\n", chan->No, p->time);
2231                         break;
2232                 case DSP_UDATA_INDICATION_DCD_ON:
2233                         if ((chan->l2prot == ISDN_PROTO_L2_MODEM) &&
2234                             (chan->fsm_state == EICON_STATE_WMCONN)) {
2235                                 chan->fsm_state = EICON_STATE_ACTIVE;
2236                                 cmd.driver = ccard->myid;
2237                                 cmd.command = ISDN_STAT_BCONN;
2238                                 cmd.arg = chan->No;
2239                                 if (p->norm > 34) {
2240                                   sprintf(cmd.parm.num, "%d/(%d)", p->speed, p->norm);
2241                                 } else {
2242                                   sprintf(cmd.parm.num, "%d/%s", p->speed, connmsg[p->norm]);
2243                                 }
2244                                 ccard->interface.statcallb(&cmd);
2245                         }
2246                         eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_ON time %d\n", chan->No, p->time);
2247                         eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No,
2248                                 p->norm, p->options, p->speed, p->delay); 
2249                         break;
2250                 case DSP_UDATA_INDICATION_CTS_OFF:
2251                         eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_OFF time %d\n", chan->No, p->time);
2252                         break;
2253                 case DSP_UDATA_INDICATION_CTS_ON:
2254                         eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_ON time %d\n", chan->No, p->time);
2255                         eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No,
2256                                 p->norm, p->options, p->speed, p->delay); 
2257                         break;
2258                 case DSP_UDATA_INDICATION_DISCONNECT:
2259                         eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DISCONNECT cause %d\n", chan->No, buffer[1]);
2260                         break;
2261                 case DSP_UDATA_INDICATION_DTMF_DIGITS_RECEIVED:
2262                         eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DTMF_REC '%c'\n", chan->No,
2263                                 dtmf_code[buffer[1]]);
2264                         cmd.driver = ccard->myid;
2265                         cmd.command = ISDN_STAT_AUDIO;
2266                         cmd.parm.num[0] = ISDN_AUDIO_DTMF;
2267                         cmd.parm.num[1] = dtmf_code[buffer[1]];
2268                         cmd.arg = chan->No;
2269                         ccard->interface.statcallb(&cmd);
2270                         break;
2271                 default:
2272                         eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED UDATA Indication 0x%02x\n", chan->No, buffer[0]);
2273         }
2274 }
2275
2276 void
2277 eicon_parse_trace(eicon_card *ccard, unsigned char *buffer, int len)
2278 {
2279         int i,j,n;
2280         int buflen = len * 3 + 30;
2281         char *p;
2282         struct trace_s {
2283                 unsigned long time;
2284                 unsigned short size;
2285                 unsigned short code;
2286                 unsigned char data[1];
2287         } *q;
2288
2289         if (!(p = kmalloc(buflen, GFP_ATOMIC))) {
2290                 eicon_log(ccard, 1, "idi_err: Ch??: could not allocate trace buffer\n");
2291                 return;
2292         }
2293         memset(p, 0, buflen);
2294         q = (struct trace_s *)buffer;
2295
2296         if (DebugVar & 512) {
2297                 if ((q->code == 3) || (q->code == 4)) {
2298                         n = (short) *(q->data);
2299                         if (n) {
2300                                 j = sprintf(p, "DTRC:");
2301                                 for (i = 0; i < n; i++) {
2302                                         j += sprintf(p + j, "%02x ", q->data[i+2]);
2303                                 }
2304                                 j += sprintf(p + j, "\n");
2305                         }
2306                 }
2307         } else {
2308                 j = sprintf(p, "XLOG: %lx %04x %04x ",
2309                         q->time, q->size, q->code);
2310
2311                 for (i = 0; i < q->size; i++) {
2312                         j += sprintf(p + j, "%02x ", q->data[i]);
2313                 }
2314                 j += sprintf(p + j, "\n");
2315         }
2316         if (strlen(p))
2317                 eicon_putstatus(ccard, p);
2318         kfree(p);
2319 }
2320
2321 void
2322 idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
2323 {
2324         int tmp;
2325         char tnum[64];
2326         int dlev;
2327         int free_buff;
2328         ulong flags;
2329         struct sk_buff *skb2;
2330         eicon_IND *ind = (eicon_IND *)skb->data;
2331         eicon_chan *chan;
2332         idi_ind_message message;
2333         isdn_ctrl cmd;
2334
2335         if (!ccard) {
2336                 eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ind\n");
2337                 dev_kfree_skb(skb);
2338                 return;
2339         }
2340
2341         if ((chan = ccard->IdTable[ind->IndId]) == NULL) {
2342                 eicon_log(ccard, 1, "idi_err: Ch??: null chan in handle_ind\n");
2343                 dev_kfree_skb(skb);
2344                 return;
2345         }
2346         
2347         if ((ind->Ind != 8) && (ind->Ind != 0xc))
2348                 dlev = 144;
2349         else
2350                 dlev = 128;
2351
2352         eicon_log(ccard, dlev, "idi_hdl: Ch%d: Ind=%x Id=%x Ch=%x MInd=%x MLen=%x Len=%x\n", chan->No,
2353                 ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
2354
2355         free_buff = 1;
2356         /* Signal Layer */
2357         if (chan->e.D3Id == ind->IndId) {
2358                 idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
2359                 switch(ind->Ind) {
2360                         case HANGUP:
2361                                 eicon_log(ccard, 8, "idi_ind: Ch%d: Hangup\n", chan->No);
2362                                 while((skb2 = skb_dequeue(&chan->e.X))) {
2363                                         dev_kfree_skb(skb2);
2364                                 }
2365                                 spin_lock_irqsave(&eicon_lock, flags);
2366                                 chan->queued = 0;
2367                                 chan->pqueued = 0;
2368                                 chan->waitq = 0;
2369                                 chan->waitpq = 0;
2370                                 spin_unlock_irqrestore(&eicon_lock, flags);
2371                                 if (message.e_cau[0] & 0x7f) {
2372                                         cmd.driver = ccard->myid;
2373                                         cmd.arg = chan->No;
2374                                         sprintf(cmd.parm.num,"E%02x%02x", 
2375                                                 chan->cause[0]&0x7f, message.e_cau[0]&0x7f); 
2376                                         cmd.command = ISDN_STAT_CAUSE;
2377                                         ccard->interface.statcallb(&cmd);
2378                                 }
2379                                 chan->cause[0] = 0; 
2380                                 if (((chan->fsm_state == EICON_STATE_ACTIVE) ||
2381                                     (chan->fsm_state == EICON_STATE_WMCONN)) ||
2382                                     ((chan->l2prot == ISDN_PROTO_L2_FAX) &&
2383                                     (chan->fsm_state == EICON_STATE_OBWAIT))) {
2384                                         chan->fsm_state = EICON_STATE_NULL;
2385                                 } else {
2386                                         if (chan->e.B2Id)
2387                                                 idi_do_req(ccard, chan, REMOVE, 1);
2388                                         chan->statectrl &= ~WAITING_FOR_HANGUP;
2389                                         chan->statectrl &= ~IN_HOLD;
2390                                         if (chan->statectrl & HAVE_CONN_REQ) {
2391                                                 eicon_log(ccard, 32, "idi_req: Ch%d: queueing delayed conn_req\n", chan->No);
2392                                                 chan->statectrl &= ~HAVE_CONN_REQ;
2393                                                 if ((chan->tskb1) && (chan->tskb2)) {
2394                                                         skb_queue_tail(&chan->e.X, chan->tskb1);
2395                                                         skb_queue_tail(&ccard->sndq, chan->tskb2); 
2396                                                         eicon_schedule_tx(ccard);
2397                                                 }
2398                                                 chan->tskb1 = NULL;
2399                                                 chan->tskb2 = NULL;
2400                                         } else {
2401                                                 chan->fsm_state = EICON_STATE_NULL;
2402                                                 cmd.driver = ccard->myid;
2403                                                 cmd.arg = chan->No;
2404                                                 cmd.command = ISDN_STAT_DHUP;
2405                                                 ccard->interface.statcallb(&cmd);
2406                                                 eicon_idi_listen_req(ccard, chan);
2407 #ifdef CONFIG_ISDN_TTY_FAX
2408                                                 chan->fax = 0;
2409 #endif
2410                                         }
2411                                 }
2412                                 break;
2413                         case INDICATE_IND:
2414                                 eicon_log(ccard, 8, "idi_ind: Ch%d: Indicate_Ind\n", chan->No);
2415                                 if (chan->fsm_state != EICON_STATE_LISTEN) {
2416                                         eicon_log(ccard, 1, "idi_err: Ch%d: Incoming call on wrong state (%d).\n",
2417                                                 chan->No, chan->fsm_state);
2418                                         idi_do_req(ccard, chan, HANGUP, 0);
2419                                         break;
2420                                 }
2421                                 chan->fsm_state = EICON_STATE_ICALL;
2422                                 idi_bc2si(message.bc, message.hlc, message.sin, &chan->si1, &chan->si2);
2423                                 strcpy(chan->cpn, message.cpn + 1);
2424                                 strcpy(chan->oad, message.oad);
2425                                 strcpy(chan->dsa, message.dsa);
2426                                 strcpy(chan->osa, message.osa);
2427                                 chan->plan = message.plan;
2428                                 chan->screen = message.screen;
2429                                 try_stat_icall_again: 
2430                                 cmd.driver = ccard->myid;
2431                                 cmd.command = ISDN_STAT_ICALL;
2432                                 cmd.arg = chan->No;
2433                                 cmd.parm.setup.si1 = chan->si1;
2434                                 cmd.parm.setup.si2 = chan->si2;
2435                                 strcpy(tnum, chan->cpn);
2436                                 if (strlen(chan->dsa)) {
2437                                         strcat(tnum, ".");
2438                                         strcat(tnum, chan->dsa);
2439                                 }
2440                                 tnum[ISDN_MSNLEN - 1] = 0;
2441                                 strcpy(cmd.parm.setup.eazmsn, tnum);
2442                                 strcpy(tnum, chan->oad);
2443                                 if (strlen(chan->osa)) {
2444                                         strcat(tnum, ".");
2445                                         strcat(tnum, chan->osa);
2446                                 }
2447                                 tnum[ISDN_MSNLEN - 1] = 0;
2448                                 strcpy(cmd.parm.setup.phone, tnum);
2449                                 cmd.parm.setup.plan = chan->plan;
2450                                 cmd.parm.setup.screen = chan->screen;
2451                                 tmp = ccard->interface.statcallb(&cmd);
2452                                 switch(tmp) {
2453                                         case 0: /* no user responding */
2454                                                 idi_do_req(ccard, chan, HANGUP, 0);
2455                                                 chan->fsm_state = EICON_STATE_NULL;
2456                                                 break;
2457                                         case 1: /* alert */
2458                                                 eicon_log(ccard, 8, "idi_req: Ch%d: Call Alert\n", chan->No);
2459                                                 if ((chan->fsm_state == EICON_STATE_ICALL) || (chan->fsm_state == EICON_STATE_ICALLW)) {
2460                                                         chan->fsm_state = EICON_STATE_ICALL;
2461                                                         idi_do_req(ccard, chan, CALL_ALERT, 0);
2462                                                 }
2463                                                 break;
2464                                         case 2: /* reject */
2465                                                 eicon_log(ccard, 8, "idi_req: Ch%d: Call Reject\n", chan->No);
2466                                                 idi_do_req(ccard, chan, REJECT, 0);
2467                                                 break;
2468                                         case 3: /* incomplete number */
2469                                                 eicon_log(ccard, 8, "idi_req: Ch%d: Incomplete Number\n", chan->No);
2470                                                 chan->fsm_state = EICON_STATE_ICALLW;
2471                                                 break;
2472                                 }
2473                                 break;
2474                         case INFO_IND:
2475                                 eicon_log(ccard, 8, "idi_ind: Ch%d: Info_Ind\n", chan->No);
2476                                 if ((chan->fsm_state == EICON_STATE_ICALLW) &&
2477                                     (message.cpn[0])) {
2478                                         strcat(chan->cpn, message.cpn + 1);
2479                                         goto try_stat_icall_again;
2480                                 }
2481                                 break;
2482                         case CALL_IND:
2483                                 eicon_log(ccard, 8, "idi_ind: Ch%d: Call_Ind\n", chan->No);
2484                                 if ((chan->fsm_state == EICON_STATE_ICALL) || (chan->fsm_state == EICON_STATE_IWAIT)) {
2485                                         chan->fsm_state = EICON_STATE_IBWAIT;
2486                                         cmd.driver = ccard->myid;
2487                                         cmd.command = ISDN_STAT_DCONN;
2488                                         cmd.arg = chan->No;
2489                                         ccard->interface.statcallb(&cmd);
2490                                         switch(chan->l2prot) {
2491                                                 case ISDN_PROTO_L2_FAX:
2492 #ifdef CONFIG_ISDN_TTY_FAX
2493                                                         if (chan->fax)
2494                                                                 chan->fax->phase = ISDN_FAX_PHASE_A;
2495 #endif
2496                                                         break;
2497                                                 case ISDN_PROTO_L2_MODEM:
2498                                                         /* do nothing, wait for connect */
2499                                                         break;
2500                                                 case ISDN_PROTO_L2_V11096:
2501                                                 case ISDN_PROTO_L2_V11019:
2502                                                 case ISDN_PROTO_L2_V11038:
2503                                                 case ISDN_PROTO_L2_TRANS:
2504                                                         idi_do_req(ccard, chan, N_CONNECT, 1);
2505                                                         break;
2506                                                 default:;
2507                                                         /* On most incoming calls we use automatic connect */
2508                                                         /* idi_do_req(ccard, chan, N_CONNECT, 1); */
2509                                         }
2510                                 } else {
2511                                         if (chan->fsm_state != EICON_STATE_ACTIVE)
2512                                                 idi_hangup(ccard, chan);
2513                                 }
2514                                 break;
2515                         case CALL_CON:
2516                                 eicon_log(ccard, 8, "idi_ind: Ch%d: Call_Con\n", chan->No);
2517                                 if (chan->fsm_state == EICON_STATE_OCALL) {
2518                                         /* check if old NetID has been removed */
2519                                         if (chan->e.B2Id) {
2520                                                 eicon_log(ccard, 1, "eicon: Ch%d: old net_id %x still exist, removing.\n",
2521                                                         chan->No, chan->e.B2Id);
2522                                                 idi_do_req(ccard, chan, REMOVE, 1);
2523                                         }
2524 #ifdef CONFIG_ISDN_TTY_FAX
2525                                         if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2526                                                 if (chan->fax) {
2527                                                         chan->fax->phase = ISDN_FAX_PHASE_A;
2528                                                 } else {
2529                                                         eicon_log(ccard, 1, "idi_ind: Call_Con with NULL fax struct, ERROR\n");
2530                                                         idi_hangup(ccard, chan);
2531                                                         break;
2532                                                 }
2533                                         }
2534 #endif
2535                                         chan->fsm_state = EICON_STATE_OBWAIT;
2536                                         cmd.driver = ccard->myid;
2537                                         cmd.command = ISDN_STAT_DCONN;
2538                                         cmd.arg = chan->No;
2539                                         ccard->interface.statcallb(&cmd);
2540
2541                                         idi_do_req(ccard, chan, ASSIGN, 1); 
2542                                         idi_do_req(ccard, chan, N_CONNECT, 1);
2543                                 } else
2544                                         idi_hangup(ccard, chan);
2545                                 break;
2546                         case AOC_IND:
2547                                 eicon_log(ccard, 8, "idi_ind: Ch%d: Advice of Charge\n", chan->No);
2548                                 break;
2549                         case CALL_HOLD_ACK:
2550                                 chan->statectrl |= IN_HOLD;
2551                                 eicon_log(ccard, 8, "idi_ind: Ch%d: Call Hold Ack\n", chan->No);
2552                                 break;
2553                         case SUSPEND_REJ:
2554                                 eicon_log(ccard, 8, "idi_ind: Ch%d: Suspend Rejected\n", chan->No);
2555                                 break;
2556                         case SUSPEND:
2557                                 eicon_log(ccard, 8, "idi_ind: Ch%d: Suspend Ack\n", chan->No);
2558                                 break;
2559                         case RESUME:
2560                                 eicon_log(ccard, 8, "idi_ind: Ch%d: Resume Ack\n", chan->No);
2561                                 break;
2562                         default:
2563                                 eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED SigIndication 0x%02x\n", chan->No, ind->Ind);
2564                 }
2565         }
2566         /* Network Layer */
2567         else if (chan->e.B2Id == ind->IndId) {
2568
2569                 if (chan->No == ccard->nchannels) {
2570                         /* Management Indication */
2571                         if (ind->Ind == 0x04) { /* Trace_Ind */
2572                                 eicon_parse_trace(ccard, ind->RBuffer.P, ind->RBuffer.length);
2573                         } else {
2574                                 idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
2575                                 chan->fsm_state = 1;
2576                         }
2577                 } 
2578                 else
2579                 switch(ind->Ind) {
2580                         case N_CONNECT_ACK:
2581                                 eicon_log(ccard, 16, "idi_ind: Ch%d: N_Connect_Ack\n", chan->No);
2582                                 if (chan->l2prot == ISDN_PROTO_L2_MODEM) {
2583                                         chan->fsm_state = EICON_STATE_WMCONN;
2584                                         break;
2585                                 }
2586                                 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2587 #ifdef CONFIG_ISDN_TTY_FAX
2588                                         chan->fsm_state = EICON_STATE_ACTIVE;
2589                                         idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2590                                         if (chan->fax) {
2591                                                 if (chan->fax->phase == ISDN_FAX_PHASE_B) {
2592                                                         idi_fax_send_header(ccard, chan, 2);
2593                                                         cmd.driver = ccard->myid;
2594                                                         cmd.command = ISDN_STAT_FAXIND;
2595                                                         cmd.arg = chan->No;
2596                                                         chan->fax->r_code = ISDN_TTY_FAX_DCS;
2597                                                         ccard->interface.statcallb(&cmd);
2598                                                 }
2599                                         }
2600                                         else {
2601                                                 eicon_log(ccard, 1, "idi_ind: N_Connect_Ack with NULL fax struct, ERROR\n");
2602                                         }
2603 #endif
2604                                         break;
2605                                 }
2606                                 chan->fsm_state = EICON_STATE_ACTIVE;
2607                                 cmd.driver = ccard->myid;
2608                                 cmd.command = ISDN_STAT_BCONN;
2609                                 cmd.arg = chan->No;
2610                                 strcpy(cmd.parm.num, "64000");
2611                                 ccard->interface.statcallb(&cmd);
2612                                 break; 
2613                         case N_CONNECT:
2614                                 eicon_log(ccard, 16,"idi_ind: Ch%d: N_Connect\n", chan->No);
2615                                 chan->e.IndCh = ind->IndCh;
2616                                 if (chan->e.B2Id) idi_do_req(ccard, chan, N_CONNECT_ACK, 1);
2617                                 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2618                                         break;
2619                                 }
2620                                 if (chan->l2prot == ISDN_PROTO_L2_MODEM) {
2621                                         chan->fsm_state = EICON_STATE_WMCONN;
2622                                         break;
2623                                 }
2624                                 chan->fsm_state = EICON_STATE_ACTIVE;
2625                                 cmd.driver = ccard->myid;
2626                                 cmd.command = ISDN_STAT_BCONN;
2627                                 cmd.arg = chan->No;
2628                                 strcpy(cmd.parm.num, "64000");
2629                                 ccard->interface.statcallb(&cmd);
2630                                 break; 
2631                         case N_DISC:
2632                                 eicon_log(ccard, 16, "idi_ind: Ch%d: N_Disc\n", chan->No);
2633                                 if (chan->e.B2Id) {
2634                                         while((skb2 = skb_dequeue(&chan->e.X))) {
2635                                                 dev_kfree_skb(skb2);
2636                                         }
2637                                         idi_do_req(ccard, chan, N_DISC_ACK, 1);
2638                                         idi_do_req(ccard, chan, REMOVE, 1);
2639                                 }
2640 #ifdef CONFIG_ISDN_TTY_FAX
2641                                 if ((chan->l2prot == ISDN_PROTO_L2_FAX) && (chan->fax)){
2642                                         idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2643                                         idi_fax_hangup(ccard, chan);
2644                                 }
2645 #endif
2646                                 chan->e.IndCh = 0;
2647                                 spin_lock_irqsave(&eicon_lock, flags);
2648                                 chan->queued = 0;
2649                                 chan->pqueued = 0;
2650                                 chan->waitq = 0;
2651                                 chan->waitpq = 0;
2652                                 spin_unlock_irqrestore(&eicon_lock, flags);
2653                                 if (!(chan->statectrl & IN_HOLD)) {
2654                                         idi_do_req(ccard, chan, HANGUP, 0);
2655                                 }
2656                                 if (chan->fsm_state == EICON_STATE_ACTIVE) {
2657                                         cmd.driver = ccard->myid;
2658                                         cmd.command = ISDN_STAT_BHUP;
2659                                         cmd.arg = chan->No;
2660                                         ccard->interface.statcallb(&cmd);
2661                                         chan->fsm_state = EICON_STATE_NULL;
2662                                         if (!(chan->statectrl & IN_HOLD)) {
2663                                                 chan->statectrl |= WAITING_FOR_HANGUP;
2664                                         }
2665                                 }
2666 #ifdef CONFIG_ISDN_TTY_FAX
2667                                 chan->fax = 0;
2668 #endif
2669                                 break; 
2670                         case N_DISC_ACK:
2671                                 eicon_log(ccard, 16, "idi_ind: Ch%d: N_Disc_Ack\n", chan->No);
2672 #ifdef CONFIG_ISDN_TTY_FAX
2673                                 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2674                                         idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2675                                         idi_fax_hangup(ccard, chan);
2676                                 }
2677 #endif
2678                                 break; 
2679                         case N_DATA_ACK:
2680                                 eicon_log(ccard, 128, "idi_ind: Ch%d: N_Data_Ack\n", chan->No);
2681                                 break;
2682                         case N_DATA:
2683                                 skb_pull(skb, sizeof(eicon_IND) - 1);
2684                                 eicon_log(ccard, 128, "idi_rcv: Ch%d: %d bytes\n", chan->No, skb->len);
2685                                 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2686 #ifdef CONFIG_ISDN_TTY_FAX
2687                                         idi_faxdata_rcv(ccard, chan, skb);
2688 #endif
2689                                 } else {
2690                                         ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb);
2691                                         free_buff = 0; 
2692                                 }
2693                                 break; 
2694                         case N_UDATA:
2695                                 idi_parse_udata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2696                                 break; 
2697 #ifdef CONFIG_ISDN_TTY_FAX
2698                         case N_EDATA:
2699                                 idi_edata_action(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2700                                 break; 
2701 #endif
2702                         default:
2703                                 eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED NetIndication 0x%02x\n", chan->No, ind->Ind);
2704                 }
2705         }
2706         else {
2707                 eicon_log(ccard, 1, "idi_ind: Ch%d: Ind is neither SIG nor NET !\n", chan->No);
2708         }
2709    if (free_buff)
2710         dev_kfree_skb(skb);
2711 }
2712
2713 int
2714 idi_handle_ack_ok(eicon_card *ccard, eicon_chan *chan, eicon_RC *ack)
2715 {
2716         ulong flags;
2717         isdn_ctrl cmd;
2718         int tqueued = 0;
2719         int twaitpq = 0;
2720
2721         if (ack->RcId != ((chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id)) {
2722                 /* I dont know why this happens, should not ! */
2723                 /* just ignoring this RC */
2724                 eicon_log(ccard, 16, "idi_ack: Ch%d: RcId %d not equal to last %d\n", chan->No, 
2725                         ack->RcId, (chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id);
2726                 return 1;
2727         }
2728
2729         /* Management Interface */      
2730         if (chan->No == ccard->nchannels) {
2731                 /* Managementinterface: changing state */
2732                 if (chan->e.Req != 0x02)
2733                         chan->fsm_state = 1;
2734         }
2735
2736         /* Remove an Id */
2737         if (chan->e.Req == REMOVE) {
2738                 if (ack->Reference != chan->e.ref) {
2739                         /* This should not happen anymore */
2740                         eicon_log(ccard, 16, "idi_ack: Ch%d: Rc-Ref %d not equal to stored %d\n", chan->No,
2741                                 ack->Reference, chan->e.ref);
2742                 }
2743                 spin_lock_irqsave(&eicon_lock, flags);
2744                 ccard->IdTable[ack->RcId] = NULL;
2745                 if (!chan->e.ReqCh) 
2746                         chan->e.D3Id = 0;
2747                 else
2748                         chan->e.B2Id = 0;
2749                 spin_unlock_irqrestore(&eicon_lock, flags);
2750                 eicon_log(ccard, 16, "idi_ack: Ch%d: Removed : Id=%x Ch=%d (%s)\n", chan->No,
2751                         ack->RcId, ack->RcCh, (chan->e.ReqCh)? "Net":"Sig");
2752                 return 1;
2753         }
2754
2755         /* Signal layer */
2756         if (!chan->e.ReqCh) {
2757                 eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
2758                         ack->RcId, ack->RcCh, ack->Reference);
2759         } else {
2760         /* Network layer */
2761                 switch(chan->e.Req & 0x0f) {
2762                         case N_CONNECT:
2763                                 chan->e.IndCh = ack->RcCh;
2764                                 eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
2765                                         ack->RcId, ack->RcCh, ack->Reference);
2766                                 break;
2767                         case N_MDATA:
2768                         case N_DATA:
2769                                 tqueued = chan->queued;
2770                                 twaitpq = chan->waitpq;
2771                                 if ((chan->e.Req & 0x0f) == N_DATA) {
2772                                         spin_lock_irqsave(&eicon_lock, flags);
2773                                         chan->waitpq = 0;
2774                                         if(chan->pqueued)
2775                                                 chan->pqueued--;
2776                                         spin_unlock_irqrestore(&eicon_lock, flags);
2777 #ifdef CONFIG_ISDN_TTY_FAX
2778                                         if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2779                                                 if (((chan->queued - chan->waitq) < 1) &&
2780                                                     (chan->fax2.Eop)) {
2781                                                         chan->fax2.Eop = 0;
2782                                                         if (chan->fax) {
2783                                                                 cmd.driver = ccard->myid;
2784                                                                 cmd.command = ISDN_STAT_FAXIND;
2785                                                                 cmd.arg = chan->No;
2786                                                                 chan->fax->r_code = ISDN_TTY_FAX_SENT;
2787                                                                 ccard->interface.statcallb(&cmd);
2788                                                         }
2789                                                         else {
2790                                                                 eicon_log(ccard, 1, "idi_ack: Sent with NULL fax struct, ERROR\n");
2791                                                         }
2792                                                 }
2793                                         }
2794 #endif
2795                                 }
2796                                 spin_lock_irqsave(&eicon_lock, flags);
2797                                 chan->queued -= chan->waitq;
2798                                 if (chan->queued < 0) chan->queued = 0;
2799                                 spin_unlock_irqrestore(&eicon_lock, flags);
2800                                 if (((chan->e.Req & 0x0f) == N_DATA) && (tqueued)) {
2801                                         cmd.driver = ccard->myid;
2802                                         cmd.command = ISDN_STAT_BSENT;
2803                                         cmd.arg = chan->No;
2804                                         cmd.parm.length = twaitpq;
2805                                         ccard->interface.statcallb(&cmd);
2806                                 }
2807                                 break;
2808                         default:
2809                                 eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
2810                                         ack->RcId, ack->RcCh, ack->Reference);
2811                 }
2812         }
2813         return 1;
2814 }
2815
2816 void
2817 idi_handle_ack(eicon_card *ccard, struct sk_buff *skb)
2818 {
2819         int j;
2820         ulong flags;
2821         eicon_RC *ack = (eicon_RC *)skb->data;
2822         eicon_chan *chan;
2823         isdn_ctrl cmd;
2824         int dCh = -1;
2825
2826         if (!ccard) {
2827                 eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ack\n");
2828                 dev_kfree_skb(skb);
2829                 return;
2830         }
2831
2832         spin_lock_irqsave(&eicon_lock, flags);
2833         if ((chan = ccard->IdTable[ack->RcId]) != NULL)
2834                 dCh = chan->No;
2835         spin_unlock_irqrestore(&eicon_lock, flags);
2836
2837         switch (ack->Rc) {
2838                 case OK_FC:
2839                 case N_FLOW_CONTROL:
2840                 case ASSIGN_RC:
2841                         eicon_log(ccard, 1, "idi_ack: Ch%d: unhandled RC 0x%x\n",
2842                                 dCh, ack->Rc);
2843                         break;
2844                 case READY_INT:
2845                 case TIMER_INT:
2846                         /* we do nothing here */
2847                         break;
2848
2849                 case OK:
2850                         if (!chan) {
2851                                 eicon_log(ccard, 1, "idi_ack: Ch%d: OK on chan without Id\n", dCh);
2852                                 break;
2853                         }
2854                         if (!idi_handle_ack_ok(ccard, chan, ack))
2855                                 chan = NULL;
2856                         break;
2857
2858                 case ASSIGN_OK:
2859                         if (chan) {
2860                                 eicon_log(ccard, 1, "idi_ack: Ch%d: ASSIGN-OK on chan already assigned (%x,%x)\n",
2861                                         chan->No, chan->e.D3Id, chan->e.B2Id);
2862                         }
2863                         spin_lock_irqsave(&eicon_lock, flags);
2864                         for(j = 0; j < ccard->nchannels + 1; j++) {
2865                                 if ((ccard->bch[j].e.ref == ack->Reference) &&
2866                                         (ccard->bch[j].e.Req == ASSIGN)) {
2867                                         if (!ccard->bch[j].e.ReqCh) 
2868                                                 ccard->bch[j].e.D3Id  = ack->RcId;
2869                                         else
2870                                                 ccard->bch[j].e.B2Id  = ack->RcId;
2871                                         ccard->IdTable[ack->RcId] = &ccard->bch[j];
2872                                         chan = &ccard->bch[j];
2873                                         break;
2874                                 }
2875                         }
2876                         spin_unlock_irqrestore(&eicon_lock, flags);
2877                         eicon_log(ccard, 16, "idi_ack: Ch%d: Id %x assigned (%s)\n", j, 
2878                                 ack->RcId, (ccard->bch[j].e.ReqCh)? "Net":"Sig");
2879                         if (j > ccard->nchannels) {
2880                                 eicon_log(ccard, 24, "idi_ack: Ch??: ref %d not found for Id %d\n", 
2881                                         ack->Reference, ack->RcId);
2882                         }
2883                         break;
2884
2885                 case OUT_OF_RESOURCES:
2886                 case UNKNOWN_COMMAND:
2887                 case WRONG_COMMAND:
2888                 case WRONG_ID:
2889                 case ADAPTER_DEAD:
2890                 case WRONG_CH:
2891                 case UNKNOWN_IE:
2892                 case WRONG_IE:
2893                 default:
2894                         if (!chan) {
2895                                 eicon_log(ccard, 1, "idi_ack: Ch%d: Not OK !! on chan without Id\n", dCh);
2896                                 break;
2897                         } else
2898                         switch (chan->e.Req) {
2899                                 case 12:        /* Alert */
2900                                         eicon_log(ccard, 2, "eicon_err: Ch%d: Alert Not OK : Rc=%d Id=%x Ch=%d\n",
2901                                                 dCh, ack->Rc, ack->RcId, ack->RcCh);
2902                                         break;
2903                                 default:
2904                                         if (dCh != ccard->nchannels)
2905                                                 eicon_log(ccard, 1, "eicon_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n",
2906                                                         dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req);
2907                         }
2908                         if (dCh == ccard->nchannels) { /* Management */
2909                                 chan->fsm_state = 2;
2910                                 eicon_log(ccard, 8, "eicon_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n",
2911                                         dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req);
2912                         } else if (dCh >= 0) {
2913                                         /* any other channel */
2914                                         /* card reports error: we hangup */
2915                                 idi_hangup(ccard, chan);
2916                                 cmd.driver = ccard->myid;
2917                                 cmd.command = ISDN_STAT_DHUP;
2918                                 cmd.arg = chan->No;
2919                                 ccard->interface.statcallb(&cmd);
2920                         }
2921         }
2922         spin_lock_irqsave(&eicon_lock, flags);
2923         if (chan) {
2924                 chan->e.ref = 0;
2925                 chan->e.busy = 0;
2926         }
2927         spin_unlock_irqrestore(&eicon_lock, flags);
2928         dev_kfree_skb(skb);
2929         eicon_schedule_tx(ccard);
2930 }
2931
2932 int
2933 idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb, int que, int chk)
2934 {
2935         struct sk_buff *xmit_skb;
2936         struct sk_buff *skb2;
2937         eicon_REQ *reqbuf;
2938         eicon_chan_ptr *chan2;
2939         int len, plen = 0, offset = 0;
2940         unsigned long flags;
2941
2942         if ((!card) || (!chan)) {
2943                 eicon_log(card, 1, "idi_err: Ch??: null card/chan in send_data\n");
2944                 return -1;
2945         }
2946
2947         if (chan->fsm_state != EICON_STATE_ACTIVE) {
2948                 eicon_log(card, 1, "idi_snd: Ch%d: send bytes on state %d !\n", chan->No, chan->fsm_state);
2949                 return -ENODEV;
2950         }
2951
2952         len = skb->len;
2953         if (len > EICON_MAX_QUEUE)      /* too much for the shared memory */
2954                 return -1;
2955         if (!len)
2956                 return 0;
2957
2958         if ((chk) && (chan->pqueued > 1))
2959                 return 0;
2960
2961         eicon_log(card, 128, "idi_snd: Ch%d: %d bytes (Pqueue=%d)\n",
2962                 chan->No, len, chan->pqueued);
2963
2964         spin_lock_irqsave(&eicon_lock, flags);
2965         while(offset < len) {
2966
2967                 plen = ((len - offset) > 270) ? 270 : len - offset;
2968
2969                 xmit_skb = alloc_skb(plen + sizeof(eicon_REQ), GFP_ATOMIC);
2970                 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
2971
2972                 if ((!xmit_skb) || (!skb2)) {
2973                         spin_unlock_irqrestore(&eicon_lock, flags);
2974                         eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_data()\n", chan->No);
2975                         if (xmit_skb) 
2976                                 dev_kfree_skb(skb);
2977                         if (skb2) 
2978                                 dev_kfree_skb(skb2);
2979                         return -ENOMEM;
2980                 }
2981
2982                 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
2983                 chan2->ptr = chan;
2984
2985                 reqbuf = (eicon_REQ *)skb_put(xmit_skb, plen + sizeof(eicon_REQ));
2986                 if ((len - offset) > 270) { 
2987                         reqbuf->Req = N_MDATA;
2988                 } else {
2989                         reqbuf->Req = N_DATA;
2990                         /* if (ack) reqbuf->Req |= N_D_BIT; */
2991                 }       
2992                 reqbuf->ReqCh = chan->e.IndCh;
2993                 reqbuf->ReqId = 1;
2994                 memcpy(&reqbuf->XBuffer.P, skb->data + offset, plen);
2995                 reqbuf->XBuffer.length = plen;
2996                 reqbuf->Reference = 1; /* Net Entity */
2997
2998                 skb_queue_tail(&chan->e.X, xmit_skb);
2999                 skb_queue_tail(&card->sndq, skb2); 
3000
3001                 offset += plen;
3002         }
3003         if (que) {
3004                 chan->queued += len;
3005                 chan->pqueued++;
3006         }
3007         spin_unlock_irqrestore(&eicon_lock, flags);
3008         eicon_schedule_tx(card);
3009         dev_kfree_skb(skb);
3010         return len;
3011 }
3012
3013
3014 int
3015 eicon_idi_manage_assign(eicon_card *card)
3016 {
3017         struct sk_buff *skb;
3018         struct sk_buff *skb2;
3019         eicon_REQ  *reqbuf;
3020         eicon_chan     *chan;
3021         eicon_chan_ptr *chan2;
3022
3023         chan = &(card->bch[card->nchannels]);
3024
3025         skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
3026         skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
3027
3028         if ((!skb) || (!skb2)) {
3029                 eicon_log(card, 1, "idi_err: alloc_skb failed in manage_assign()\n");
3030                 if (skb) 
3031                         dev_kfree_skb(skb);
3032                 if (skb2) 
3033                         dev_kfree_skb(skb2);
3034                 return -ENOMEM;
3035         }
3036
3037         chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
3038         chan2->ptr = chan;
3039
3040         reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
3041
3042         reqbuf->XBuffer.P[0] = 0;
3043         reqbuf->Req = ASSIGN;
3044         reqbuf->ReqCh = 0;
3045         reqbuf->ReqId = MAN_ID;
3046         reqbuf->XBuffer.length = 1;
3047         reqbuf->Reference = 2; /* Man Entity */
3048
3049         skb_queue_tail(&chan->e.X, skb);
3050         skb_queue_tail(&card->sndq, skb2);
3051         eicon_schedule_tx(card);
3052         return(0);
3053 }
3054
3055
3056 int
3057 eicon_idi_manage_remove(eicon_card *card)
3058 {
3059         struct sk_buff *skb;
3060         struct sk_buff *skb2;
3061         eicon_REQ  *reqbuf;
3062         eicon_chan     *chan;
3063         eicon_chan_ptr *chan2;
3064
3065         chan = &(card->bch[card->nchannels]);
3066
3067         skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
3068         skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
3069
3070         if ((!skb) || (!skb2)) {
3071                 eicon_log(card, 1, "idi_err: alloc_skb failed in manage_remove()\n");
3072                 if (skb) 
3073                         dev_kfree_skb(skb);
3074                 if (skb2) 
3075                         dev_kfree_skb(skb2);
3076                 return -ENOMEM;
3077         }
3078
3079         chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
3080         chan2->ptr = chan;
3081
3082         reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
3083
3084         reqbuf->Req = REMOVE;
3085         reqbuf->ReqCh = 0;
3086         reqbuf->ReqId = 1;
3087         reqbuf->XBuffer.length = 0;
3088         reqbuf->Reference = 2; /* Man Entity */
3089
3090         skb_queue_tail(&chan->e.X, skb);
3091         skb_queue_tail(&card->sndq, skb2);
3092         eicon_schedule_tx(card);
3093         return(0);
3094 }
3095
3096
3097 int
3098 eicon_idi_manage(eicon_card *card, eicon_manifbuf *mb)
3099 {
3100         int l = 0;
3101         int ret = 0;
3102         int timeout;
3103         int i;
3104         struct sk_buff *skb;
3105         struct sk_buff *skb2;
3106         eicon_REQ  *reqbuf;
3107         eicon_chan     *chan;
3108         eicon_chan_ptr *chan2;
3109
3110         chan = &(card->bch[card->nchannels]);
3111
3112         if (!(chan->e.D3Id)) {
3113                 chan->e.D3Id = 1;
3114                 while((skb2 = skb_dequeue(&chan->e.X)))
3115                         dev_kfree_skb(skb2);
3116                 chan->e.busy = 0;
3117  
3118                 if ((ret = eicon_idi_manage_assign(card))) {
3119                         chan->e.D3Id = 0;
3120                         return(ret); 
3121                 }
3122
3123                 timeout = jiffies + HZ / 2;
3124                 while (time_before(jiffies, timeout)) {
3125                         if (chan->e.B2Id) break;
3126                         SLEEP(10);
3127                 }
3128                 if (!chan->e.B2Id) {
3129                         chan->e.D3Id = 0;
3130                         return -EIO;
3131                 }
3132         }
3133
3134         chan->fsm_state = 0;
3135
3136         if (!(manbuf = kmalloc(sizeof(eicon_manifbuf), GFP_KERNEL))) {
3137                 eicon_log(card, 1, "idi_err: alloc_manifbuf failed\n");
3138                 return -ENOMEM;
3139         }
3140         if (copy_from_user(manbuf, mb, sizeof(eicon_manifbuf))) {
3141                 kfree(manbuf);
3142                 return -EFAULT;
3143         }
3144
3145         skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
3146         skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
3147
3148         if ((!skb) || (!skb2)) {
3149                 eicon_log(card, 1, "idi_err_manif: alloc_skb failed in manage()\n");
3150                 if (skb) 
3151                         dev_kfree_skb(skb);
3152                 if (skb2) 
3153                         dev_kfree_skb(skb2);
3154                 kfree(manbuf);
3155                 return -ENOMEM;
3156         }
3157
3158         chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
3159         chan2->ptr = chan;
3160
3161         reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
3162
3163         reqbuf->XBuffer.P[l++] = ESC;
3164         reqbuf->XBuffer.P[l++] = 6;
3165         reqbuf->XBuffer.P[l++] = 0x80;
3166         for (i = 0; i < manbuf->length[0]; i++)
3167                 reqbuf->XBuffer.P[l++] = manbuf->data[i];
3168         reqbuf->XBuffer.P[1] = manbuf->length[0] + 1;
3169
3170         reqbuf->XBuffer.P[l++] = 0;
3171         reqbuf->Req = (manbuf->count) ? manbuf->count : MAN_READ;
3172         reqbuf->ReqCh = 0;
3173         reqbuf->ReqId = 1;
3174         reqbuf->XBuffer.length = l;
3175         reqbuf->Reference = 2; /* Man Entity */
3176
3177         skb_queue_tail(&chan->e.X, skb);
3178         skb_queue_tail(&card->sndq, skb2);
3179
3180         manbuf->count = 0;
3181         manbuf->pos = 0;
3182
3183         eicon_schedule_tx(card);
3184
3185         timeout = jiffies + HZ / 2;
3186         while (time_before(jiffies, timeout)) {
3187                 if (chan->fsm_state) break;
3188                 SLEEP(10);
3189         }
3190         if ((!chan->fsm_state) || (chan->fsm_state == 2)) {
3191                 kfree(manbuf);
3192                 return -EIO;
3193         }
3194         if (copy_to_user(mb, manbuf, sizeof(eicon_manifbuf))) {
3195                 kfree(manbuf);
3196                 return -EFAULT;
3197         }
3198
3199         kfree(manbuf);
3200   return(0);
3201 }