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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [isdn/] [hisax/] [q931.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/* $Id: q931.c,v 1.1.1.1 2001-09-10 07:44:18 simons Exp $
2
 
3
 * q931.c       code to decode ITU Q.931 call control messages
4
 *
5
 * Author       Jan den Ouden
6
 *
7
 * Changelog
8
 *
9
 * Pauline Middelink    general improvements
10
 *
11
 * Beat Doebeli         cause texts, display information element
12
 *
13
 * Karsten Keil         cause texts, display information element for 1TR6
14
 *
15
 *
16
 * $Log: not supported by cvs2svn $
17
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
18
 * Initial revision
19
 *
20
 * Revision 1.5.2.3  1998/11/03 00:07:28  keil
21
 * certification related changes
22
 * fixed logging for smaller stack use
23
 *
24
 * Revision 1.5.2.2  1998/10/25 18:16:32  fritz
25
 * Replaced some read-only variables by defines.
26
 *
27
 * Revision 1.5.2.1  1997/10/17 22:14:20  keil
28
 * update to last hisax version
29
 *
30
 * Revision 1.6  1997/07/27 21:09:44  keil
31
 * move functions to isdnl3.c
32
 *
33
 * Revision 1.5  1997/04/06 22:56:43  keil
34
 * Some cosmetic changes
35
 *
36
 * Revision 1.4  1997/02/09 00:29:11  keil
37
 * new interface handling, one interface per card
38
 *
39
 * Revision 1.3  1997/01/21 22:24:59  keil
40
 * cleanups
41
 *
42
 * Revision 1.2  1996/10/27 22:12:45  keil
43
 * reporting unknown level 3 protocol ids
44
 *
45
 * Revision 1.1  1996/10/13 20:04:56  keil
46
 * Initial revision
47
 *
48
 *
49
 */
50
 
51
 
52
#define __NO_VERSION__
53
#include "hisax.h"
54
#include "l3_1tr6.h"
55
 
56
void
57
iecpy(u_char * dest, u_char * iestart, int ieoffset)
58
{
59
        u_char *p;
60
        int l;
61
 
62
        p = iestart + ieoffset + 2;
63
        l = iestart[1] - ieoffset;
64
        while (l--)
65
                *dest++ = *p++;
66
        *dest++ = '\0';
67
}
68
 
69
/*
70
 * According to Table 4-2/Q.931
71
 */
72
static
73
struct MessageType {
74
        u_char nr;
75
        char *descr;
76
} mtlist[] = {
77
 
78
        {
79
                0x1, "ALERTING"
80
        },
81
        {
82
                0x2, "CALL PROCEEDING"
83
        },
84
        {
85
                0x7, "CONNECT"
86
        },
87
        {
88
                0xf, "CONNECT ACKNOWLEDGE"
89
        },
90
        {
91
                0x3, "PROGRESS"
92
        },
93
        {
94
                0x5, "SETUP"
95
        },
96
        {
97
                0xd, "SETUP ACKNOWLEDGE"
98
        },
99
        {
100
                0x26, "RESUME"
101
        },
102
        {
103
                0x2e, "RESUME ACKNOWLEDGE"
104
        },
105
        {
106
                0x22, "RESUME REJECT"
107
        },
108
        {
109
                0x25, "SUSPEND"
110
        },
111
        {
112
                0x2d, "SUSPEND ACKNOWLEDGE"
113
        },
114
        {
115
                0x21, "SUSPEND REJECT"
116
        },
117
        {
118
                0x20, "USER INFORMATION"
119
        },
120
        {
121
                0x45, "DISCONNECT"
122
        },
123
        {
124
                0x4d, "RELEASE"
125
        },
126
        {
127
                0x5a, "RELEASE COMPLETE"
128
        },
129
        {
130
                0x46, "RESTART"
131
        },
132
        {
133
                0x4e, "RESTART ACKNOWLEDGE"
134
        },
135
        {
136
                0x60, "SEGMENT"
137
        },
138
        {
139
                0x79, "CONGESTION CONTROL"
140
        },
141
        {
142
                0x7b, "INFORMATION"
143
        },
144
        {
145
                0x62, "FACILITY"
146
        },
147
        {
148
                0x6e, "NOTIFY"
149
        },
150
        {
151
                0x7d, "STATUS"
152
        },
153
        {
154
                0x75, "STATUS ENQUIRY"
155
        }
156
};
157
 
158
#define MTSIZE sizeof(mtlist)/sizeof(struct MessageType)
159
 
160
static
161
struct MessageType mt_n0[] =
162
{
163
        {MT_N0_REG_IND, "REGister INDication"},
164
        {MT_N0_CANC_IND, "CANCel INDication"},
165
        {MT_N0_FAC_STA, "FACility STAtus"},
166
        {MT_N0_STA_ACK, "STAtus ACKnowledge"},
167
        {MT_N0_STA_REJ, "STAtus REJect"},
168
        {MT_N0_FAC_INF, "FACility INFormation"},
169
        {MT_N0_INF_ACK, "INFormation ACKnowledge"},
170
        {MT_N0_INF_REJ, "INFormation REJect"},
171
        {MT_N0_CLOSE, "CLOSE"},
172
        {MT_N0_CLO_ACK, "CLOse ACKnowledge"}
173
};
174
 
175
#define MT_N0_LEN (sizeof(mt_n0) / sizeof(struct MessageType))
176
 
177
static
178
struct MessageType mt_n1[] =
179
{
180
        {MT_N1_ESC, "ESCape"},
181
        {MT_N1_ALERT, "ALERT"},
182
        {MT_N1_CALL_SENT, "CALL SENT"},
183
        {MT_N1_CONN, "CONNect"},
184
        {MT_N1_CONN_ACK, "CONNect ACKnowledge"},
185
        {MT_N1_SETUP, "SETUP"},
186
        {MT_N1_SETUP_ACK, "SETUP ACKnowledge"},
187
        {MT_N1_RES, "RESume"},
188
        {MT_N1_RES_ACK, "RESume ACKnowledge"},
189
        {MT_N1_RES_REJ, "RESume REJect"},
190
        {MT_N1_SUSP, "SUSPend"},
191
        {MT_N1_SUSP_ACK, "SUSPend ACKnowledge"},
192
        {MT_N1_SUSP_REJ, "SUSPend REJect"},
193
        {MT_N1_USER_INFO, "USER INFO"},
194
        {MT_N1_DET, "DETach"},
195
        {MT_N1_DISC, "DISConnect"},
196
        {MT_N1_REL, "RELease"},
197
        {MT_N1_REL_ACK, "RELease ACKnowledge"},
198
        {MT_N1_CANC_ACK, "CANCel ACKnowledge"},
199
        {MT_N1_CANC_REJ, "CANCel REJect"},
200
        {MT_N1_CON_CON, "CONgestion CONtrol"},
201
        {MT_N1_FAC, "FACility"},
202
        {MT_N1_FAC_ACK, "FACility ACKnowledge"},
203
        {MT_N1_FAC_CAN, "FACility CANcel"},
204
        {MT_N1_FAC_REG, "FACility REGister"},
205
        {MT_N1_FAC_REJ, "FACility REJect"},
206
        {MT_N1_INFO, "INFOrmation"},
207
        {MT_N1_REG_ACK, "REGister ACKnowledge"},
208
        {MT_N1_REG_REJ, "REGister REJect"},
209
        {MT_N1_STAT, "STATus"}
210
};
211
 
212
#define MT_N1_LEN (sizeof(mt_n1) / sizeof(struct MessageType))
213
 
214
static struct MessageType fac_1tr6[] =
215
{
216
        {FAC_Sperre, "Sperre"},
217
        {FAC_Forward1, "Forward 1"},
218
        {FAC_Forward2, "Forward 2"},
219
        {FAC_Konferenz, "Konferenz"},
220
        {FAC_GrabBchan, "Grab Bchannel"},
221
        {FAC_Reactivate, "Reactivate"},
222
        {FAC_Konferenz3, "Dreier Konferenz"},
223
        {FAC_Dienstwechsel1, "Einseitiger Dienstwechsel"},
224
        {FAC_Dienstwechsel2, "Zweiseitiger Dienstwechsel"},
225
        {FAC_NummernIdent, "Rufnummer-Identifizierung"},
226
        {FAC_GBG, "GBG"},
227
        {FAC_DisplayUebergeben, "Display Uebergeben"},
228
        {FAC_DisplayUmgeleitet, "Display Umgeleitet"},
229
        {FAC_Unterdruecke, "Unterdruecke Rufnummer"},
230
        {FAC_Deactivate, "Deactivate"},
231
        {FAC_Activate, "Activate"},
232
        {FAC_SPV, "SPV"},
233
        {FAC_Rueckwechsel, "Rueckwechsel"},
234
        {FAC_Umleitung, "Umleitung"}
235
};
236
#define FAC_1TR6_LEN (sizeof(fac_1tr6) / sizeof(struct MessageType))
237
 
238
static int
239
prbits(char *dest, u_char b, int start, int len)
240
{
241
        char *dp = dest;
242
 
243
        b = b << (8 - start);
244
        while (len--) {
245
                if (b & 0x80)
246
                        *dp++ = '1';
247
                else
248
                        *dp++ = '0';
249
                b = b << 1;
250
        }
251
        return (dp - dest);
252
}
253
 
254
static
255
u_char *
256
skipext(u_char * p)
257
{
258
        while (!(*p++ & 0x80));
259
        return (p);
260
}
261
 
262
/*
263
 * Cause Values According to Q.850
264
 * edescr: English description
265
 * ddescr: German description used by Swissnet II (Swiss Telecom
266
 *         not yet written...
267
 */
268
 
269
static
270
struct CauseValue {
271
        u_char nr;
272
        char *edescr;
273
        char *ddescr;
274
} cvlist[] = {
275
 
276
        {
277
                0x01, "Unallocated (unassigned) number", "Nummer nicht zugeteilt"
278
        },
279
        {
280
                0x02, "No route to specified transit network", ""
281
        },
282
        {
283
                0x03, "No route to destination", ""
284
        },
285
        {
286
                0x04, "Send special information tone", ""
287
        },
288
        {
289
                0x05, "Misdialled trunk prefix", ""
290
        },
291
        {
292
                0x06, "Channel unacceptable", "Kanal nicht akzeptierbar"
293
        },
294
        {
295
                0x07, "Channel awarded and being delivered in an established channel", ""
296
        },
297
        {
298
                0x08, "Preemption", ""
299
        },
300
        {
301
                0x09, "Preemption - circuit reserved for reuse", ""
302
        },
303
        {
304
                0x10, "Normal call clearing", "Normale Ausloesung"
305
        },
306
        {
307
                0x11, "User busy", "TNB besetzt"
308
        },
309
        {
310
                0x12, "No user responding", ""
311
        },
312
        {
313
                0x13, "No answer from user (user alerted)", ""
314
        },
315
        {
316
                0x14, "Subscriber absent", ""
317
        },
318
        {
319
                0x15, "Call rejected", ""
320
        },
321
        {
322
                0x16, "Number changed", ""
323
        },
324
        {
325
                0x1a, "non-selected user clearing", ""
326
        },
327
        {
328
                0x1b, "Destination out of order", ""
329
        },
330
        {
331
                0x1c, "Invalid number format (address incomplete)", ""
332
        },
333
        {
334
                0x1d, "Facility rejected", ""
335
        },
336
        {
337
                0x1e, "Response to Status enquiry", ""
338
        },
339
        {
340
                0x1f, "Normal, unspecified", ""
341
        },
342
        {
343
                0x22, "No circuit/channel available", ""
344
        },
345
        {
346
                0x26, "Network out of order", ""
347
        },
348
        {
349
                0x27, "Permanent frame mode connection out-of-service", ""
350
        },
351
        {
352
                0x28, "Permanent frame mode connection operational", ""
353
        },
354
        {
355
                0x29, "Temporary failure", ""
356
        },
357
        {
358
                0x2a, "Switching equipment congestion", ""
359
        },
360
        {
361
                0x2b, "Access information discarded", ""
362
        },
363
        {
364
                0x2c, "Requested circuit/channel not available", ""
365
        },
366
        {
367
                0x2e, "Precedence call blocked", ""
368
        },
369
        {
370
                0x2f, "Resource unavailable, unspecified", ""
371
        },
372
        {
373
                0x31, "Quality of service unavailable", ""
374
        },
375
        {
376
                0x32, "Requested facility not subscribed", ""
377
        },
378
        {
379
                0x35, "Outgoing calls barred within CUG", ""
380
        },
381
        {
382
                0x37, "Incoming calls barred within CUG", ""
383
        },
384
        {
385
                0x39, "Bearer capability not authorized", ""
386
        },
387
        {
388
                0x3a, "Bearer capability not presently available", ""
389
        },
390
        {
391
                0x3e, "Inconsistency in designated outgoing access information and subscriber class ", " "
392
        },
393
        {
394
                0x3f, "Service or option not available, unspecified", ""
395
        },
396
        {
397
                0x41, "Bearer capability not implemented", ""
398
        },
399
        {
400
                0x42, "Channel type not implemented", ""
401
        },
402
        {
403
                0x43, "Requested facility not implemented", ""
404
        },
405
        {
406
                0x44, "Only restricted digital information bearer capability is available", ""
407
        },
408
        {
409
                0x4f, "Service or option not implemented", ""
410
        },
411
        {
412
                0x51, "Invalid call reference value", ""
413
        },
414
        {
415
                0x52, "Identified channel does not exist", ""
416
        },
417
        {
418
                0x53, "A suspended call exists, but this call identity does not", ""
419
        },
420
        {
421
                0x54, "Call identity in use", ""
422
        },
423
        {
424
                0x55, "No call suspended", ""
425
        },
426
        {
427
                0x56, "Call having the requested call identity has been cleared", ""
428
        },
429
        {
430
                0x57, "User not member of CUG", ""
431
        },
432
        {
433
                0x58, "Incompatible destination", ""
434
        },
435
        {
436
                0x5a, "Non-existent CUG", ""
437
        },
438
        {
439
                0x5b, "Invalid transit network selection", ""
440
        },
441
        {
442
                0x5f, "Invalid message, unspecified", ""
443
        },
444
        {
445
                0x60, "Mandatory information element is missing", ""
446
        },
447
        {
448
                0x61, "Message type non-existent or not implemented", ""
449
        },
450
        {
451
                0x62, "Message not compatible with call state or message type non-existent or not implemented ", " "
452
        },
453
        {
454
                0x63, "Information element/parameter non-existent or not implemented", ""
455
        },
456
        {
457
                0x64, "Invalid information element contents", ""
458
        },
459
        {
460
                0x65, "Message not compatible with call state", ""
461
        },
462
        {
463
                0x66, "Recovery on timer expiry", ""
464
        },
465
        {
466
                0x67, "Parameter non-existent or not implemented - passed on", ""
467
        },
468
        {
469
                0x6e, "Message with unrecognized parameter discarded", ""
470
        },
471
        {
472
                0x6f, "Protocol error, unspecified", ""
473
        },
474
        {
475
                0x7f, "Interworking, unspecified", ""
476
        },
477
};
478
 
479
#define CVSIZE sizeof(cvlist)/sizeof(struct CauseValue)
480
 
481
static
482
int
483
prcause(char *dest, u_char * p)
484
{
485
        u_char *end;
486
        char *dp = dest;
487
        int i, cause;
488
 
489
        end = p + p[1] + 1;
490
        p += 2;
491
        dp += sprintf(dp, "    coding ");
492
        dp += prbits(dp, *p, 7, 2);
493
        dp += sprintf(dp, " location ");
494
        dp += prbits(dp, *p, 4, 4);
495
        *dp++ = '\n';
496
        p = skipext(p);
497
 
498
        cause = 0x7f & *p++;
499
 
500
        /* locate cause value */
501
        for (i = 0; i < CVSIZE; i++)
502
                if (cvlist[i].nr == cause)
503
                        break;
504
 
505
        /* display cause value if it exists */
506
        if (i == CVSIZE)
507
                dp += sprintf(dp, "Unknown cause type %x!\n", cause);
508
        else
509
                dp += sprintf(dp, "  cause value %x : %s \n", cause, cvlist[i].edescr);
510
 
511
        while (!0) {
512
                if (p > end)
513
                        break;
514
                dp += sprintf(dp, "    diag attribute %d ", *p++ & 0x7f);
515
                dp += sprintf(dp, " rej %d ", *p & 0x7f);
516
                if (*p & 0x80) {
517
                        *dp++ = '\n';
518
                        break;
519
                } else
520
                        dp += sprintf(dp, " av %d\n", (*++p) & 0x7f);
521
        }
522
        return (dp - dest);
523
 
524
}
525
 
526
static
527
struct MessageType cause_1tr6[] =
528
{
529
        {CAUSE_InvCRef, "Invalid Call Reference"},
530
        {CAUSE_BearerNotImpl, "Bearer Service Not Implemented"},
531
        {CAUSE_CIDunknown, "Caller Identity unknown"},
532
        {CAUSE_CIDinUse, "Caller Identity in Use"},
533
        {CAUSE_NoChans, "No Channels available"},
534
        {CAUSE_FacNotImpl, "Facility Not Implemented"},
535
        {CAUSE_FacNotSubscr, "Facility Not Subscribed"},
536
        {CAUSE_OutgoingBarred, "Outgoing calls barred"},
537
        {CAUSE_UserAccessBusy, "User Access Busy"},
538
        {CAUSE_NegativeGBG, "Negative GBG"},
539
        {CAUSE_UnknownGBG, "Unknown  GBG"},
540
        {CAUSE_NoSPVknown, "No SPV known"},
541
        {CAUSE_DestNotObtain, "Destination not obtainable"},
542
        {CAUSE_NumberChanged, "Number changed"},
543
        {CAUSE_OutOfOrder, "Out Of Order"},
544
        {CAUSE_NoUserResponse, "No User Response"},
545
        {CAUSE_UserBusy, "User Busy"},
546
        {CAUSE_IncomingBarred, "Incoming Barred"},
547
        {CAUSE_CallRejected, "Call Rejected"},
548
        {CAUSE_NetworkCongestion, "Network Congestion"},
549
        {CAUSE_RemoteUser, "Remote User initiated"},
550
        {CAUSE_LocalProcErr, "Local Procedure Error"},
551
        {CAUSE_RemoteProcErr, "Remote Procedure Error"},
552
        {CAUSE_RemoteUserSuspend, "Remote User Suspend"},
553
        {CAUSE_RemoteUserResumed, "Remote User Resumed"},
554
        {CAUSE_UserInfoDiscarded, "User Info Discarded"}
555
};
556
 
557
int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType));
558
 
