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

Subversion Repositories or1k

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

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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