OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [isdn/] [hisax/] [l3dss1.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* $Id: l3dss1.c,v 1.1 2005-12-20 10:17:01 jcastillo Exp $
2
 
3
 * EURO/DSS1 D-channel protocol
4
 *
5
 * Author       Karsten Keil (keil@temic-ech.spacenet.de)
6
 *              based on the teles driver from Jan den Ouden
7
 *
8
 *              This file is (c) under GNU PUBLIC LICENSE
9
 *              For changes and modifications please read
10
 *              ../../../Documentation/isdn/HiSax.cert
11
 *
12
 * Thanks to    Jan den Ouden
13
 *              Fritz Elfert
14
 *
15
 * $Log: not supported by cvs2svn $
16
 * Revision 1.1.1.1  2001/09/10 07:44:18  simons
17
 * Initial import
18
 *
19
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
20
 * Initial revision
21
 *
22
 * Revision 1.16.2.8  1998/11/03 00:07:14  keil
23
 * certification related changes
24
 * fixed logging for smaller stack use
25
 *
26
 * Revision 1.16.2.7  1998/10/25 18:16:25  fritz
27
 * Replaced some read-only variables by defines.
28
 *
29
 * Revision 1.16.2.6  1998/10/23 15:00:56  fritz
30
 * Eliminated a compiler warning.
31
 *
32
 * Revision 1.16.2.5  1998/09/27 13:06:48  keil
33
 * Apply most changes from 2.1.X (HiSax 3.1)
34
 *
35
 * Revision 1.16.2.4  1998/05/27 18:06:08  keil
36
 * HiSax 3.0
37
 *
38
 * Revision 1.16.2.3  1998/02/03 23:16:06  keil
39
 * german AOC
40
 *
41
 * Revision 1.16.2.2  1997/11/15 18:54:15  keil
42
 * cosmetics
43
 *
44
 * Revision 1.16.2.1  1997/10/17 22:14:16  keil
45
 * update to last hisax version
46
 *
47
 * Revision 2.2  1997/08/07 17:44:36  keil
48
 * Fix RESTART
49
 *
50
 * Revision 2.1  1997/08/03 14:36:33  keil
51
 * Implement RESTART procedure
52
 *
53
 * Revision 2.0  1997/07/27 21:15:43  keil
54
 * New Callref based layer3
55
 *
56
 * Revision 1.17  1997/06/26 11:11:46  keil
57
 * SET_SKBFREE now on creation of a SKB
58
 *
59
 * Revision 1.15  1997/04/17 11:50:48  keil
60
 * pa->loc was undefined, if it was not send by the exchange
61
 *
62
 * Old log removed /KKe
63
 *
64
 */
65
 
66
#define __NO_VERSION__
67
#include "hisax.h"
68
#include "isdnl3.h"
69
#include "l3dss1.h"
70
#include <linux/ctype.h>
71
 
72
extern char *HiSax_getrev(const char *revision);
73
const char *dss1_revision = "$Revision: 1.1 $";
74
 
75
#define EXT_BEARER_CAPS 1
76
 
77
#define MsgHead(ptr, cref, mty) \
78
        *ptr++ = 0x8; \
79
        *ptr++ = 0x1; \
80
        *ptr++ = cref^0x80; \
81
        *ptr++ = mty
82
 
83
 
84
#if HISAX_DE_AOC
85
static void
86
l3dss1_parse_facility(struct l3_process *pc, u_char * p)
87
{
88
        int qd_len = 0;
89
 
90
        p++;
91
        qd_len = *p++;
92
        if (qd_len == 0) {
93
                l3_debug(pc->st, "qd_len == 0");
94
                return;
95
        }
96
        if ((*p & 0x1F) != 0x11) {      /* Service discriminator, supplementary service */
97
                l3_debug(pc->st, "supplementary service != 0x11");
98
                return;
99
        }
100
        while (qd_len > 0 && !(*p & 0x80)) {     /* extension ? */
101
                p++;
102
                qd_len--;
103
        }
104
        if (qd_len < 2) {
105
                l3_debug(pc->st, "qd_len < 2");
106
                return;
107
        }
108
        p++;
109
        qd_len--;
110
        if ((*p & 0xE0) != 0xA0) {      /* class and form */
111
                l3_debug(pc->st, "class and form != 0xA0");
112
                return;
113
        }
114
        switch (*p & 0x1F) {    /* component tag */
115
                case 1: /* invoke */
116
                        {
117
                                unsigned char nlen = 0, ilen;
118
                                int ident;
119
 
120
                                p++;
121
                                qd_len--;
122
                                if (qd_len < 1) {
123
                                        l3_debug(pc->st, "qd_len < 1");
124
                                        break;
125
                                }
126
                                if (*p & 0x80) {        /* length format */
127
                                        l3_debug(pc->st, "*p & 0x80 length format");
128
                                        break;
129
                                }
130
                                nlen = *p++;
131
                                qd_len--;
132
                                if (qd_len < nlen) {
133
                                        l3_debug(pc->st, "qd_len < nlen");
134
                                        return;
135
                                }
136
                                qd_len -= nlen;
137
 
138
                                if (nlen < 2) {
139
                                        l3_debug(pc->st, "nlen < 2");
140
                                        return;
141
                                }
142
                                if (*p != 0x02) {       /* invoke identifier tag */
143
                                        l3_debug(pc->st, "invoke identifier tag !=0x02");
144
                                        return;
145
                                }
146
                                p++;
147
                                nlen--;
148
                                if (*p & 0x80) {        /* length format */
149
                                        l3_debug(pc->st, "*p & 0x80 length format 2");
150
                                        break;
151
                                }
152
                                ilen = *p++;
153
                                nlen--;
154
                                if (ilen > nlen || ilen == 0) {
155
                                        l3_debug(pc->st, "ilen > nlen || ilen == 0");
156
                                        return;
157
                                }
158
                                nlen -= ilen;
159
                                ident = 0;
160
                                while (ilen > 0) {
161
                                        ident = (ident << 8) | (*p++ & 0xFF);   /* invoke identifier */
162
                                        ilen--;
163
                                }
164
 
165
                                if (nlen < 2) {
166
                                        l3_debug(pc->st, "nlen < 2 22");
167
                                        return;
168
                                }
169
                                if (*p != 0x02) {       /* operation value */
170
                                        l3_debug(pc->st, "operation value !=0x02");
171
                                        return;
172
                                }
173
                                p++;
174
                                nlen--;
175
                                ilen = *p++;
176
                                nlen--;
177
                                if (ilen > nlen || ilen == 0) {
178
                                        l3_debug(pc->st, "ilen > nlen || ilen == 0 22");
179
                                        return;
180
                                }
181
                                nlen -= ilen;
182
                                ident = 0;
183
                                while (ilen > 0) {
184
                                        ident = (ident << 8) | (*p++ & 0xFF);
185
                                        ilen--;
186
                                }
187
 
188
#define FOO1(s,a,b) \
189
            while(nlen > 1) {           \
190
                    int ilen = p[1];    \
191
                    if(nlen < ilen+2) { \
192
                            l3_debug(pc->st, "FOO1  nlen < ilen+2"); \
193
                            return;             \
194
                    }                   \
195
                    nlen -= ilen+2;             \
196
                    if((*p & 0xFF) == (a)) {    \
197
                            int nlen = ilen;    \
198
                            p += 2;             \
199
                            b;          \
200
                    } else {            \
201
                            p += ilen+2;        \
202
                    }                   \
203
            }
204
 
205
                                switch (ident) {
206
                                        default:
207
                                                break;
208
                                        case 0x22:      /* during */
209
                                                FOO1("1A", 0x30, FOO1("1C", 0xA1, FOO1("1D", 0x30, FOO1("1E", 0x02, ( {
210
                                                               ident = 0;
211
                                                        nlen = (nlen)?nlen:0; /* Make gcc happy */
212
                                                        while (ilen > 0) {
213
                                                                                                                     ident = (ident << 8) | *p++;
214
                                                                  ilen--;
215
                                                                        }
216
                                                                                                                     if (ident > pc->para.chargeinfo) {
217
                                                                                                                     pc->para.chargeinfo = ident;
218
                                                                                                                     pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);
219
                                                                        }
220
                                                                                                                     if (pc->st->l3.debug & L3_DEB_CHARGE) {
221
                                                                                                                     if (*(p + 2) == 0) {
222
                                                                                                                     l3_debug(pc->st, "charging info during %d", pc->para.chargeinfo);
223
                                                                        }
224
                                                                   else {
225
                                                                                                                     l3_debug(pc->st, "charging info final %d", pc->para.chargeinfo);
226
                                                                        }
227
                                                                        }
228
                                                                        }
229
                                                                    )))))
230
                                                        break;
231
                                        case 0x24:      /* final */
232
                                                FOO1("2A", 0x30, FOO1("2B", 0x30, FOO1("2C", 0xA1, FOO1("2D", 0x30, FOO1("2E", 0x02, ( {
233
                                                               ident = 0;
234
                                                        nlen = (nlen)?nlen:0; /* Make gcc happy */
235
                                                        while (ilen > 0) {
236
                                                                                                                                      ident = (ident << 8) | *p++;
237
                                                                  ilen--;
238
                                                                        }
239
                                                                                                                                      if (ident > pc->para.chargeinfo) {
240
                                                                                                                                      pc->para.chargeinfo = ident;
241
                                                                                                                                      pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);
242
                                                                        }
243
                                                                                                                                      if (pc->st->l3.debug & L3_DEB_CHARGE) {
244
                                                                                                                                      l3_debug(pc->st, "charging info final %d", pc->para.chargeinfo);
245
                                                                        }
246
                                                                        }
247
                                                                   ))))))
248
                                                        break;
249
                                }
250
#undef FOO1
251
 
252
                        }
253
                        break;
254
                case 2: /* return result */
255
                        l3_debug(pc->st, "return result break");
256
                        break;
257
                case 3: /* return error */
258
                        l3_debug(pc->st, "return error break");
259
                        break;
260
                default:
261
                        l3_debug(pc->st, "default break");
262
                        break;
263
        }