559
static int
560
prcause_1tr6(char *dest, u_char * p)
561
{
562
        char *dp = dest;
563
        int i, cause;
564
 
565
        p++;
566
        if (0 == *p) {
567
                dp += sprintf(dp, "   OK (cause length=0)\n");
568
                return (dp - dest);
569
        } else if (*p > 1) {
570
                dp += sprintf(dp, "    coding ");
571
                dp += prbits(dp, p[2], 7, 2);
572
                dp += sprintf(dp, " location ");
573
                dp += prbits(dp, p[2], 4, 4);
574
                *dp++ = '\n';
575
        }
576
        p++;
577
        cause = 0x7f & *p;
578
 
579
        /* locate cause value */
580
        for (i = 0; i < cause_1tr6_len; i++)
581
                if (cause_1tr6[i].nr == cause)
582
                        break;
583
 
584
        /* display cause value if it exists */
585
        if (i == cause_1tr6_len)
586
                dp += sprintf(dp, "Unknown cause type %x!\n", cause);
587
        else
588
                dp += sprintf(dp, "  cause value %x : %s \n", cause, cause_1tr6[i].descr);
589
 
590
        return (dp - dest);
591
 
592
}
593
 
594
static int
595
prchident(char *dest, u_char * p)
596
{
597
        char *dp = dest;
598
 
599
        p += 2;
600
        dp += sprintf(dp, "    octet 3 ");
601
        dp += prbits(dp, *p, 8, 8);
602
        *dp++ = '\n';
603
        return (dp - dest);
604
}
605
 
