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