264
}
265
#endif
266
 
267
static int
268
l3dss1_check_messagetype_validity(int mt)
269
{
270
/* verify if a message type exists */
271
        switch (mt) {
272
                case MT_ALERTING:
273
                case MT_CALL_PROCEEDING:
274
                case MT_CONNECT:
275
                case MT_CONNECT_ACKNOWLEDGE:
276
                case MT_PROGRESS:
277
                case MT_SETUP:
278
                case MT_SETUP_ACKNOWLEDGE:
279
                case MT_RESUME:
280
                case MT_RESUME_ACKNOWLEDGE:
281
                case MT_RESUME_REJECT:
282
                case MT_SUSPEND:
283
                case MT_SUSPEND_ACKNOWLEDGE:
284
                case MT_SUSPEND_REJECT:
285
                case MT_USER_INFORMATION:
286
                case MT_DISCONNECT:
287
                case MT_RELEASE:
288
                case MT_RELEASE_COMPLETE:
289
                case MT_RESTART:
290
                case MT_RESTART_ACKNOWLEDGE:
291
                case MT_SEGMENT:
292
                case MT_CONGESTION_CONTROL:
293
                case MT_INFORMATION:
294
                case MT_FACILITY:
295
                case MT_NOTIFY:
296
                case MT_STATUS:
297
                case MT_STATUS_ENQUIRY:
298
                        return(1);
299
                default:
300
                        return(0);
301
        }
302
        return(0);
303
}
304
 
305
static void
306
l3dss1_message(struct l3_process *pc, u_char mt)
307
{
308
        struct sk_buff *skb;
309
        u_char *p;
310
 
311
        if (!(skb = l3_alloc_skb(4)))
312
                return;
313
        p = skb_put(skb, 4);
314
        MsgHead(p, pc->callref, mt);
315
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
316
}
317
 
318
static void
319
l3dss1_release_req(struct l3_process *pc, u_char pr, void *arg)
320
{
321
        StopAllL3Timer(pc);
322
        newl3state(pc, 19);
323
        l3dss1_message(pc, MT_RELEASE);
324
        L3AddTimer(&pc->timer, T308, CC_T308_1);
325
}
326
 
327
static void
328
l3dss1_release_cmpl(struct l3_process *pc, u_char pr, void *arg)
329
{
330
        u_char *p;
331
        struct sk_buff *skb = arg;
332
        int cause = -1;
333
 
334
        p = skb->data;
335
        pc->para.loc = 0;
336
        if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
337
                p++;
338
                if (*p++ == 2)
339
                        pc->para.loc = *p++;
340
                cause = *p & 0x7f;
341
        }
342
        dev_kfree_skb(skb, FREE_READ);
343
        StopAllL3Timer(pc);
344
        pc->para.cause = cause;
345
        newl3state(pc, 0);
346
        pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc);
347
        release_l3_process(pc);
348
}
349
 
350
#if EXT_BEARER_CAPS
351
 
352
u_char *
353
EncodeASyncParams(u_char * p, u_char si2)
354
{                               // 7c 06 88  90 21 42 00 bb
355
 
356
        p[0] = p[1] = 0;
357
        p[2] = 0x80;
358
        if (si2 & 32)           // 7 data bits
359
 
360
                p[2] += 16;
361
        else                    // 8 data bits
362
 
363
                p[2] += 24;
364
 
365
        if (si2 & 16)           // 2 stop bits
366
 
367
                p[2] += 96;
368
        else                    // 1 stop bit
369
 
370
                p[2] = 32;
371
 
372
        if (si2 & 8)            // even parity
373
 
374
                p[2] += 2;
375
        else                    // no parity
376
 
377
                p[2] += 3;
378
 
379
        switch (si2 & 0x07) {
380
                case 0:
381
                        p[0] = 66;       // 1200 bit/s
382
 
383
                        break;
384
                case 1:
385
                        p[0] = 88;       // 1200/75 bit/s
386
 
387
                        break;
388
                case 2:
389
                        p[0] = 87;       // 75/1200 bit/s
390
 
391
                        break;
392
                case 3:
393
                        p[0] = 67;       // 2400 bit/s
394
 
395
                        break;
396
                case 4:
397
                        p[0] = 69;       // 4800 bit/s
398
 
399
                        break;
400
                case 5:
401
                        p[0] = 72;       // 9600 bit/s
402
 
403
                        break;
404
                case 6:
405
                        p[0] = 73;       // 14400 bit/s
406
 
407
                        break;
408
                case 7:
409
                        p[0] = 75;       // 19200 bit/s
410
 
411
                        break;
412
        }
413
        return p + 3;
414
}
415
 
416
u_char
417
EncodeSyncParams(u_char si2, u_char ai)
418
{
419
 
420
        switch (si2) {
421
                case 0:
422
                        return ai + 2;  // 1200 bit/s
423
 
424
                case 1:
425
                        return ai + 24;         // 1200/75 bit/s
426
 
427
                case 2:
428
                        return ai + 23;         // 75/1200 bit/s
429
 
430
                case 3:
431
                        return ai + 3;  // 2400 bit/s
432
 
433
                case 4:
434
                        return ai + 5;  // 4800 bit/s
435
 
436
                case 5:
437
                        return ai + 8;  // 9600 bit/s
438
 
439
                case 6:
440
                        return ai + 9;  // 14400 bit/s
441
 
442
                case 7:
443
                        return ai + 11;         // 19200 bit/s
444
 
445
                case 8:
446
                        return ai + 14;         // 48000 bit/s
447
 
448
                case 9:
449
                        return ai + 15;         // 56000 bit/s
450
 
451
                case 15:
452
                        return ai + 40;         // negotiate bit/s
453
 
454
                default:
455
                        break;
456
        }
457
        return ai;
458
}
459
 
460
 
461
static u_char
462
DecodeASyncParams(u_char si2, u_char * p)
463
{
464
        u_char info;
465
 
466
        switch (p[5]) {
467
                case 66:        // 1200 bit/s
468
 
469
                        break;  // si2 don't change
470
 
471
                case 88:        // 1200/75 bit/s
472
 
473
                        si2 += 1;
474
                        break;
475
                case 87:        // 75/1200 bit/s
476
 
477
                        si2 += 2;
478
                        break;
479
                case 67:        // 2400 bit/s
480
 
481
                        si2 += 3;
482
                        break;
483
                case 69:        // 4800 bit/s
484
 
485
                        si2 += 4;
486
                        break;
487
                case 72:        // 9600 bit/s
488
 
489
                        si2 += 5;
490
                        break;
491
                case 73:        // 14400 bit/s
492
 
493
                        si2 += 6;
494
                        break;
495
                case 75:        // 19200 bit/s
496
 
497
                        si2 += 7;
498
                        break;
499
        }
500
 
501
        info = p[7] & 0x7f;
502
        if ((info & 16) && (!(info & 8)))       // 7 data bits
503
 
504
                si2 += 32;      // else 8 data bits
505
 
506
        if ((info & 96) == 96)  // 2 stop bits
507
 
508
                si2 += 16;      // else 1 stop bit
509
 
510
        if ((info & 2) && (!(info & 1)))        // even parity
511
 
512
                si2 += 8;       // else no parity
513
 
514
        return si2;
515
}
516
 
517
 
518
static u_char
519
DecodeSyncParams(u_char si2, u_char info)
520
{
521
        info &= 0x7f;
522
        switch (info) {
523
                case 40:        // bit/s negotiation failed  ai := 165 not 175!
524
 
525
                        return si2 + 15;
526
                case 15:        // 56000 bit/s failed, ai := 0 not 169 !
527
 
528
                        return si2 + 9;
529
                case 14:        // 48000 bit/s
530
 
531
                        return si2 + 8;
532
                case 11:        // 19200 bit/s
533
 
534
                        return si2 + 7;
535
                case 9: // 14400 bit/s
536
 
537
                        return si2 + 6;
538
                case 8: // 9600  bit/s
539
 
540
                        return si2 + 5;
541
                case 5: // 4800  bit/s
542
 
543
                        return si2 + 4;
544
                case 3: // 2400  bit/s
545
 
546
                        return si2 + 3;
547
                case 23:        // 75/1200 bit/s
548
 
549
                        return si2 + 2;
550
                case 24:        // 1200/75 bit/s
551
 
552
                        return si2 + 1;
553
                default:        // 1200 bit/s
554
 
555
                        return si2;
556
        }
557
}
558
 