606
static int
607
prcalled(char *dest, u_char * p)
608
{
609
        int l;
610
        char *dp = dest;
611
 
612
        p++;
613
        l = *p++ - 1;
614
        dp += sprintf(dp, "    octet 3 ");
615
        dp += prbits(dp, *p++, 8, 8);
616
        *dp++ = '\n';
617
        dp += sprintf(dp, "    number digits ");
618
        while (l--)
619
                *dp++ = *p++;
620
        *dp++ = '\n';
621
        return (dp - dest);
622
}
623
static int
624
prcalling(char *dest, u_char * p)
625
{
626
        int l;
627
        char *dp = dest;
628
 
629
        p++;
630
        l = *p++ - 1;
631
        dp += sprintf(dp, "    octet 3 ");
632
        dp += prbits(dp, *p, 8, 8);
633
        *dp++ = '\n';
634
        if (!(*p & 0x80)) {
635
                dp += sprintf(dp, "    octet 3a ");
636
                dp += prbits(dp, *++p, 8, 8);
637
                *dp++ = '\n';
638
                l--;
639
        };
640
        p++;
641
 
642
        dp += sprintf(dp, "    number digits ");
643
        while (l--)
644
                *dp++ = *p++;
645
        *dp++ = '\n';
646
        return (dp - dest);
647
}
648
 
