2 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 *---------------------------------------------------------------------------
27 * q931.c - print Q.931 traces
28 * ---------------------------
30 * $Id: q931.c,v 1.3 2003/10/06 09:43:28 itojun Exp $
34 * last edit-date: [Mon Feb 14 14:51:13 2000]
36 *---------------------------------------------------------------------------*/
40 /*---------------------------------------------------------------------------*
41 * decode Q.931 protocol
42 *---------------------------------------------------------------------------*/
44 decode_q931(char *pbuf
, int n
, int off
, unsigned char *buf
, int raw
)
62 for (i
= 0; i
< n
; i
+= 16)
64 sprintf((pbuf
+strlen(pbuf
)),"Dump:%.3d ", i
+off
);
65 for (j
= 0; j
< 16; j
++)
67 sprintf((pbuf
+strlen(pbuf
)),"%02x ", buf
[i
+ j
]);
69 sprintf((pbuf
+strlen(pbuf
))," ");
70 sprintf((pbuf
+strlen(pbuf
))," ");
71 for (j
= 0; j
< 16 && i
+ j
< n
; j
++)
72 if (isprint(buf
[i
+ j
]))
73 sprintf((pbuf
+strlen(pbuf
)),"%c", buf
[i
+ j
]);
75 sprintf((pbuf
+strlen(pbuf
)),".");
76 sprintf((pbuf
+strlen(pbuf
)),"\n");
82 sprintf((pbuf
+strlen(pbuf
)), "Q931: ");
84 /* protocol discriminator */
88 if (pd
>= 0x00 && pd
<= 0x07)
89 sprintf((pbuf
+strlen(pbuf
)), "pd=User-User (0x%02x)\n",pd
);
91 sprintf((pbuf
+strlen(pbuf
)), "pd=Q.931/I.451, ");
92 else if (pd
>= 0x10 && pd
<= 0x3f)
93 sprintf((pbuf
+strlen(pbuf
)), "pd=Other Layer 3 or X.25 (0x%02x)\n",pd
);
94 else if (pd
>= 0x40 && pd
<= 0x4f)
95 sprintf((pbuf
+strlen(pbuf
)), "pd=National Use (0x%02x)\n",pd
);
96 else if (pd
>= 0x50 && pd
<= 0xfe)
97 sprintf((pbuf
+strlen(pbuf
)), "pd=Other Layer 3 or X.25 (0x%02x)\n",pd
);
99 sprintf((pbuf
+strlen(pbuf
)), "pd=Reserved (0x%02x)\n",pd
);
110 sprintf((pbuf
+strlen(pbuf
)), "cr=Dummy, ");
113 sprintf((pbuf
+strlen(pbuf
)), "cr=0x%02x %s, ", (buf
[i
+1] & 0x7f), (buf
[i
+1] & 0x80) ? "(from destination)" : "(from origination)");
116 sprintf((pbuf
+strlen(pbuf
)), "cr=0x%02x 0x%02x %s, ", (buf
[i
+1] & 0x7f), (buf
[i
+2] & 0x7f), (buf
[i
+1] & 0x80) ? "(org)" : "(dst)");
124 sprintf((pbuf
+strlen(pbuf
)), "message=");
128 /* escape to nationally specific message type */
131 sprintf((pbuf
+strlen(pbuf
)), "ESCAPE: ");
134 /* call establishment */
137 sprintf((pbuf
+strlen(pbuf
)), "ALERTING: ");
140 sprintf((pbuf
+strlen(pbuf
)), "CALL PROCEEDING: ");
143 sprintf((pbuf
+strlen(pbuf
)), "PROGRESS: ");
146 sprintf((pbuf
+strlen(pbuf
)), "SETUP: ");
149 sprintf((pbuf
+strlen(pbuf
)), "CONNECT: ");
152 sprintf((pbuf
+strlen(pbuf
)), "SETUP ACKNOWLEDGE: ");
155 sprintf((pbuf
+strlen(pbuf
)), "CONNECT ACKNOWLEDGE: ");
158 /* call information phase */
161 sprintf((pbuf
+strlen(pbuf
)), "USER INFORMATION: ");
164 sprintf((pbuf
+strlen(pbuf
)), "SUSPEND REJECT: ");
167 sprintf((pbuf
+strlen(pbuf
)), "RESUME REJECT: ");
170 sprintf((pbuf
+strlen(pbuf
)), "HOLD: ");
173 sprintf((pbuf
+strlen(pbuf
)), "SUSPEND: ");
176 sprintf((pbuf
+strlen(pbuf
)), "RESUME: ");
179 sprintf((pbuf
+strlen(pbuf
)), "HOLD ACKNOWLEDGE: ");
182 sprintf((pbuf
+strlen(pbuf
)), "SUSPEND ACKNOWLEDGE: ");
185 sprintf((pbuf
+strlen(pbuf
)), "RESUME ACKNOWLEDGE: ");
188 sprintf((pbuf
+strlen(pbuf
)), "HOLD REJECT (Q.932): ");
191 sprintf((pbuf
+strlen(pbuf
)), "RETRIEVE (Q.932): ");
194 sprintf((pbuf
+strlen(pbuf
)), "RETRIEVE ACKNOWLEDGE (Q.932): ");
197 sprintf((pbuf
+strlen(pbuf
)), "RETRIEVE REJECT (Q.932): ");
203 sprintf((pbuf
+strlen(pbuf
)), "DETACH: ");
206 sprintf((pbuf
+strlen(pbuf
)), "DISCONNECT: ");
209 sprintf((pbuf
+strlen(pbuf
)), "RESTART: ");
212 sprintf((pbuf
+strlen(pbuf
)), "DETACH ACKNOWLEDGE: ");
215 sprintf((pbuf
+strlen(pbuf
)), "RELEASE: ");
218 sprintf((pbuf
+strlen(pbuf
)), "RESTART ACKNOWLEDGE: ");
221 sprintf((pbuf
+strlen(pbuf
)), "RELEASE COMPLETE: ");
227 sprintf((pbuf
+strlen(pbuf
)), "SEGMENT: ");
230 sprintf((pbuf
+strlen(pbuf
)), "FACILITY (Q.932): ");
233 sprintf((pbuf
+strlen(pbuf
)), "REGISTER (Q.932): ");
236 sprintf((pbuf
+strlen(pbuf
)), "CANCEL ACKNOWLEDGE: ");
239 sprintf((pbuf
+strlen(pbuf
)), "FACILITY ACKNOWLEDGE: ");
242 sprintf((pbuf
+strlen(pbuf
)), "REGISTER ACKNOWLEDGE: ");
245 sprintf((pbuf
+strlen(pbuf
)), "NOTIFY: ");
248 sprintf((pbuf
+strlen(pbuf
)), "CANCEL REJECT: ");
251 sprintf((pbuf
+strlen(pbuf
)), "FACILITY REJECT: ");
254 sprintf((pbuf
+strlen(pbuf
)), "REGISTER REJECT: ");
257 sprintf((pbuf
+strlen(pbuf
)), "STATUS ENQIRY: ");
260 sprintf((pbuf
+strlen(pbuf
)), "CONGESTION CONTROL: ");
263 sprintf((pbuf
+strlen(pbuf
)), "INFORMATION: ");
266 sprintf((pbuf
+strlen(pbuf
)), "STATUS: ");
269 sprintf((pbuf
+strlen(pbuf
)), "UNDEFINED, TYPE=0x%02x, ", buf
[i
]);
273 /* other information elements */
279 sprintf((pbuf
+strlen(pbuf
)), "\n ");
283 /* single octett info element */
285 switch (buf
[i
] & 0x70)
287 case 0x00: /* reserved */
288 sprintf((pbuf
+strlen(pbuf
)), "[reserved single octett info]");
291 case 0x10: /* shift */
292 oldcodeset
= codeset
;
293 codeset
= buf
[i
] & 0x07;
298 sprintf((pbuf
+strlen(pbuf
)), "[shift: codeset=%d lock=%d]", codeset
, codelock
);
301 case 0x20: /* more data */
303 sprintf((pbuf
+strlen(pbuf
)), "[sending complete]");
305 sprintf((pbuf
+strlen(pbuf
)), "[more data]");
308 case 0x30: /* congestion level */
309 sprintf((pbuf
+strlen(pbuf
)), "[congestion level=");
310 switch (buf
[i
] & 0x0f)
313 sprintf((pbuf
+strlen(pbuf
)), "rx-ready]");
316 sprintf((pbuf
+strlen(pbuf
)), "rx-not-ready]");
319 sprintf((pbuf
+strlen(pbuf
)), "reserved (0x%02x)]", buf
[i
] & 0x0f);
324 case 0x50: /* repeat ind */
325 sprintf((pbuf
+strlen(pbuf
)), "[repeat indicator]");
329 sprintf((pbuf
+strlen(pbuf
)), "[UNKNOWN SINGLE OCTET ELEMENT 0x%02x]", buf
[i
]);
338 /* variable length info element */
345 sprintf((pbuf
+strlen(pbuf
)), "[segmented message: ");
348 sprintf((pbuf
+strlen(pbuf
)), "[bearer capability: ");
349 i
+= p_q931bc(pbuf
, &buf
[i
]);
353 sprintf((pbuf
+strlen(pbuf
)), "[cause: ");
354 i
+= p_q931cause(pbuf
, &buf
[i
]);
358 sprintf((pbuf
+strlen(pbuf
)), "[connected address (old): ");
361 sprintf((pbuf
+strlen(pbuf
)), "[extended facility (Q.932: )");
364 sprintf((pbuf
+strlen(pbuf
)), "[call identity: ");
367 sprintf((pbuf
+strlen(pbuf
)), "[call state: ");
371 sprintf((pbuf
+strlen(pbuf
)), "Std=");
372 switch ((buf
[i
] & 0x60) >> 5)
375 sprintf((pbuf
+strlen(pbuf
)), "CCITT");
378 sprintf((pbuf
+strlen(pbuf
)), "ISO/IEC");
381 sprintf((pbuf
+strlen(pbuf
)), "National");
384 sprintf((pbuf
+strlen(pbuf
)), "Special");
387 sprintf((pbuf
+strlen(pbuf
)), ", State=");
389 switch ((buf
[i
] & 0x3f))
392 sprintf((pbuf
+strlen(pbuf
)), "Null");
395 sprintf((pbuf
+strlen(pbuf
)), "Call initiated");
398 sprintf((pbuf
+strlen(pbuf
)), "Overlap sending");
401 sprintf((pbuf
+strlen(pbuf
)), "Outgoing call proceeding");
404 sprintf((pbuf
+strlen(pbuf
)), "Call delivered");
407 sprintf((pbuf
+strlen(pbuf
)), "Call present");
410 sprintf((pbuf
+strlen(pbuf
)), "Call received");
413 sprintf((pbuf
+strlen(pbuf
)), "Connect request");
416 sprintf((pbuf
+strlen(pbuf
)), "Incoming call proceeding");
419 sprintf((pbuf
+strlen(pbuf
)), "Active");
422 sprintf((pbuf
+strlen(pbuf
)), "Disconnect request");
425 sprintf((pbuf
+strlen(pbuf
)), "Disconnect indication");
428 sprintf((pbuf
+strlen(pbuf
)), "Suspend request");
431 sprintf((pbuf
+strlen(pbuf
)), "Resume request");
434 sprintf((pbuf
+strlen(pbuf
)), "Release request");
437 sprintf((pbuf
+strlen(pbuf
)), "Call abort");
440 sprintf((pbuf
+strlen(pbuf
)), "Overlap receiving");
443 sprintf((pbuf
+strlen(pbuf
)), "Restart request");
446 sprintf((pbuf
+strlen(pbuf
)), "Restart");
449 sprintf((pbuf
+strlen(pbuf
)), "ERROR: undefined/reserved");
452 sprintf((pbuf
+strlen(pbuf
)), "]");
457 sprintf((pbuf
+strlen(pbuf
)), "[channel id: channel=");
461 switch (buf
[i
] & 0x03)
464 sprintf((pbuf
+strlen(pbuf
)), "no channel");
467 sprintf((pbuf
+strlen(pbuf
)), "B-1");
470 sprintf((pbuf
+strlen(pbuf
)), "B-2");
473 sprintf((pbuf
+strlen(pbuf
)), "any channel");
477 sprintf((pbuf
+strlen(pbuf
)), " (exclusive)]");
479 sprintf((pbuf
+strlen(pbuf
)), " (preferred)]");
484 sprintf((pbuf
+strlen(pbuf
)), "[data link connection id (Q.933): ");
487 i
+= q932_facility(pbuf
, &buf
[i
]);
491 sprintf((pbuf
+strlen(pbuf
)), "[progress ind: ");
495 sprintf((pbuf
+strlen(pbuf
)), "Std=");
496 switch ((buf
[i
] & 0x60) >> 5)
499 sprintf((pbuf
+strlen(pbuf
)), "CCITT");
502 sprintf((pbuf
+strlen(pbuf
)), "ISO/IEC");
505 sprintf((pbuf
+strlen(pbuf
)), "National");
508 sprintf((pbuf
+strlen(pbuf
)), "Local");
511 sprintf((pbuf
+strlen(pbuf
)), ", Loc=");
513 switch ((buf
[i
] & 0x0f))
516 sprintf((pbuf
+strlen(pbuf
)), "User");
519 sprintf((pbuf
+strlen(pbuf
)), "Private network serving local user");
522 sprintf((pbuf
+strlen(pbuf
)), "Public network serving local user");
525 sprintf((pbuf
+strlen(pbuf
)), "Transit network");
528 sprintf((pbuf
+strlen(pbuf
)), "Public network serving remote user");
531 sprintf((pbuf
+strlen(pbuf
)), "Private network serving remote user");
534 sprintf((pbuf
+strlen(pbuf
)), "Network beyond interworking point");
537 sprintf((pbuf
+strlen(pbuf
)), "ERROR: undefined/reserved");
543 sprintf((pbuf
+strlen(pbuf
)), "\n Description: ");
545 switch ((buf
[i
] & 0x7f))
548 sprintf((pbuf
+strlen(pbuf
)), "Call is not end-to-end ISDN");
551 sprintf((pbuf
+strlen(pbuf
)), "Destination address is non-ISDN");
554 sprintf((pbuf
+strlen(pbuf
)), "Origination address is non-ISDN");
557 sprintf((pbuf
+strlen(pbuf
)), "Call has returned to the ISDN");
560 sprintf((pbuf
+strlen(pbuf
)), "Interworking occurred, Service change");
563 sprintf((pbuf
+strlen(pbuf
)), "In-band info or appropriate pattern now available");
566 sprintf((pbuf
+strlen(pbuf
)), "ERROR: undefined/reserved");
569 sprintf((pbuf
+strlen(pbuf
)), "]");
574 sprintf((pbuf
+strlen(pbuf
)), "[network specific facilities: ");
577 sprintf((pbuf
+strlen(pbuf
)), "[terminal capabilities: ");
580 sprintf((pbuf
+strlen(pbuf
)), "[notification indicator: ");
581 i
+= p_q931notification(pbuf
, &buf
[i
]);
585 sprintf((pbuf
+strlen(pbuf
)), "[display: ");
589 for (j
= 0; j
< len
; j
++)
591 sprintf((pbuf
+strlen(pbuf
)),"%c", buf
[j
+i
]);
593 sprintf((pbuf
+strlen(pbuf
)),"]");
598 sprintf((pbuf
+strlen(pbuf
)), "[date/time: ");
603 sprintf((pbuf
+strlen(pbuf
)),"%.2d.%.2d.%.2d",
604 buf
[i
+2], buf
[i
+1], buf
[i
]);
608 sprintf((pbuf
+strlen(pbuf
))," %.2d", buf
[i
+3]);
613 sprintf((pbuf
+strlen(pbuf
)),":%.2d", buf
[i
+4]);
618 sprintf((pbuf
+strlen(pbuf
)),":%.2d", buf
[i
+5]);
621 sprintf((pbuf
+strlen(pbuf
)),"]");
626 sprintf((pbuf
+strlen(pbuf
)), "[keypad: ");
629 sprintf((pbuf
+strlen(pbuf
)), "[keypad echo: ");
632 sprintf((pbuf
+strlen(pbuf
)), "[information req (Q.932): ");
635 sprintf((pbuf
+strlen(pbuf
)), "[signal: ");
638 sprintf((pbuf
+strlen(pbuf
)), "[switchhook: ");
641 sprintf((pbuf
+strlen(pbuf
)), "[feature activation (Q.932): ");
644 sprintf((pbuf
+strlen(pbuf
)), "[feature ind (Q.932): ");
647 sprintf((pbuf
+strlen(pbuf
)), "[service profile id (Q.932): ");
650 sprintf((pbuf
+strlen(pbuf
)), "[endpoint id (Q.932): ");
653 sprintf((pbuf
+strlen(pbuf
)), "[information rate: ");
656 sprintf((pbuf
+strlen(pbuf
)), "[precedence level (Q.955): ");
659 sprintf((pbuf
+strlen(pbuf
)), "[end-to-end transit delay: ");
662 sprintf((pbuf
+strlen(pbuf
)), "[transit delay detection and indication: ");
665 sprintf((pbuf
+strlen(pbuf
)), "[packet layer binary parameters: ");
668 sprintf((pbuf
+strlen(pbuf
)), "[packet layer window size: ");
671 sprintf((pbuf
+strlen(pbuf
)), "[packet size: ");
674 sprintf((pbuf
+strlen(pbuf
)), "[closed user group: ");
677 sprintf((pbuf
+strlen(pbuf
)), "[link layer core parameters (Q.933): ");
680 sprintf((pbuf
+strlen(pbuf
)), "[link layer protocol parameters (Q.933): ");
683 sprintf((pbuf
+strlen(pbuf
)), "[reverse charging information: ");
686 sprintf((pbuf
+strlen(pbuf
)), "[connected number (Q.951): ");
687 i
+= p_q931address(pbuf
, &buf
[i
]);
693 sprintf((pbuf
+strlen(pbuf
)), "[connected subaddress (Q.951): ");
696 sprintf((pbuf
+strlen(pbuf
)), "[X.213 priority (Q.933): ");
699 sprintf((pbuf
+strlen(pbuf
)), "[report type (Q.933): ");
702 sprintf((pbuf
+strlen(pbuf
)), "[link integrity verification (Q.933): ");
705 sprintf((pbuf
+strlen(pbuf
)), "[PVC status (Q.933): ");
708 sprintf((pbuf
+strlen(pbuf
)), "[calling party number: ");
709 i
+= p_q931address(pbuf
, &buf
[i
]);
713 sprintf((pbuf
+strlen(pbuf
)), "[calling party subaddress: ");
716 sprintf((pbuf
+strlen(pbuf
)), "[called party number: ");
717 i
+= p_q931address(pbuf
, &buf
[i
]);
721 sprintf((pbuf
+strlen(pbuf
)), "[called party subaddress: ");
724 sprintf((pbuf
+strlen(pbuf
)), "[redirecting number: ");
725 i
+= p_q931redir(pbuf
, &buf
[i
]);
729 sprintf((pbuf
+strlen(pbuf
)), "[redirection number: ");
730 i
+= p_q931redir(pbuf
, &buf
[i
]);
734 sprintf((pbuf
+strlen(pbuf
)), "[transit network selection: ");
737 sprintf((pbuf
+strlen(pbuf
)), "[restart indicator: ");
740 sprintf((pbuf
+strlen(pbuf
)), "[low layer compatibility: ");
743 sprintf((pbuf
+strlen(pbuf
)), "[high layer compatibility:");
744 i
+= p_q931high_compat(pbuf
, &buf
[i
]);
748 sprintf((pbuf
+strlen(pbuf
)), "[user-user: ");
749 i
+= p_q931user_user(pbuf
, &buf
[i
]);
753 sprintf((pbuf
+strlen(pbuf
)), "[escape for extension: ");
756 sprintf((pbuf
+strlen(pbuf
)), "[UNKNOWN INFO-ELEMENT-ID=0x%02x: ", buf
[i
]);
762 sprintf((pbuf
+strlen(pbuf
)), "[UNKNOWN CODESET=%d, IE=0x%02x: ", codeset
, buf
[i
]);
765 i
++; /* index -> length */
769 sprintf((pbuf
+strlen(pbuf
)), "LEN=0x%02x, DATA=", len
);
771 i
++; /* index -> 1st param */
773 for (j
= 0; j
< len
; j
++)
775 sprintf((pbuf
+strlen(pbuf
)),"0x%02x ", buf
[j
+i
]);
778 sprintf((pbuf
+strlen(pbuf
)),"]");
784 if (!codelock
&& (codeset
!= oldcodeset
))
785 codeset
= oldcodeset
;
788 sprintf((pbuf
+strlen(pbuf
)),"\n");