559
static u_char
560
DecodeSI2(struct sk_buff *skb)
561
{
562
        u_char *p;              //, *pend=skb->data + skb->len;
563
 
564
        if ((p = findie(skb->data, skb->len, 0x7c, 0))) {
565
                switch (p[4] & 0x0f) {
566
                        case 0x01:
567
                                if (p[1] == 0x04)       // sync. Bitratenadaption
568
 
569
                                        return DecodeSyncParams(160, p[5]);     // V.110/X.30
570
 
571
                                else if (p[1] == 0x06)  // async. Bitratenadaption
572
 
573
                                        return DecodeASyncParams(192, p);       // V.110/X.30
574
 
575
                                break;
576
                        case 0x08:      // if (p[5] == 0x02) // sync. Bitratenadaption
577
 
578
                                return DecodeSyncParams(176, p[5]);     // V.120
579
 
580
                                break;
581
                }
582
        }
583
        return 0;
584
}
585
 
586
#endif
587
 
588
 
589
static void
590
l3dss1_setup_req(struct l3_process *pc, u_char pr,
591
                 void *arg)
592
{
593
        struct sk_buff *skb;
594
        u_char tmp[128];
595
        u_char *p = tmp;
596
        u_char channel = 0;
597
        u_char screen = 0x80;
598
        u_char *teln;
599
        u_char *msn;
600
        u_char *sub;
601
        u_char *sp;
602
        int l;
603
 
604
        MsgHead(p, pc->callref, MT_SETUP);
605
 
606
        /*
607
         * Set Bearer Capability, Map info from 1TR6-convention to EDSS1
608
         */
609
#if HISAX_EURO_SENDCOMPLETE
610
        *p++ = 0xa1;            /* complete indicator */
611
#endif
612
        switch (pc->para.setup.si1) {
613
                case 1: /* Telephony                               */
614
                        *p++ = 0x4;     /* BC-IE-code                              */
615
                        *p++ = 0x3;     /* Length                                  */
616
                        *p++ = 0x90;    /* Coding Std. CCITT, 3.1 kHz audio     */
617
                        *p++ = 0x90;    /* Circuit-Mode 64kbps                     */
618
                        *p++ = 0xa3;    /* A-Law Audio                             */
619
                        break;
620
                case 5: /* Datatransmission 64k, BTX               */
621
                case 7: /* Datatransmission 64k                    */
622
                default:
623
                        *p++ = 0x4;     /* BC-IE-code                              */
624
                        *p++ = 0x2;     /* Length                                  */
625
                        *p++ = 0x88;    /* Coding Std. CCITT, unrestr. dig. Inform. */
626
                        *p++ = 0x90;    /* Circuit-Mode 64kbps                      */
627
                        break;
628
        }
629
        /*
630
         * What about info2? Mapping to High-Layer-Compatibility?
631
         */
632
        teln = pc->para.setup.phone;
633
        if (*teln) {
634
                /* parse number for special things */
635
                if (!isdigit(*teln)) {
636
                        switch (0x5f & *teln) {
637
                                case 'C':
638
                                        channel = 0x08;
639
                                case 'P':
640
                                        channel |= 0x80;
641
                                        teln++;
642
                                        if (*teln == '1')
643
                                                channel |= 0x01;
644
                                        else
645
                                                channel |= 0x02;
646
                                        break;
647
                                case 'R':
648
                                        screen = 0xA0;
649
                                        break;
650
                                case 'D':
651
                                        screen = 0x80;
652
                                        break;
653
                                default:
654
                                        if (pc->debug & L3_DEB_WARN)
655
                                                l3_debug(pc->st, "Wrong MSN Code");
656
                                        break;
657
                        }
658
                        teln++;
659
                }
660
        }
661
        if (channel) {
662
                *p++ = IE_CHANNEL_ID;
663
                *p++ = 1;
664
                *p++ = channel;
665
        }
666
        msn = pc->para.setup.eazmsn;
667
        sub = NULL;
668
        sp = msn;
669
        while (*sp) {
670
                if ('.' == *sp) {
671
                        sub = sp;
672
                        *sp = 0;
673
                } else
674
                        sp++;
675
        }
676
        if (*msn) {
677
                *p++ = 0x6c;
678
                *p++ = strlen(msn) + (screen ? 2 : 1);
679
                /* Classify as AnyPref. */
680
                if (screen) {
681
                        *p++ = 0x01;    /* Ext = '0'B, Type = '000'B, Plan = '0001'B. */
682
                        *p++ = screen;
683
                } else
684
                        *p++ = 0x81;    /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
685
                while (*msn)
686
                        *p++ = *msn++ & 0x7f;
687
        }
688
        if (sub) {
689
                *sub++ = '.';
690
                *p++ = 0x6d;    /* Calling party subaddress */
691
                *p++ = strlen(sub) + 2;
692
                *p++ = 0x80;    /* NSAP coded */
693
                *p++ = 0x50;    /* local IDI format */
694
                while (*sub)
695
                        *p++ = *sub++ & 0x7f;
696
        }
697
        sub = NULL;
698
        sp = teln;
699
        while (*sp) {
700
                if ('.' == *sp) {
701
                        sub = sp;
702
                        *sp = 0;
703
                } else
704
                        sp++;
705
        }
706
        *p++ = 0x70;
707
        *p++ = strlen(teln) + 1;
708
        /* Classify as AnyPref. */
709
        *p++ = 0x81;            /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
710
        while (*teln)
711
                *p++ = *teln++ & 0x7f;
712
 
713
        if (sub) {
714
                *sub++ = '.';
715
                *p++ = 0x71;    /* Called party subaddress */
716
                *p++ = strlen(sub) + 2;
717
                *p++ = 0x80;    /* NSAP coded */
718
                *p++ = 0x50;    /* local IDI format */
719
                while (*sub)
720
                        *p++ = *sub++ & 0x7f;
721
        }
722
#if EXT_BEARER_CAPS
723
        if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) {       // sync. Bitratenadaption, V.110/X.30
724
 
725
                *p++ = 0x7c;
726
                *p++ = 0x04;
727
                *p++ = 0x88;
728
                *p++ = 0x90;
729
                *p++ = 0x21;
730
                *p++ = EncodeSyncParams(pc->para.setup.si2 - 160, 0x80);
731
        } else if ((pc->para.setup.si2 >= 176) && (pc->para.setup.si2 <= 191)) {        // sync. Bitratenadaption, V.120
732
 
733
                *p++ = 0x7c;
734
                *p++ = 0x05;
735
                *p++ = 0x88;
736
                *p++ = 0x90;
737
                *p++ = 0x28;
738
                *p++ = EncodeSyncParams(pc->para.setup.si2 - 176, 0);
739
                *p++ = 0x82;
740
        } else if (pc->para.setup.si2 >= 192) {         // async. Bitratenadaption, V.110/X.30
741
 
742
                *p++ = 0x7c;
743
                *p++ = 0x06;
744
                *p++ = 0x88;
745
                *p++ = 0x90;
746
                *p++ = 0x21;
747
                p = EncodeASyncParams(p, pc->para.setup.si2 - 192);
748
#if HISAX_SEND_STD_LLC_IE
749
        } else {
750
                *p++ = 0x7c;
751
                *p++ = 0x02;
752
                *p++ = 0x88;
753
                *p++ = 0x90;
754
#endif
755
        }
756
#endif
757
        l = p - tmp;
758
        if (!(skb = l3_alloc_skb(l)))
759
                return;
760
        memcpy(skb_put(skb, l), tmp, l);
761
        L3DelTimer(&pc->timer);
762
        L3AddTimer(&pc->timer, T303, CC_T303);
763
        newl3state(pc, 1);
764
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
765
}
766
 
767
static void
768
l3dss1_call_proc(struct l3_process *pc, u_char pr, void *arg)
769
{
770
        u_char *p;
771
        struct sk_buff *skb = arg;
772
 
773
        L3DelTimer(&pc->timer);
774
        p = skb->data;
775
        if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {
776
                pc->para.bchannel = p[2] & 0x3;
777
                if ((!pc->para.bchannel) && (pc->debug & L3_DEB_WARN))
778
                        l3_debug(pc->st, "setup answer without bchannel");
779
        } else if (pc->debug & L3_DEB_WARN)
780
                l3_debug(pc->st, "setup answer without bchannel");
781
        dev_kfree_skb(skb, FREE_READ);
782
        newl3state(pc, 3);
783
        L3AddTimer(&pc->timer, T310, CC_T310);
784
        pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc);
785
}
786
 
787
static void
788
l3dss1_setup_ack(struct l3_process *pc, u_char pr, void *arg)
789
{
790
        u_char *p;
791
        struct sk_buff *skb = arg;
792
 
793
        L3DelTimer(&pc->timer);
794
        p = skb->data;
795
        if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {
796
                pc->para.bchannel = p[2] & 0x3;
797
                if ((!pc->para.bchannel) && (pc->debug & L3_DEB_WARN))
798
                        l3_debug(pc->st, "setup answer without bchannel");
799
        } else if (pc->debug & L3_DEB_WARN)
800
                l3_debug(pc->st, "setup answer without bchannel");
801
        dev_kfree_skb(skb, FREE_READ);
802
        newl3state(pc, 2);
803
        L3AddTimer(&pc->timer, T304, CC_T304);
804
        pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);