649
static
650
int
651
prbearer(char *dest, u_char * p)
652
{
653
        char *dp = dest, ch;
654
 
655
        p += 2;
656
        dp += sprintf(dp, "    octet 3  ");
657
        dp += prbits(dp, *p++, 8, 8);
658
        *dp++ = '\n';
659
        dp += sprintf(dp, "    octet 4  ");
660
        dp += prbits(dp, *p, 8, 8);
661
        *dp++ = '\n';
662
        if ((*p++ & 0x1f) == 0x18) {
663
                dp += sprintf(dp, "    octet 4.1 ");
664
                dp += prbits(dp, *p++, 8, 8);
665
                *dp++ = '\n';
666
        }
667
        /* check for user information layer 1 */
668
        if ((*p & 0x60) == 0x20) {
669
                ch = ' ';
670
                do {
671
                        dp += sprintf(dp, "    octet 5%c ", ch);
672
                        dp += prbits(dp, *p, 8, 8);
673
                        *dp++ = '\n';
674
                        if (ch == ' ')
675
                                ch = 'a';
676
                        else
677
                                ch++;
678
                }
679
                while (!(*p++ & 0x80));
680
        }
681
        /* check for user information layer 2 */
682
        if ((*p & 0x60) == 0x40) {
683
                dp += sprintf(dp, "    octet 6  ");
684
                dp += prbits(dp, *p++, 8, 8);
685
                *dp++ = '\n';
686
        }
687
        /* check for user information layer 3 */
688
        if ((*p & 0x60) == 0x60) {
689
                dp += sprintf(dp, "    octet 7  ");
690
                dp += prbits(dp, *p++, 8, 8);
691
                *dp++ = '\n';
692
        }
693
        return (dp - dest);
694
}
695
 
