diff options
Diffstat (limited to 'usr.sbin/i4b/isdntrace/q931.c')
-rw-r--r-- | usr.sbin/i4b/isdntrace/q931.c | 783 |
1 files changed, 783 insertions, 0 deletions
diff --git a/usr.sbin/i4b/isdntrace/q931.c b/usr.sbin/i4b/isdntrace/q931.c new file mode 100644 index 0000000..3cc2a38 --- /dev/null +++ b/usr.sbin/i4b/isdntrace/q931.c @@ -0,0 +1,783 @@ +/* + * Copyright (c) 1997, 1998 Hellmuth Michaelis. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + *--------------------------------------------------------------------------- + * + * q931.c - print Q.931 traces + * --------------------------- + * + * $Id: q931.c,v 1.4 1998/12/05 18:04:19 hm Exp $ + * + * last edit-date: [Sat Dec 5 18:20:31 1998] + * + *---------------------------------------------------------------------------*/ + +#include "trace.h" + +/*---------------------------------------------------------------------------* + * decode Q.931 protocol + *---------------------------------------------------------------------------*/ +void +decode_q931(char *pbuf, int n, int off, unsigned char *buf, int raw) +{ + int codeset = 0; + int codelock = 0; + int oldcodeset = 0; + + int pd; + int len; + int j; + int i; + + if(n <= 0) + return; + + *pbuf = '\0'; + + if(raw) + { + + for (i = 0; i < n; i += 16) + { + sprintf((pbuf+strlen(pbuf)),"Dump:%.3d ", i+off); + for (j = 0; j < 16; j++) + if (i + j < n) + sprintf((pbuf+strlen(pbuf)),"%02x ", buf[i + j]); + else + sprintf((pbuf+strlen(pbuf))," "); + sprintf((pbuf+strlen(pbuf))," "); + for (j = 0; j < 16 && i + j < n; j++) + if (isprint(buf[i + j])) + sprintf((pbuf+strlen(pbuf)),"%c", buf[i + j]); + else + sprintf((pbuf+strlen(pbuf)),"."); + sprintf((pbuf+strlen(pbuf)),"\n"); + } + } + + i = 0; + + sprintf((pbuf+strlen(pbuf)), "Q931: "); + + /* protocol discriminator */ + + pd = buf[i]; + + if(pd >= 0x00 && pd <= 0x07) + sprintf((pbuf+strlen(pbuf)), "pd=User-User (0x%02x), ",pd); + else if(pd == 0x08) + sprintf((pbuf+strlen(pbuf)), "pd=Q.931/I.451, "); + else if(pd >= 0x10 && pd <= 0x3f) + sprintf((pbuf+strlen(pbuf)), "pd=Other Layer 3 or X.25 (0x%02x), ",pd); + else if(pd >= 0x40 && pd <= 0x4f) + sprintf((pbuf+strlen(pbuf)), "pd=National Use (0x%02x), ",pd); + else if(pd >= 0x50 && pd <= 0xfe) + sprintf((pbuf+strlen(pbuf)), "pd=Other Layer 3 or X.25 (0x%02x), ",pd); + else + sprintf((pbuf+strlen(pbuf)), "pd=Reserved (0x%02x), ",pd); + + /* call reference */ + + i++; + + len = buf[i] & 0x0f; + + switch(len) + { + case 0: + sprintf((pbuf+strlen(pbuf)), "cr=Dummy, "); + break; + case 1: + sprintf((pbuf+strlen(pbuf)), "cr=0x%02x %s, ", (buf[i+1] & 0x7f), (buf[i+1] & 0x80) ? "(from destination)" : "(from origination)"); + break; + case 2: + sprintf((pbuf+strlen(pbuf)), "cr=0x%02x 0x%02x %s, ", (buf[i+1] & 0x7f), (buf[i+2] & 0x7f), (buf[i+1] & 0x80) ? "(org)" : "(dst)"); + break; + } + + i += (len+1); + + /* message type */ + + sprintf((pbuf+strlen(pbuf)), "message="); + + switch(buf[i]) + { + /* escape to nationally specific message type */ + + case 0x00: + sprintf((pbuf+strlen(pbuf)), "ESCAPE: "); + break; + + /* call establishment */ + + case 0x01: + sprintf((pbuf+strlen(pbuf)), "ALERTING: "); + break; + case 0x02: + sprintf((pbuf+strlen(pbuf)), "CALL PROCEEDING: "); + break; + case 0x03: + sprintf((pbuf+strlen(pbuf)), "PROGRESS: "); + break; + case 0x05: + sprintf((pbuf+strlen(pbuf)), "SETUP: "); + break; + case 0x07: + sprintf((pbuf+strlen(pbuf)), "CONNECT: "); + break; + case 0x0d: + sprintf((pbuf+strlen(pbuf)), "SETUP ACKNOWLEDGE: "); + break; + case 0x0f: + sprintf((pbuf+strlen(pbuf)), "CONNECT ACKNOWLEDGE: "); + break; + + /* call information phase */ + + case 0x20: + sprintf((pbuf+strlen(pbuf)), "USER INFORMATION: "); + break; + case 0x21: + sprintf((pbuf+strlen(pbuf)), "SUSPEND REJECT: "); + break; + case 0x22: + sprintf((pbuf+strlen(pbuf)), "RESUME REJECT: "); + break; + case 0x24: + sprintf((pbuf+strlen(pbuf)), "HOLD (Q.932): "); + break; + case 0x25: + sprintf((pbuf+strlen(pbuf)), "SUSPEND: "); + break; + case 0x26: + sprintf((pbuf+strlen(pbuf)), "RESUME: "); + break; + case 0x28: + sprintf((pbuf+strlen(pbuf)), "HOLD ACKNOWLEDGE (Q.932): "); + break; + case 0x2d: + sprintf((pbuf+strlen(pbuf)), "SUSPEND ACKNOWLEDGE: "); + break; + case 0x2e: + sprintf((pbuf+strlen(pbuf)), "RESUME ACKNOWLEDGE: "); + break; + case 0x30: + sprintf((pbuf+strlen(pbuf)), "HOLD REJECT (Q.932): "); + break; + case 0x31: + sprintf((pbuf+strlen(pbuf)), "RETRIEVE (Q.932): "); + break; + case 0x32: + sprintf((pbuf+strlen(pbuf)), "RETRIEVE ACKNOWLEDGE (Q.932): "); + break; + case 0x37: + sprintf((pbuf+strlen(pbuf)), "RETRIEVE REJECT (Q.932): "); + break; + + /* call clearing */ + + case 0x40: + sprintf((pbuf+strlen(pbuf)), "DETACH: "); + break; + case 0x45: + sprintf((pbuf+strlen(pbuf)), "DISCONNECT: "); + break; + case 0x46: + sprintf((pbuf+strlen(pbuf)), "RESTART: "); + break; + case 0x48: + sprintf((pbuf+strlen(pbuf)), "DETACH ACKNOWLEDGE: "); + break; + case 0x4d: + sprintf((pbuf+strlen(pbuf)), "RELEASE: "); + break; + case 0x4e: + sprintf((pbuf+strlen(pbuf)), "RESTART ACKNOWLEDGE: "); + break; + case 0x5a: + sprintf((pbuf+strlen(pbuf)), "RELEASE COMPLETE: "); + break; + + /* misc messages */ + + case 0x60: + sprintf((pbuf+strlen(pbuf)), "SEGMENT: "); + break; + case 0x62: + sprintf((pbuf+strlen(pbuf)), "FACILITY (Q.932): "); + break; + case 0x64: + sprintf((pbuf+strlen(pbuf)), "REGISTER (Q.932): "); + break; + case 0x68: + sprintf((pbuf+strlen(pbuf)), "CANCEL ACKNOWLEDGE: "); + break; + case 0x6a: + sprintf((pbuf+strlen(pbuf)), "FACILITY ACKNOWLEDGE: "); + break; + case 0x6c: + sprintf((pbuf+strlen(pbuf)), "REGISTER ACKNOWLEDGE: "); + break; + case 0x6e: + sprintf((pbuf+strlen(pbuf)), "NOTIFY: "); + break; + case 0x70: + sprintf((pbuf+strlen(pbuf)), "CANCEL REJECT: "); + break; + case 0x72: + sprintf((pbuf+strlen(pbuf)), "FACILITY REJECT: "); + break; + case 0x74: + sprintf((pbuf+strlen(pbuf)), "REGISTER REJECT: "); + break; + case 0x75: + sprintf((pbuf+strlen(pbuf)), "STATUS ENQIRY: "); + break; + case 0x79: + sprintf((pbuf+strlen(pbuf)), "CONGESTION CONTROL: "); + break; + case 0x7b: + sprintf((pbuf+strlen(pbuf)), "INFORMATION: "); + break; + case 0x7d: + sprintf((pbuf+strlen(pbuf)), "STATUS: "); + break; + default: + sprintf((pbuf+strlen(pbuf)), "UNDEFINED, TYPE=0x%02x, ", buf[i]); + break; + } + + /* other information elements */ + + i++; + + for (; i < n;) + { + sprintf((pbuf+strlen(pbuf)), "\n "); + + if(buf[i] & 0x80) + { + /* single octett info element */ + + switch(buf[i] & 0x70) + { + case 0x00: /* reserved */ + sprintf((pbuf+strlen(pbuf)), "[reserved single octett info]"); + break; + + case 0x10: /* shift */ + oldcodeset = codeset; + codeset = buf[i] & 0x07; + if(buf[i] & 0x08) + codelock = 0; + else + codelock = 1; + sprintf((pbuf+strlen(pbuf)), "[shift: codeset=%d lock=%d]", codeset, codelock); + break; + + case 0x20: /* more data */ + if(buf[i] & 0x01) + sprintf((pbuf+strlen(pbuf)), "[sending complete]"); + else + sprintf((pbuf+strlen(pbuf)), "[more data]"); + break; + + case 0x30: /* congestion level */ + sprintf((pbuf+strlen(pbuf)), "[congestion level="); + switch(buf[i] & 0x0f) + { + case 0x00: + sprintf((pbuf+strlen(pbuf)), "rx-ready]"); + break; + case 0x0f: + sprintf((pbuf+strlen(pbuf)), "rx-not-ready]"); + break; + default: + sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)]", buf[i] & 0x0f); + break; + } + break; + + case 0x50: /* repeat ind */ + sprintf((pbuf+strlen(pbuf)), "[repeat indicator]"); + break; + + default: + sprintf((pbuf+strlen(pbuf)), "[UNKNOWN SINGLE OCTET ELEMENT 0x%02x]", buf[i]); + break; + } + + i++; /* next */ + + } + else + { + /* variable length info element */ + + if(codeset == 0) + { + switch(buf[i]) + { + case 0x00: + sprintf((pbuf+strlen(pbuf)), "[segmented message: "); + break; + case 0x04: + sprintf((pbuf+strlen(pbuf)), "[bearer capability: "); + i += p_q931bc(pbuf, &buf[i]); + goto next; + break; + case 0x08: + sprintf((pbuf+strlen(pbuf)), "[cause: "); + i += p_q931cause(pbuf, &buf[i]); + goto next; + break; + case 0x0c: + sprintf((pbuf+strlen(pbuf)), "[connected address (old): "); + break; + case 0x0d: + sprintf((pbuf+strlen(pbuf)), "[extended facility (Q.932: )"); + break; + case 0x10: + sprintf((pbuf+strlen(pbuf)), "[call identity: "); + break; + case 0x14: + sprintf((pbuf+strlen(pbuf)), "[call state: "); + i++; + len = buf[i]; + i++; + sprintf((pbuf+strlen(pbuf)), "Std="); + switch((buf[i] & 0x60) >> 5) + { + case 0: + sprintf((pbuf+strlen(pbuf)), "CCITT"); + break; + case 1: + sprintf((pbuf+strlen(pbuf)), "ISO/IEC"); + break; + case 2: + sprintf((pbuf+strlen(pbuf)), "National"); + break; + case 3: + sprintf((pbuf+strlen(pbuf)), "Special"); + break; + } + sprintf((pbuf+strlen(pbuf)), ", State="); + + switch((buf[i] & 0x3f)) + { + case 0: + sprintf((pbuf+strlen(pbuf)), "Null"); + break; + case 1: + sprintf((pbuf+strlen(pbuf)), "Call initiated"); + break; + case 2: + sprintf((pbuf+strlen(pbuf)), "Overlap sending"); + break; + case 3: + sprintf((pbuf+strlen(pbuf)), "Outgoing call proceeding"); + break; + case 4: + sprintf((pbuf+strlen(pbuf)), "Call delivered"); + break; + case 6: + sprintf((pbuf+strlen(pbuf)), "Call present"); + break; + case 7: + sprintf((pbuf+strlen(pbuf)), "Call received"); + break; + case 8: + sprintf((pbuf+strlen(pbuf)), "Connect request"); + break; + case 9: + sprintf((pbuf+strlen(pbuf)), "Incoming call proceeding"); + break; + case 10: + sprintf((pbuf+strlen(pbuf)), "Active"); + break; + case 11: + sprintf((pbuf+strlen(pbuf)), "Disconnect request"); + break; + case 12: + sprintf((pbuf+strlen(pbuf)), "Disconnect indication"); + break; + case 15: + sprintf((pbuf+strlen(pbuf)), "Suspend request"); + break; + case 17: + sprintf((pbuf+strlen(pbuf)), "Resume request"); + break; + case 19: + sprintf((pbuf+strlen(pbuf)), "Release request"); + break; + case 22: + sprintf((pbuf+strlen(pbuf)), "Call abort"); + break; + case 25: + sprintf((pbuf+strlen(pbuf)), "Overlap receiving"); + break; + case 0x3d: + sprintf((pbuf+strlen(pbuf)), "Restart request"); + break; + case 0x3e: + sprintf((pbuf+strlen(pbuf)), "Restart"); + break; + default: + sprintf((pbuf+strlen(pbuf)), "ERROR: undefined/reserved"); + break; + } + sprintf((pbuf+strlen(pbuf)), "]"); + i++; + goto next; + break; + case 0x18: + sprintf((pbuf+strlen(pbuf)), "[channel id: channel="); + i++; + len = buf[i]; + i++; + switch(buf[i] & 0x03) + { + case 0: + sprintf((pbuf+strlen(pbuf)), "no channel"); + break; + case 1: + sprintf((pbuf+strlen(pbuf)), "B-1"); + break; + case 2: + sprintf((pbuf+strlen(pbuf)), "B-2"); + break; + case 3: + sprintf((pbuf+strlen(pbuf)), "any channel"); + break; + } + if(buf[i] & 0x08) + sprintf((pbuf+strlen(pbuf)), " (exclusive)]"); + else + sprintf((pbuf+strlen(pbuf)), " (preferred)]"); + i++; + goto next; + break; + case 0x19: + sprintf((pbuf+strlen(pbuf)), "[data link connection id (Q.933): "); + break; + case 0x1c: + i += q932_facility(pbuf, &buf[i]); + goto next; + break; + case 0x1e: + sprintf((pbuf+strlen(pbuf)), "[progress ind: "); + i++; + len = buf[i]; + i++; + sprintf((pbuf+strlen(pbuf)), "Std="); + switch((buf[i] & 0x60) >> 5) + { + case 0: + sprintf((pbuf+strlen(pbuf)), "CCITT"); + break; + case 1: + sprintf((pbuf+strlen(pbuf)), "ISO/IEC"); + break; + case 2: + sprintf((pbuf+strlen(pbuf)), "National"); + break; + case 3: + sprintf((pbuf+strlen(pbuf)), "Local"); + break; + } + sprintf((pbuf+strlen(pbuf)), ", Loc="); + + switch((buf[i] & 0x0f)) + { + case 0: + sprintf((pbuf+strlen(pbuf)), "User"); + break; + case 1: + sprintf((pbuf+strlen(pbuf)), "Private network serving local user"); + break; + case 2: + sprintf((pbuf+strlen(pbuf)), "Public network serving local user"); + break; + case 3: + sprintf((pbuf+strlen(pbuf)), "Transit network"); + break; + case 4: + sprintf((pbuf+strlen(pbuf)), "Public network serving remote user"); + break; + case 5: + sprintf((pbuf+strlen(pbuf)), "Private network serving remote user"); + break; + case 6: + sprintf((pbuf+strlen(pbuf)), "Network beyond interworking point"); + break; + default: + sprintf((pbuf+strlen(pbuf)), "ERROR: undefined/reserved"); + break; + } + + i++; + + sprintf((pbuf+strlen(pbuf)), "\n Description: "); + + switch((buf[i] & 0x7f)) + { + case 1: + sprintf((pbuf+strlen(pbuf)), "Call is not end-to-end ISDN"); + break; + case 2: + sprintf((pbuf+strlen(pbuf)), "Destination address is non-ISDN"); + break; + case 3: + sprintf((pbuf+strlen(pbuf)), "Origination address is non-ISDN"); + break; + case 4: + sprintf((pbuf+strlen(pbuf)), "Call has returned to the ISDN"); + break; + case 5: + sprintf((pbuf+strlen(pbuf)), "Interworking occured, Service change"); + break; + case 8: + sprintf((pbuf+strlen(pbuf)), "In-band info or appropriate pattern now available"); + break; + default: + sprintf((pbuf+strlen(pbuf)), "ERROR: undefined/reserved"); + break; + } + sprintf((pbuf+strlen(pbuf)), "]"); + i++; + goto next; + break; + case 0x20: + sprintf((pbuf+strlen(pbuf)), "[network specific facilities: "); + break; + case 0x24: + sprintf((pbuf+strlen(pbuf)), "[terminal capabilities: "); + break; + case 0x27: + sprintf((pbuf+strlen(pbuf)), "[notification ind: "); + break; + case 0x28: + sprintf((pbuf+strlen(pbuf)), "[display: "); + i++; + len = buf[i]; + i++; + for(j = 0; j < len; j++) + { + sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]); + } + sprintf((pbuf+strlen(pbuf)),"]"); + i += j; + goto next; + break; + case 0x29: + sprintf((pbuf+strlen(pbuf)), "[date/time: "); + i++; + len = buf[i]; + i++; + j = 0; + sprintf((pbuf+strlen(pbuf)),"%.2d.%.2d.%.2d", + buf[i+2], buf[i+1], buf[i]); + j+=3; + if(j < len) + { + sprintf((pbuf+strlen(pbuf))," %.2d", buf[i+3]); + j++; + } + if(j < len) + { + sprintf((pbuf+strlen(pbuf)),":%.2d", buf[i+4]); + j++; + } + if(j < len) + { + sprintf((pbuf+strlen(pbuf)),":%.2d", buf[i+5]); + j++; + } + sprintf((pbuf+strlen(pbuf)),"]"); + i += len; + goto next; + break; + case 0x2c: + sprintf((pbuf+strlen(pbuf)), "[keypad: "); + break; + case 0x30: + sprintf((pbuf+strlen(pbuf)), "[keypad echo: "); + break; + case 0x32: + sprintf((pbuf+strlen(pbuf)), "[information req (Q.932): "); + break; + case 0x34: + sprintf((pbuf+strlen(pbuf)), "[signal: "); + break; + case 0x36: + sprintf((pbuf+strlen(pbuf)), "[switchhook: "); + break; + case 0x38: + sprintf((pbuf+strlen(pbuf)), "[feature activation (Q.932): "); + break; + case 0x39: + sprintf((pbuf+strlen(pbuf)), "[feature ind (Q.932): "); + break; + case 0x3a: + sprintf((pbuf+strlen(pbuf)), "[service profile id (Q.932): "); + break; + case 0x3b: + sprintf((pbuf+strlen(pbuf)), "[endpoint id (Q.932): "); + break; + case 0x40: + sprintf((pbuf+strlen(pbuf)), "[information rate: "); + break; + case 0x41: + sprintf((pbuf+strlen(pbuf)), "[precedence level (Q.955): "); + break; + case 0x42: + sprintf((pbuf+strlen(pbuf)), "[end-to-end transit delay: "); + break; + case 0x43: + sprintf((pbuf+strlen(pbuf)), "[transit delay detection and indication: "); + break; + case 0x44: + sprintf((pbuf+strlen(pbuf)), "[packet layer binary parameters: "); + break; + case 0x45: + sprintf((pbuf+strlen(pbuf)), "[packet layer window size: "); + break; + case 0x46: + sprintf((pbuf+strlen(pbuf)), "[packet size: "); + break; + case 0x47: + sprintf((pbuf+strlen(pbuf)), "[closed user group: "); + break; + case 0x48: + sprintf((pbuf+strlen(pbuf)), "[link layer core parameters (Q.933): "); + break; + case 0x49: + sprintf((pbuf+strlen(pbuf)), "[link layer protocol parameters (Q.933): "); + break; + case 0x4a: + sprintf((pbuf+strlen(pbuf)), "[reverse charging information: "); + break; + case 0x4c: + sprintf((pbuf+strlen(pbuf)), "[connected number (Q.951): "); + i += p_q931address(pbuf, &buf[i]); + goto next; + break; + + break; + case 0x4d: + sprintf((pbuf+strlen(pbuf)), "[connected subaddress (Q.951): "); + break; + case 0x50: + sprintf((pbuf+strlen(pbuf)), "[X.213 priority (Q.933): "); + break; + case 0x51: + sprintf((pbuf+strlen(pbuf)), "[report type (Q.933): "); + break; + case 0x53: + sprintf((pbuf+strlen(pbuf)), "[link integrity verification (Q.933): "); + break; + case 0x57: + sprintf((pbuf+strlen(pbuf)), "[PVC status (Q.933): "); + break; + case 0x6c: + sprintf((pbuf+strlen(pbuf)), "[calling party number: "); + i += p_q931address(pbuf, &buf[i]); + goto next; + break; + case 0x6d: + sprintf((pbuf+strlen(pbuf)), "[calling party subaddress: "); + break; + case 0x70: + sprintf((pbuf+strlen(pbuf)), "[called party number: "); + i += p_q931address(pbuf, &buf[i]); + goto next; + break; + case 0x71: + sprintf((pbuf+strlen(pbuf)), "[called party subaddress: "); + break; + case 0x74: + sprintf((pbuf+strlen(pbuf)), "[redirecting number: "); + break; + case 0x76: + sprintf((pbuf+strlen(pbuf)), "[redirection number: "); + break; + case 0x78: + sprintf((pbuf+strlen(pbuf)), "[transit network selection: "); + break; + case 0x79: + sprintf((pbuf+strlen(pbuf)), "[restart indicator: "); + break; + case 0x7c: + sprintf((pbuf+strlen(pbuf)), "[low layer compatibility: "); + break; + case 0x7d: + sprintf((pbuf+strlen(pbuf)), "[high layer compatibility:"); + i += p_q931high_compat(pbuf, &buf[i]); + goto next; + break; + case 0x7e: + sprintf((pbuf+strlen(pbuf)), "[user-user: "); + break; + case 0x7f: + sprintf((pbuf+strlen(pbuf)), "[escape for extension: "); + break; + default: + sprintf((pbuf+strlen(pbuf)), "[UNKNOWN INFO-ELEMENT-ID=0x%02x: ", buf[i]); + break; + } + } + else + { + sprintf((pbuf+strlen(pbuf)), "[UNKNOWN CODESET=%d, IE=0x%02x: ", codeset, buf[i]); + } + + i++; /* index -> length */ + + len = buf[i]; + + sprintf((pbuf+strlen(pbuf)), "LEN=0x%02x, DATA=", len); + + i++; /* index -> 1st param */ + + for(j = 0; j < len; j++) + { + sprintf((pbuf+strlen(pbuf)),"0x%02x ", buf[j+i]); + } + + sprintf((pbuf+strlen(pbuf)),"]"); + + i += len; + +next: + + if(!codelock && (codeset != oldcodeset)) + codeset = oldcodeset; + } + } + sprintf((pbuf+strlen(pbuf)),"\n"); +} + +/* EOF */ + |