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