696
static int
697
general(char *dest, u_char * p)
698
{
699
        char *dp = dest;
700
        char ch = ' ';
701
        int l, octet = 3;
702
 
703
        p++;
704
        l = *p++;
705
        /* Iterate over all octets in the information element */
706
        while (l--) {
707
                dp += sprintf(dp, "    octet %d%c ", octet, ch);
708
                dp += prbits(dp, *p++, 8, 8);
709
                *dp++ = '\n';
710
 
711
                /* last octet in group? */
712
                if (*p & 0x80) {
713
                        octet++;
714
                        ch = ' ';
715
                } else if (ch == ' ')
716
                        ch = 'a';
717
                else
718
                        ch++;
719
        }
720
        return (dp - dest);
721
}
722
 
723
static int
724
prcharge(char *dest, u_char * p)
725
{
726
        char *dp = dest;
727
        int l;
728
 
729
        p++;
730
        l = *p++ - 1;
731
        dp += sprintf(dp, "    GEA ");
732
        dp += prbits(dp, *p++, 8, 8);
733
        dp += sprintf(dp, "  Anzahl: ");
734
        /* Iterate over all octets in the * information element */
735
        while (l--)
736
                *dp++ = *p++;
737
        *dp++ = '\n';
738
        return (dp - dest);
739
}
740
static int
741
prtext(char *dest, u_char * p)
742
{
743
        char *dp = dest;
744
        int l;
745
 
746
        p++;
747
        l = *p++;
748
        dp += sprintf(dp, "    ");
749
        /* Iterate over all octets in the * information element */
750
        while (l--)
751
                *dp++ = *p++;
752
        *dp++ = '\n';
753
        return (dp - dest);
754
}
755
static int
756
display(char *dest, u_char * p)
757
{
758
        char *dp = dest;
759
        char ch = ' ';
760
        int l, octet = 3;
761
 
762
        p++;
763
        l = *p++;
764
        /* Iterate over all octets in the * display-information element */
765
        dp += sprintf(dp, "   \"");
766
        while (l--) {
767
                dp += sprintf(dp, "%c", *p++);
768
 
769
                /* last octet in group? */
770
                if (*p & 0x80) {
771
                        octet++;
772
                        ch = ' ';
773
                } else if (ch == ' ')
774
                        ch = 'a';
775
 
776
                else
777
                        ch++;
778
        }
779
        *dp++ = '\"';
780
        *dp++ = '\n';
781
        return (dp - dest);
782
}
783
 
784
int
785
prfacility(char *dest, u_char * p)
786
{
787
        char *dp = dest;
788
        int l, l2;
789
 
790
        p++;
791
        l = *p++;
792
        dp += sprintf(dp, "    octet 3 ");
793
        dp += prbits(dp, *p++, 8, 8);
794
        dp += sprintf(dp, "\n");
795
        l -= 1;
796
 
797
        while (l > 0) {
798
                dp += sprintf(dp, "   octet 4 ");
799
                dp += prbits(dp, *p++, 8, 8);
800
                dp += sprintf(dp, "\n");
801
                dp += sprintf(dp, "   octet 5 %d\n", l2 = *p++ & 0x7f);
802
                l -= 2;
803
                dp += sprintf(dp, "   contents ");
804
                while (l2--) {
805
                        dp += sprintf(dp, "%2x ", *p++);
806
                        l--;
807
                }
808
                dp += sprintf(dp, "\n");
809
        }
810
 
811
        return (dp - dest);
812
}
813
 
