1 /* $Id: eicon_idi.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
3 * ISDN lowlevel-module for Eicon active cards.
6 * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
7 * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
9 * Thanks to Deutsche Mailbox Saar-Lor-Lux GmbH
10 * for sponsoring and testing fax
11 * capabilities with Diva Server cards.
12 * (dor@deutschemailbox.de)
14 * This software may be used and distributed according to the terms
15 * of the GNU General Public License, incorporated herein by reference.
19 #include <linux/config.h>
20 #define __NO_VERSION__
22 #include "eicon_idi.h"
23 #include "eicon_dsp.h"
26 #undef EICON_FULL_SERVICE_OKTETT
28 char *eicon_idi_revision = "$Revision: 1.1.4.1 $";
30 eicon_manifbuf *manbuf;
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);
37 idi_assign_req(eicon_REQ *reqbuf, int signet, eicon_chan *chan)
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 */
61 reqbuf->ReqId = DSIG_ID;
62 reqbuf->XBuffer.length = l;
63 reqbuf->Reference = 0; /* Sig Entity */
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 */
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 */
84 case ISDN_PROTO_L2_MODEM:
85 if (chan->fsm_state == EICON_STATE_IWAIT)
86 reqbuf->XBuffer.P[l++] = 9; /* V.42 incoming */
88 reqbuf->XBuffer.P[l++] = 10; /* V.42 */
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 */
95 reqbuf->XBuffer.P[l++] = 2; /* transparent */
98 reqbuf->XBuffer.P[l++] = 1;
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;
110 case ISDN_PROTO_L3_TRANS:
112 reqbuf->XBuffer.P[l++] = 4;
114 reqbuf->XBuffer.P[l++] = 0; /* end */
115 reqbuf->Req = ASSIGN;
117 reqbuf->ReqId = NL_ID;
118 reqbuf->XBuffer.length = l;
119 reqbuf->Reference = 1; /* Net Entity */
125 idi_put_req(eicon_REQ *reqbuf, int rq, int signet, int Ch)
130 reqbuf->XBuffer.length = 1;
131 reqbuf->XBuffer.P[0] = 0;
132 reqbuf->Reference = signet;
137 idi_put_suspend_req(eicon_REQ *reqbuf, eicon_chan *chan)
139 reqbuf->Req = SUSPEND;
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 */
152 idi_call_res_req(eicon_REQ *reqbuf, eicon_chan *chan)
155 reqbuf->Req = CALL_RES;
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;
175 case ISDN_PROTO_L2_V11096:
176 reqbuf->XBuffer.P[2] = 0x0d;
177 reqbuf->XBuffer.P[3] = 5;
178 reqbuf->XBuffer.P[4] = 0;
180 case ISDN_PROTO_L2_V11019:
181 reqbuf->XBuffer.P[2] = 0x0d;
182 reqbuf->XBuffer.P[3] = 6;
183 reqbuf->XBuffer.P[4] = 0;
185 case ISDN_PROTO_L2_V11038:
186 reqbuf->XBuffer.P[2] = 0x0d;
187 reqbuf->XBuffer.P[3] = 7;
188 reqbuf->XBuffer.P[4] = 0;
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;
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;
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 */
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);
221 idi_do_req(eicon_card *card, eicon_chan *chan, int cmd, int layer)
224 struct sk_buff *skb2;
226 eicon_chan_ptr *chan2;
228 skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
229 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
231 if ((!skb) || (!skb2)) {
232 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in do_req()\n", chan->No);
240 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
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;
249 idi_assign_req(reqbuf, layer, chan);
253 idi_put_req(reqbuf, REMOVE, layer, 0);
256 idi_put_req(reqbuf, INDICATE_REQ, 0, 0);
259 idi_put_req(reqbuf, HANGUP, 0, 0);
262 idi_put_suspend_req(reqbuf, chan);
265 idi_put_req(reqbuf, RESUME, 0 ,0);
268 idi_put_req(reqbuf, REJECT, 0 ,0);
271 idi_put_req(reqbuf, CALL_ALERT, 0, 0);
274 idi_call_res_req(reqbuf, chan);
277 idi_put_req(reqbuf, CALL_HOLD, 0, 0);
279 case N_CONNECT|0x700:
280 idi_put_req(reqbuf, N_CONNECT, 1, 0);
282 case N_CONNECT_ACK|0x700:
283 idi_put_req(reqbuf, N_CONNECT_ACK, 1, 0);
286 idi_put_req(reqbuf, N_DISC, 1, chan->e.IndCh);
288 case N_DISC_ACK|0x700:
289 idi_put_req(reqbuf, N_DISC_ACK, 1, chan->e.IndCh);
292 eicon_log(card, 1, "idi_req: Ch%d: Unknown request\n", chan->No);
298 skb_queue_tail(&chan->e.X, skb);
299 skb_queue_tail(&card->sndq, skb2);
300 eicon_schedule_tx(card);
305 eicon_idi_listen_req(eicon_card *card, eicon_chan *chan)
307 if ((!card) || (!chan))
310 eicon_log(card, 16, "idi_req: Ch%d: Listen_Req eazmask=0x%x\n",chan->No, chan->eazmask);
312 idi_do_req(card, chan, ASSIGN, 0);
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;
324 idi_si2bc(int si1, int si2, char *bc, char *hlc)
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
334 bc[0] = 0x80; /* Speech */
335 hlc[0] = 0x02; /* hlc len */
336 hlc[1] = 0x91; /* first hic */
337 hlc[2] = 0x81; /* Telephony */
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
347 hlc[0] = 0x02; /* hlc len */
348 hlc[1] = 0x91; /* first hic */
349 hlc[2] = 0x84; /* Fax Gr.2/3 */
364 idi_hangup(eicon_card *card, eicon_chan *chan)
366 if ((!card) || (!chan))
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);
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;
379 eicon_log(card, 8, "idi_req: Ch%d: Hangup\n", chan->No);
380 #ifdef CONFIG_ISDN_TTY_FAX
387 capipmsg(eicon_card *card, eicon_chan *chan, capi_msg *cm)
389 if ((cm->para[0] != 3) || (cm->para[1] != 0))
393 if (cm->para[4] != 0)
395 switch(cm->para[3]) {
396 case 4: /* Suspend */
397 eicon_log(card, 8, "idi_req: Ch%d: Call Suspend\n", chan->No);
399 idi_do_req(card, chan, SUSPEND, 0);
401 idi_do_req(card, chan, CALL_HOLD, 0);
405 eicon_log(card, 8, "idi_req: Ch%d: Call Resume\n", chan->No);
406 idi_do_req(card, chan, RESUME, 0);
413 idi_connect_res(eicon_card *card, eicon_chan *chan)
415 if ((!card) || (!chan))
418 chan->fsm_state = EICON_STATE_IWAIT;
420 /* check if old NetID has been removed */
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);
427 idi_do_req(card, chan, ASSIGN, 1);
428 idi_do_req(card, chan, CALL_RES, 0);
433 idi_connect_req(eicon_card *card, eicon_chan *chan, char *phone,
434 char *eazmsn, int si1, int si2)
439 unsigned char *sub, *sp;
441 unsigned char hlc[5];
443 struct sk_buff *skb2;
445 eicon_chan_ptr *chan2;
447 if ((!card) || (!chan))
450 skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
451 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
453 if ((!skb) || (!skb2)) {
454 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in connect_req()\n", chan->No);
462 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
465 reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
466 reqbuf->Req = CALL_REQ;
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;
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 */
490 reqbuf->XBuffer.P[l++] = *sub++ & 0x7f;
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;
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 */
514 reqbuf->XBuffer.P[l++] = *sub++ & 0x7f;
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;
524 else if ((tmp = idi_si2bc(si1, si2, bc, hlc)) > 0) {
525 reqbuf->XBuffer.P[l++] = BC;
526 reqbuf->XBuffer.P[l++] = tmp;
528 reqbuf->XBuffer.P[l++] = bc[i];
530 reqbuf->XBuffer.P[l++] = HLC;
531 reqbuf->XBuffer.P[l++] = tmp;
533 reqbuf->XBuffer.P[l++] = hlc[i];
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;
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;
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;
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;
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;
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;
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 */
599 reqbuf->XBuffer.P[l++] = 0; /* end */
600 reqbuf->XBuffer.length = l;
601 reqbuf->Reference = 0; /* Sig Entity */
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;
611 skb_queue_tail(&chan->e.X, skb);
612 skb_queue_tail(&card->sndq, skb2);
613 eicon_schedule_tx(card);
616 eicon_log(card, 8, "idi_req: Ch%d: Conn_Req %s -> %s\n",chan->No, eazmsn, phone);
622 idi_IndParse(eicon_card *ccard, eicon_chan *chan, idi_ind_message *message, unsigned char *buffer, int len)
633 memset(message, 0, sizeof(idi_ind_message));
635 if ((!len) || (!buffer[pos])) return;
644 wlen = buffer[pos++];
647 if (pos > len) return;
649 if (lock & 0x80) lock &= 0x7f;
652 if((w&0xf0) == SHIFT) {
654 if(!(codeset & 0x08)) lock = codeset & 7;
659 if (w==ESC && wlen >=2) {
660 code = buffer[pos++]|0x800;
664 code |= (codeset<<8);
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);
674 if (wlen > sizeof(message->oad)) {
680 message->plan = buffer[pos++];
681 if (message->plan &0x80)
684 message->screen = buffer[pos++];
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);
694 if (wlen > sizeof(message->rdn)) {
700 if (!(buffer[pos++] & 0x80)) {
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,
711 if (wlen > sizeof(message->cpn)) {
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);
721 if (wlen > sizeof(message->dsa)) {
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);
731 if (wlen > sizeof(message->osa)) {
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);
742 eicon_log(ccard, 2, "idi_inf: Ch%d: Connected Address in ind, len:%x\n",
746 if (wlen > sizeof(message->bc)) {
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]);
756 if (wlen > sizeof(message->e_bc)) {
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]);
765 if (wlen > sizeof(message->llc)) {
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]);
775 if (wlen > sizeof(message->hlc)) {
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]);
787 if (wlen > sizeof(message->display)) {
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,
797 if (wlen > sizeof(message->keypad)) {
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,
809 switch(buffer[pos] & 127) {
811 eicon_log(ccard, 4, "idi_inf: Ch%d: User suspended.\n", chan->No);
814 eicon_log(ccard, 4, "idi_inf: Ch%d: User resumed.\n", chan->No);
817 eicon_log(ccard, 4, "idi_inf: Ch%d: Bearer service change.\n", chan->No);
820 eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Notification %x.\n",
821 chan->No, buffer[pos] & 127);
829 switch(buffer[pos+1] & 127) {
831 eicon_log(ccard, 4, "idi_inf: Ch%d: Call is not end-to-end ISDN.\n", chan->No);
834 eicon_log(ccard, 4, "idi_inf: Ch%d: Destination address is non ISDN.\n", chan->No);
837 eicon_log(ccard, 4, "idi_inf: Ch%d: Origination address is non ISDN.\n", chan->No);
840 eicon_log(ccard, 4, "idi_inf: Ch%d: Call has returned to the ISDN.\n", chan->No);
843 eicon_log(ccard, 4, "idi_inf: Ch%d: Interworking has occurred.\n", chan->No);
846 eicon_log(ccard, 4, "idi_inf: Ch%d: In-band information available.\n", chan->No);
849 eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Progress %x.\n",
850 chan->No, buffer[pos+1] & 127);
856 if (wlen > sizeof(message->cau)) {
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]);
867 if (wlen > sizeof(message->e_cau)) {
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]);
877 if (wlen > sizeof(message->e_chi)) {
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,
888 message->e_mt=buffer[pos++];
889 eicon_log(ccard, 4, "idi_inf: Ch%d: EMT=0x%x\n", chan->No, message->e_mt);
892 if (wlen > sizeof(message->dt)) {
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]);
903 if (wlen > sizeof(message->sin)) {
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]);
913 eicon_log(ccard, 2, "idi_inf: Ch%d: Called Party Status in ind\n", chan->No);
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);
923 cmd.driver = ccard->myid;
924 cmd.command = ISDN_STAT_CINF;
926 ccard->interface.statcallb(&cmd);
929 eicon_log(ccard, 2, "idi_inf: Ch%d: Date in ind\n", chan->No);
933 eicon_log(ccard, 2, "idi_inf: Ch%d: Sending Complete in ind.\n", chan->No);
947 /* Not yet interested in this */
951 /* Managment Information Element */
953 eicon_log(ccard, 1, "idi_err: manbuf not allocated\n");
956 memcpy(&manbuf->data[manbuf->pos], &buffer[pos], wlen);
957 manbuf->length[manbuf->count] = 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);
973 idi_bc2si(unsigned char *bc, unsigned char *hlc, unsigned char *sin, unsigned char *si1, unsigned char *si2)
978 switch (bc[0] & 0x7f) {
979 case 0x00: /* Speech */
981 #ifdef EICON_FULL_SERVICE_OKTETT
986 case 0x10: /* 3.1 Khz audio */
988 #ifdef EICON_FULL_SERVICE_OKTETT
993 case 0x08: /* Unrestricted digital information */
997 case 0x09: /* Restricted digital information */
1001 /* Unrestr. digital information with
1002 * tones/announcements ( or 7 kHz audio
1006 case 0x18: /* Video */
1010 switch (bc[1] & 0x7f) {
1011 case 0x40: /* packed mode */
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; */
1024 /********************* FAX stuff ***************************/
1026 #ifdef CONFIG_ISDN_TTY_FAX
1029 idi_fill_in_T30(eicon_chan *chan, unsigned char *buffer)
1031 eicon_t30_s *t30 = (eicon_t30_s *) buffer;
1034 eicon_log(NULL, 1,"idi_T30: fill_in with NULL fax struct, ERROR\n");
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;
1044 t30->pages_high = 0;
1045 t30->atf = 1; /* optimised for AT+F command set */
1047 t30->feature_bits_low = 0;
1048 t30->feature_bits_high = 0;
1049 t30->control_bits_low = 0;
1050 t30->control_bits_high = 0;
1052 if (chan->fax->nbc) {
1053 /* set compression by DCC value */
1054 switch(chan->fax->compression) {
1055 case (0): /* 1-D modified */
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;
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;
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;
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;
1089 switch(chan->fax->ecm) {
1090 case (0): /* disable ECM */
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;
1099 t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
1100 t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
1104 if (DebugVar & 128) {
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);
1126 return(sizeof(eicon_t30_s));
1129 /* send fax struct */
1131 idi_send_edata(eicon_card *card, eicon_chan *chan)
1133 struct sk_buff *skb;
1134 struct sk_buff *skb2;
1136 eicon_chan_ptr *chan2;
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);
1142 eicon_log(card, 128, "idi_snd: Ch%d: edata (fax)\n", chan->No);
1144 skb = alloc_skb(sizeof(eicon_REQ) + sizeof(eicon_t30_s), GFP_ATOMIC);
1145 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
1147 if ((!skb) || (!skb2)) {
1148 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_edata()\n", chan->No);
1152 dev_kfree_skb(skb2);
1156 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
1159 reqbuf = (eicon_REQ *)skb_put(skb, sizeof(eicon_t30_s) + sizeof(eicon_REQ));
1161 reqbuf->Req = N_EDATA;
1162 reqbuf->ReqCh = chan->e.IndCh;
1165 reqbuf->XBuffer.length = idi_fill_in_T30(chan, reqbuf->XBuffer.P);
1166 reqbuf->Reference = 1; /* Net Entity */
1168 skb_queue_tail(&chan->e.X, skb);
1169 skb_queue_tail(&card->sndq, skb2);
1170 eicon_schedule_tx(card);
1175 idi_parse_edata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len)
1177 eicon_t30_s *p = (eicon_t30_s *)buffer;
1180 if (DebugVar & 128) {
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);
1204 eicon_log(ccard, 1, "idi_edata: parse to NULL fax struct, ERROR\n");
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;
1225 if (p->feature_bits_low & T30_FEATURE_BIT_T6_CODING) {
1226 chan->fax->r_compression = 3;
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;
1237 idi_fax_send_header(eicon_card *card, eicon_chan *chan, int header)
1239 static __u16 wd2sff[] = {
1240 1728, 2048, 2432, 1216, 864
1242 static __u16 ln2sff[2][3] = {
1243 { 1143, 1401, 0 } , { 2287, 2802, 0 }
1245 struct sk_buff *skb;
1246 eicon_sff_dochead *doc;
1247 eicon_sff_pagehead *page;
1251 eicon_log(card, 1, "idi_fax: send head with NULL fax struct, ERROR\n");
1254 if (header == 2) { /* DocHeader + PageHeader */
1255 skb = alloc_skb(sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead), GFP_ATOMIC);
1257 skb = alloc_skb(sizeof(eicon_sff_pagehead), GFP_ATOMIC);
1260 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_header()\n", chan->No);
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);
1273 page = (eicon_sff_pagehead *)skb_put(skb, sizeof(eicon_sff_pagehead));
1274 memset(page, 0, sizeof(eicon_sff_pagehead));
1278 case 1: /* PageHeaderEnd */
1279 page->pageheadid = 254;
1280 page->pageheadlen = 0;
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);
1295 idi_send_data(card, chan, 0, skb, 0, 0);
1299 idi_fax_cmd(eicon_card *card, eicon_chan *chan)
1303 if ((!card) || (!chan))
1307 eicon_log(card, 1, "idi_fax: cmd with NULL fax struct, ERROR\n");
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);
1316 if (chan->fax->phase == ISDN_FAX_PHASE_D) {
1317 idi_send_edata(card, chan);
1322 case ISDN_TTY_FAX_DR:
1323 if (chan->fax->phase == ISDN_FAX_PHASE_B) {
1324 idi_send_edata(card, chan);
1326 cmd.driver = card->myid;
1327 cmd.command = ISDN_STAT_FAXIND;
1329 chan->fax->r_code = ISDN_TTY_FAX_CFR;
1330 card->interface.statcallb(&cmd);
1332 cmd.driver = card->myid;
1333 cmd.command = ISDN_STAT_FAXIND;
1335 chan->fax->r_code = ISDN_TTY_FAX_RID;
1336 card->interface.statcallb(&cmd);
1338 /* telling 1-D compression */
1339 chan->fax->r_compression = 0;
1340 cmd.driver = card->myid;
1341 cmd.command = ISDN_STAT_FAXIND;
1343 chan->fax->r_code = ISDN_TTY_FAX_DCS;
1344 card->interface.statcallb(&cmd);
1346 chan->fax2.NextObject = FAX_OBJECT_DOCU;
1347 chan->fax2.PrevObject = FAX_OBJECT_DOCU;
1351 if (chan->fax->phase == ISDN_FAX_PHASE_D) {
1352 idi_send_edata(card, chan);
1357 case ISDN_TTY_FAX_ET:
1358 switch(chan->fax->fet) {
1361 idi_fax_send_header(card, chan, 0);
1364 idi_fax_send_header(card, chan, 1);
1372 idi_edata_rcveop(eicon_card *card, eicon_chan *chan)
1377 eicon_log(card, 1, "idi_edata: rcveop with NULL fax struct, ERROR\n");
1380 cmd.driver = card->myid;
1381 cmd.command = ISDN_STAT_FAXIND;
1383 chan->fax->r_code = ISDN_TTY_FAX_ET;
1384 card->interface.statcallb(&cmd);
1388 idi_reset_fax_stat(eicon_chan *chan)
1390 chan->fax2.LineLen = 0;
1391 chan->fax2.LineData = 0;
1392 chan->fax2.LineDataLen = 0;
1393 chan->fax2.NullByteExist = 0;
1395 chan->fax2.PageCount = 0;
1400 idi_edata_action(eicon_card *ccard, eicon_chan *chan, char *buffer, int len)
1405 eicon_log(ccard, 1, "idi_edata: action with NULL fax struct, ERROR\n");
1408 if (chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) {
1409 idi_parse_edata(ccard, chan, buffer, len);
1411 if (chan->fax->phase == ISDN_FAX_PHASE_A) {
1412 idi_reset_fax_stat(chan);
1414 chan->fsm_state = EICON_STATE_ACTIVE;
1415 cmd.driver = ccard->myid;
1416 cmd.command = ISDN_STAT_BCONN;
1418 strcpy(cmd.parm.num, "");
1419 ccard->interface.statcallb(&cmd);
1421 cmd.driver = ccard->myid;
1422 cmd.command = ISDN_STAT_FAXIND;
1424 chan->fax->r_code = ISDN_TTY_FAX_FCON;
1425 ccard->interface.statcallb(&cmd);
1427 cmd.driver = ccard->myid;
1428 cmd.command = ISDN_STAT_FAXIND;
1430 chan->fax->r_code = ISDN_TTY_FAX_RID;
1431 ccard->interface.statcallb(&cmd);
1433 cmd.driver = ccard->myid;
1434 cmd.command = ISDN_STAT_FAXIND;
1436 chan->fax->r_code = ISDN_TTY_FAX_DIS;
1437 ccard->interface.statcallb(&cmd);
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;
1445 chan->fax->r_code = ISDN_TTY_FAX_DIS;
1446 ccard->interface.statcallb(&cmd);
1449 cmd.driver = ccard->myid;
1450 cmd.command = ISDN_STAT_FAXIND;
1452 chan->fax->r_code = ISDN_TTY_FAX_SENT; /* OK message */
1453 ccard->interface.statcallb(&cmd);
1455 if (chan->fax->phase == ISDN_FAX_PHASE_D) {
1457 if ((chan->fax->code == EDATA_T30_MCF) &&
1458 (chan->fax->fet != 2)) {
1459 cmd.driver = ccard->myid;
1460 cmd.command = ISDN_STAT_FAXIND;
1462 chan->fax->r_code = ISDN_TTY_FAX_PTS;
1463 ccard->interface.statcallb(&cmd);
1466 switch(chan->fax->fet) {
1467 case 0: /* new page */
1468 /* stay in phase D , wait on cmd +FDT */
1470 case 1: /* new document */
1471 /* link-level switch to phase B */
1473 case 2: /* session end */
1475 /* send_edata produces error on some */
1476 /* fax-machines here, so we don't */
1477 /* idi_send_edata(ccard, chan); */
1483 if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
1484 idi_parse_edata(ccard, chan, buffer, len);
1486 if ((chan->fax->code == EDATA_T30_DCS) &&
1487 (chan->fax->phase == ISDN_FAX_PHASE_A)) {
1488 idi_reset_fax_stat(chan);
1490 cmd.driver = ccard->myid;
1491 cmd.command = ISDN_STAT_BCONN;
1493 strcpy(cmd.parm.num, "");
1494 ccard->interface.statcallb(&cmd);
1496 cmd.driver = ccard->myid;
1497 cmd.command = ISDN_STAT_FAXIND;
1499 chan->fax->r_code = ISDN_TTY_FAX_FCON_I;
1500 ccard->interface.statcallb(&cmd);
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;
1507 chan->fax->r_code = ISDN_TTY_FAX_RID;
1508 ccard->interface.statcallb(&cmd);
1510 cmd.driver = ccard->myid;
1511 cmd.command = ISDN_STAT_FAXIND;
1513 chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;
1514 ccard->interface.statcallb(&cmd);
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;
1521 chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;
1522 ccard->interface.statcallb(&cmd);
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);
1531 idi_edata_rcveop(ccard, chan);
1535 idi_edata_rcveop(ccard, chan);
1539 idi_edata_rcveop(ccard, chan);
1547 fax_put_rcv(eicon_card *ccard, eicon_chan *chan, u_char *Data, int len)
1549 struct sk_buff *skb;
1551 skb = alloc_skb(len + MAX_HEADER_LEN, GFP_ATOMIC);
1553 eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_put_rcv()\n", chan->No);
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);
1562 idi_faxdata_rcv(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb)
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;
1574 eicon_sff_pagehead *ob_page;
1576 __u16 Cl2Eol = 0x8000;
1578 # define EVENT_NONE 0
1579 # define EVENT_NEEDDATA 1
1582 eicon_log(ccard, 1, "idi_fax: rcvdata with NULL fax struct, ERROR\n");
1588 if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
1589 InBuf.Data = skb->data;
1590 InBuf.Size = skb->len;
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;
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;
1607 ObjectSize = sizeof(eicon_sff_dochead);
1608 Length = ObjectSize;
1609 if (LineBuf.Len < Length) {
1610 Length -= LineBuf.Len;
1612 LineBuf.Next = LineBuf.Data;
1613 InBuf.Len += Length;
1614 InBuf.Next += Length;
1616 LineBuf.Len -= Length;
1617 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1618 memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
1620 chan->fax2.PrevObject = FAX_OBJECT_DOCU;
1621 chan->fax2.NextObject = FAX_OBJECT_PAGE;
1624 case FAX_OBJECT_PAGE:
1625 Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
1627 Event = EVENT_NEEDDATA;
1630 if (LineBuf.Len == 0) {
1631 *LineBuf.Next++ = *InBuf.Next++;
1635 if (LineBuf.Len == 1) {
1636 *LineBuf.Next++ = *InBuf.Next++;
1640 PageHeaderLen = *(LineBuf.Data + 1);
1641 ObjectSize = (PageHeaderLen == 0) ? 2 : sizeof(eicon_sff_pagehead);
1642 if (Length < ObjectSize) {
1643 Event = EVENT_NEEDDATA;
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;
1657 ob_page = (eicon_sff_pagehead *)LineBuf.Data;
1658 switch(ob_page->linelength) {
1660 chan->fax->r_width = 1;
1663 chan->fax->r_width = 2;
1666 chan->fax->r_width = 3;
1669 chan->fax->r_width = 4;
1673 chan->fax->r_width = 0;
1675 switch(ob_page->pagelength) {
1678 chan->fax->r_length = 0;
1682 chan->fax->r_length = 1;
1685 chan->fax->r_length = 2;
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);
1690 LineBuf.Len -= Length;
1691 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1692 memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
1694 chan->fax2.PrevObject = FAX_OBJECT_PAGE;
1695 chan->fax2.NextObject = FAX_OBJECT_LINE;
1698 case FAX_OBJECT_LINE:
1699 Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
1701 Event = EVENT_NEEDDATA;
1704 if (LineBuf.Len == 0) {
1705 *LineBuf.Next++ = *InBuf.Next++;
1709 Recordtype = *LineBuf.Data;
1710 if (Recordtype == 0) {
1711 /* recordtype pixel row (2 byte length) */
1713 if (Length < ObjHeadLen) {
1714 Event = EVENT_NEEDDATA;
1717 while (LineBuf.Len < ObjHeadLen) {
1718 *LineBuf.Next++ = *InBuf.Next++;
1722 ObjDataLen = *((__u16*) (LineBuf.Data + 1));
1723 ObjectSize = ObjHeadLen + ObjDataLen;
1724 if (Length < ObjectSize) {
1725 Event = EVENT_NEEDDATA;
1729 if ((Recordtype >= 1) && (Recordtype <= 216)) {
1730 /* recordtype pixel row (1 byte length) */
1732 ObjDataLen = Recordtype;
1733 ObjectSize = ObjHeadLen + ObjDataLen;
1734 if (Length < ObjectSize) {
1735 Event = EVENT_NEEDDATA;
1739 if ((Recordtype >= 217) && (Recordtype <= 253)) {
1740 /* recordtype empty lines */
1743 ObjectSize = ObjHeadLen + ObjDataLen;
1745 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1746 memmove(LineBuf.Data, LineBuf.Data + 1, LineBuf.Len);
1749 if (Recordtype == 254) {
1750 /* recordtype page header */
1751 chan->fax2.PrevObject = FAX_OBJECT_LINE;
1752 chan->fax2.NextObject = FAX_OBJECT_PAGE;
1755 /* recordtype user information */
1757 if (Length < ObjHeadLen) {
1758 Event = EVENT_NEEDDATA;
1761 while (LineBuf.Len < ObjHeadLen) {
1762 *LineBuf.Next++ = *InBuf.Next++;
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);
1775 /* user information */
1776 if (Length < ObjectSize) {
1777 Event = EVENT_NEEDDATA;
1780 Length = ObjectSize;
1781 if (LineBuf.Len < Length) {
1782 Length -= LineBuf.Len;
1784 LineBuf.Next = LineBuf.Data;
1785 InBuf.Len += Length;
1786 InBuf.Next += Length;
1788 LineBuf.Len -= Length;
1789 LineBuf.Next = LineBuf.Data + LineBuf.Len;
1790 memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
1795 Length = ObjectSize;
1796 if (LineBuf.Len > ObjHeadLen) {
1797 fax_put_rcv(ccard, chan, LineBuf.Data + ObjHeadLen,
1798 (LineBuf.Len - ObjHeadLen));
1800 Length -= LineBuf.Len;
1802 LineBuf.Next = LineBuf.Data;
1804 fax_put_rcv(ccard, chan, InBuf.Next, Length);
1805 InBuf.Len += Length;
1806 InBuf.Next += Length;
1808 fax_put_rcv(ccard, chan, (__u8 *)&Cl2Eol, sizeof(Cl2Eol));
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,
1818 memcpy(LineBuf.Next, InBuf.Next, Length);
1819 LineBuf.Len += Length;
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 */
1829 # undef EVENT_NEEDDATA
1835 idi_fax_send_outbuf(eicon_card *ccard, eicon_chan *chan, eicon_OBJBUFFER *OutBuf)
1837 struct sk_buff *skb;
1839 skb = alloc_skb(OutBuf->Len, GFP_ATOMIC);
1841 eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_outbuf()\n", chan->No);
1844 memcpy(skb_put(skb, OutBuf->Len), OutBuf->Data, OutBuf->Len);
1847 OutBuf->Next = OutBuf->Data;
1849 return(idi_send_data(ccard, chan, 0, skb, 1, 0));
1853 idi_faxdata_send(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb)
1856 eicon_OBJBUFFER InBuf;
1859 eicon_OBJBUFFER OutBuf;
1860 eicon_OBJBUFFER LineBuf;
1862 unsigned int LineDataLen;
1867 # define EVENT_NONE 0
1868 # define EVENT_EOD 1
1869 # define EVENT_EOL 2
1870 # define EVENT_EOP 3
1872 if ((!ccard) || (!chan))
1876 eicon_log(ccard, 1, "idi_fax: senddata with NULL fax struct, ERROR\n");
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. */
1887 if (chan->fax->phase != ISDN_FAX_PHASE_C) {
1892 if (chan->queued + skb->len > 1200)
1894 if (chan->pqueued > 1)
1897 InBuf.Data = skb->data;
1898 InBuf.Size = skb->len;
1900 InBuf.Next = InBuf.Data;
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;
1911 OutBuf.Data = chan->fax2.abFrame;
1912 OutBuf.Size = sizeof(chan->fax2.abFrame);
1914 OutBuf.Next = OutBuf.Data;
1923 if (InBuf.Len >= InBuf.Size) {
1927 if ((chan->fax2.Dle != _DLE_) && *InBuf.Next == _DLE_) {
1928 chan->fax2.Dle = _DLE_;
1931 if (InBuf.Len >= InBuf.Size) {
1936 if (chan->fax2.Dle == _DLE_) {
1938 if (*InBuf.Next == _ETX_) {
1942 if (*InBuf.Next == _DLE_) {
1946 "idi_err: Ch%d: unknown DLE escape %02x found\n",
1947 chan->No, *InBuf.Next);
1950 if (InBuf.Len >= InBuf.Size) {
1957 InData = *InBuf.Next++;
1958 InMask = (chan->fax->bor) ? 0x80 : 0x01;
1963 if (InData & InMask)
1964 LineData |= 0x80000000;
1970 if ((LineDataLen >= T4_EOL_BITSIZE) &&
1971 ((LineData & T4_EOL_MASK_DWORD) == T4_EOL_DWORD)) {
1973 if (LineDataLen > T4_EOL_BITSIZE) {
1975 ((LineData & ~T4_EOL_MASK_DWORD) >>
1976 (32 - LineDataLen));
1978 if (! chan->fax2.NullByteExist) {
1979 chan->fax2.NullBytesPos = LineBuf.Len;
1980 chan->fax2.NullByteExist = 1;
1983 chan->fax2.NullByteExist = 0;
1985 if (LineBuf.Len < LineBuf.Size) {
1986 *LineBuf.Next++ = Byte;
1993 if (LineDataLen >= T4_EOL_BITSIZE + 8) {
1995 ((LineData & ~T4_EOL_MASK_DWORD) >>
1996 (32 - T4_EOL_BITSIZE - 8));
1997 LineData &= T4_EOL_MASK_DWORD;
1998 LineDataLen = T4_EOL_BITSIZE;
2000 if (! chan->fax2.NullByteExist) {
2001 chan->fax2.NullBytesPos = LineBuf.Len;
2002 chan->fax2.NullByteExist = 1;
2005 chan->fax2.NullByteExist = 0;
2007 if (LineBuf.Len < LineBuf.Size) {
2008 *LineBuf.Next++ = Byte;
2013 if (Event != EVENT_NONE)
2017 if ((Event != EVENT_EOL) && (Event != EVENT_EOP))
2020 if ((Event == EVENT_EOP) && (LineDataLen > 0)) {
2021 LineData >>= 32 - LineDataLen;
2023 while (LineData != 0) {
2024 Byte = (__u8) LineData;
2027 if (! chan->fax2.NullByteExist) {
2028 chan->fax2.NullBytesPos = LineBuf.Len;
2029 chan->fax2.NullByteExist = 1;
2032 chan->fax2.NullByteExist = 0;
2034 if (LineBuf.Len < LineBuf.Size) {
2035 *LineBuf.Next++ = Byte;
2041 if (chan->fax2.NullByteExist) {
2042 if (chan->fax2.NullBytesPos == 0) {
2045 LineBuf.Len = chan->fax2.NullBytesPos + 1;
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);
2052 if (LineBuf.Len <= 216) {
2053 *OutBuf.Next++ = (__u8) LineBuf.Len;
2057 *(__u16 *) OutBuf.Next = (__u16) LineBuf.Len;
2058 OutBuf.Next += sizeof(__u16);
2061 memcpy(OutBuf.Next, LineBuf.Data, LineBuf.Len);
2062 OutBuf.Next += LineBuf.Len;
2063 OutBuf.Len += LineBuf.Len;
2066 LineBuf.Next = LineBuf.Data;
2067 chan->fax2.NullByteExist = 0;
2068 if (Event == EVENT_EOP)
2074 if (Event == EVENT_EOP) {
2076 chan->fax2.PageCount++;
2077 cmd.driver = ccard->myid;
2078 cmd.command = ISDN_STAT_FAXIND;
2080 chan->fax->r_code = ISDN_TTY_FAX_EOP;
2081 ccard->interface.statcallb(&cmd);
2083 if (OutBuf.Len > 0) {
2084 ret = idi_fax_send_outbuf(ccard, chan, &OutBuf);
2087 chan->fax2.LineLen = LineBuf.Len;
2088 chan->fax2.LineData = LineData;
2089 chan->fax2.LineDataLen = LineDataLen;
2104 idi_fax_hangup(eicon_card *ccard, eicon_chan *chan)
2109 eicon_log(ccard, 1, "idi_fax: hangup with NULL fax struct, ERROR\n");
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;
2117 chan->fax->r_code = ISDN_TTY_FAX_PTS;
2118 ccard->interface.statcallb(&cmd);
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;
2127 ccard->interface.statcallb(&cmd);
2130 #endif /******** FAX ********/
2133 idi_send_udata(eicon_card *card, eicon_chan *chan, int UReq, u_char *buffer, int len)
2135 struct sk_buff *skb;
2136 struct sk_buff *skb2;
2138 eicon_chan_ptr *chan2;
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);
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]);
2147 skb = alloc_skb(sizeof(eicon_REQ) + len + 1, GFP_ATOMIC);
2148 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
2150 if ((!skb) || (!skb2)) {
2151 eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_udata()\n", chan->No);
2155 dev_kfree_skb(skb2);
2159 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
2162 reqbuf = (eicon_REQ *)skb_put(skb, 1 + len + sizeof(eicon_REQ));
2164 reqbuf->Req = N_UDATA;
2165 reqbuf->ReqCh = chan->e.IndCh;
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 */
2173 skb_queue_tail(&chan->e.X, skb);
2174 skb_queue_tail(&card->sndq, skb2);
2175 eicon_schedule_tx(card);
2180 idi_audio_cmd(eicon_card *ccard, eicon_chan *chan, int cmd, u_char *value)
2183 struct enable_dtmf_s *dtmf_buf = (struct enable_dtmf_s *)buf;
2185 if ((!ccard) || (!chan))
2190 case ISDN_AUDIO_SETDD:
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,
2198 idi_send_udata(ccard, chan,
2199 DSP_UDATA_REQUEST_DISABLE_DTMF_RECEIVER,
2207 idi_parse_udata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len)
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'
2222 if ((!ccard) || (!chan))
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);
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);
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;
2240 sprintf(cmd.parm.num, "%d/(%d)", p->speed, p->norm);
2242 sprintf(cmd.parm.num, "%d/%s", p->speed, connmsg[p->norm]);
2244 ccard->interface.statcallb(&cmd);
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);
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);
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);
2258 case DSP_UDATA_INDICATION_DISCONNECT:
2259 eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DISCONNECT cause %d\n", chan->No, buffer[1]);
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]];
2269 ccard->interface.statcallb(&cmd);
2272 eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED UDATA Indication 0x%02x\n", chan->No, buffer[0]);
2277 eicon_parse_trace(eicon_card *ccard, unsigned char *buffer, int len)
2280 int buflen = len * 3 + 30;
2284 unsigned short size;
2285 unsigned short code;
2286 unsigned char data[1];
2289 if (!(p = kmalloc(buflen, GFP_ATOMIC))) {
2290 eicon_log(ccard, 1, "idi_err: Ch??: could not allocate trace buffer\n");
2293 memset(p, 0, buflen);
2294 q = (struct trace_s *)buffer;
2296 if (DebugVar & 512) {
2297 if ((q->code == 3) || (q->code == 4)) {
2298 n = (short) *(q->data);
2300 j = sprintf(p, "DTRC:");
2301 for (i = 0; i < n; i++) {
2302 j += sprintf(p + j, "%02x ", q->data[i+2]);
2304 j += sprintf(p + j, "\n");
2308 j = sprintf(p, "XLOG: %lx %04x %04x ",
2309 q->time, q->size, q->code);
2311 for (i = 0; i < q->size; i++) {
2312 j += sprintf(p + j, "%02x ", q->data[i]);
2314 j += sprintf(p + j, "\n");
2317 eicon_putstatus(ccard, p);
2322 idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
2329 struct sk_buff *skb2;
2330 eicon_IND *ind = (eicon_IND *)skb->data;
2332 idi_ind_message message;
2336 eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ind\n");
2341 if ((chan = ccard->IdTable[ind->IndId]) == NULL) {
2342 eicon_log(ccard, 1, "idi_err: Ch??: null chan in handle_ind\n");
2347 if ((ind->Ind != 8) && (ind->Ind != 0xc))
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);
2357 if (chan->e.D3Id == ind->IndId) {
2358 idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
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);
2365 spin_lock_irqsave(&eicon_lock, flags);
2370 spin_unlock_irqrestore(&eicon_lock, flags);
2371 if (message.e_cau[0] & 0x7f) {
2372 cmd.driver = ccard->myid;
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);
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;
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);
2401 chan->fsm_state = EICON_STATE_NULL;
2402 cmd.driver = ccard->myid;
2404 cmd.command = ISDN_STAT_DHUP;
2405 ccard->interface.statcallb(&cmd);
2406 eicon_idi_listen_req(ccard, chan);
2407 #ifdef CONFIG_ISDN_TTY_FAX
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);
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;
2433 cmd.parm.setup.si1 = chan->si1;
2434 cmd.parm.setup.si2 = chan->si2;
2435 strcpy(tnum, chan->cpn);
2436 if (strlen(chan->dsa)) {
2438 strcat(tnum, chan->dsa);
2440 tnum[ISDN_MSNLEN - 1] = 0;
2441 strcpy(cmd.parm.setup.eazmsn, tnum);
2442 strcpy(tnum, chan->oad);
2443 if (strlen(chan->osa)) {
2445 strcat(tnum, chan->osa);
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);
2453 case 0: /* no user responding */
2454 idi_do_req(ccard, chan, HANGUP, 0);
2455 chan->fsm_state = EICON_STATE_NULL;
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);
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);
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;
2475 eicon_log(ccard, 8, "idi_ind: Ch%d: Info_Ind\n", chan->No);
2476 if ((chan->fsm_state == EICON_STATE_ICALLW) &&
2478 strcat(chan->cpn, message.cpn + 1);
2479 goto try_stat_icall_again;
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;
2489 ccard->interface.statcallb(&cmd);
2490 switch(chan->l2prot) {
2491 case ISDN_PROTO_L2_FAX:
2492 #ifdef CONFIG_ISDN_TTY_FAX
2494 chan->fax->phase = ISDN_FAX_PHASE_A;
2497 case ISDN_PROTO_L2_MODEM:
2498 /* do nothing, wait for connect */
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);
2507 /* On most incoming calls we use automatic connect */
2508 /* idi_do_req(ccard, chan, N_CONNECT, 1); */
2511 if (chan->fsm_state != EICON_STATE_ACTIVE)
2512 idi_hangup(ccard, chan);
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 */
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);
2524 #ifdef CONFIG_ISDN_TTY_FAX
2525 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
2527 chan->fax->phase = ISDN_FAX_PHASE_A;
2529 eicon_log(ccard, 1, "idi_ind: Call_Con with NULL fax struct, ERROR\n");
2530 idi_hangup(ccard, chan);
2535 chan->fsm_state = EICON_STATE_OBWAIT;
2536 cmd.driver = ccard->myid;
2537 cmd.command = ISDN_STAT_DCONN;
2539 ccard->interface.statcallb(&cmd);
2541 idi_do_req(ccard, chan, ASSIGN, 1);
2542 idi_do_req(ccard, chan, N_CONNECT, 1);
2544 idi_hangup(ccard, chan);
2547 eicon_log(ccard, 8, "idi_ind: Ch%d: Advice of Charge\n", chan->No);
2550 chan->statectrl |= IN_HOLD;
2551 eicon_log(ccard, 8, "idi_ind: Ch%d: Call Hold Ack\n", chan->No);
2554 eicon_log(ccard, 8, "idi_ind: Ch%d: Suspend Rejected\n", chan->No);
2557 eicon_log(ccard, 8, "idi_ind: Ch%d: Suspend Ack\n", chan->No);
2560 eicon_log(ccard, 8, "idi_ind: Ch%d: Resume Ack\n", chan->No);
2563 eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED SigIndication 0x%02x\n", chan->No, ind->Ind);
2567 else if (chan->e.B2Id == ind->IndId) {
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);
2574 idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
2575 chan->fsm_state = 1;
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;
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);
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;
2596 chan->fax->r_code = ISDN_TTY_FAX_DCS;
2597 ccard->interface.statcallb(&cmd);
2601 eicon_log(ccard, 1, "idi_ind: N_Connect_Ack with NULL fax struct, ERROR\n");
2606 chan->fsm_state = EICON_STATE_ACTIVE;
2607 cmd.driver = ccard->myid;
2608 cmd.command = ISDN_STAT_BCONN;
2610 strcpy(cmd.parm.num, "64000");
2611 ccard->interface.statcallb(&cmd);
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) {
2620 if (chan->l2prot == ISDN_PROTO_L2_MODEM) {
2621 chan->fsm_state = EICON_STATE_WMCONN;
2624 chan->fsm_state = EICON_STATE_ACTIVE;
2625 cmd.driver = ccard->myid;
2626 cmd.command = ISDN_STAT_BCONN;
2628 strcpy(cmd.parm.num, "64000");
2629 ccard->interface.statcallb(&cmd);
2632 eicon_log(ccard, 16, "idi_ind: Ch%d: N_Disc\n", chan->No);
2634 while((skb2 = skb_dequeue(&chan->e.X))) {
2635 dev_kfree_skb(skb2);
2637 idi_do_req(ccard, chan, N_DISC_ACK, 1);
2638 idi_do_req(ccard, chan, REMOVE, 1);
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);
2647 spin_lock_irqsave(&eicon_lock, flags);
2652 spin_unlock_irqrestore(&eicon_lock, flags);
2653 if (!(chan->statectrl & IN_HOLD)) {
2654 idi_do_req(ccard, chan, HANGUP, 0);
2656 if (chan->fsm_state == EICON_STATE_ACTIVE) {
2657 cmd.driver = ccard->myid;
2658 cmd.command = ISDN_STAT_BHUP;
2660 ccard->interface.statcallb(&cmd);
2661 chan->fsm_state = EICON_STATE_NULL;
2662 if (!(chan->statectrl & IN_HOLD)) {
2663 chan->statectrl |= WAITING_FOR_HANGUP;
2666 #ifdef CONFIG_ISDN_TTY_FAX
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);
2680 eicon_log(ccard, 128, "idi_ind: Ch%d: N_Data_Ack\n", chan->No);
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);
2690 ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb);
2695 idi_parse_udata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2697 #ifdef CONFIG_ISDN_TTY_FAX
2699 idi_edata_action(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
2703 eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED NetIndication 0x%02x\n", chan->No, ind->Ind);
2707 eicon_log(ccard, 1, "idi_ind: Ch%d: Ind is neither SIG nor NET !\n", chan->No);
2714 idi_handle_ack_ok(eicon_card *ccard, eicon_chan *chan, eicon_RC *ack)
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);
2729 /* Management Interface */
2730 if (chan->No == ccard->nchannels) {
2731 /* Managementinterface: changing state */
2732 if (chan->e.Req != 0x02)
2733 chan->fsm_state = 1;
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);
2743 spin_lock_irqsave(&eicon_lock, flags);
2744 ccard->IdTable[ack->RcId] = NULL;
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");
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);
2761 switch(chan->e.Req & 0x0f) {
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);
2769 tqueued = chan->queued;
2770 twaitpq = chan->waitpq;
2771 if ((chan->e.Req & 0x0f) == N_DATA) {
2772 spin_lock_irqsave(&eicon_lock, flags);
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) &&
2783 cmd.driver = ccard->myid;
2784 cmd.command = ISDN_STAT_FAXIND;
2786 chan->fax->r_code = ISDN_TTY_FAX_SENT;
2787 ccard->interface.statcallb(&cmd);
2790 eicon_log(ccard, 1, "idi_ack: Sent with NULL fax struct, ERROR\n");
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;
2804 cmd.parm.length = twaitpq;
2805 ccard->interface.statcallb(&cmd);
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);
2817 idi_handle_ack(eicon_card *ccard, struct sk_buff *skb)
2821 eicon_RC *ack = (eicon_RC *)skb->data;
2827 eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ack\n");
2832 spin_lock_irqsave(&eicon_lock, flags);
2833 if ((chan = ccard->IdTable[ack->RcId]) != NULL)
2835 spin_unlock_irqrestore(&eicon_lock, flags);
2839 case N_FLOW_CONTROL:
2841 eicon_log(ccard, 1, "idi_ack: Ch%d: unhandled RC 0x%x\n",
2846 /* we do nothing here */
2851 eicon_log(ccard, 1, "idi_ack: Ch%d: OK on chan without Id\n", dCh);
2854 if (!idi_handle_ack_ok(ccard, chan, ack))
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);
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;
2870 ccard->bch[j].e.B2Id = ack->RcId;
2871 ccard->IdTable[ack->RcId] = &ccard->bch[j];
2872 chan = &ccard->bch[j];
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);
2885 case OUT_OF_RESOURCES:
2886 case UNKNOWN_COMMAND:
2895 eicon_log(ccard, 1, "idi_ack: Ch%d: Not OK !! on chan without Id\n", dCh);
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);
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);
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;
2919 ccard->interface.statcallb(&cmd);
2922 spin_lock_irqsave(&eicon_lock, flags);
2927 spin_unlock_irqrestore(&eicon_lock, flags);
2929 eicon_schedule_tx(ccard);
2933 idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb, int que, int chk)
2935 struct sk_buff *xmit_skb;
2936 struct sk_buff *skb2;
2938 eicon_chan_ptr *chan2;
2939 int len, plen = 0, offset = 0;
2940 unsigned long flags;
2942 if ((!card) || (!chan)) {
2943 eicon_log(card, 1, "idi_err: Ch??: null card/chan in send_data\n");
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);
2953 if (len > EICON_MAX_QUEUE) /* too much for the shared memory */
2958 if ((chk) && (chan->pqueued > 1))
2961 eicon_log(card, 128, "idi_snd: Ch%d: %d bytes (Pqueue=%d)\n",
2962 chan->No, len, chan->pqueued);
2964 spin_lock_irqsave(&eicon_lock, flags);
2965 while(offset < len) {
2967 plen = ((len - offset) > 270) ? 270 : len - offset;
2969 xmit_skb = alloc_skb(plen + sizeof(eicon_REQ), GFP_ATOMIC);
2970 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
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);
2978 dev_kfree_skb(skb2);
2982 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
2985 reqbuf = (eicon_REQ *)skb_put(xmit_skb, plen + sizeof(eicon_REQ));
2986 if ((len - offset) > 270) {
2987 reqbuf->Req = N_MDATA;
2989 reqbuf->Req = N_DATA;
2990 /* if (ack) reqbuf->Req |= N_D_BIT; */
2992 reqbuf->ReqCh = chan->e.IndCh;
2994 memcpy(&reqbuf->XBuffer.P, skb->data + offset, plen);
2995 reqbuf->XBuffer.length = plen;
2996 reqbuf->Reference = 1; /* Net Entity */
2998 skb_queue_tail(&chan->e.X, xmit_skb);
2999 skb_queue_tail(&card->sndq, skb2);
3004 chan->queued += len;
3007 spin_unlock_irqrestore(&eicon_lock, flags);
3008 eicon_schedule_tx(card);
3015 eicon_idi_manage_assign(eicon_card *card)
3017 struct sk_buff *skb;
3018 struct sk_buff *skb2;
3021 eicon_chan_ptr *chan2;
3023 chan = &(card->bch[card->nchannels]);
3025 skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
3026 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
3028 if ((!skb) || (!skb2)) {
3029 eicon_log(card, 1, "idi_err: alloc_skb failed in manage_assign()\n");
3033 dev_kfree_skb(skb2);
3037 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
3040 reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
3042 reqbuf->XBuffer.P[0] = 0;
3043 reqbuf->Req = ASSIGN;
3045 reqbuf->ReqId = MAN_ID;
3046 reqbuf->XBuffer.length = 1;
3047 reqbuf->Reference = 2; /* Man Entity */
3049 skb_queue_tail(&chan->e.X, skb);
3050 skb_queue_tail(&card->sndq, skb2);
3051 eicon_schedule_tx(card);
3057 eicon_idi_manage_remove(eicon_card *card)
3059 struct sk_buff *skb;
3060 struct sk_buff *skb2;
3063 eicon_chan_ptr *chan2;
3065 chan = &(card->bch[card->nchannels]);
3067 skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
3068 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
3070 if ((!skb) || (!skb2)) {
3071 eicon_log(card, 1, "idi_err: alloc_skb failed in manage_remove()\n");
3075 dev_kfree_skb(skb2);
3079 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
3082 reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
3084 reqbuf->Req = REMOVE;
3087 reqbuf->XBuffer.length = 0;
3088 reqbuf->Reference = 2; /* Man Entity */
3090 skb_queue_tail(&chan->e.X, skb);
3091 skb_queue_tail(&card->sndq, skb2);
3092 eicon_schedule_tx(card);
3098 eicon_idi_manage(eicon_card *card, eicon_manifbuf *mb)
3104 struct sk_buff *skb;
3105 struct sk_buff *skb2;
3108 eicon_chan_ptr *chan2;
3110 chan = &(card->bch[card->nchannels]);
3112 if (!(chan->e.D3Id)) {
3114 while((skb2 = skb_dequeue(&chan->e.X)))
3115 dev_kfree_skb(skb2);
3118 if ((ret = eicon_idi_manage_assign(card))) {
3123 timeout = jiffies + HZ / 2;
3124 while (time_before(jiffies, timeout)) {
3125 if (chan->e.B2Id) break;
3128 if (!chan->e.B2Id) {
3134 chan->fsm_state = 0;
3136 if (!(manbuf = kmalloc(sizeof(eicon_manifbuf), GFP_KERNEL))) {
3137 eicon_log(card, 1, "idi_err: alloc_manifbuf failed\n");
3140 if (copy_from_user(manbuf, mb, sizeof(eicon_manifbuf))) {
3145 skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
3146 skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
3148 if ((!skb) || (!skb2)) {
3149 eicon_log(card, 1, "idi_err_manif: alloc_skb failed in manage()\n");
3153 dev_kfree_skb(skb2);
3158 chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
3161 reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
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;
3170 reqbuf->XBuffer.P[l++] = 0;
3171 reqbuf->Req = (manbuf->count) ? manbuf->count : MAN_READ;
3174 reqbuf->XBuffer.length = l;
3175 reqbuf->Reference = 2; /* Man Entity */
3177 skb_queue_tail(&chan->e.X, skb);
3178 skb_queue_tail(&card->sndq, skb2);
3183 eicon_schedule_tx(card);
3185 timeout = jiffies + HZ / 2;
3186 while (time_before(jiffies, timeout)) {
3187 if (chan->fsm_state) break;
3190 if ((!chan->fsm_state) || (chan->fsm_state == 2)) {
3194 if (copy_to_user(mb, manbuf, sizeof(eicon_manifbuf))) {