805
}
806
 
807
static void
808
l3dss1_disconnect(struct l3_process *pc, u_char pr, void *arg)
809
{
810
        u_char *p;
811
        struct sk_buff *skb = arg;
812
        int cause = -1;
813
 
814
        StopAllL3Timer(pc);
815
        p = skb->data;
816
        pc->para.loc = 0;
817
        if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
818
                p++;
819
                if (*p++ == 2)
820
                        pc->para.loc = *p++;
821
                cause = *p & 0x7f;
822
        }
823
        dev_kfree_skb(skb, FREE_READ);
824
        newl3state(pc, 12);
825
        pc->para.cause = cause;
826
        pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);
827
}
828
 
829
static void
830
l3dss1_connect(struct l3_process *pc, u_char pr, void *arg)
831
{
832
        struct sk_buff *skb = arg;
833
 
834
        dev_kfree_skb(skb, FREE_READ);
835
        L3DelTimer(&pc->timer); /* T310 */
836
        newl3state(pc, 10);
837
        pc->para.chargeinfo = 0;
838
        pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc);
839
}
840
 
841
static void
842
l3dss1_alerting(struct l3_process *pc, u_char pr, void *arg)
843
{
844
        struct sk_buff *skb = arg;
845
 
846
        dev_kfree_skb(skb, FREE_READ);
847
        L3DelTimer(&pc->timer); /* T304 */
848
        newl3state(pc, 4);
849
        pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc);
850
}
851
 
852
static void
853
l3dss1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg)
854
{
855
        /* This routine is called if here was no SETUP made (checks in dss1up and in
856
         * l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code
857
         * MT_STATUS_ENQUIRE in the NULL state is handled too
858
         */
859
        u_char tmp[16];
860
        u_char *p = tmp;
861
        int l;
862
        struct sk_buff *skb;
863
 
864
        switch (pc->para.cause) {
865
                case 81:        /* 0x51 invalid callreference */
866
                case 88:        /* 0x58 incomp destination */
867
                case 96:        /* 0x60 mandory IE missing */
868
                case 101:       /* 0x65 incompatible Callstate */
869
                        MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
870
                        *p++ = IE_CAUSE;
871
                        *p++ = 0x2;
872
                        *p++ = 0x80;
873
                        *p++ = pc->para.cause | 0x80;
874
                        break;
875
                default:
876
                        printk(KERN_ERR "HiSax internal error l3dss1_msg_without_setup\n");
877
                        return;
878
        }
879
        l = p - tmp;
880
        if (!(skb = l3_alloc_skb(l)))
881
                return;
882
        memcpy(skb_put(skb, l), tmp, l);
883
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
884
        release_l3_process(pc);
885
}
886
 
887
static void
888
l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
889
{
890
        u_char *p, *ptmp[8];
891
        int i;
892
        int bcfound = 0;
893
        char tmp[80];
894
        struct sk_buff *skb = arg;
895
 
896
        /* ETS 300-104 1.3.4 and 1.3.5
897
         * we need to detect unknown inform. element from 0 to 7
898
         */
899
        p = skb->data;
900
        for (i = 0; i < 8; i++)
901
                ptmp[i] = skb->data;
902
        if (findie(ptmp[1], skb->len, 0x01, 0)
903
            || findie(ptmp[2], skb->len, 0x02, 0)
904
            || findie(ptmp[3], skb->len, 0x03, 0)
905
            || findie(ptmp[5], skb->len, 0x05, 0)
906
            || findie(ptmp[6], skb->len, 0x06, 0)
907
            || findie(ptmp[7], skb->len, 0x07, 0)) {
908
                /* if ie is < 8 and not 0 nor 4, send RELEASE_COMPLETE
909
                 * cause 0x60
910
                 */
911
                pc->para.cause = 0x60;
912
                dev_kfree_skb(skb, FREE_READ);
913
                l3dss1_msg_without_setup(pc, pr, NULL);
914
                return;
915
        }
916
        /*
917
         * Channel Identification
918
         */
919
        p = skb->data;
920
        if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {
921
                pc->para.bchannel = p[2] & 0x3;
922
                if (pc->para.bchannel)
923
                        bcfound++;
924
                else if (pc->debug & L3_DEB_WARN)
925
                        l3_debug(pc->st, "setup without bchannel");
926
        } else {
927
                if (pc->debug & L3_DEB_WARN)
928
                        l3_debug(pc->st, "setup without bchannel");
929
                pc->para.cause = 0x60;
930
                dev_kfree_skb(skb, FREE_READ);
931
                l3dss1_msg_without_setup(pc, pr, NULL);
932
                return;
933
        }
934
        /*
935
           * Bearer Capabilities
936
         */
937
        p = skb->data;
938
        if ((p = findie(p, skb->len, 0x04, 0))) {
939
                pc->para.setup.si2 = 0;
940
                switch (p[2] & 0x1f) {
941
                        case 0x00:
942
                                /* Speech */
943
                        case 0x10:
944
                                /* 3.1 Khz audio */
945
                                pc->para.setup.si1 = 1;
946
                                break;
947
                        case 0x08:
948
                                /* Unrestricted digital information */
949
                                pc->para.setup.si1 = 7;
950
/* JIM, 05.11.97 I wanna set service indicator 2 */
951
#if EXT_BEARER_CAPS
952
                                pc->para.setup.si2 = DecodeSI2(skb);
953
                                printk(KERN_DEBUG "HiSax: SI=%d, AI=%d\n",
954
                                 pc->para.setup.si1, pc->para.setup.si2);
955
#endif
956
                                break;
957
                        case 0x09:
958
                                /* Restricted digital information */
959
                                pc->para.setup.si1 = 2;
960
                                break;
961
                        case 0x11:
962
                                /* Unrestr. digital information  with tones/announcements */
963
                                pc->para.setup.si1 = 3;
964
                                break;
965
                        case 0x18:
966
                                /* Video */
967
                                pc->para.setup.si1 = 4;
968
                                break;
969
                        default:
970
                                pc->para.setup.si1 = 0;
971
                }
972
        } else {
973
                if (pc->debug & L3_DEB_WARN)
974
                        l3_debug(pc->st, "setup without bearer capabilities");
975
                /* ETS 300-104 1.3.3 */
976
                pc->para.cause = 0x60;
977
                dev_kfree_skb(skb, FREE_READ);
978
                l3dss1_msg_without_setup(pc, pr, NULL);
979
                return;
980
        }
981
 
982
        p = skb->data;
983
        if ((p = findie(p, skb->len, 0x70, 0)))
984
                iecpy(pc->para.setup.eazmsn, p, 1);
985
        else
986
                pc->para.setup.eazmsn[0] = 0;
987
 
988
        p = skb->data;
989
        if ((p = findie(p, skb->len, 0x71, 0))) {
990
                /* Called party subaddress */
991
                if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
992
                        tmp[0] = '.';
993
                        iecpy(&tmp[1], p, 2);
994
                        strcat(pc->para.setup.eazmsn, tmp);
995
                } else if (pc->debug & L3_DEB_WARN)
996
                        l3_debug(pc->st, "wrong called subaddress");
997
        }
998
        p = skb->data;
999
        if ((p = findie(p, skb->len, 0x6c, 0))) {
1000
                pc->para.setup.plan = p[2];
1001
                if (p[2] & 0x80) {
1002
                        iecpy(pc->para.setup.phone, p, 1);
1003
                        pc->para.setup.screen = 0;
1004
                } else {
1005
                        iecpy(pc->para.setup.phone, p, 2);
1006
                        pc->para.setup.screen = p[3];
1007
                }
1008
        } else {
1009
                pc->para.setup.phone[0] = 0;
1010
                pc->para.setup.plan = 0;
1011
                pc->para.setup.screen = 0;
1012
        }
1013
        p = skb->data;
1014
        if ((p = findie(p, skb->len, 0x6d, 0))) {
1015
                /* Calling party subaddress */
1016
                if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
1017
                        tmp[0] = '.';
1018
                        iecpy(&tmp[1], p, 2);
1019
                        strcat(pc->para.setup.phone, tmp);
1020
                } else if (pc->debug & L3_DEB_WARN)
1021
                        l3_debug(pc->st, "wrong calling subaddress");
1022
        }
1023
        dev_kfree_skb(skb, FREE_READ);
1024
 
1025
        if (bcfound) {
1026
                if ((pc->para.setup.si1 != 7) && (pc->debug & L3_DEB_WARN)) {
1027
                        l3_debug(pc->st, "non-digital call: %s -> %s",
1028
                            pc->para.setup.phone, pc->para.setup.eazmsn);
1029
                }
1030
                if ((pc->para.setup.si1 != 7) &&
1031
                    test_bit(FLG_PTP, &pc->st->l2.flag)) {
1032
                        pc->para.cause = 0x58;
1033
                        l3dss1_msg_without_setup(pc, pr, NULL);
1034
                        return;
1035
                }
1036
                newl3state(pc, 6);
1037
                pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc);