814
static
815
struct InformationElement {
816
        u_char nr;
817
        char *descr;
818
        int (*f) (char *, u_char *);
819
} ielist[] = {
820
 
821
        {
822
                0x00, "Segmented message", general
823
        },
824
        {
825
                0x04, "Bearer capability", prbearer
826
        },
827
        {
828
                0x08, "Cause", prcause
829
        },
830
        {
831
                0x10, "Call identity", general
832
        },
833
        {
834
                0x14, "Call state", general
835
        },
836
        {
837
                0x18, "Channel identification", prchident
838
        },
839
        {
840
                0x1c, "Facility", prfacility
841
        },
842
        {
843
                0x1e, "Progress indicator", general
844
        },
845
        {
846
                0x20, "Network-specific facilities", general
847
        },
848
        {
849
                0x27, "Notification indicator", general
850
        },
851
        {
852
                0x28, "Display", display
853
        },
854
        {
855
                0x29, "Date/Time", general
856
        },
857
        {
858
                0x2c, "Keypad facility", general
859
        },
860
        {
861
                0x34, "Signal", general
862
        },
863
        {
864
                0x40, "Information rate", general
865
        },
866
        {
867
                0x42, "End-to-end delay", general
868
        },
869
        {
870
                0x43, "Transit delay selection and indication", general
871
        },
872
        {
873
                0x44, "Packet layer binary parameters", general
874
        },
875
        {
876
                0x45, "Packet layer window size", general
877
        },
878
        {
879
                0x46, "Packet size", general
880
        },
881
        {
882
                0x47, "Closed user group", general
883
        },
884
        {
885
                0x4a, "Reverse charge indication", general
886
        },
887
        {
888
                0x6c, "Calling party number", prcalling
889
        },
890
        {
891
                0x6d, "Calling party subaddress", general
892
        },
893
        {
894
                0x70, "Called party number", prcalled
895
        },
896
        {
897
                0x71, "Called party subaddress", general
898
        },
899
        {
900
                0x74, "Redirecting number", general
901
        },
902
        {
903
                0x78, "Transit network selection", general
904
        },
905
        {
906
                0x79, "Restart indicator", general
907
        },
908
        {
909
                0x7c, "Low layer compatibility", general
910
        },
911
        {
912
                0x7d, "High layer compatibility", general
913
        },
914
        {
915
                0x7e, "User-user", general
916
        },
917
        {
918
                0x7f, "Escape for extension", general
919
        },
920
};
921
 
922
 
923
#define IESIZE sizeof(ielist)/sizeof(struct InformationElement)
924
 
925
static struct InformationElement we_0[] =
926
{
927
        {WE0_cause, "Cause", prcause_1tr6},
928
        {WE0_connAddr, "Connecting Address", prcalled},
929
        {WE0_callID, "Call IDentity", general},
930
        {WE0_chanID, "Channel IDentity", general},
931
        {WE0_netSpecFac, "Network Specific Facility", general},
932
        {WE0_display, "Display", general},
933
        {WE0_keypad, "Keypad", general},
934
        {WE0_origAddr, "Origination Address", prcalled},
935
        {WE0_destAddr, "Destination Address", prcalled},
936
        {WE0_userInfo, "User Info", general}
937
};
938
 
939
#define WE_0_LEN (sizeof(we_0) / sizeof(struct InformationElement))
940
 
941
static struct InformationElement we_6[] =
942
{
943
        {WE6_serviceInd, "Service Indicator", general},
944
        {WE6_chargingInfo, "Charging Information", prcharge},
945
        {WE6_date, "Date", prtext},
946
        {WE6_facSelect, "Facility Select", general},
947
        {WE6_facStatus, "Facility Status", general},
948
        {WE6_statusCalled, "Status Called", general},
949
        {WE6_addTransAttr, "Additional Transmission Attributes", general}
950
};
951
#define WE_6_LEN (sizeof(we_6) / sizeof(struct InformationElement))
952
 
953
int
954
QuickHex(char *txt, u_char * p, int cnt)
955
{
956
        register int i;
957
        register char *t = txt;
958
        register u_char w;
959
 
960
        for (i = 0; i < cnt; i++) {
961
                *t++ = ' ';
962
                w = (p[i] >> 4) & 0x0f;
963
                if (w < 10)
964
                        *t++ = '0' + w;
965
                else
966
                        *t++ = 'A' - 10 + w;
967
                w = p[i] & 0x0f;
968
                if (w < 10)
969
                        *t++ = '0' + w;
970
                else
971
                        *t++ = 'A' - 10 + w;
972
        }
973
        *t++ = 0;
974
        return (t - txt);
975
}
976
 
977
void
978
LogFrame(struct IsdnCardState *cs, u_char * buf, int size)
979
{
980
        char *dp;
981
 
982
        if (size < 1)
983
                return;
984
        dp = cs->dlog;
985
        if (size < MAX_DLOG_SPACE / 3 - 10) {
986
                *dp++ = 'H';
987
                *dp++ = 'E';
988
                *dp++ = 'X';
989
                *dp++ = ':';
990
                dp += QuickHex(dp, buf, size);
991
                dp--;
992
                *dp++ = '\n';
993
                *dp = 0;
994
                HiSax_putstatus(cs, NULL, cs->dlog);
995
        } else
996
                HiSax_putstatus(cs, "LogFrame: ", "warning Frame too big (%d)", size);
997
}
998
 
