This source file includes following definitions.
- findie
- iecpy
- getcallref
- prbits
- skipext
- prcause
- prchident
- prcalled
- prcalling
- prbearer
- general
- display
- prfacility
- hexdump
- dlogframe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #define __NO_VERSION__
16 #include "teles.h"
17
18 byte *
19 findie(byte * p, int size, byte ie, int wanted_set)
20 {
21 int l, codeset, maincodeset;
22 byte *pend = p + size;
23
24
25 p++;
26 l = (*p++) & 0xf;
27 p += l;
28 p++;
29 codeset = 0;
30 maincodeset = 0;
31
32 while (p < pend) {
33 if ((*p & 0xf0) == 0x90) {
34 codeset = *p & 0x07;
35 if (!(*p & 0x08))
36 maincodeset = codeset;
37 }
38 if (*p & 0x80)
39 p++;
40 else {
41 if (codeset == wanted_set) {
42 if (*p == ie)
43 return (p);
44 if (*p > ie)
45 return (NULL);
46 }
47 p++;
48 l = *p++;
49 p += l;
50 codeset = maincodeset;
51 }
52 }
53 return (NULL);
54 }
55
56 void
57 iecpy(byte * dest, byte * iestart, int ieoffset)
58 {
59 byte *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 int
70 getcallref(byte * p)
71 {
72 p++;
73 p++;
74 return (*p);
75 }
76
77
78
79
80 static
81 struct MessageType {
82 byte nr;
83 char *descr;
84 } mtlist[] = {
85
86 {
87 0x1, "ALERTING"
88 },
89 {
90 0x2, "CALL PROCEEDING"
91 },
92 {
93 0x7, "CONNECT"
94 },
95 {
96 0xf, "CONNECT ACKNOWLEDGE"
97 },
98 {
99 0x3, "PROGRESS"
100 },
101 {
102 0x5, "SETUP"
103 },
104 {
105 0xd, "SETUP ACKNOWLEDGE"
106 },
107 {
108 0x26, "RESUME"
109 },
110 {
111 0x2e, "RESUME ACKNOWLEDGE"
112 },
113 {
114 0x22, "RESUME REJECT"
115 },
116 {
117 0x25, "SUSPEND"
118 },
119 {
120 0x2d, "SUSPEND ACKNOWLEDGE"
121 },
122 {
123 0x21, "SUSPEND REJECT"
124 },
125 {
126 0x20, "USER INFORMATION"
127 },
128 {
129 0x45, "DISCONNECT"
130 },
131 {
132 0x4d, "RELEASE"
133 },
134 {
135 0x5a, "RELEASE COMPLETE"
136 },
137 {
138 0x46, "RESTART"
139 },
140 {
141 0x4e, "RESTART ACKNOWLEDGE"
142 },
143 {
144 0x60, "SEGMENT"
145 },
146 {
147 0x79, "CONGESTION CONTROL"
148 },
149 {
150 0x7b, "INFORMATION"
151 },
152 {
153 0x62, "FACILITY"
154 },
155 {
156 0x6e, "NOTIFY"
157 },
158 {
159 0x7d, "STATUS"
160 },
161 {
162 0x75, "STATUS ENQUIRY"
163 }
164 };
165
166 #define MTSIZE sizeof(mtlist)/sizeof(struct MessageType)
167
168
169 static
170 int
171 prbits(char *dest, byte b, int start, int len)
172 {
173 char *dp = dest;
174
175 b = b << (8 - start);
176 while (len--) {
177 if (b & 0x80)
178 *dp++ = '1';
179 else
180 *dp++ = '0';
181 b = b << 1;
182 }
183 return (dp - dest);
184 }
185
186 static
187 byte *
188 skipext(byte * p)
189 {
190 while (!(*p++ & 0x80));
191 return (p);
192 }
193
194
195
196
197
198
199
200
201 static
202 struct CauseValue {
203 byte nr;
204 char *edescr;
205 char *ddescr;
206 } cvlist[] = {
207
208 {
209 0x01, "Unallocated (unassigned) number", "Nummer nicht zugeteilt"
210 },
211 {
212 0x02, "No route to specified transit network", ""
213 },
214 {
215 0x03, "No route to destination", ""
216 },
217 {
218 0x04, "Send special information tone", ""
219 },
220 {
221 0x05, "Misdialled trunk prefix", ""
222 },
223 {
224 0x06, "Channel unacceptable", "Kanal nicht akzeptierbar"
225 },
226 {
227 0x07, "Channel awarded and being delivered in an established channel", ""
228 },
229 {
230 0x08, "Preemption", ""
231 },
232 {
233 0x09, "Preemption - circuit reserved for reuse", ""
234 },
235 {
236 0x10, "Normal call clearing", "Normale Ausloesung"
237 },
238 {
239 0x11, "User busy", "TNB besetzt"
240 },
241 {
242 0x12, "No user responding", ""
243 },
244 {
245 0x13, "No answer from user (user alerted)", ""
246 },
247 {
248 0x14, "Subscriber absent", ""
249 },
250 {
251 0x15, "Call rejected", ""
252 },
253 {
254 0x16, "Number changed", ""
255 },
256 {
257 0x1a, "non-selected user clearing", ""
258 },
259 {
260 0x1b, "Destination out of order", ""
261 },
262 {
263 0x1c, "Invalid number format (address incomplete)", ""
264 },
265 {
266 0x1d, "Facility rejected", ""
267 },
268 {
269 0x1e, "Response to Status enuiry", ""
270 },
271 {
272 0x1f, "Normal, unspecified", ""
273 },
274 {
275 0x22, "No circuit/channel available", ""
276 },
277 {
278 0x26, "Network out of order", ""
279 },
280 {
281 0x27, "Permanent frame mode connection out-of-service", ""
282 },
283 {
284 0x28, "Permanent frame mode connection operational", ""
285 },
286 {
287 0x29, "Temporary failure", ""
288 },
289 {
290 0x2a, "Switching equipment congestion", ""
291 },
292 {
293 0x2b, "Access information discarded", ""
294 },
295 {
296 0x2c, "Requested circuit/channel not available", ""
297 },
298 {
299 0x2e, "Precedence call blocked", ""
300 },
301 {
302 0x2f, "Resource unavailable, unspecified", ""
303 },
304 {
305 0x31, "Quality of service unavailable", ""
306 },
307 {
308 0x32, "Requested facility not subscribed", ""
309 },
310 {
311 0x35, "Outgoing calls barred within CUG", ""
312 },
313 {
314 0x37, "Incoming calls barred within CUG", ""
315 },
316 {
317 0x39, "Bearer capability not auhorized", ""
318 },
319 {
320 0x3a, "Bearer capability not presently available", ""
321 },
322 {
323 0x3e, "Inconsistency in designated outgoing access information and subscriber class ", " "
324 },
325 {
326 0x3f, "Service or option not available, unspecified", ""
327 },
328 {
329 0x41, "Bearer capability not implemented", ""
330 },
331 {
332 0x42, "Channel type not implemented", ""
333 },
334 {
335 0x43, "Requested facility not implemented", ""
336 },
337 {
338 0x44, "Only restricted digital information bearer capability is available", ""
339 },
340 {
341 0x4f, "Service or option not implemented", ""
342 },
343 {
344 0x51, "Invalid call reference value", ""
345 },
346 {
347 0x52, "Identified channel does not exist", ""
348 },
349 {
350 0x53, "A suspended call exists, but this call identity does not", ""
351 },
352 {
353 0x54, "Call identity in use", ""
354 },
355 {
356 0x55, "No call suspended", ""
357 },
358 {
359 0x56, "Call having the requested call identity has been cleared", ""
360 },
361 {
362 0x57, "User not member of CUG", ""
363 },
364 {
365 0x58, "Incompatible destination", ""
366 },
367 {
368 0x5a, "Non-existent CUG", ""
369 },
370 {
371 0x5b, "Invalid transit network selection", ""
372 },
373 {
374 0x5f, "Invalid message, unspecified", ""
375 },
376 {
377 0x60, "Mandatory information element is missing", ""
378 },
379 {
380 0x61, "Message type non-existent or not implemented", ""
381 },
382 {
383 0x62, "Message not compatible with call state or message type non-existent or not implemented ", " "
384 },
385 {
386 0x63, "Information element/parameter non-existent or not implemented", ""
387 },
388 {
389 0x64, "Invalid information element contents", ""
390 },
391 {
392 0x65, "Message not compatible with call state", ""
393 },
394 {
395 0x66, "Recovery on timer expiry", ""
396 },
397 {
398 0x67, "Parameter non-existent or not implemented - passed on", ""
399 },
400 {
401 0x6e, "Message with unrecognized parameter discarded", ""
402 },
403 {
404 0x6f, "Protocol error, unspecified", ""
405 },
406 {
407 0x7f, "Interworking, unspecified", ""
408 },
409 };
410
411 #define CVSIZE sizeof(cvlist)/sizeof(struct CauseValue)
412
413 static
414 int
415 prcause(char *dest, byte * p)
416 {
417 byte *end;
418 char *dp = dest;
419 int i, cause;
420
421 end = p + p[1] + 1;
422 p += 2;
423 dp += sprintf(dp, " coding ");
424 dp += prbits(dp, *p, 7, 2);
425 dp += sprintf(dp, " location ");
426 dp += prbits(dp, *p, 4, 4);
427 *dp++ = '\n';
428 p = skipext(p);
429
430 cause = 0x7f & *p++;
431
432
433 for (i = 0; i < CVSIZE; i++)
434 if (cvlist[i].nr == cause)
435 break;
436
437
438 if (i == CVSIZE)
439 dp += sprintf(dp, "Unknown cause type %x!\n", cause);
440 else
441 dp += sprintf(dp, " cause value %x : %s \n", cause, cvlist[i].edescr);
442
443
444 #if 0
445 dp += sprintf(dp," cause value ");
446 dp += prbits(dp,*p++,7,7);
447 *dp++ = '\n';
448 #endif
449 while (!0) {
450 if (p > end)
451 break;
452 dp += sprintf(dp, " diag attribute %d ", *p++ & 0x7f);
453 dp += sprintf(dp, " rej %d ", *p & 0x7f);
454 if (*p & 0x80) {
455 *dp++ = '\n';
456 break;
457 } else
458 dp += sprintf(dp, " av %d\n", (*++p) & 0x7f);
459 }
460 return (dp - dest);
461
462 }
463
464 static
465 int
466 prchident(char *dest, byte * p)
467 {
468 char *dp = dest;
469
470 p += 2;
471 dp += sprintf(dp, " octet 3 ");
472 dp += prbits(dp, *p, 8, 8);
473 *dp++ = '\n';
474 return (dp - dest);
475 }
476 static
477 int
478 prcalled(char *dest, byte * p)
479 {
480 int l;
481 char *dp = dest;
482
483 p++;
484 l = *p++ - 1;
485 dp += sprintf(dp, " octet 3 ");
486 dp += prbits(dp, *p++, 8, 8);
487 *dp++ = '\n';
488 dp += sprintf(dp, " number digits ");
489 while (l--)
490 *dp++ = *p++;
491 *dp++ = '\n';
492 return (dp - dest);
493 }
494 static
495 int
496 prcalling(char *dest, byte * p)
497 {
498 int l;
499 char *dp = dest;
500
501 p++;
502 l = *p++ - 1;
503 dp += sprintf(dp, " octet 3 ");
504 dp += prbits(dp, *p, 8, 8);
505 *dp++ = '\n';
506 if (!(*p & 0x80)) {
507 dp += sprintf(dp, " octet 3a ");
508 dp += prbits(dp, *++p, 8, 8);
509 *dp++ = '\n';
510 l--;
511 };
512
513 p++;
514
515 dp += sprintf(dp, " number digits ");
516 while (l--)
517 *dp++ = *p++;
518 *dp++ = '\n';
519 return (dp - dest);
520 }
521
522 static
523 int
524 prbearer(char *dest, byte * p)
525 {
526 char *dp = dest, ch;
527
528 p += 2;
529 dp += sprintf(dp, " octet 3 ");
530 dp += prbits(dp, *p++, 8, 8);
531 *dp++ = '\n';
532 dp += sprintf(dp, " octet 4 ");
533 dp += prbits(dp, *p, 8, 8);
534 *dp++ = '\n';
535 if ((*p++ & 0x1f) == 0x18) {
536 dp += sprintf(dp, " octet 4.1 ");
537 dp += prbits(dp, *p++, 8, 8);
538 *dp++ = '\n';
539 }
540
541 if ((*p & 0x60) == 0x20) {
542 ch = ' ';
543 do {
544 dp += sprintf(dp, " octet 5%c ", ch);
545 dp += prbits(dp, *p, 8, 8);
546 *dp++ = '\n';
547 if (ch == ' ')
548 ch = 'a';
549 else
550 ch++;
551 }
552 while (!(*p++ & 0x80));
553 }
554
555 if ((*p & 0x60) == 0x40) {
556 dp += sprintf(dp, " octet 6 ");
557 dp += prbits(dp, *p++, 8, 8);
558 *dp++ = '\n';
559 }
560
561 if ((*p & 0x60) == 0x60) {
562 dp += sprintf(dp, " octet 7 ");
563 dp += prbits(dp, *p++, 8, 8);
564 *dp++ = '\n';
565 }
566 return (dp - dest);
567 }
568
569 static
570 int
571 general(char *dest, byte * p)
572 {
573 char *dp = dest;
574 char ch = ' ';
575 int l, octet = 3;
576
577 p++;
578 l = *p++;
579
580 while (l--) {
581 dp += sprintf(dp, " octet %d%c ", octet, ch);
582 dp += prbits(dp, *p++, 8, 8);
583 *dp++ = '\n';
584
585
586 if (*p & 0x80) {
587 octet++;
588 ch = ' ';
589 } else if (ch == ' ')
590 ch = 'a';
591
592 else
593 ch++;
594 }
595 return (dp - dest);
596 }
597
598 static
599 int
600 display(char *dest, byte * p)
601 {
602 char *dp = dest;
603 char ch = ' ';
604 int l, octet = 3;
605
606 p++;
607 l = *p++;
608
609 dp += sprintf(dp, " \"");
610 while (l--) {
611 dp += sprintf(dp, "%c", *p++);
612
613
614 if (*p & 0x80) {
615 octet++;
616 ch = ' ';
617 } else if (ch == ' ')
618 ch = 'a';
619
620 else
621 ch++;
622 }
623 *dp++ = '\"';
624 *dp++ = '\n';
625 return (dp - dest);
626 }
627
628 int
629 prfacility(char *dest, byte * p)
630 {
631 char *dp = dest;
632 int l, l2;
633
634 p++;
635 l = *p++;
636 dp += sprintf(dp, " octet 3 ");
637 dp += prbits(dp, *p++, 8, 8);
638 dp += sprintf(dp, "\n");
639 l -= 1;
640
641 while (l > 0) {
642 dp += sprintf(dp, " octet 4 ");
643 dp += prbits(dp, *p++, 8, 8);
644 dp += sprintf(dp, "\n");
645 dp += sprintf(dp, " octet 5 %d\n", l2 = *p++ & 0x7f);
646 l -= 2;
647 dp += sprintf(dp, " contents ");
648 while (l2--) {
649 dp += sprintf(dp, "%2x ", *p++);
650 l--;
651 }
652 dp += sprintf(dp, "\n");
653 }
654
655 return (dp - dest);
656 }
657
658 static
659 struct InformationElement {
660 byte nr;
661 char *descr;
662 int (*f) (char *, byte *);
663 } ielist[] = {
664
665 {
666 0x00, "Segmented message", general
667 },
668 {
669 0x04, "Bearer capability", prbearer
670 },
671 {
672 0x08, "Cause", prcause
673 },
674 {
675 0x10, "Call identity", general
676 },
677 {
678 0x14, "Call state", general
679 },
680 {
681 0x18, "Channel identification", prchident
682 },
683 {
684 0x1c, "Facility", prfacility
685 },
686 {
687 0x1e, "Progress indicator", general
688 },
689 {
690 0x20, "Network-specific facilities", general
691 },
692 {
693 0x27, "Notification indicator", general
694 },
695 {
696 0x28, "Display", display
697 },
698 {
699 0x29, "Date/Time", general
700 },
701 {
702 0x2c, "Keypad facility", general
703 },
704 {
705 0x34, "Signal", general
706 },
707 {
708 0x40, "Information rate", general
709 },
710 {
711 0x42, "End-to-end delay", general
712 },
713 {
714 0x43, "Transit delay selection and indication", general
715 },
716 {
717 0x44, "Packet layer binary parameters", general
718 },
719 {
720 0x45, "Packet layer window size", general
721 },
722 {
723 0x46, "Packet size", general
724 },
725 {
726 0x47, "Closed user group", general
727 },
728 {
729 0x4a, "Reverse charge indication", general
730 },
731 {
732 0x6c, "Calling party number", prcalling
733 },
734 {
735 0x6d, "Calling party subaddress", general
736 },
737 {
738 0x70, "Called party number", prcalled
739 },
740 {
741 0x71, "Called party subaddress", general
742 },
743 {
744 0x74, "Redirecting number", general
745 },
746 {
747 0x78, "Transit network selection", general
748 },
749 {
750 0x79, "Restart indicator", general
751 },
752 {
753 0x7c, "Low layer compatibility", general
754 },
755 {
756 0x7d, "High layer compatibility", general
757 },
758 {
759 0x7e, "User-user", general
760 },
761 {
762 0x7f, "Escape for extension", general
763 },
764 };
765
766 #define IESIZE sizeof(ielist)/sizeof(struct InformationElement)
767
768 #ifdef FRITZDEBUG
769 void
770 hexdump(byte * buf, int len, char *comment)
771 {
772 static char dbuf[1024];
773 char *p = dbuf;
774
775 p += sprintf(p, "%s: ", comment);
776 while (len) {
777 p += sprintf(p, "%02x ", *p++);
778 len--;
779 }
780 p += sprintf(p, "\n");
781
782 teles_putstatus(dbuf);
783 }
784 #endif
785
786 void
787 dlogframe(struct IsdnCardState *sp, byte * buf, int size, char *comment)
788 {
789 byte *bend = buf + size;
790 char *dp;
791 int i;
792
793
794 dp = sp->dlogspace;
795 dp += sprintf(dp, "%s\n", comment);
796
797 {
798 byte *p = buf;
799
800 dp += sprintf(dp, "hex: ");
801 while (p < bend)
802 dp += sprintf(dp, "%02x ", *p++);
803 dp += sprintf(dp, "\n");
804 teles_putstatus(sp->dlogspace);
805 dp = sp->dlogspace;
806 }
807
808 for (i = 0; i < MTSIZE; i++)
809 if (mtlist[i].nr == buf[3])
810 break;
811
812
813 if (i == MTSIZE)
814 dp += sprintf(dp, "Unknown message type %x!\n", buf[3]);
815 else
816 dp += sprintf(dp, "call reference %d size %d message type %s\n",
817 buf[2], size, mtlist[i].descr);
818
819
820 buf += 4;
821 while (buf < bend) {
822
823 if (*buf & 0x80) {
824 switch ((*buf >> 4) & 7) {
825 case 1:
826 dp += sprintf(dp, " Shift %x\n", *buf & 0xf);
827 break;
828 case 3:
829 dp += sprintf(dp, " Congestion level %x\n", *buf & 0xf);
830 break;
831 case 5:
832 dp += sprintf(dp, " Repeat indicator %x\n", *buf & 0xf);
833 break;
834 case 2:
835 if (*buf == 0xa0) {
836 dp += sprintf(dp, " More data\n");
837 break;
838 }
839 if (*buf == 0xa1) {
840 dp += sprintf(dp, " Sending complete\n");
841 }
842 break;
843
844 default:
845 dp += sprintf(dp, " Reserved %x\n", *buf);
846 break;
847 }
848 buf++;
849 continue;
850 }
851
852 for (i = 0; i < IESIZE; i++)
853 if (*buf == ielist[i].nr)
854 break;
855
856
857 if (i != IESIZE) {
858 dp += sprintf(dp, " %s\n", ielist[i].descr);
859 dp += ielist[i].f(dp, buf);
860 } else
861 dp += sprintf(dp, " attribute %x attribute size %d\n", *buf, buf[1]);
862
863
864 buf += buf[1] + 2;
865 }
866
867 dp += sprintf(dp, "\n");
868 teles_putstatus(sp->dlogspace);
869 }