1038
        } else
1039
                release_l3_process(pc);
1040
}
1041
 
1042
static void
1043
l3dss1_reset(struct l3_process *pc, u_char pr, void *arg)
1044
{
1045
        release_l3_process(pc);
1046
}
1047
 
1048
static void
1049
l3dss1_setup_rsp(struct l3_process *pc, u_char pr,
1050
                 void *arg)
1051
{
1052
        newl3state(pc, 8);
1053
        l3dss1_message(pc, MT_CONNECT);
1054
        L3DelTimer(&pc->timer);
1055
        L3AddTimer(&pc->timer, T313, CC_T313);
1056
}
1057
 
1058
static void
1059
l3dss1_connect_ack(struct l3_process *pc, u_char pr, void *arg)
1060
{
1061
        struct sk_buff *skb = arg;
1062
 
1063
        dev_kfree_skb(skb, FREE_READ);
1064
        newl3state(pc, 10);
1065
        L3DelTimer(&pc->timer);
1066
        pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc);
1067
}
1068
 
1069
static void
1070
l3dss1_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
1071
{
1072
        struct sk_buff *skb;
1073
        u_char tmp[16];
1074
        u_char *p = tmp;
1075
        int l;
1076
        u_char cause = 0x10;
1077
 
1078
        if (pc->para.cause > 0)
1079
                cause = pc->para.cause;
1080
 
1081
        StopAllL3Timer(pc);
1082
 
1083
        MsgHead(p, pc->callref, MT_DISCONNECT);
1084
 
1085
        *p++ = IE_CAUSE;
1086
        *p++ = 0x2;
1087
        *p++ = 0x80;
1088
        *p++ = cause | 0x80;
1089
 
1090
        l = p - tmp;
1091
        if (!(skb = l3_alloc_skb(l)))
1092
                return;
1093
        memcpy(skb_put(skb, l), tmp, l);
1094
        newl3state(pc, 11);
1095
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
1096
        L3AddTimer(&pc->timer, T305, CC_T305);
1097
}
1098
 
1099
static void
1100
l3dss1_reject_req(struct l3_process *pc, u_char pr, void *arg)
1101
{
1102
        struct sk_buff *skb;
1103
        u_char tmp[16];
1104
        u_char *p = tmp;
1105
        int l;
1106
        u_char cause = 0x95;
1107
 
1108
        if (pc->para.cause > 0)
1109
                cause = pc->para.cause;
1110
 
1111
        MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
1112
 
1113
        *p++ = IE_CAUSE;
1114
        *p++ = 0x2;
1115
        *p++ = 0x80;
1116
        *p++ = cause;
1117
 
1118
        l = p - tmp;
1119
        if (!(skb = l3_alloc_skb(l)))
1120
                return;
1121
        memcpy(skb_put(skb, l), tmp, l);
1122
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
1123
        pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
1124
        newl3state(pc, 0);
1125
        release_l3_process(pc);
1126
}
1127
 
1128
static void
1129
l3dss1_release(struct l3_process *pc, u_char pr, void *arg)
1130
{
1131
        u_char *p;
1132
        struct sk_buff *skb = arg;
1133
        int cause = -1;
1134
 
1135
        p = skb->data;
1136
        if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
1137
                p++;
1138
                if (*p++ == 2)
1139
                        pc->para.loc = *p++;
1140
                cause = *p & 0x7f;
1141
        }
1142
        p = skb->data;
1143
        if ((p = findie(p, skb->len, IE_FACILITY, 0))) {
1144
#if HISAX_DE_AOC
1145
                l3dss1_parse_facility(pc, p);
1146
#else
1147
                p = NULL;
1148
#endif
1149
        }
1150
        dev_kfree_skb(skb, FREE_READ);
1151
        StopAllL3Timer(pc);
1152
        pc->para.cause = cause;
1153
        l3dss1_message(pc, MT_RELEASE_COMPLETE);
1154
        pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
1155
        newl3state(pc, 0);
1156
        release_l3_process(pc);
1157
}
1158
 
1159
static void
1160
l3dss1_alert_req(struct l3_process *pc, u_char pr,
1161
                 void *arg)
1162
{
1163
        newl3state(pc, 7);
1164
        l3dss1_message(pc, MT_ALERTING);
1165
}
1166
 
1167
static void
1168
l3dss1_status_enq(struct l3_process *pc, u_char pr, void *arg)
1169
{
1170
        u_char tmp[16];
1171
        u_char *p = tmp;
1172
        int l;
1173
        struct sk_buff *skb = arg;
1174
 
1175
        dev_kfree_skb(skb, FREE_READ);
1176
 
1177
        MsgHead(p, pc->callref, MT_STATUS);
1178
 
1179
        *p++ = IE_CAUSE;
1180
        *p++ = 0x2;
1181
        *p++ = 0x80;
1182
        *p++ = 0x9E;            /* answer status enquire */
1183
 
1184
        *p++ = 0x14;            /* CallState */
1185
        *p++ = 0x1;
1186
        *p++ = pc->state & 0x3f;
1187
 
1188
        l = p - tmp;
1189
        if (!(skb = l3_alloc_skb(l)))
1190
                return;
1191
        memcpy(skb_put(skb, l), tmp, l);
1192
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
1193
}
1194
 
1195
static void
1196
l3dss1_status_req(struct l3_process *pc, u_char pr, void *arg)
1197
{
1198
        /* ETS 300-104 7.4.1, 8.4.1, 10.3.1, 11.4.1, 12.4.1, 13.4.1, 14.4.1...
1199
           if setup has been made and a non expected message type is received, we must send MT_STATUS cause 0x62  */
1200
        u_char tmp[16];
1201
        u_char *p = tmp;
1202
        int l;
1203
        struct sk_buff *skb = arg;
1204
 
1205
        dev_kfree_skb(skb, FREE_READ);
1206
 
1207
        MsgHead(p, pc->callref, MT_STATUS);
1208
 
1209
        *p++ = IE_CAUSE;
1210
        *p++ = 0x2;
1211
        *p++ = 0x80;
1212
        *p++ = 0x62 | 0x80;     /* status sending */
1213
 
1214
        *p++ = 0x14;            /* CallState */
1215
        *p++ = 0x1;
1216
        *p++ = pc->state & 0x3f;
1217
 
1218
        l = p - tmp;
1219
        if (!(skb = l3_alloc_skb(l)))
1220
                return;
1221
        memcpy(skb_put(skb, l), tmp, l);
1222
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
1223
}
1224
 
1225
static void
1226
l3dss1_release_ind(struct l3_process *pc, u_char pr, void *arg)
1227
{
1228
        u_char *p;
1229
        struct sk_buff *skb = arg;
1230
        int callState = 0;
1231
        p = skb->data;
1232
 
1233
        if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) {
1234
                p++;
1235
                if (1 == *p++)
1236
                        callState = *p;
1237
        }
1238
        if (callState == 0) {
1239
                /* ETS 300-104 7.6.1, 8.6.1, 10.6.1... and 16.1
1240
                 * set down layer 3 without sending any message
1241
                 */
1242
                pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
1243
                newl3state(pc, 0);
1244
                release_l3_process(pc);
1245
        } else {
1246
                pc->st->l3.l3l4(pc->st, CC_IGNORE | INDICATION, pc);
1247
        }
1248
}
1249
 
1250
static void
1251
l3dss1_t303(struct l3_process *pc, u_char pr, void *arg)
1252
{
1253
        if (pc->N303 > 0) {
1254
                pc->N303--;
1255
                L3DelTimer(&pc->timer);
1256
                l3dss1_setup_req(pc, pr, arg);
1257
        } else {
1258
                L3DelTimer(&pc->timer);
1259
                pc->st->l3.l3l4(pc->st, CC_NOSETUP_RSP, pc);
1260
                release_l3_process(pc);
1261
        }
1262
}
1263
 
1264
static void
1265
l3dss1_t304(struct l3_process *pc, u_char pr, void *arg)
1266
{
1267
        L3DelTimer(&pc->timer);
1268
        pc->para.cause = 0xE6;
1269
        l3dss1_disconnect_req(pc, pr, NULL);
1270
        pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
1271
 
1272
}
1273
 
1274
static void
1275
l3dss1_t305(struct l3_process *pc, u_char pr, void *arg)
1276
{
1277
        u_char tmp[16];
1278
        u_char *p = tmp;
1279
        int l;
1280
        struct sk_buff *skb;
1281
        u_char cause = 0x90;
1282
 
1283
        L3DelTimer(&pc->timer);
1284
        if (pc->para.cause > 0)
1285
                cause = pc->para.cause | 0x80;
1286
 
1287
        MsgHead(p, pc->callref, MT_RELEASE);
1288
 
1289
        *p++ = IE_CAUSE;
1290
        *p++ = 0x2;
1291
        *p++ = 0x80;
1292
        *p++ = cause;
1293
 
1294
        l = p - tmp;
1295
        if (!(skb = l3_alloc_skb(l)))
1296
                return;
1297
        memcpy(skb_put(skb, l), tmp, l);
1298
        newl3state(pc, 19);
1299
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
1300
        L3AddTimer(&pc->timer, T308, CC_T308_1);
1301
}
1302
 