999
void
1000
dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
1001
{
1002
        u_char *bend, *buf;
1003
        char *dp;
1004
        unsigned char pd, cr_l, cr, mt;
1005
        unsigned char sapi, tei, ftyp;
1006
        int i, cset = 0, cs_old = 0, cs_fest = 0;
1007
        int size, finish = 0;
1008
 
1009
        if (skb->len < 3)
1010
                return;
1011
        /* display header */
1012
        dp = cs->dlog;
1013
        dp += jiftime(dp, jiffies);
1014
        *dp++ = ' ';
1015
        sapi = skb->data[0] >> 2;
1016
        tei  = skb->data[1] >> 1;
1017
        ftyp = skb->data[2];
1018
        buf = skb->data;
1019
        dp += sprintf(dp, "frame %s ", dir ? "network->user" : "user->network");
1020
        size = skb->len;
1021
 
1022
        if (tei == GROUP_TEI) {
1023
                if (sapi == CTRL_SAPI) { /* sapi 0 */
1024
                        if (ftyp == 3) {
1025
                                dp += sprintf(dp, "broadcast\n");
1026
                                buf += 3;
1027
                                size -= 3;
1028
                        } else {
1029
                                dp += sprintf(dp, "no UI broadcast\n");
1030
                                finish = 1;
1031
                        }
1032
                } else if (sapi == TEI_SAPI) {
1033
                        dp += sprintf(dp, "tei managment\n");
1034
                        finish = 1;
1035
                } else {
1036
                        dp += sprintf(dp, "unknown sapi %d broadcast\n", sapi);
1037
                        finish = 1;
1038
                }
1039
        } else {
1040
                if (sapi == CTRL_SAPI) {
1041
                        if (!(ftyp & 1)) { /* IFrame */
1042
                                dp += sprintf(dp, "with tei %d\n", tei);
1043
                                buf += 4;
1044
                                size -= 4;
1045
                        } else {
1046
                                dp += sprintf(dp, "SFrame with tei %d\n", tei);
1047
                                finish = 1;
1048
                        }
1049
                } else {
1050
                        dp += sprintf(dp, "unknown sapi %d tei %d\n", sapi, tei);
1051
                        finish = 1;
1052
                }
1053
        }
1054
        bend = skb->data + skb->len;
1055
        if (buf >= bend) {
1056
                dp += sprintf(dp, "frame too short\n");
1057
                finish = 1;
1058
        }
1059
        if (finish) {
1060
                *dp = 0;
1061
                HiSax_putstatus(cs, NULL, cs->dlog);
1062
                return;
1063
        }
1064
        if ((0xfe & buf[0]) == PROTO_DIS_N0) {   /* 1TR6 */
1065
                /* locate message type */
1066
                pd = *buf++;
1067
                cr_l = *buf++;
1068
                if (cr_l)
1069
                        cr = *buf++;
1070
                else
1071
                        cr = 0;
1072
                mt = *buf++;
1073
                if (pd == PROTO_DIS_N0) {       /* N0 */
1074
                        for (i = 0; i < MT_N0_LEN; i++)
1075
                                if (mt_n0[i].nr == mt)
1076
                                        break;
1077
                        /* display message type if it exists */
1078
                        if (i == MT_N0_LEN)
1079
                                dp += sprintf(dp, "callref %d %s size %d unknown message type N0 %x!\n",
1080
                                              cr & 0x7f, (cr & 0x80) ? "called" : "caller",
1081
                                              size, mt);
1082
                        else
1083
                                dp += sprintf(dp, "callref %d %s size %d message type %s\n",
1084
                                              cr & 0x7f, (cr & 0x80) ? "called" : "caller",
1085
                                              size, mt_n0[i].descr);
1086
                } else {        /* N1 */
1087
                        for (i = 0; i < MT_N1_LEN; i++)
1088
                                if (mt_n1[i].nr == mt)
1089
                                        break;
1090
                        /* display message type if it exists */
1091
                        if (i == MT_N1_LEN)
1092
                                dp += sprintf(dp, "callref %d %s size %d unknown message type N1 %x!\n",
1093
                                              cr & 0x7f, (cr & 0x80) ? "called" : "caller",
1094
                                              size, mt);
1095
                        else
1096
                                dp += sprintf(dp, "callref %d %s size %d message type %s\n",
1097
                                              cr & 0x7f, (cr & 0x80) ? "called" : "caller",
1098
                                              size, mt_n1[i].descr);
1099
                }
1100
 
1101
                /* display each information element */
1102
                while (buf < bend) {
1103
                        /* Is it a single octet information element? */
1104
                        if (*buf & 0x80) {
1105
                                switch ((*buf >> 4) & 7) {
1106
                                        case 1:
1107
                                                dp += sprintf(dp, "  Shift %x\n", *buf & 0xf);
1108
                                                cs_old = cset;
1109
                                                cset = *buf & 7;
1110
                                                cs_fest = *buf & 8;
1111
                                                break;
1112
                                        case 3:
1113
                                                dp += sprintf(dp, "  Congestion level %x\n", *buf & 0xf);
1114
                                                break;
1115
                                        case 2:
1116
                                                if (*buf == 0xa0) {
1117
                                                        dp += sprintf(dp, "  More data\n");
1118
                                                        break;
1119
                                                }
1120
                                                if (*buf == 0xa1) {
1121
                                                        dp += sprintf(dp, "  Sending complete\n");
1122
                                                }
1123
                                                break;
1124
                                                /* fall through */
1125
                                        default:
1126
                                                dp += sprintf(dp, "  Reserved %x\n", *buf);
1127
                                                break;
1128
                                }
1129
                                buf++;
1130
                                continue;
1131
                        }
1132
                        /* No, locate it in the table */
1133
                        if (cset == 0) {
1134
                                for (i = 0; i < WE_0_LEN; i++)
1135
                                        if (*buf == we_0[i].nr)
1136
                                                break;
1137
 
1138
                                /* When found, give appropriate msg */
1139
                                if (i != WE_0_LEN) {
1140
                                        dp += sprintf(dp, "  %s\n", we_0[i].descr);
1141
                                        dp += we_0[i].f(dp, buf);
1142
                                } else
1143
                                        dp += sprintf(dp, "  Codeset %d attribute %x attribute size %d\n", cset, *buf, buf[1]);
1144
                        } else if (cset == 6) {
1145
                                for (i = 0; i < WE_6_LEN; i++)
1146
                                        if (*buf == we_6[i].nr)
1147
                                                break;
1148
 
1149
                                /* When found, give appropriate msg */
1150
                                if (i != WE_6_LEN) {
1151
                                        dp += sprintf(dp, "  %s\n", we_6[i].descr);
1152
                                        dp += we_6[i].f(dp, buf);
1153
                                } else
1154
                                        dp += sprintf(dp, "  Codeset %d attribute %x attribute size %d\n", cset, *buf, buf[1]);
1155
                        } else
1156
                                dp += sprintf(dp, "  Unknown Codeset %d attribute %x attribute size %d\n", cset, *buf, buf[1]);
1157
                        /* Skip to next element */
1158
                        if (cs_fest == 8) {
1159
                                cset = cs_old;
1160
                                cs_old = 0;
1161
                                cs_fest = 0;
1162
                        }
1163
                        buf += buf[1] + 2;
1164
                }
1165
        } else if (buf[0] == 8) {        /* EURO */
1166
                /* locate message type */
1167
                buf++;
1168
                cr_l = *buf++;
1169
                if (cr_l)
1170
                        cr = *buf++;
1171
                else
1172
                        cr = 0;
1173
                mt = *buf++;
1174
                for (i = 0; i < MTSIZE; i++)
1175
                        if (mtlist[i].nr == mt)
1176
                                break;
1177
 
1178
                /* display message type if it exists */
1179
                if (i == MTSIZE)
1180
                        dp += sprintf(dp, "callref %d %s size %d unknown message type %x!\n",
1181
                            cr & 0x7f, (cr & 0x80) ? "called" : "caller",
1182
                                      size, mt);
1183
                else
1184
                        dp += sprintf(dp, "callref %d %s size %d message type %s\n",
1185
                            cr & 0x7f, (cr & 0x80) ? "called" : "caller",
1186
                                      size, mtlist[i].descr);
1187
 
1188
                /* display each information element */
1189
                while (buf < bend) {
1190
                        /* Is it a single octet information element? */
1191
                        if (*buf & 0x80) {
1192
                                switch ((*buf >> 4) & 7) {
1193
                                        case 1:
1194
                                                dp += sprintf(dp, "  Shift %x\n", *buf & 0xf);
1195
                                                break;
1196
                                        case 3:
1197
                                                dp += sprintf(dp, "  Congestion level %x\n", *buf & 0xf);
1198
                                                break;
1199
                                        case 5:
1200
                                                dp += sprintf(dp, "  Repeat indicator %x\n", *buf & 0xf);
1201
                                                break;
1202
                                        case 2:
1203
                                                if (*buf == 0xa0) {
1204
                                                        dp += sprintf(dp, "  More data\n");
1205
                                                        break;
1206
                                                }
1207
                                                if (*buf == 0xa1) {
1208
                                                        dp += sprintf(dp, "  Sending complete\n");
1209
                                                }
1210
                                                break;
1211
                                                /* fall through */
1212
                                        default:
1213
                                                dp += sprintf(dp, "  Reserved %x\n", *buf);
1214
                                                break;
1215
                                }
1216
                                buf++;
1217
                                continue;
1218
                        }
1219
                        /* No, locate it in the table */
1220
                        for (i = 0; i < IESIZE; i++)
1221
                                if (*buf == ielist[i].nr)
1222
                                        break;
1223
 
1224
                        /* When not found, give appropriate msg */
1225
                        if (i != IESIZE) {
1226
                                dp += sprintf(dp, "  %s\n", ielist[i].descr);
1227
                                dp += ielist[i].f(dp, buf);
1228
                        } else
1229
                                dp += sprintf(dp, "  attribute %x attribute size %d\n", *buf, buf[1]);
1230
 
1231
                        /* Skip to next element */
1232
                        buf += buf[1] + 2;
1233
                }
1234
        } else {
1235
                dp += sprintf(dp, "Unknown protocol %x!", buf[0]);
1236
        }
1237
        *dp = 0;
1238
        HiSax_putstatus(cs, NULL, cs->dlog);
1239
}

powered by: WebSVN 2.1.0

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