1048 lines
23 KiB
C
1048 lines
23 KiB
C
/*
|
|
* Copyright (c) 1997, 2000 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_util.c - utility functions to print Q.931 traces
|
|
* -----------------------------------------------------
|
|
*
|
|
* $Id: q931_util.c,v 1.3 2003/10/06 09:43:28 itojun Exp $
|
|
*
|
|
* $FreeBSD$
|
|
*
|
|
* last edit-date: [Tue Feb 15 13:52:09 2000]
|
|
*
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
#include "trace.h"
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* decode and print the cause
|
|
*---------------------------------------------------------------------------*/
|
|
int
|
|
p_q931cause(char *pbuf, unsigned char *buf)
|
|
{
|
|
int j;
|
|
int len;
|
|
int i = 0;
|
|
int ls;
|
|
int r = 0;
|
|
int rflag = 0;
|
|
|
|
i++; /* index -> length */
|
|
|
|
len = buf[i];
|
|
|
|
i++; /* coding/location */
|
|
len--;
|
|
|
|
ls = buf[i];
|
|
|
|
i++;
|
|
len--;
|
|
|
|
if (!(buf[i-1] & 0x80))
|
|
{
|
|
r = buf[i];
|
|
rflag = 1;
|
|
i++;
|
|
len--;
|
|
}
|
|
|
|
sprintf((pbuf+strlen(pbuf)), "%s ", print_cause_q850(buf[i] & 0x7f));
|
|
|
|
sprintf((pbuf+strlen(pbuf)), "\n (location=");
|
|
|
|
switch (ls & 0x0f)
|
|
{
|
|
case 0x00:
|
|
sprintf((pbuf+strlen(pbuf)), "user");
|
|
break;
|
|
case 0x01:
|
|
sprintf((pbuf+strlen(pbuf)), "private network serving local user");
|
|
break;
|
|
case 0x02:
|
|
sprintf((pbuf+strlen(pbuf)), "public network serving local user");
|
|
break;
|
|
case 0x03:
|
|
sprintf((pbuf+strlen(pbuf)), "transit network");
|
|
break;
|
|
case 0x04:
|
|
sprintf((pbuf+strlen(pbuf)), "public network serving remote user");
|
|
break;
|
|
case 0x05:
|
|
sprintf((pbuf+strlen(pbuf)), "private network serving remote user");
|
|
break;
|
|
case 0x07:
|
|
sprintf((pbuf+strlen(pbuf)), "international network");
|
|
break;
|
|
case 0x0a:
|
|
sprintf((pbuf+strlen(pbuf)), "network beyond interworking point");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", ls & 0x0f);
|
|
break;
|
|
}
|
|
|
|
sprintf((pbuf+strlen(pbuf)), ", std=");
|
|
|
|
switch ((ls & 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;
|
|
}
|
|
|
|
if (rflag)
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)), ", rec=");
|
|
|
|
switch (r & 0x7f)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), "Q.931");
|
|
break;
|
|
case 3:
|
|
sprintf((pbuf+strlen(pbuf)), "X.21");
|
|
break;
|
|
case 4:
|
|
sprintf((pbuf+strlen(pbuf)), "X.25");
|
|
break;
|
|
case 5:
|
|
sprintf((pbuf+strlen(pbuf)), "Q.1031/Q.1051");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "Reserved");
|
|
break;
|
|
}
|
|
}
|
|
|
|
sprintf((pbuf+strlen(pbuf)),")");
|
|
|
|
i++;
|
|
len--;
|
|
|
|
for (j = 0; j < len; j++)
|
|
sprintf((pbuf+strlen(pbuf))," 0x%02x", buf[j+i]);
|
|
|
|
sprintf((pbuf+strlen(pbuf)),"]");
|
|
|
|
i += (len+1);
|
|
|
|
return(i);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* decode and print the bearer capability
|
|
*---------------------------------------------------------------------------*/
|
|
int
|
|
p_q931bc(char *pbuf, unsigned char *buf)
|
|
{
|
|
int len;
|
|
int i = 0;
|
|
int mr = 0;
|
|
|
|
i++; /* index -> length */
|
|
|
|
len = buf[i];
|
|
|
|
i++;
|
|
|
|
sprintf((pbuf+strlen(pbuf)), "\n cap=");
|
|
|
|
switch (buf[i] & 0x1f)
|
|
{
|
|
case 0x00:
|
|
sprintf((pbuf+strlen(pbuf)), "speech");
|
|
break;
|
|
case 0x08:
|
|
sprintf((pbuf+strlen(pbuf)), "unrestricted digital information");
|
|
break;
|
|
case 0x09:
|
|
sprintf((pbuf+strlen(pbuf)), "restricted digital information");
|
|
break;
|
|
case 0x10:
|
|
sprintf((pbuf+strlen(pbuf)), "3.1 kHz audio");
|
|
break;
|
|
case 0x11:
|
|
sprintf((pbuf+strlen(pbuf)), "unrestricted digital information with tones");
|
|
break;
|
|
case 0x18:
|
|
sprintf((pbuf+strlen(pbuf)), "video");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f);
|
|
break;
|
|
}
|
|
|
|
sprintf((pbuf+strlen(pbuf)), "\n 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)), "NSI Std");
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
len--;
|
|
|
|
sprintf((pbuf+strlen(pbuf)), "\n rate=");
|
|
|
|
switch (buf[i] & 0x1f)
|
|
{
|
|
case 0x00:
|
|
sprintf((pbuf+strlen(pbuf)), "packet mode");
|
|
break;
|
|
case 0x10:
|
|
sprintf((pbuf+strlen(pbuf)), "64 kbit/s");
|
|
break;
|
|
case 0x11:
|
|
sprintf((pbuf+strlen(pbuf)), "2 x 64 kbit/s");
|
|
break;
|
|
case 0x13:
|
|
sprintf((pbuf+strlen(pbuf)), "384 kbit/s");
|
|
break;
|
|
case 0x15:
|
|
sprintf((pbuf+strlen(pbuf)), "1536 kbit/s");
|
|
break;
|
|
case 0x17:
|
|
sprintf((pbuf+strlen(pbuf)), "1920 kbit/s");
|
|
break;
|
|
case 0x18:
|
|
sprintf((pbuf+strlen(pbuf)), "Multirate");
|
|
mr = 1;
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f);
|
|
break;
|
|
}
|
|
|
|
sprintf((pbuf+strlen(pbuf)), "\n mode=");
|
|
|
|
switch ((buf[i] & 0x60) >> 5)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), "circuit");
|
|
break;
|
|
case 2:
|
|
sprintf((pbuf+strlen(pbuf)), "packet");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", ((buf[i] & 0x60) >> 5));
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
len--;
|
|
|
|
if (!len)
|
|
goto exit;
|
|
|
|
if (mr)
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)), "\n rate multiplier=%d", buf[i] & 0x7f);
|
|
i++;
|
|
len--;
|
|
}
|
|
|
|
if (!len)
|
|
goto exit;
|
|
|
|
sprintf((pbuf+strlen(pbuf)), "\n layer1=");
|
|
|
|
switch (buf[i] & 0x1f)
|
|
{
|
|
case 0x01:
|
|
sprintf((pbuf+strlen(pbuf)), "V.110");
|
|
break;
|
|
case 0x02:
|
|
sprintf((pbuf+strlen(pbuf)), "G.711 mu-law");
|
|
break;
|
|
case 0x03:
|
|
sprintf((pbuf+strlen(pbuf)), "G.711 A-law");
|
|
break;
|
|
case 0x04:
|
|
sprintf((pbuf+strlen(pbuf)), "G.721");
|
|
break;
|
|
case 0x05:
|
|
sprintf((pbuf+strlen(pbuf)), "H.221/H.242");
|
|
break;
|
|
case 0x07:
|
|
sprintf((pbuf+strlen(pbuf)), "Non-Std");
|
|
break;
|
|
case 0x08:
|
|
sprintf((pbuf+strlen(pbuf)), "V.120");
|
|
break;
|
|
case 0x09:
|
|
sprintf((pbuf+strlen(pbuf)), "X.31");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f);
|
|
break;
|
|
}
|
|
i++;
|
|
len--;
|
|
|
|
if (!len)
|
|
goto exit;
|
|
|
|
if (!(buf[i-1] & 0x80))
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)), "\n user rate=0x%02x ", buf[i] & 0x1f);
|
|
|
|
if (buf[i] & 0x40)
|
|
sprintf((pbuf+strlen(pbuf)), "(async,");
|
|
else
|
|
sprintf((pbuf+strlen(pbuf)), "(sync,");
|
|
|
|
if (buf[i] & 0x20)
|
|
sprintf((pbuf+strlen(pbuf)), "in-band neg. possible)");
|
|
else
|
|
sprintf((pbuf+strlen(pbuf)), "in-band neg not possible)");
|
|
|
|
i++;
|
|
len--;
|
|
}
|
|
|
|
if (!len)
|
|
goto exit;
|
|
|
|
if (!(buf[i-1] & 0x80))
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)), "\n clk/flow=0x%02x", buf[i] & 0x1f);
|
|
|
|
sprintf((pbuf+strlen(pbuf)), "\n intermediate rate=");
|
|
|
|
switch ((buf[i] & 0x60) >> 5)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), "not used");
|
|
break;
|
|
case 1:
|
|
sprintf((pbuf+strlen(pbuf)), "8 kbit/s");
|
|
break;
|
|
case 2:
|
|
sprintf((pbuf+strlen(pbuf)), "16 kbit/s");
|
|
break;
|
|
case 3:
|
|
sprintf((pbuf+strlen(pbuf)), "32 kbit/s");
|
|
break;
|
|
}
|
|
i++;
|
|
len--;
|
|
}
|
|
|
|
if (!len)
|
|
goto exit;
|
|
|
|
if (!(buf[i-1] & 0x80))
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)), "\n hdr/mfrm/etc.=0x%02x", buf[i]);
|
|
i++;
|
|
len--;
|
|
}
|
|
|
|
if (!len)
|
|
goto exit;
|
|
|
|
if (!(buf[i-1] & 0x80))
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)), "\n stop/data/parity=0x%02x", buf[i]);
|
|
i++;
|
|
len--;
|
|
}
|
|
|
|
if (!len)
|
|
goto exit;
|
|
|
|
if (!(buf[i-1] & 0x80))
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)), "\n modemtype=0x%02x", buf[i]);
|
|
i++;
|
|
len--;
|
|
}
|
|
|
|
if (!len)
|
|
goto exit;
|
|
|
|
switch (buf[i] & 0x7f)
|
|
{
|
|
case 0x42:
|
|
sprintf((pbuf+strlen(pbuf)), "\n layer2=Q.921/I.441");
|
|
break;
|
|
case 0x46:
|
|
sprintf((pbuf+strlen(pbuf)), "\n layer2=X.25 link");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "\n layer2=0x%02x",(buf[i] & 0x7f));
|
|
break;
|
|
}
|
|
i++;
|
|
len--;
|
|
|
|
if (!len)
|
|
goto exit;
|
|
|
|
switch (buf[i] & 0x7f)
|
|
{
|
|
case 0x62:
|
|
sprintf((pbuf+strlen(pbuf)), "\n layer3=Q.921/I.441");
|
|
break;
|
|
case 0x66:
|
|
sprintf((pbuf+strlen(pbuf)), "\n layer3=X.25 packet");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "\n layer3=0x%02x",(buf[i] & 0x7f));
|
|
break;
|
|
}
|
|
i++;
|
|
len--;
|
|
|
|
exit:
|
|
sprintf((pbuf+strlen(pbuf)), "]");
|
|
return(i);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* decode and print the ISDN (telephone) number
|
|
*---------------------------------------------------------------------------*/
|
|
int
|
|
p_q931address(char *pbuf, unsigned char *buf)
|
|
{
|
|
int j;
|
|
int len;
|
|
int i = 0;
|
|
int tp;
|
|
int ind = 0;
|
|
int indflag = 0;
|
|
|
|
i++; /* index -> length */
|
|
len = buf[i];
|
|
|
|
i++; /* index -> type/plan */
|
|
tp = buf[i];
|
|
|
|
i++;
|
|
len--;
|
|
|
|
if (!(tp & 0x80))
|
|
{
|
|
ind = buf[i];
|
|
indflag = 1;
|
|
i++;
|
|
len--;
|
|
}
|
|
|
|
for (j = 0; j < len; j++)
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
|
|
}
|
|
|
|
switch ((tp & 0x70) >> 4)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=unknown, ");
|
|
break;
|
|
case 1:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=international, ");
|
|
break;
|
|
case 2:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=national, ");
|
|
break;
|
|
case 3:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=network specific, ");
|
|
break;
|
|
case 4:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=subscriber, ");
|
|
break;
|
|
case 6:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=abbreviated, ");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=reserved (%d), ", ((tp & 0x70) >> 4));
|
|
break;
|
|
}
|
|
|
|
switch (tp & 0x0f)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=unknown");
|
|
break;
|
|
case 1:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=ISDN");
|
|
break;
|
|
case 3:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=Data");
|
|
break;
|
|
case 4:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=Telex");
|
|
break;
|
|
case 8:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=National");
|
|
break;
|
|
case 9:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=private");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=reserved (%d)", (tp & 0x0f));
|
|
break;
|
|
}
|
|
|
|
if (indflag)
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)), ",\n ");
|
|
switch ((ind & 0x60) >> 5)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), "presentation allowed, ");
|
|
break;
|
|
case 1:
|
|
sprintf((pbuf+strlen(pbuf)), "presentation restricted, ");
|
|
break;
|
|
case 2:
|
|
sprintf((pbuf+strlen(pbuf)), "number not available, ");
|
|
break;
|
|
case 3:
|
|
sprintf((pbuf+strlen(pbuf)), "reserved, ");
|
|
break;
|
|
}
|
|
|
|
switch (ind & 0x03)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), "screening user provided: not screened");
|
|
break;
|
|
case 1:
|
|
sprintf((pbuf+strlen(pbuf)), "screening user provided: verified & passed");
|
|
break;
|
|
case 2:
|
|
sprintf((pbuf+strlen(pbuf)), "screening user provided: verified & failed");
|
|
break;
|
|
case 3:
|
|
sprintf((pbuf+strlen(pbuf)), "screening network provided");
|
|
break;
|
|
}
|
|
}
|
|
|
|
sprintf((pbuf+strlen(pbuf)),")]");
|
|
|
|
i += j;
|
|
|
|
return(i);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* decode and print HL comatibility
|
|
*---------------------------------------------------------------------------*/
|
|
int
|
|
p_q931high_compat(char *pbuf, unsigned char *buf)
|
|
{
|
|
int len = buf[1];
|
|
|
|
sprintf(pbuf+strlen(pbuf), " standard=");
|
|
|
|
switch ((buf[2] >> 5) & 0x03)
|
|
{
|
|
case 0: sprintf(pbuf+strlen(pbuf), "CCITT");
|
|
break;
|
|
case 1: sprintf(pbuf+strlen(pbuf), "unknown international standard");
|
|
break;
|
|
case 2: sprintf(pbuf+strlen(pbuf), "unknown national standard");
|
|
break;
|
|
case 3: sprintf(pbuf+strlen(pbuf), "local network standard");
|
|
}
|
|
|
|
len--;
|
|
|
|
sprintf(pbuf+strlen(pbuf), ", characteristics=");
|
|
|
|
switch (buf[3] & 0x7f)
|
|
{
|
|
case 0x01:
|
|
sprintf(pbuf+strlen(pbuf), "Telephony");
|
|
break;
|
|
case 0x04:
|
|
sprintf(pbuf+strlen(pbuf), "Fax Group 2/3");
|
|
break;
|
|
case 0x21:
|
|
sprintf(pbuf+strlen(pbuf), "Fax Group 4 Class I (F.184)");
|
|
break;
|
|
case 0x24:
|
|
sprintf(pbuf+strlen(pbuf), "Teletex basic/mixed (F.230) or Fax Group 4 Class II/III (F.184)");
|
|
break;
|
|
case 0x28:
|
|
sprintf(pbuf+strlen(pbuf), "Teletex basic/processable (F.220)");
|
|
break;
|
|
case 0x31:
|
|
sprintf(pbuf+strlen(pbuf), "Teletex basic mode (F.200)");
|
|
break;
|
|
case 0x32:
|
|
sprintf(pbuf+strlen(pbuf), "Videotex (F.300 and T.101)");
|
|
break;
|
|
case 0x35:
|
|
sprintf(pbuf+strlen(pbuf), "Telex (F.60)");
|
|
break;
|
|
case 0x38:
|
|
sprintf(pbuf+strlen(pbuf), "MHS (X.400 series)");
|
|
break;
|
|
case 0x41:
|
|
sprintf(pbuf+strlen(pbuf), "OSI application (X.200 series)");
|
|
break;
|
|
case 0x5e:
|
|
sprintf(pbuf+strlen(pbuf), "Maintenance");
|
|
break;
|
|
case 0x5f:
|
|
sprintf(pbuf+strlen(pbuf), "Management");
|
|
break;
|
|
case 0x7f:
|
|
sprintf(pbuf+strlen(pbuf), "reserved");
|
|
break;
|
|
default:
|
|
sprintf(pbuf+strlen(pbuf), "UNKNOWN (0x%02x)", buf[3]);
|
|
break;
|
|
}
|
|
|
|
len--;
|
|
|
|
if (!len)
|
|
{
|
|
sprintf(pbuf+strlen(pbuf), "]");
|
|
return 4;
|
|
}
|
|
|
|
sprintf(pbuf+strlen(pbuf), " of ");
|
|
|
|
switch (buf[4] & 0x7f)
|
|
{
|
|
case 0x01:
|
|
sprintf(pbuf+strlen(pbuf), "Telephony");
|
|
break;
|
|
case 0x04:
|
|
sprintf(pbuf+strlen(pbuf), "Fax Group 2/3");
|
|
break;
|
|
case 0x21:
|
|
sprintf(pbuf+strlen(pbuf), "Fax Group 4 Class I (F.184)");
|
|
break;
|
|
case 0x24:
|
|
sprintf(pbuf+strlen(pbuf), "Teletex basic/mixed (F.230) or Fax Group 4 Class II/III (F.184)");
|
|
break;
|
|
case 0x28:
|
|
sprintf(pbuf+strlen(pbuf), "Teletex basic/processable (F.220)");
|
|
break;
|
|
case 0x31:
|
|
sprintf(pbuf+strlen(pbuf), "Teletex basic mode (F.200)");
|
|
break;
|
|
case 0x32:
|
|
sprintf(pbuf+strlen(pbuf), "Videotex (F.300 and T.101)");
|
|
break;
|
|
case 0x35:
|
|
sprintf(pbuf+strlen(pbuf), "Telex (F.60)");
|
|
break;
|
|
case 0x38:
|
|
sprintf(pbuf+strlen(pbuf), "MHS (X.400 series)");
|
|
break;
|
|
case 0x41:
|
|
sprintf(pbuf+strlen(pbuf), "OSI application (X.200 series)");
|
|
break;
|
|
case 0x7f:
|
|
sprintf(pbuf+strlen(pbuf), "reserved");
|
|
break;
|
|
default:
|
|
sprintf(pbuf+strlen(pbuf), "UNKNOWN (0x%02x)", buf[3]);
|
|
break;
|
|
}
|
|
sprintf(pbuf+strlen(pbuf), "]");
|
|
return 5;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* decode and print user-user IE
|
|
*---------------------------------------------------------------------------*/
|
|
int
|
|
p_q931user_user(char *pbuf, unsigned char *buf)
|
|
{
|
|
int j;
|
|
int len;
|
|
int i = 0;
|
|
int pd;
|
|
|
|
i++; /* index -> length */
|
|
len = buf[i];
|
|
|
|
i++; /* index -> protocoldiscriminator */
|
|
pd = buf[i];
|
|
|
|
switch (pd)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=user-specific");
|
|
break;
|
|
case 1:
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=OSI high-layer protocols");
|
|
break;
|
|
case 2:
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=X.244");
|
|
break;
|
|
case 3:
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=reserved for system management");
|
|
break;
|
|
case 4:
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=IA5 characters");
|
|
break;
|
|
case 6:
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=X.208/X.209 coded user info");
|
|
break;
|
|
case 7:
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=V.120 rate adaption");
|
|
break;
|
|
case 8:
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=Q.931/I.451 user network call control messages");
|
|
break;
|
|
default:
|
|
if (pd >= 0x10 && pd <= 0x3f)
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=0x%x=reserved for other L3 protocols incl. X.25", pd);
|
|
else if (pd >= 0x40 && pd <= 0x47)
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=0x%x=national use", pd);
|
|
else if (pd >= 0x48 && pd <= 0x4f)
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=0x%x=reserved for ETSI", pd);
|
|
else if (pd >= 0x50 && pd <= 0xfe)
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=0x%x=reserved for other L3 protocols incl. X.25", pd);
|
|
else
|
|
sprintf((pbuf+strlen(pbuf)), "(pd=0x%x=reserved", pd);
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
len--;
|
|
|
|
sprintf((pbuf+strlen(pbuf)),": (");
|
|
|
|
for (j = 0; j < len; j++)
|
|
{
|
|
if (pd == 4)
|
|
sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
|
|
else
|
|
sprintf((pbuf+strlen(pbuf)),"0x%2x", buf[j+i]);
|
|
}
|
|
|
|
sprintf((pbuf+strlen(pbuf)),"))]");
|
|
|
|
i += j;
|
|
|
|
return(i);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* decode and notification indicator IE (Q.932, p44)
|
|
*---------------------------------------------------------------------------*/
|
|
int
|
|
p_q931notification(char *pbuf, unsigned char *buf)
|
|
{
|
|
int j = 0;
|
|
int len;
|
|
int i = 0;
|
|
int nd;
|
|
|
|
i++; /* index -> length */
|
|
len = buf[i];
|
|
|
|
i++; /* index -> notification description */
|
|
nd = buf[i];
|
|
|
|
switch (nd)
|
|
{
|
|
case 0x80:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, user suspended", nd);
|
|
break;
|
|
case 0x81:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, user resumed", nd);
|
|
break;
|
|
case 0x82:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, bearer service changed", nd);
|
|
break;
|
|
|
|
case 0x83:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, BER coded information", nd);
|
|
break;
|
|
|
|
case 0xc2:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, conference established", nd);
|
|
break;
|
|
case 0xc3:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, conference disconnected", nd);
|
|
break;
|
|
case 0xc4:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, other party added", nd);
|
|
break;
|
|
case 0xc5:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, isolated", nd);
|
|
break;
|
|
case 0xc6:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, reattached", nd);
|
|
break;
|
|
case 0xc7:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, other party isolated", nd);
|
|
break;
|
|
case 0xc8:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, other party reattached", nd);
|
|
break;
|
|
case 0xc9:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, other party split", nd);
|
|
break;
|
|
case 0xca:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, other party disconnected", nd);
|
|
break;
|
|
case 0xcb:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, conference floating", nd);
|
|
break;
|
|
case 0xcc:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, conference disconnected, preemption", nd);
|
|
break;
|
|
case 0xcf:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, conference floating, server user preempted", nd);
|
|
break;
|
|
|
|
case 0xe0:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, call is a waiting call", nd);
|
|
break;
|
|
case 0xe8:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, diversion activated", nd);
|
|
break;
|
|
case 0xe9: /* ECT, EN 300 369-1 V1.2.4 p12) */
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, call transferred, alerting", nd);
|
|
break;
|
|
case 0xea: /* ECT, EN 300 369-1 V1.2.4 p12) */
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, call transferred, active", nd);
|
|
break;
|
|
case 0xee:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, reverse charging", nd);
|
|
break;
|
|
|
|
case 0xf9:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, remote hold", nd);
|
|
break;
|
|
case 0xfa:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, remote retrieval", nd);
|
|
break;
|
|
case 0xfb:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, call is diverting", nd);
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "0x%2x, undefined", nd);
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
len--;
|
|
|
|
if (len)
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)),": (");
|
|
|
|
for (; j < len; j++)
|
|
{
|
|
if (nd == 4)
|
|
sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
|
|
else
|
|
sprintf((pbuf+strlen(pbuf)),"0x%2x", buf[j+i]);
|
|
}
|
|
|
|
sprintf((pbuf+strlen(pbuf)),")");
|
|
}
|
|
sprintf((pbuf+strlen(pbuf)),"]");
|
|
i += j;
|
|
|
|
return(i);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
* decode and print redirecting/redirection number
|
|
*---------------------------------------------------------------------------*/
|
|
int
|
|
p_q931redir(char *pbuf, unsigned char *buf)
|
|
{
|
|
int j;
|
|
int len;
|
|
int i = 0;
|
|
int tp;
|
|
int ind = 0;
|
|
int indflag = 0;
|
|
int reas = 0;
|
|
int reasflag = 0;
|
|
|
|
i++; /* index -> length */
|
|
len = buf[i];
|
|
|
|
i++; /* index -> type/plan */
|
|
tp = buf[i];
|
|
|
|
i++;
|
|
len--;
|
|
|
|
if (!(tp & 0x80))
|
|
{
|
|
ind = buf[i];
|
|
indflag = 1;
|
|
i++;
|
|
len--;
|
|
|
|
if (!(ind & 0x80))
|
|
{
|
|
reas = buf[i];
|
|
reasflag = 1;
|
|
i++;
|
|
len--;
|
|
}
|
|
}
|
|
|
|
for (j = 0; j < len; j++)
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
|
|
}
|
|
|
|
switch ((tp & 0x70) >> 4)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=unknown, ");
|
|
break;
|
|
case 1:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=international, ");
|
|
break;
|
|
case 2:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=national, ");
|
|
break;
|
|
case 3:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=network specific, ");
|
|
break;
|
|
case 4:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=subscriber, ");
|
|
break;
|
|
case 6:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=abbreviated, ");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), " (type=reserved (%d), ", ((tp & 0x70) >> 4));
|
|
break;
|
|
}
|
|
|
|
switch (tp & 0x0f)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=unknown");
|
|
break;
|
|
case 1:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=ISDN");
|
|
break;
|
|
case 3:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=Data");
|
|
break;
|
|
case 4:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=Telex");
|
|
break;
|
|
case 8:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=National");
|
|
break;
|
|
case 9:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=private");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "plan=reserved (%d)", (tp & 0x0f));
|
|
break;
|
|
}
|
|
|
|
if (indflag)
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)), ",\n ");
|
|
switch ((ind & 0x60) >> 5)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), "presentation allowed");
|
|
break;
|
|
case 1:
|
|
sprintf((pbuf+strlen(pbuf)), "presentation restricted");
|
|
break;
|
|
case 2:
|
|
sprintf((pbuf+strlen(pbuf)), "number not available");
|
|
break;
|
|
case 3:
|
|
sprintf((pbuf+strlen(pbuf)), "reserved");
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (reasflag)
|
|
{
|
|
sprintf((pbuf+strlen(pbuf)), ",\n ");
|
|
switch (reas & 0x0f)
|
|
{
|
|
case 0:
|
|
sprintf((pbuf+strlen(pbuf)), "reason for diversion: unknown");
|
|
break;
|
|
case 1:
|
|
sprintf((pbuf+strlen(pbuf)), "reason for diversion: call forwarding busy");
|
|
break;
|
|
case 2:
|
|
sprintf((pbuf+strlen(pbuf)), "reason for diversion: call forwarding unconditional");
|
|
break;
|
|
case 0xa:
|
|
sprintf((pbuf+strlen(pbuf)), "reason for diversion: called DTE");
|
|
break;
|
|
case 0xf:
|
|
sprintf((pbuf+strlen(pbuf)), "reason for diversion: call forwarding unconditional");
|
|
break;
|
|
default:
|
|
sprintf((pbuf+strlen(pbuf)), "reason for diversion: reserved (0x%2x)",reas & 0x0f);
|
|
break;
|
|
}
|
|
}
|
|
|
|
sprintf((pbuf+strlen(pbuf)),")]");
|
|
|
|
i += j;
|
|
|
|
return(i);
|
|
}
|
|
|
|
/* EOF */
|
|
|