1303
static void
1304
l3dss1_t310(struct l3_process *pc, u_char pr, void *arg)
1305
{
1306
        L3DelTimer(&pc->timer);
1307
        pc->para.cause = 0xE6;
1308
        l3dss1_disconnect_req(pc, pr, NULL);
1309
        pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
1310
}
1311
 
1312
static void
1313
l3dss1_t313(struct l3_process *pc, u_char pr, void *arg)
1314
{
1315
        L3DelTimer(&pc->timer);
1316
        pc->para.cause = 0xE6;
1317
        l3dss1_disconnect_req(pc, pr, NULL);
1318
        pc->st->l3.l3l4(pc->st, CC_CONNECT_ERR, pc);
1319
}
1320
 
1321
static void
1322
l3dss1_t308_1(struct l3_process *pc, u_char pr, void *arg)
1323
{
1324
        newl3state(pc, 19);
1325
        L3DelTimer(&pc->timer);
1326
        l3dss1_message(pc, MT_RELEASE);
1327
        L3AddTimer(&pc->timer, T308, CC_T308_2);
1328
}
1329
 
1330
static void
1331
l3dss1_t308_2(struct l3_process *pc, u_char pr, void *arg)
1332
{
1333
        L3DelTimer(&pc->timer);
1334
        pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc);
1335
        release_l3_process(pc);
1336
}
1337
 
1338
static void
1339
l3dss1_t318(struct l3_process *pc, u_char pr, void *arg)
1340
{
1341
        L3DelTimer(&pc->timer);
1342
        pc->para.cause = 0x66;  /* Timer expiry */
1343
        pc->para.loc = 0;        /* local */
1344
        pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc);
1345
        newl3state(pc, 19);
1346
        l3dss1_message(pc, MT_RELEASE);
1347
        L3AddTimer(&pc->timer, T308, CC_T308_1);
1348
}
1349
 
1350
static void
1351
l3dss1_t319(struct l3_process *pc, u_char pr, void *arg)
1352
{
1353
        L3DelTimer(&pc->timer);
1354
        pc->para.cause = 0x66;  /* Timer expiry */
1355
        pc->para.loc = 0;        /* local */
1356
        pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc);
1357
        newl3state(pc, 10);
1358
}
1359
 
1360
static void
1361
l3dss1_restart(struct l3_process *pc, u_char pr, void *arg)
1362
{
1363
        L3DelTimer(&pc->timer);
1364
        pc->st->l3.l3l4(pc->st, CC_DLRL | INDICATION, pc);
1365
        release_l3_process(pc);
1366
}
1367
 
1368
static void
1369
l3dss1_status(struct l3_process *pc, u_char pr, void *arg)
1370
{
1371
        u_char *p;
1372
        char tmp[64], *t;
1373
        int l;
1374
        struct sk_buff *skb = arg;
1375
        int cause, callState;
1376
 
1377
        cause = callState = -1;
1378
        p = skb->data;
1379
        t = tmp;
1380
        if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
1381
                p++;
1382
                l = *p++;
1383
                t += sprintf(t, "Status CR %x Cause:", pc->callref);
1384
                while (l--) {
1385
                        cause = *p;
1386
                        t += sprintf(t, " %2x", *p++);
1387
                }
1388
        } else
1389
                sprintf(t, "Status CR %x no Cause", pc->callref);
1390
        l3_debug(pc->st, tmp);
1391
        p = skb->data;
1392
        t = tmp;
1393
        t += sprintf(t, "Status state %x ", pc->state);
1394
        if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) {
1395
                p++;
1396
                if (1 == *p++) {
1397
                        callState = *p;
1398
                        t += sprintf(t, "peer state %x", *p);
1399
                } else
1400
                        t += sprintf(t, "peer state len error");
1401
        } else
1402
                sprintf(t, "no peer state");
1403
        l3_debug(pc->st, tmp);
1404
        if (((cause & 0x7f) == 0x6f) && (callState == 0)) {
1405
                /* ETS 300-104 7.6.1, 8.6.1, 10.6.1...
1406
                 * if received MT_STATUS with cause == 0x6f and call
1407
                 * state == 0, then we must set down layer 3
1408
                 */
1409
                l3dss1_release_ind(pc, pr, arg);
1410
        } else
1411
                dev_kfree_skb(skb, FREE_READ);
1412
}
1413
 
1414
static void
1415
l3dss1_facility(struct l3_process *pc, u_char pr, void *arg)
1416
{
1417
        u_char *p;
1418
        struct sk_buff *skb = arg;
1419
 
1420
        p = skb->data;
1421
        if ((p = findie(p, skb->len, IE_FACILITY, 0))) {
1422
#if HISAX_DE_AOC
1423
                l3dss1_parse_facility(pc, p);
1424
#else
1425
                p = NULL;
1426
#endif
1427
        }
1428
}
1429
 
1430
static void
1431
l3dss1_suspend_req(struct l3_process *pc, u_char pr, void *arg)
1432
{
1433
        struct sk_buff *skb;
1434
        u_char tmp[32];
1435
        u_char *p = tmp;
1436
        u_char i, l;
1437
        u_char *msg = pc->chan->setup.phone;
1438
 
1439
        MsgHead(p, pc->callref, MT_SUSPEND);
1440
 
1441
        *p++ = IE_CALLID;
1442
        l = *msg++;
1443
        if (l && (l <= 10)) {   /* Max length 10 octets */
1444
                *p++ = l;
1445
                for (i = 0; i < l; i++)
1446
                        *p++ = *msg++;
1447
        } else {
1448
                l3_debug(pc->st, "SUS wrong CALLID len %d", l);
1449
                return;
1450
        }
1451
        l = p - tmp;
1452
        if (!(skb = l3_alloc_skb(l)))
1453
                return;
1454
        memcpy(skb_put(skb, l), tmp, l);
1455
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
1456
        newl3state(pc, 15);
1457
        L3AddTimer(&pc->timer, T319, CC_T319);
1458
}
1459
 
1460
static void
1461
l3dss1_suspend_ack(struct l3_process *pc, u_char pr, void *arg)
1462
{
1463
        struct sk_buff *skb = arg;
1464
 
1465
        L3DelTimer(&pc->timer);
1466
        newl3state(pc, 0);
1467
        dev_kfree_skb(skb, FREE_READ);
1468
        pc->para.cause = -1;
1469
        pc->st->l3.l3l4(pc->st, CC_SUSPEND | CONFIRM, pc);
1470
        release_l3_process(pc);
1471
}
1472
 
1473
static void
1474
l3dss1_suspend_rej(struct l3_process *pc, u_char pr, void *arg)
1475
{
1476
        u_char *p;
1477
        struct sk_buff *skb = arg;
1478
        int cause = -1;
1479
 
1480
        L3DelTimer(&pc->timer);
1481
        p = skb->data;
1482
        if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
1483
                p++;
1484
                if (*p++ == 2)
1485
                        pc->para.loc = *p++;
1486
                cause = *p & 0x7f;
1487
        }
1488
        dev_kfree_skb(skb, FREE_READ);
1489
        pc->para.cause = cause;
1490
        pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc);
1491
        newl3state(pc, 10);
1492
}
1493
 
1494
static void
1495
l3dss1_resume_req(struct l3_process *pc, u_char pr, void *arg)
1496
{
1497
        struct sk_buff *skb;
1498
        u_char tmp[32];
1499
        u_char *p = tmp;
1500
        u_char i, l;
1501
        u_char *msg = pc->para.setup.phone;
1502
 
1503
        MsgHead(p, pc->callref, MT_RESUME);
1504
 
1505
        *p++ = IE_CALLID;
1506
        l = *msg++;
1507
        if (l && (l <= 10)) {   /* Max length 10 octets */
1508
                *p++ = l;
1509
                for (i = 0; i < l; i++)
1510
                        *p++ = *msg++;
1511
        } else {
1512
                l3_debug(pc->st, "RES wrong CALLID len %d", l);
1513
                return;
1514
        }
1515
        l = p - tmp;
1516
        if (!(skb = l3_alloc_skb(l)))
1517
                return;
1518
        memcpy(skb_put(skb, l), tmp, l);
1519
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
1520
        newl3state(pc, 17);
1521
        L3AddTimer(&pc->timer, T319, CC_T319);
1522
}
1523
 
1524
static void
1525
l3dss1_resume_ack(struct l3_process *pc, u_char pr, void *arg)
1526
{
1527
        u_char *p;
1528
        struct sk_buff *skb = arg;
1529
 
1530
        L3DelTimer(&pc->timer);
1531
        p = skb->data;
1532
        if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {
1533
                pc->para.bchannel = p[2] & 0x3;
1534
                if ((!pc->para.bchannel) && (pc->debug & L3_DEB_WARN))
1535
                        l3_debug(pc->st, "resume ack without bchannel");
1536
        } else if (pc->debug & L3_DEB_WARN)
1537
                l3_debug(pc->st, "resume ack without bchannel");
1538
        dev_kfree_skb(skb, FREE_READ);
1539
        pc->st->l3.l3l4(pc->st, CC_RESUME | CONFIRM, pc);
1540
        newl3state(pc, 10);
1541
}
1542
 
