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