1543
static void
1544
l3dss1_resume_rej(struct l3_process *pc, u_char pr, void *arg)
1545
{
1546
        u_char *p;
1547
        struct sk_buff *skb = arg;
1548
        int cause = -1;
1549
 
1550
        L3DelTimer(&pc->timer);
1551
        p = skb->data;
1552
        if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
1553
                p++;
1554
                if (*p++ == 2)
1555
                        pc->para.loc = *p++;
1556
                cause = *p & 0x7f;
1557
        }
1558
        dev_kfree_skb(skb, FREE_READ);
1559
        pc->para.cause = cause;
1560
        newl3state(pc, 0);
1561
        pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc);
1562
        release_l3_process(pc);
1563
}
1564
 
1565
static void
1566
l3dss1_global_restart(struct l3_process *pc, u_char pr, void *arg)
1567
{
1568
        u_char tmp[32];
1569
        u_char *p;
1570
        u_char ri, ch = 0, chan = 0;
1571
        int l;
1572
        struct sk_buff *skb = arg;
1573
        struct l3_process *up;
1574
 
1575
        newl3state(pc, 2);
1576
        L3DelTimer(&pc->timer);
1577
        p = skb->data;
1578
        if ((p = findie(p, skb->len, IE_RESTART_IND, 0))) {
1579
                ri = p[2];
1580
                l3_debug(pc->st, "Restart %x", ri);
1581
        } else {
1582
                l3_debug(pc->st, "Restart without restart IE");
1583
                ri = 0x86;
1584
        }
1585
        p = skb->data;
1586
        if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {
1587
                chan = p[2] & 3;
1588
                ch = p[2];
1589
                if (pc->st->l3.debug)
1590
                        l3_debug(pc->st, "Restart for channel %d", chan);
1591
        }
1592
        dev_kfree_skb(skb, FREE_READ);
1593
        newl3state(pc, 2);
1594
        up = pc->st->l3.proc;
1595
        while (up) {
1596
                if ((ri & 7) == 7)
1597
                        up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
1598
                else if (up->para.bchannel == chan)
1599
                        up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
1600
                up = up->next;
1601
        }
1602
        p = tmp;
1603
        MsgHead(p, pc->callref, MT_RESTART_ACKNOWLEDGE);
1604
        if (chan) {
1605
                *p++ = IE_CHANNEL_ID;
1606
                *p++ = 1;
1607
                *p++ = ch | 0x80;
1608
        }
1609
        *p++ = 0x79;            /* RESTART Ind */
1610
        *p++ = 1;
1611
        *p++ = ri;
1612
        l = p - tmp;
1613
        if (!(skb = l3_alloc_skb(l)))
1614
                return;
1615
        memcpy(skb_put(skb, l), tmp, l);
1616
        newl3state(pc, 0);
1617
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
1618
}
1619
/* *INDENT-OFF* */
1620
static struct stateentry downstatelist[] =
1621
{
1622
        {SBIT(0),
1623
         CC_SETUP | REQUEST, l3dss1_setup_req},
1624
        {SBIT(0),
1625
         CC_RESUME | REQUEST, l3dss1_resume_req},
1626
        {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(10),
1627
         CC_DISCONNECT | REQUEST, l3dss1_disconnect_req},
1628
        {SBIT(12),
1629
         CC_RELEASE | REQUEST, l3dss1_release_req},
1630
        {ALL_STATES,
1631
         CC_DLRL | REQUEST, l3dss1_reset},
1632
        {ALL_STATES,
1633
         CC_RESTART | REQUEST, l3dss1_restart},
1634
        {SBIT(6),
1635
         CC_IGNORE | REQUEST, l3dss1_reset},
1636
        {SBIT(6),
1637
         CC_REJECT | REQUEST, l3dss1_reject_req},
1638
        {SBIT(6),
1639
         CC_ALERTING | REQUEST, l3dss1_alert_req},
1640
        {SBIT(6) | SBIT(7),
1641
         CC_SETUP | RESPONSE, l3dss1_setup_rsp},
1642
        {SBIT(10),
1643
         CC_SUSPEND | REQUEST, l3dss1_suspend_req},
1644
        {SBIT(1),
1645
         CC_T303, l3dss1_t303},
1646
        {SBIT(2),
1647
         CC_T304, l3dss1_t304},
1648
        {SBIT(3),
1649
         CC_T310, l3dss1_t310},
1650
        {SBIT(8),
1651
         CC_T313, l3dss1_t313},
1652
        {SBIT(11),
1653
         CC_T305, l3dss1_t305},
1654
        {SBIT(15),
1655
         CC_T319, l3dss1_t319},
1656
        {SBIT(17),
1657
         CC_T318, l3dss1_t318},
1658
        {SBIT(19),
1659
         CC_T308_1, l3dss1_t308_1},
1660
        {SBIT(19),
1661
         CC_T308_2, l3dss1_t308_2},
1662
};
1663
 
1664
#define DOWNSLLEN \
1665
        (sizeof(downstatelist) / sizeof(struct stateentry))
1666
 
1667
static struct stateentry datastatelist[] =
1668
{
1669
        {ALL_STATES,
1670
         MT_STATUS_ENQUIRY, l3dss1_status_enq},
1671
        {ALL_STATES,
1672
         MT_FACILITY, l3dss1_facility},
1673
        {SBIT(19),
1674
         MT_STATUS, l3dss1_release_ind},
1675
        {ALL_STATES,
1676
         MT_STATUS, l3dss1_status},
1677
        {SBIT(0) | SBIT(6),
1678
         MT_SETUP, l3dss1_setup},
1679
        {SBIT(1) | SBIT(2),
1680
         MT_CALL_PROCEEDING, l3dss1_call_proc},
1681
        {SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
1682
         MT_CALL_PROCEEDING, l3dss1_status_req},
1683
        {SBIT(1),
1684
         MT_SETUP_ACKNOWLEDGE, l3dss1_setup_ack},
1685
        {SBIT(2) | SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
1686
         MT_SETUP_ACKNOWLEDGE, l3dss1_status_req},
1687
        {SBIT(1) | SBIT(2) | SBIT(3),
1688
         MT_ALERTING, l3dss1_alerting},
1689
        {SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
1690
         MT_ALERTING, l3dss1_status_req},
1691
        {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) |
1692
         SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19),
1693
         MT_RELEASE_COMPLETE, l3dss1_release_cmpl},
1694
        {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) |
1695
         SBIT(11) | SBIT(12) | SBIT(15) /* | SBIT(17) | SBIT(19)*/,
1696
         MT_RELEASE, l3dss1_release},
1697
        {SBIT(19),  MT_RELEASE, l3dss1_release_ind},
1698
        {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) | SBIT(15),
1699
         MT_DISCONNECT, l3dss1_disconnect},
1700
        {SBIT(11),
1701
         MT_DISCONNECT, l3dss1_release_req},
1702
        {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4),
1703
         MT_CONNECT, l3dss1_connect},
1704
        {SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
1705
         MT_CONNECT, l3dss1_status_req},
1706
        {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(11) | SBIT(19),
1707
         MT_CONNECT_ACKNOWLEDGE, l3dss1_status_req},
1708
        {SBIT(8),
1709
         MT_CONNECT_ACKNOWLEDGE, l3dss1_connect_ack},
1710
        {SBIT(15),
1711
         MT_SUSPEND_ACKNOWLEDGE, l3dss1_suspend_ack},
1712
        {SBIT(15),
1713
         MT_SUSPEND_REJECT, l3dss1_suspend_rej},
1714
        {SBIT(17),
1715
         MT_RESUME_ACKNOWLEDGE, l3dss1_resume_ack},
1716
        {SBIT(17),
1717
         MT_RESUME_REJECT, l3dss1_resume_rej},
1718
        {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(15) | SBIT(17) | SBIT(19),
1719
         MT_INVALID, l3dss1_status_req},
1720
};
1721
 
1722
#define DATASLLEN \
1723
        (sizeof(datastatelist) / sizeof(struct stateentry))
1724
 
1725
static struct stateentry globalmes_list[] =
1726
{
1727
        {ALL_STATES,
1728
         MT_STATUS, l3dss1_status},
1729
        {SBIT(0),
1730
         MT_RESTART, l3dss1_global_restart},
1731
/*      {SBIT(1),
1732
         MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack},
1733
*/
1734
};
1735
#define GLOBALM_LEN \
1736
        (sizeof(globalmes_list) / sizeof(struct stateentry))
1737
/* *INDENT-ON* */
1738
 
1739
 
1740
static void
1741
global_handler(struct PStack *st, int mt, struct sk_buff *skb)
1742
{
1743
        int i;
1744
        struct l3_process *proc = st->l3.global;
1745
 
1746
        for (i = 0; i < GLOBALM_LEN; i++)
1747
                if ((mt == globalmes_list[i].primitive) &&
1748
                    ((1 << proc->state) & globalmes_list[i].state))
1749
                        break;
1750
        if (i == GLOBALM_LEN) {
1751
                dev_kfree_skb(skb, FREE_READ);
1752
                if (st->l3.debug & L3_DEB_STATE) {
1753
                        l3_debug(st, "dss1 global state %d mt %x unhandled",
1754
                                proc->state, mt);
1755
                }
1756
                return;
1757
        } else {
1758
                if (st->l3.debug & L3_DEB_STATE) {
1759
                        l3_debug(st, "dss1 global %d mt %x",
1760
                                proc->state, mt);
1761
                }
1762
                globalmes_list[i].rout(proc, mt, skb);
1763
        }
1764
}
1765
 
1766
static void
1767
dss1up(struct PStack *st, int pr, void *arg)
1768
{
1769
        int i, mt, cr, cause, callState;
1770
        char *ptr;
1771
        struct sk_buff *skb = arg;
1772
        struct l3_process *proc;
1773
 
1774
        switch (pr) {
1775
                case (DL_DATA | INDICATION):
1776
                case (DL_UNIT_DATA | INDICATION):
1777
                        break;
1778
                case (DL_ESTABLISH | CONFIRM):
1779
                case (DL_ESTABLISH | INDICATION):
1780
                case (DL_RELEASE | INDICATION):
1781
                case (DL_RELEASE | CONFIRM):
1782
                        l3_msg(st, pr, arg);
1783
                        return;
1784
                        break;
1785
        }
1786
        if (skb->data[0] != PROTO_DIS_EURO) {
1787
                if (st->l3.debug & L3_DEB_PROTERR) {
1788
                        l3_debug(st, "dss1up%sunexpected discriminator %x message len %d",
1789
                                 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
1790
                                 skb->data[0], skb->len);
1791
                }
1792
                dev_kfree_skb(skb, FREE_READ);
1793
                return;
1794
        }
1795
        cr = getcallref(skb->data);
1796
        mt = skb->data[skb->data[1] + 2];
1797
        if (!cr) {              /* Global CallRef */
1798
                global_handler(st, mt, skb);
1799
                return;
1800
        } else if (cr == -1) {  /* Dummy Callref */
1801
                dev_kfree_skb(skb, FREE_READ);
1802
                return;
1803
        } else if (!(proc = getl3proc(st, cr))) {
1804
                /* No transaction process exist, that means no call with
1805
                 * this callreference is active
1806
                 */
1807
                if (mt == MT_SETUP) {
1808
                        /* Setup creates a new transaction process */
1809
                        if (!(proc = new_l3_process(st, cr))) {
1810
                                /* May be to answer with RELEASE_COMPLETE and
1811
                                 * CAUSE 0x2f "Resource unavailable", but this
1812
                                 * need a new_l3_process too ... arghh
1813
                                 */
1814
                                dev_kfree_skb(skb, FREE_READ);
1815
                                return;
1816
                        }
1817
                } else if (mt == MT_STATUS) {
1818
                        cause = 0;
1819
                        if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
1820
                                ptr++;
1821
                                if (*ptr++ == 2)
1822
                                        ptr++;
1823
                                cause = *ptr & 0x7f;
1824
                        }
1825
                        callState = 0;
1826
                        if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {
1827
                                ptr++;
1828
                                if (*ptr++ == 2)
1829
                                        ptr++;
1830
                                callState = *ptr;
1831
                        }
1832
                        if (callState == 0) {
1833
                                /* ETS 300-104 part 2.4.1
1834
                                 * if setup has not been made and a message type
1835
                                 * MT_STATUS is received with call state == 0,
1836
                                 * we must send nothing
1837
                                 */
1838
                                dev_kfree_skb(skb, FREE_READ);
1839
                                return;
1840
                        } else {
1841
                                /* ETS 300-104 part 2.4.2
1842
                                 * if setup has not been made and a message type
1843
                                 * MT_STATUS is received with call state != 0,
1844
                                 * we must send MT_RELEASE_COMPLETE cause 101
1845
                                 */
1846
                                dev_kfree_skb(skb, FREE_READ);
1847
                                if ((proc = new_l3_process(st, cr))) {
1848
                                        proc->para.cause = 0x65;        /* 101 */
1849
                                        l3dss1_msg_without_setup(proc, 0, NULL);
1850
                                }
1851
                                return;
1852
                        }
1853
                } else if (mt == MT_RELEASE_COMPLETE) {
1854
                        dev_kfree_skb(skb, FREE_READ);
1855
                        return;
1856
                } else {
1857
                        /* ETS 300-104 part 2
1858
                         * if setup has not been made and a message type
1859
                         * (except MT_SETUP and RELEASE_COMPLETE) is received,
1860
                         * we must send MT_RELEASE_COMPLETE cause 81 */
1861
                        dev_kfree_skb(skb, FREE_READ);
1862
                        if ((proc = new_l3_process(st, cr))) {
1863
                                proc->para.cause = 0x51;        /* 81 */
1864
                                l3dss1_msg_without_setup(proc, 0, NULL);
1865
                        }
1866
                        return;
1867
                }
1868
        } else if (!l3dss1_check_messagetype_validity(mt)) {
1869
                /* ETS 300-104 7.4.2, 8.4.2, 10.3.2, 11.4.2, 12.4.2, 13.4.2,
1870
                 * 14.4.2...
1871
                 * if setup has been made and invalid message type is received,
1872
                 * we must send MT_STATUS cause 0x62
1873
                 */
1874
                mt = MT_INVALID;        /* sorry, not clean, but do the right thing ;-) */
1875
        }
1876
        for (i = 0; i < DATASLLEN; i++)
1877
                if ((mt == datastatelist[i].primitive) &&
1878
                    ((1 << proc->state) & datastatelist[i].state))
1879
                        break;
1880
        if (i == DATASLLEN) {
1881
                dev_kfree_skb(skb, FREE_READ);
1882
                if (st->l3.debug & L3_DEB_STATE) {
1883
                        l3_debug(st, "dss1up%sstate %d mt %x unhandled",
1884
                                (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
1885
                                proc->state, mt);
1886
                }
1887
                return;
1888
        } else {
1889
                if (st->l3.debug & L3_DEB_STATE) {
1890
                        l3_debug(st, "dss1up%sstate %d mt %x",
1891
                                (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
1892
                                proc->state, mt);
1893
                }
1894
                datastatelist[i].rout(proc, pr, skb);
1895
        }
1896
}
1897
 
1898
static void
1899
dss1down(struct PStack *st, int pr, void *arg)
1900
{
1901
        int i, cr;
1902
        struct l3_process *proc;
1903
        struct Channel *chan;
1904
 
1905
        if (((DL_ESTABLISH | REQUEST) == pr) || ((DL_RELEASE | REQUEST) == pr)) {
1906
                l3_msg(st, pr, NULL);
1907
                return;
1908
        } else if (((CC_SETUP | REQUEST) == pr) || ((CC_RESUME | REQUEST) == pr)) {
1909
                chan = arg;
1910
                cr = newcallref();
1911
                cr |= 0x80;
1912
                if ((proc = new_l3_process(st, cr))) {
1913
                        proc->chan = chan;
1914
                        chan->proc = proc;
1915
                        proc->para.setup = chan->setup;
1916
                        proc->callref = cr;
1917
                }
1918
        } else {
1919
                proc = arg;
1920
        }
1921
        if (!proc) {
1922
                printk(KERN_ERR "HiSax dss1down without proc pr=%04x\n", pr);
1923
                return;
1924
        }
1925
        for (i = 0; i < DOWNSLLEN; i++)
1926
                if ((pr == downstatelist[i].primitive) &&
1927
                    ((1 << proc->state) & downstatelist[i].state))
1928
                        break;
1929
        if (i == DOWNSLLEN) {
1930
                if (st->l3.debug & L3_DEB_STATE) {
1931
                        l3_debug(st, "dss1down state %d prim %d unhandled",
1932
                                proc->state, pr);
1933
                }
1934
        } else {
1935
                if (st->l3.debug & L3_DEB_STATE) {
1936
                        l3_debug(st, "dss1down state %d prim %d",
1937
                                proc->state, pr);
1938
                }
1939
                downstatelist[i].rout(proc, pr, arg);
1940
        }
1941
}
1942
 
1943
void
1944
setstack_dss1(struct PStack *st)
1945
{
1946
        char tmp[64];
1947
 
1948
        st->lli.l4l3 = dss1down;
1949
        st->l2.l2l3 = dss1up;
1950
        st->l3.N303 = 1;
1951
        if (!(st->l3.global = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) {
1952
                printk(KERN_ERR "HiSax can't get memory for dss1 global CR\n");
1953
        } else {
1954
                st->l3.global->state = 0;
1955
                st->l3.global->callref = 0;
1956
                st->l3.global->next = NULL;
1957
                st->l3.global->debug = L3_DEB_WARN;
1958
                st->l3.global->st = st;
1959
                st->l3.global->N303 = 1;
1960
                L3InitTimer(st->l3.global, &st->l3.global->timer);
1961
        }
1962
        strcpy(tmp, dss1_revision);
1963
        printk(KERN_INFO "HiSax: DSS1 Rev. %s\n", HiSax_getrev(tmp));
1964
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.