1434 lines
40 KiB
C
1434 lines
40 KiB
C
|
|
/*
|
|
*
|
|
Copyright (c) Eicon Technology Corporation, 2000.
|
|
*
|
|
This source file is supplied for the exclusive use with Eicon
|
|
Technology Corporation's range of DIVA Server Adapters.
|
|
*
|
|
Eicon File Revision : 1.8
|
|
*
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
*
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the GNU General Public License for more details.
|
|
*
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*
|
|
*/
|
|
/* -------------------------------------------------
|
|
This LOG.C does output to STREAM
|
|
-------------------------------------------------- */
|
|
/* VST #include "platform.h" */
|
|
/*------------------------------------------------------------------*/
|
|
/* File: log.c */
|
|
/* Copyright (c) Diehl ISDN GmbH 1993 - 1998 */
|
|
/* */
|
|
/* xlog interpretation */
|
|
/*------------------------------------------------------------------*/
|
|
#define byte unsigned char
|
|
#define word unsigned short
|
|
#define dword unsigned long
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "cau_1tr6.h"
|
|
#include "cau_q931.h"
|
|
#include "pc.h"
|
|
#if !defined(N_XON)
|
|
#define N_XON 15 /* clear RNR state */
|
|
#endif
|
|
int diva_convert_be2le = 0;
|
|
word diva_word2le (word w);
|
|
/*----------------------------------------------------------------*/
|
|
/* Prints into a buffer instead into a file if PRT2BUF is defined */
|
|
#define Out stream
|
|
static word o; /* index to buffer, not used if printed to file */
|
|
/*----------------------------------------------------------------*/
|
|
/* Define max byte count of a message to print before "cont" */
|
|
/* variable can be set externally to change this behaviour */
|
|
word maxout = 30;
|
|
#define LOBYTE(w) ((byte)(w))
|
|
#define HIBYTE(w) ((byte)(((word)(w) >> 8) & 0xFF))
|
|
struct l1s {
|
|
short length;
|
|
unsigned char i[22];
|
|
};
|
|
struct l2s {
|
|
short code;
|
|
short length;
|
|
unsigned char i[20];
|
|
};
|
|
struct nu_info_s {
|
|
short code;
|
|
short Id;
|
|
short info;
|
|
short info1;
|
|
};
|
|
union par {
|
|
char text[42];
|
|
struct l1s l1;
|
|
struct l2s l2;
|
|
struct nu_info_s nu_info;
|
|
};
|
|
typedef struct xlog_s XLOG;
|
|
struct xlog_s {
|
|
short code;
|
|
union par info;
|
|
};
|
|
typedef struct log_s LOG;
|
|
struct log_s {
|
|
word length;
|
|
word code;
|
|
word timeh;
|
|
word timel;
|
|
byte buffer[80];
|
|
};
|
|
#define ZERO_BASED_INDEX_VALID(x,t) ((unsigned)x < sizeof(t)/sizeof(t[0]))
|
|
#define ONE_BASED_INDEX_VALID(x,t) ((unsigned)x <= sizeof(t)/sizeof(t[0]))
|
|
static char *ll_name[13] = {
|
|
"LL_UDATA",
|
|
"LL_ESTABLISH",
|
|
"LL_RELEASE",
|
|
"LL_DATA",
|
|
"LL_LOCAL",
|
|
"LL_REMOTE",
|
|
"",
|
|
"LL_TEST",
|
|
"LL_MDATA",
|
|
"LL_BUDATA",
|
|
"",
|
|
"LL_XID",
|
|
"LL_XID_R"
|
|
};
|
|
static char *ns_name[13] = {
|
|
"N-MDATA",
|
|
"N-CONNECT",
|
|
"N-CONNECT ACK",
|
|
"N-DISC",
|
|
"N-DISC ACK",
|
|
"N-RESET",
|
|
"N-RESET ACK",
|
|
"N-DATA",
|
|
"N-EDATA",
|
|
"N-UDATA",
|
|
"N-BDATA",
|
|
"N-DATA ACK",
|
|
"N-EDATA ACK"
|
|
};
|
|
static char * l1_name[] = {
|
|
"SYNC_LOST",
|
|
"SYNC_GAINED",
|
|
"L1_DOWN",
|
|
"L1_UP",
|
|
"ACTIVATION_REQ",
|
|
"PS1_DOWN",
|
|
"PS1_UP",
|
|
"L1_FC1",
|
|
"L1_FC2",
|
|
"L1_FC3",
|
|
"L1_FC4"
|
|
};
|
|
static struct {
|
|
byte code;
|
|
char * name;
|
|
} capi20_command[] = {
|
|
{ 0x01, "ALERT" },
|
|
{ 0x02, "CONNECT" },
|
|
{ 0x03, "CONNECT_ACTIVE" },
|
|
{ 0x04, "DISCONNECT" },
|
|
{ 0x05, "LISTEN" },
|
|
{ 0x08, "INFO" },
|
|
{ 0x41, "SELECT_B" },
|
|
{ 0x80, "FACILITY" },
|
|
{ 0x82, "CONNECT_B3" },
|
|
{ 0x83, "CONNECT_B3_ACTIVE" },
|
|
{ 0x84, "DISCONNECT_B3" },
|
|
{ 0x86, "DATA_B3" },
|
|
{ 0x87, "RESET_B3" },
|
|
{ 0x88, "CONNECT_B3_T90_ACTIVE" },
|
|
{ 0xd4, "PORTABILITY" }, /* suspend/resume */
|
|
{ 0xff, "MANUFACTURER" }
|
|
};
|
|
static struct {
|
|
byte code;
|
|
char * name;
|
|
} capi11_command[] = {
|
|
{ 0x01, "RESET_B3" },
|
|
{ 0x02, "CONNECT" },
|
|
{ 0x03, "CONNECT_ACTIVE" },
|
|
{ 0x04, "DISCONNECT" },
|
|
{ 0x05, "LISTEN" },
|
|
{ 0x06, "GET_PARMS" },
|
|
{ 0x07, "INFO" },
|
|
{ 0x08, "DATA" },
|
|
{ 0x09, "CONNECT_INFO" },
|
|
{ 0x40, "SELECT_B2" },
|
|
{ 0x80, "SELECT_B3" },
|
|
{ 0x81, "LISTEN_B3" },
|
|
{ 0x82, "CONNECT_B3" },
|
|
{ 0x83, "CONNECT_B3_ACTIVE" },
|
|
{ 0x84, "DISCONNECT_B3" },
|
|
{ 0x85, "GET_B3_PARMS" },
|
|
{ 0x86, "DATA_B3" },
|
|
{ 0x87, "HANDSET" },
|
|
};
|
|
static struct {
|
|
byte code;
|
|
char * name;
|
|
} capi20_subcommand[] = {
|
|
{ 0x80, "REQ" },
|
|
{ 0x81, "CON" },
|
|
{ 0x82, "IND" },
|
|
{ 0x83, "RES" }
|
|
};
|
|
static struct {
|
|
byte code;
|
|
char * name;
|
|
} capi11_subcommand[] = {
|
|
{ 0x00, "REQ" },
|
|
{ 0x01, "CON" },
|
|
{ 0x02, "IND" },
|
|
{ 0x03, "RES" }
|
|
};
|
|
#define PD_MAX 4
|
|
static struct {
|
|
byte code;
|
|
char * name;
|
|
} pd[PD_MAX] = {
|
|
{ 0x08, "Q.931 " },
|
|
{ 0x0c, "CORNET " },
|
|
{ 0x40, "DKZE " },
|
|
{ 0x41, "1TR6 " }
|
|
};
|
|
#define MT_MAX 34
|
|
static struct {
|
|
byte code;
|
|
char * name;
|
|
} mt[MT_MAX] = {
|
|
{ 0x01, "ALERT" },
|
|
{ 0x02, "CALL_PROC" },
|
|
{ 0x03, "PROGRESS" },
|
|
{ 0x05, "SETUP" },
|
|
{ 0x07, "CONN" },
|
|
{ 0x0d, "SETUP_ACK" },
|
|
{ 0x0f, "CONN_ACK" },
|
|
{ 0x20, "USER_INFO" },
|
|
{ 0x21, "SUSP_REJ" },
|
|
{ 0x22, "RESUME_REJ" },
|
|
{ 0x24, "HOLD_REQ" },
|
|
{ 0x25, "SUSP" },
|
|
{ 0x26, "RESUME" },
|
|
{ 0x28, "HOLD_ACK" },
|
|
{ 0x30, "HOLD_REJ" },
|
|
{ 0x31, "RETRIEVE_REQ" },
|
|
{ 0x33, "RETRIEVE_ACK" },
|
|
{ 0x37, "RETRIEVE_REJ" },
|
|
{ 0x2d, "SUSP_ACK" },
|
|
{ 0x2e, "RESUME_ACK" },
|
|
{ 0x45, "DISC" },
|
|
{ 0x46, "RESTART" },
|
|
{ 0x4d, "REL" },
|
|
{ 0x4e, "RESTART_ACK" },
|
|
{ 0x5a, "REL_COM" },
|
|
{ 0x60, "SEGMENT" },
|
|
{ 0x62, "FACILITY" },
|
|
{ 0x64, "REGISTER" },
|
|
{ 0x6d, "GINFO" },
|
|
{ 0x6e, "NOTIFY" },
|
|
{ 0x75, "STATUS_ENQ" },
|
|
{ 0x79, "CONGESTION_CTRL" },
|
|
{ 0x7d, "STATUS" },
|
|
{ 0x7b, "INFO" }
|
|
};
|
|
#define IE_MAX 41
|
|
static struct {
|
|
word code;
|
|
char * name;
|
|
} ie[IE_MAX] = {
|
|
{ 0x00a1, "Sending complete" },
|
|
{ 0x00a0, "MORE" },
|
|
{ 0x00b0, "Congestion level" },
|
|
{ 0x00d0, "Repeat indicator" },
|
|
{ 0x0000, "SMSG" },
|
|
{ 0x0004, "Bearer Capability" },
|
|
{ 0x0008, "Cause" },
|
|
{ 0x000c, "Connected Address" },
|
|
{ 0x0010, "Call Identity" },
|
|
{ 0x0014, "Call State" },
|
|
{ 0x0018, "Channel Id" },
|
|
{ 0x001a, "Advice of Charge" },
|
|
{ 0x001c, "Facility" },
|
|
{ 0x001e, "Progress Indicator" },
|
|
{ 0x0020, "NSF" },
|
|
{ 0x0027, "Notify Indicator" },
|
|
{ 0x0028, "Display" },
|
|
{ 0x0029, "Date" },
|
|
{ 0x002c, "Key " },
|
|
{ 0x0034, "Signal" },
|
|
{ 0x003a, "SPID" },
|
|
{ 0x003b, "Endpoint Id" },
|
|
{ 0x004c, "Connected Number" },
|
|
{ 0x006c, "Calling Party Number" },
|
|
{ 0x006d, "Calling Party Subaddress" },
|
|
{ 0x0070, "Called Party Number" },
|
|
{ 0x0071, "Called Party Subaddress" },
|
|
{ 0x0074, "Redirected Number" },
|
|
{ 0x0076, "Redirecting Number" },
|
|
{ 0x0078, "TNET" },
|
|
{ 0x0079, "Restart Indicator" },
|
|
{ 0x007c, "LLC" },
|
|
{ 0x007d, "HLC" },
|
|
{ 0x007e, "User User Info" },
|
|
{ 0x007f, "ESC" },
|
|
{ 0x051a, "Advice of Charge" },
|
|
{ 0x061a, "Advice of Charge" },
|
|
{ 0x0601, "Service Indicator" },
|
|
{ 0x0602, "Charging Info" },
|
|
{ 0x0603, "Date" },
|
|
{ 0x0607, "Called Party State" }
|
|
};
|
|
static char * sig_state[] = {
|
|
"Null state",
|
|
"Call initiated",
|
|
"Overlap sending",
|
|
"Outgoing call proceeding",
|
|
"Call delivered",
|
|
"",
|
|
"Call present",
|
|
"Call received",
|
|
"Connect request",
|
|
"Incoming call proceeding",
|
|
"Active",
|
|
"Disconnect request",
|
|
"Disconnect indication",
|
|
"",
|
|
"",
|
|
"Suspend request",
|
|
"",
|
|
"Resume request",
|
|
"",
|
|
"Release request",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"Overlap receiving"
|
|
};
|
|
static char * sig_timeout[] = {
|
|
"",
|
|
"T303",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"T313",
|
|
"",
|
|
"T309",
|
|
"T305",
|
|
"",
|
|
"",
|
|
"",
|
|
"T319",
|
|
"",
|
|
"T318",
|
|
"",
|
|
"T308",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"T302"
|
|
};
|
|
struct msg_s {
|
|
word code;
|
|
word length;
|
|
byte info[1000];
|
|
} message = {0,0,{0}};
|
|
/* MIPS CPU exeption context structure */
|
|
struct xcptcontext {
|
|
dword sr;
|
|
dword cr;
|
|
dword epc;
|
|
dword vaddr;
|
|
dword regs[32];
|
|
dword mdlo;
|
|
dword mdhi;
|
|
dword reseverd;
|
|
dword xclass;
|
|
}xcp;
|
|
/* MIPS CPU exception classes */
|
|
#define XCPC_GENERAL 0
|
|
#define XCPC_TLBMISS 1
|
|
#define XCPC_XTLBMISS 2
|
|
#define XCPC_CACHEERR 3
|
|
#define XCPC_CLASS 0x0ff
|
|
#define XCPC_USRSTACK 0x100
|
|
#define XCPTINTR 0
|
|
#define XCPTMOD 1
|
|
#define XCPTTLBL 2
|
|
#define XCPTTLBS 3
|
|
#define XCPTADEL 4
|
|
#define XCPTADES 5
|
|
#define XCPTIBE 6
|
|
#define XCPTDBE 7
|
|
#define XCPTSYS 8
|
|
#define XCPTBP 9
|
|
#define XCPTRI 10
|
|
#define XCPTCPU 11
|
|
#define XCPTOVF 12
|
|
#define XCPTTRAP 13
|
|
#define XCPTVCEI 14
|
|
#define XCPTFPE 15
|
|
#define XCPTCP2 16
|
|
#define XCPTRES17 17
|
|
#define XCPTRES18 18
|
|
#define XCPTRES19 19
|
|
#define XCPTRES20 20
|
|
#define XCPTRES21 21
|
|
#define XCPTRES22 22
|
|
#define XCPTWATCH 23
|
|
#define XCPTRES24 24
|
|
#define XCPTRES25 25
|
|
#define XCPTRES26 26
|
|
#define XCPTRES27 27
|
|
#define XCPTRES28 28
|
|
#define XCPTRES29 29
|
|
#define XCPTRES30 30
|
|
#define XCPTVCED 31
|
|
#define NXCPT 32
|
|
/* exception classes */
|
|
#define XCPC_GENERAL 0
|
|
#define XCPC_TLBMISS 1
|
|
#define XCPC_XTLBMISS 2
|
|
#define XCPC_CACHEERR 3
|
|
#define XCPC_CLASS 0x0ff
|
|
#define XCPC_USRSTACK 0x100
|
|
/*------------------------------------------------------------------*/
|
|
/* local function prototypes */
|
|
/*------------------------------------------------------------------*/
|
|
word xlog(FILE * stream,XLOG * buffer);
|
|
void xlog_sig(FILE * stream, struct msg_s * message);
|
|
void call_failed_event(FILE * stream, struct msg_s * message, word code);
|
|
void display_q931_message(FILE * stream, struct msg_s * message);
|
|
void display_ie(FILE * stream, byte pd, word w, byte * ie);
|
|
void spid_event(FILE * stream, struct msg_s * message, word code);
|
|
static void rc2str (byte rc, char* p);
|
|
static void encode_sig_req (byte req, char* p, int is_req);
|
|
static void encode_man_req (byte req, char* p, int is_req);
|
|
word xlog(FILE *stream, XLOG * buffer)
|
|
{
|
|
word i;
|
|
word n;
|
|
word code;
|
|
word offs;
|
|
word Id;
|
|
byte nl_sec;
|
|
static char tmp[128];
|
|
o = 0;
|
|
offs = 0;
|
|
buffer->code = diva_word2le (buffer->code);
|
|
switch((byte)buffer->code) {
|
|
case 1:
|
|
n = diva_word2le(buffer->info.l1.length);
|
|
if(buffer->code &0xff00) fprintf(Out,"B%d-X(%03d) ",buffer->code>>8,n);
|
|
else fprintf(Out,"B-X(%03d) ",n);
|
|
if(maxout>30) fprintf(Out,"\n (%04d) - ",0);
|
|
for(i=0;i<n && i<maxout;i++)
|
|
{
|
|
fprintf(Out,"%02X ",buffer->info.l1.i[i]);
|
|
if(++offs>=20 && maxout>30)
|
|
{
|
|
fprintf(Out,"\n (%04d) - ",i+1);
|
|
offs = 0;
|
|
}
|
|
}
|
|
if(n>i) fprintf(Out,"cont");
|
|
break;
|
|
case 2:
|
|
n = diva_word2le(buffer->info.l1.length);
|
|
if(buffer->code &0xff00) fprintf(Out,"B%d-R(%03d) ",buffer->code>>8,n);
|
|
else fprintf(Out,"B-R(%03d) ",n);
|
|
if(maxout>30) fprintf(Out,"\n (%04d) - ",0);
|
|
for(i=0;i<n && i<maxout;i++)
|
|
{
|
|
fprintf(Out,"%02X ",buffer->info.l1.i[i]);
|
|
if(++offs>=20 && maxout>30)
|
|
{
|
|
fprintf(Out,"\n (%04d) - ",i+1);
|
|
offs = 0;
|
|
}
|
|
}
|
|
if(n>i) fprintf(Out,"cont");
|
|
break;
|
|
case 3:
|
|
n = diva_word2le(buffer->info.l1.length);
|
|
fprintf(Out,"D-X(%03d) ",n);
|
|
for(i=0;i<n && i<maxout;i++)
|
|
fprintf(Out,"%02X ",buffer->info.l1.i[i]);
|
|
if(n>i) fprintf(Out,"cont");
|
|
break;
|
|
case 4:
|
|
n = diva_word2le(buffer->info.l1.length);
|
|
fprintf(Out,"D-R(%03d) ",n);
|
|
for(i=0;i<n && i<maxout;i++)
|
|
fprintf(Out,"%02X ",buffer->info.l1.i[i]);
|
|
if(n>i) fprintf(Out,"cont");
|
|
break;
|
|
case 5:
|
|
n = diva_word2le(buffer->info.l2.length);
|
|
fprintf(Out,"SIG-EVENT(%03d)%04X - ",n,diva_word2le(buffer->info.l2.code));
|
|
for(i=0;i<n && i<maxout;i++)
|
|
fprintf(Out,"%02X ",buffer->info.l2.i[i]);
|
|
if(n>i) fprintf(Out,"cont");
|
|
break;
|
|
case 6:
|
|
code = diva_word2le(buffer->info.l2.code);
|
|
if(code && code <= 13)
|
|
fprintf(Out,"%s IND",ll_name[code-1]);
|
|
else
|
|
fprintf(Out,"UNKNOWN LL IND");
|
|
break;
|
|
case 7:
|
|
code = diva_word2le(buffer->info.l2.code);
|
|
if(code && code <= 13)
|
|
fprintf(Out,"%s REQ",ll_name[code-1]);
|
|
else
|
|
fprintf(Out,"UNKNOWN LL REQ");
|
|
break;
|
|
case 8:
|
|
n = diva_word2le(buffer->info.l2.length);
|
|
fprintf(Out,"DEBUG%04X - ",diva_word2le(buffer->info.l2.code));
|
|
for(i=0;i<n && i<maxout;i++)
|
|
fprintf(Out,"%02X ",buffer->info.l2.i[i]);
|
|
if(n>i) fprintf(Out,"cont");
|
|
break;
|
|
case 9: {
|
|
char tmp[2];
|
|
*(word*)&tmp[0] = diva_word2le(*(word*)&buffer->info.text[0]);
|
|
fprintf(Out,"MDL-ERROR(%s)", &tmp[0]);
|
|
}
|
|
break;
|
|
case 10:
|
|
fprintf(Out,"UTASK->PC(%02X)",diva_word2le(buffer->info.l2.code));
|
|
break;
|
|
case 11:
|
|
fprintf(Out,"PC->UTASK(%02X)",diva_word2le(buffer->info.l2.code));
|
|
break;
|
|
case 12:
|
|
n = diva_word2le(buffer->info.l1.length);
|
|
fprintf(Out,"X-X(%03d) ",n);
|
|
for(i=0;i<n && i<maxout;i++)
|
|
fprintf(Out,"%02X ",buffer->info.l1.i[i]);
|
|
if(n>i) fprintf(Out,"cont");
|
|
break;
|
|
case 13:
|
|
n = diva_word2le(buffer->info.l1.length);
|
|
fprintf(Out,"X-R(%03d) ",n);
|
|
for(i=0;i<n && i<maxout;i++)
|
|
fprintf(Out,"%02X ",buffer->info.l1.i[i]);
|
|
if(n>i) fprintf(Out,"cont");
|
|
break;
|
|
case 14:
|
|
code = diva_word2le(buffer->info.nu_info.code)-1;
|
|
Id = diva_word2le(buffer->info.nu_info.Id);
|
|
nl_sec = HIBYTE(diva_word2le(buffer->info.nu_info.Id));
|
|
if((code &0x0f)<=12)
|
|
fprintf(Out,"[%02x] %s IND Id:%02x, Ch:%02x", nl_sec,
|
|
ns_name[code &0x0f],
|
|
(byte)Id, HIBYTE(diva_word2le(buffer->info.nu_info.code)));
|
|
else
|
|
fprintf(Out,"[%02x] N-UNKNOWN NS IND(%02x) Id:%02x, Ch:%02x", nl_sec,
|
|
(byte)(code+1),
|
|
(byte)Id, HIBYTE(diva_word2le(buffer->info.nu_info.code)));
|
|
break;
|
|
case 15:
|
|
code = diva_word2le(buffer->info.nu_info.code)-1;
|
|
Id = diva_word2le(buffer->info.nu_info.Id);
|
|
nl_sec = HIBYTE(diva_word2le(buffer->info.nu_info.Id));
|
|
if (((byte)Id) == NL_ID) {
|
|
fprintf(Out,"[%02x] %s REQ Id:%s, Ch:%02x", nl_sec, "N-ASSIGN",
|
|
"NL_ID", HIBYTE(diva_word2le(buffer->info.nu_info.code)));
|
|
} else if ((byte)(code+1) == REMOVE) {
|
|
fprintf(Out,"[%02x] %s REQ Id:%02x, Ch:%02x", nl_sec, "N-REMOVE",
|
|
(byte)Id, HIBYTE(diva_word2le(buffer->info.nu_info.code)));
|
|
} else if ((byte)(code+1) == N_XON) {
|
|
fprintf(Out,"[%02x] %s REQ Id:%02x, Ch:%02x", nl_sec, "N-XON",
|
|
(byte)Id, HIBYTE(diva_word2le(buffer->info.nu_info.code)));
|
|
} else if ((byte)(code+1) == UREMOVE) {
|
|
fprintf(Out,"[%02x] %s REQ Id:%02x, Ch:%02x", nl_sec, "N-UREMOVE",
|
|
(byte)Id, HIBYTE(diva_word2le(buffer->info.nu_info.code)));
|
|
} else if((code & 0x0f)<=12) {
|
|
fprintf(Out,"[%02x] %s REQ Id:%02x, Ch:%02x", nl_sec, ns_name[code &0x0f],
|
|
(byte)Id, HIBYTE(diva_word2le(buffer->info.nu_info.code)));
|
|
} else {
|
|
fprintf(Out,"[%02x] N-UNKNOWN NS REQ(%02x) Id:%02x, Ch:%02x", nl_sec,
|
|
(byte)(code+1),
|
|
(byte)Id, HIBYTE(diva_word2le(buffer->info.nu_info.code)));
|
|
}
|
|
break;
|
|
case 16:
|
|
fprintf(Out,"TASK %02i: %s",
|
|
diva_word2le(buffer->info.l2.code),buffer->info.l2.i);
|
|
break;
|
|
case 18:
|
|
code = diva_word2le(buffer->info.l2.code);
|
|
fprintf(Out,"IO-REQ %02x",code);
|
|
break;
|
|
case 19:
|
|
code = diva_word2le(buffer->info.l2.code);
|
|
fprintf(Out,"IO-CON %02x",code);
|
|
break;
|
|
case 20:
|
|
code = diva_word2le(buffer->info.l2.code);
|
|
if ( ZERO_BASED_INDEX_VALID(code,l1_name) )
|
|
fprintf(Out, l1_name[code]);
|
|
else
|
|
fprintf(Out, "UNKNOWN L1 STATE (0x%04x)", code);
|
|
break;
|
|
case 21:
|
|
for(i=0;i<(word)diva_word2le(buffer->info.l2.length);i++)
|
|
message.info[message.length++] = buffer->info.l2.i[i];
|
|
if(diva_word2le(buffer->info.l2.code)) {
|
|
switch(diva_word2le(buffer->info.l2.code) &0xff) {
|
|
case 1:
|
|
xlog_sig(stream,&message);
|
|
break;
|
|
default:
|
|
fprintf(Out,"MSG%04X - ",diva_word2le(buffer->info.l2.code));
|
|
for(i=0;i<message.length;i++)
|
|
fprintf(Out,"%02X ",message.info[i]);
|
|
break;
|
|
}
|
|
message.length = 0;
|
|
}
|
|
else {
|
|
fprintf(Out,"MORE");
|
|
}
|
|
break;
|
|
case 22:
|
|
for(i=0;i<(word)diva_word2le(buffer->info.l2.length);i++)
|
|
message.info[message.length++] = buffer->info.l2.i[i];
|
|
if(diva_word2le(buffer->info.l2.code)) {
|
|
switch(diva_word2le(buffer->info.l2.code) &0xff) {
|
|
case 1:
|
|
call_failed_event(stream, &message, diva_word2le(buffer->info.l2.code));
|
|
break;
|
|
case 2:
|
|
spid_event(stream, &message, diva_word2le(buffer->info.l2.code));
|
|
break;
|
|
default:
|
|
fprintf(Out,"EVENT%04X - ",diva_word2le(buffer->info.l2.code));
|
|
for(i=0;i<message.length;i++)
|
|
fprintf(Out,"%02X ",message.info[i]);
|
|
break;
|
|
}
|
|
message.length = 0;
|
|
}
|
|
else {
|
|
fprintf(Out,"MORE");
|
|
}
|
|
break;
|
|
case 23:
|
|
fprintf(Out,"EYE");
|
|
for(i=0; i<(word)diva_word2le(buffer->info.l1.length); i+=2) {
|
|
fprintf(Out," %02x%02x",buffer->info.l1.i[i+1],buffer->info.l1.i[i]);
|
|
}
|
|
break;
|
|
case 24:
|
|
fprintf(Out, "%s", buffer->info.text);
|
|
break;
|
|
case 50:
|
|
//--- register dump comes in two blocks, each 80 Bytes long. Print
|
|
//--- content after second part has been arrived
|
|
if (0 == ((byte)(buffer->code>>8))) // first part
|
|
{
|
|
for (i=0; i<20; i++)
|
|
((dword *)(&xcp.sr))[i] = ((dword *)&buffer->info.text)[i];
|
|
fprintf(Out,"Register Dump part #1 received.");
|
|
break; // wait for next
|
|
}
|
|
for (i=0; i<20; i++)
|
|
((dword *)(&xcp.sr))[i+20] = ((dword *)&buffer->info.text)[i];
|
|
fprintf(Out,"Register Dump part #2 received, printing now:\n");
|
|
fprintf(Out,"CPU Exception Class: %04lx Code:", xcp.xclass);
|
|
switch ((xcp.cr &0x0000007c) >> 2)
|
|
{
|
|
case XCPTINTR: fprintf(Out,"interrupt "); break;
|
|
case XCPTMOD: fprintf(Out,"TLB mod /IBOUND "); break;
|
|
case XCPTTLBL: fprintf(Out,"TLB load /DBOUND "); break;
|
|
case XCPTTLBS: fprintf(Out,"TLB store "); break;
|
|
case XCPTADEL: fprintf(Out,"Address error load "); break;
|
|
case XCPTADES: fprintf(Out,"Address error store "); break;
|
|
case XCPTIBE: fprintf(Out,"Instruction load bus error "); break;
|
|
case XCPTDBE: fprintf(Out,"Data load/store bus error "); break;
|
|
case XCPTSYS: fprintf(Out,"Syscall "); break;
|
|
case XCPTBP: fprintf(Out,"Breakpoint "); break;
|
|
case XCPTCPU: fprintf(Out,"Coprocessor unusable "); break;
|
|
case XCPTRI: fprintf(Out,"Reverd instruction "); break;
|
|
case XCPTOVF: fprintf(Out,"Overflow "); break;
|
|
case 23: fprintf(Out,"WATCH "); break;
|
|
default: fprintf(Out,"Unknown Code "); break;
|
|
}
|
|
fprintf(Out,"\n");
|
|
fprintf(Out,"sr = %08lx\t",xcp.sr);
|
|
fprintf(Out,"cr = %08lx\t",xcp.cr);
|
|
fprintf(Out,"epc = %08lx\t",xcp.epc);
|
|
fprintf(Out,"vadr= %08lx\n",xcp.vaddr);
|
|
fprintf(Out,"zero= %08lx\t",xcp.regs[0]);
|
|
fprintf(Out,"at = %08lx\t",xcp.regs[1]);
|
|
fprintf(Out,"v0 = %08lx\t",xcp.regs[2]);
|
|
fprintf(Out,"v1 = %08lx\n",xcp.regs[3]);
|
|
fprintf(Out,"a0 = %08lx\t",xcp.regs[4]);
|
|
fprintf(Out,"a1 = %08lx\t",xcp.regs[5]);
|
|
fprintf(Out,"a2 = %08lx\t",xcp.regs[6]);
|
|
fprintf(Out,"a3 = %08lx\n",xcp.regs[7]);
|
|
fprintf(Out,"t0 = %08lx\t",xcp.regs[8]);
|
|
fprintf(Out,"t1 = %08lx\t",xcp.regs[9]);
|
|
fprintf(Out,"t2 = %08lx\t",xcp.regs[10]);
|
|
fprintf(Out,"t3 = %08lx\n",xcp.regs[11]);
|
|
fprintf(Out,"t4 = %08lx\t",xcp.regs[12]);
|
|
fprintf(Out,"t5 = %08lx\t",xcp.regs[13]);
|
|
fprintf(Out,"t6 = %08lx\t",xcp.regs[14]);
|
|
fprintf(Out,"t7 = %08lx\n",xcp.regs[15]);
|
|
fprintf(Out,"s0 = %08lx\t",xcp.regs[16]);
|
|
fprintf(Out,"s1 = %08lx\t",xcp.regs[17]);
|
|
fprintf(Out,"s2 = %08lx\t",xcp.regs[18]);
|
|
fprintf(Out,"s3 = %08lx\n",xcp.regs[19]);
|
|
fprintf(Out,"s4 = %08lx\t",xcp.regs[20]);
|
|
fprintf(Out,"s5 = %08lx\t",xcp.regs[21]);
|
|
fprintf(Out,"s6 = %08lx\t",xcp.regs[22]);
|
|
fprintf(Out,"s7 = %08lx\n",xcp.regs[23]);
|
|
fprintf(Out,"t8 = %08lx\t",xcp.regs[24]);
|
|
fprintf(Out,"t9 = %08lx\t",xcp.regs[25]);
|
|
fprintf(Out,"k0 = %08lx\t",xcp.regs[26]);
|
|
fprintf(Out,"k1 = %08lx\n",xcp.regs[27]);
|
|
fprintf(Out,"gp = %08lx\t",xcp.regs[28]);
|
|
fprintf(Out,"sp = %08lx\t",xcp.regs[29]);
|
|
fprintf(Out,"s8 = %08lx\t",xcp.regs[30]);
|
|
fprintf(Out,"ra = %08lx\n",xcp.regs[31]);
|
|
fprintf(Out,"mdlo= %08lx\t",xcp.mdlo);
|
|
fprintf(Out,"mdhi= %08lx\n",xcp.mdhi);
|
|
break;
|
|
case 128:
|
|
case 129:
|
|
n = buffer->info.l1.length;
|
|
if(buffer->code==128) fprintf(Out,"CAPI20_PUT(%03d) ",n);
|
|
else fprintf(Out,"CAPI20_GET(%03d) ",n);
|
|
fprintf(Out,"APPL %04x ",*(word *)&buffer->info.l1.i[0]);
|
|
fprintf(Out,"%04x:%08lx ",*(word *)&buffer->info.l1.i[4],
|
|
*(dword *)&buffer->info.l1.i[6]);
|
|
for(i=0;i<15 && buffer->info.l1.i[2]!=capi20_command[i].code;i++);
|
|
if(i<15) fprintf(Out,"%s ",capi20_command[i].name);
|
|
else fprintf(Out,"CMD(%x) ",buffer->info.l1.i[2]);
|
|
for(i=0;i<4 && buffer->info.l1.i[3]!=capi20_subcommand[i].code;i++);
|
|
if(i<4) fprintf(Out,"%s",capi20_subcommand[i].name);
|
|
else fprintf(Out,"SUB(%x)",buffer->info.l1.i[3]);
|
|
fprintf(Out,"\n ");
|
|
for(i=10;i<n-2;i++)
|
|
fprintf(Out,"%02X ",buffer->info.l1.i[i]);
|
|
break;
|
|
case 130:
|
|
case 131:
|
|
n = buffer->info.l1.length;
|
|
if(buffer->code==130) fprintf(Out,"CAPI11_PUT(%03d) ",n);
|
|
else fprintf(Out,"CAPI11_GET(%03d) ",n);
|
|
fprintf(Out,"APPL %04x ",*(word *)&buffer->info.l1.i[0]);
|
|
fprintf(Out,"%04x:",*(word *)&buffer->info.l1.i[4]);
|
|
for(i=0;i<18 && buffer->info.l1.i[2]!=capi11_command[i].code;i++);
|
|
if(i<18) fprintf(Out,"%s ",capi11_command[i].name);
|
|
else fprintf(Out,"CMD(%x) ",buffer->info.l1.i[2]);
|
|
for(i=0;i<4 && buffer->info.l1.i[3]!=capi11_subcommand[i].code;i++);
|
|
if(i<4) fprintf(Out,"%s",capi11_subcommand[i].name);
|
|
else fprintf(Out,"SUB(%x)",buffer->info.l1.i[3]);
|
|
fprintf(Out,"\n ");
|
|
for(i=6;i<n-2;i++)
|
|
fprintf(Out,"%02X ",buffer->info.l1.i[i]);
|
|
break;
|
|
case 201: { /* Log Return Code */
|
|
char *p;
|
|
Id = diva_word2le(buffer->info.nu_info.Id);
|
|
nl_sec = HIBYTE(diva_word2le(buffer->info.nu_info.Id));
|
|
code = (byte)diva_word2le(buffer->info.nu_info.code);
|
|
sprintf (tmp, "[%02x] N-RC=", nl_sec);
|
|
p = &tmp[strlen(tmp)];
|
|
rc2str ((byte)code, p);
|
|
p = &tmp[strlen(tmp)];
|
|
if (((byte)Id) == NL_ID + GL_ERR_ID) {
|
|
sprintf (p, " Id:%s, Ch:%02x",
|
|
"NL_ID+GL_ERR_ID", HIBYTE(diva_word2le(buffer->info.nu_info.code)));
|
|
} else {
|
|
sprintf (p, " Id:%02x, Ch:%02x",
|
|
(byte)Id, HIBYTE(diva_word2le(buffer->info.nu_info.code)));
|
|
}
|
|
fprintf(Out,"%s", tmp);
|
|
} break;
|
|
case 202:
|
|
Id = diva_word2le(buffer->info.nu_info.Id);
|
|
code = diva_word2le(buffer->info.nu_info.code);
|
|
nl_sec = HIBYTE(diva_word2le(buffer->info.nu_info.Id));
|
|
fprintf(Out,"[%02x] N-RNR Id:%02x, Ch:%02x",
|
|
nl_sec, (byte)Id, HIBYTE(code));
|
|
break;
|
|
case 220: /* log XDI request */ {
|
|
char *p;
|
|
code = diva_word2le(buffer->info.nu_info.info) - 1;
|
|
sprintf (tmp, "XDI[%02x] ",
|
|
HIBYTE(diva_word2le(buffer->info.nu_info.code)));
|
|
p = &tmp[strlen(tmp)];
|
|
switch (HIBYTE(diva_word2le(buffer->info.nu_info.info))) {
|
|
case NL_ID: /* NL REQ */
|
|
if (((byte)(code+1) == ASSIGN) &&
|
|
(((byte)diva_word2le(buffer->info.nu_info.Id)) == NL_ID)) {
|
|
strcpy (p,"N-ASSIGN");
|
|
} else if ((byte)(code+1) == REMOVE) {
|
|
strcpy (p, "N-REMOVE");
|
|
} else if ((byte)(code+1) == N_XON) {
|
|
strcpy (p, "N-XON");
|
|
} else if ((byte)(code+1) == UREMOVE) {
|
|
strcpy (p, "N-UREMOVE");
|
|
} else if((code & 0x0f)<=12) {
|
|
strcpy (p, ns_name[code &0x0f]);
|
|
} else {
|
|
sprintf (p, "N-UNKNOWN NS(%02x)",
|
|
(byte)diva_word2le(buffer->info.nu_info.info));
|
|
}
|
|
break;
|
|
case DSIG_ID: /* SIG REQ */
|
|
Id = (byte)diva_word2le(buffer->info.nu_info.Id);
|
|
if (Id == DSIG_ID) {
|
|
strcpy (p, "S-ASSIGN");
|
|
} else {
|
|
encode_sig_req ((byte)diva_word2le(buffer->info.nu_info.info),
|
|
p, 1);
|
|
}
|
|
break;
|
|
case MAN_ID:
|
|
encode_man_req ((byte)diva_word2le(buffer->info.nu_info.info), p, 1);
|
|
break;
|
|
default:
|
|
sprintf (p, "?-(%02x)",
|
|
(byte)diva_word2le(buffer->info.nu_info.info));
|
|
break;
|
|
}
|
|
strcat (tmp, " REQ Id:");
|
|
p = &tmp[strlen(tmp)];
|
|
Id = (byte)diva_word2le(buffer->info.nu_info.Id);
|
|
switch (Id) {
|
|
case DSIG_ID:
|
|
strcpy (p, "DSIG_ID");
|
|
break;
|
|
case NL_ID:
|
|
strcpy (p, "NL_ID");
|
|
break;
|
|
case BLLC_ID:
|
|
strcpy (p, "BLLC_ID");
|
|
break;
|
|
case TASK_ID:
|
|
strcpy (p, "TASK_ID");
|
|
break;
|
|
case TIMER_ID:
|
|
strcpy (p, "TIMER_ID");
|
|
break;
|
|
case TEL_ID:
|
|
strcpy (p, "TEL_ID");
|
|
break;
|
|
case MAN_ID:
|
|
strcpy (p, "MAN_ID");
|
|
break;
|
|
default:
|
|
sprintf (p, "%02x", Id);
|
|
break;
|
|
}
|
|
p = &tmp[strlen(tmp)];
|
|
sprintf (p, ", Ch:%02x, A(%02x)",
|
|
HIBYTE(diva_word2le(buffer->info.nu_info.Id)),
|
|
(byte)diva_word2le(buffer->info.nu_info.code));
|
|
fprintf(Out,"%s", tmp);
|
|
} break;
|
|
case 221: { /* XDI RC code log */
|
|
char *p;
|
|
byte A = LOBYTE(diva_word2le(buffer->info.nu_info.code));
|
|
byte s = HIBYTE(diva_word2le(buffer->info.nu_info.code));
|
|
byte id = LOBYTE(diva_word2le(buffer->info.nu_info.Id));
|
|
byte ch = HIBYTE(diva_word2le(buffer->info.nu_info.Id));
|
|
byte rc = LOBYTE(diva_word2le(buffer->info.nu_info.info));
|
|
byte t = HIBYTE(diva_word2le(buffer->info.nu_info.info));
|
|
byte cb = LOBYTE(diva_word2le(buffer->info.nu_info.info1));
|
|
Id = id;
|
|
sprintf (tmp, "XDI[%02x] ", s);
|
|
p = &tmp[strlen(tmp)];
|
|
|
|
switch (t) {
|
|
case NL_ID: /* NL REQ */
|
|
strcpy (p, "N-");
|
|
break;
|
|
case DSIG_ID: /* SIG REQ */
|
|
strcpy (p, "S-");
|
|
break;
|
|
case MAN_ID:
|
|
strcpy (p, "MAN-");
|
|
break;
|
|
}
|
|
strcat (p, "RC=");
|
|
p = &tmp[strlen(tmp)];
|
|
if (rc == READY_INT) {
|
|
strcat (p, "READY_INT");
|
|
} else {
|
|
rc2str (rc, p);
|
|
}
|
|
p = &tmp[strlen(tmp)];
|
|
if (id == NL_ID + GL_ERR_ID) {
|
|
sprintf (p, " Id:%s, Ch:%02x", "NL_ID+GL_ERR_ID", ch);
|
|
} else if (id == DSIG_ID + GL_ERR_ID) {
|
|
sprintf (p, " Id:%s, Ch:%02x", "DSIG_ID+GL_ERR_ID", ch);
|
|
} else if (id == MAN_ID + GL_ERR_ID) {
|
|
sprintf (p, " Id:%s, Ch:%02x", "MAN_ID+GL_ERR_ID", ch);
|
|
} else {
|
|
sprintf (p, " Id:%02x, Ch:%02x", id, ch);
|
|
}
|
|
switch (cb) {
|
|
case 0: /* delivery */
|
|
strcat (tmp, " DELIVERY");
|
|
break;
|
|
case 1: /* callback */
|
|
strcat (tmp, " CALLBACK");
|
|
break;
|
|
case 2: /* assign */
|
|
strcat (tmp, " ASSIGN");
|
|
break;
|
|
}
|
|
p = &tmp[strlen(tmp)];
|
|
sprintf (p, " A(%02x)", A);
|
|
|
|
fprintf(Out,"%s", tmp);
|
|
} break;
|
|
case 222: {/* XDI xlog IND */
|
|
char *p;
|
|
byte A = LOBYTE(diva_word2le(buffer->info.nu_info.code));
|
|
byte s = HIBYTE(diva_word2le(buffer->info.nu_info.code));
|
|
byte id = LOBYTE(diva_word2le(buffer->info.nu_info.Id));
|
|
byte ch = HIBYTE(diva_word2le(buffer->info.nu_info.Id));
|
|
byte ind = LOBYTE(diva_word2le(buffer->info.nu_info.info));
|
|
byte t = HIBYTE(diva_word2le(buffer->info.nu_info.info));
|
|
byte rnr = LOBYTE(diva_word2le(buffer->info.nu_info.info1));
|
|
byte val = HIBYTE(diva_word2le(buffer->info.nu_info.info1));
|
|
|
|
Id = id;
|
|
sprintf (tmp, "XDI[%02x] ", s);
|
|
p = &tmp[strlen(tmp)];
|
|
switch (t) {
|
|
case NL_ID: /* NL REQ */
|
|
if (((ind-1) & 0x0f)<=12) {
|
|
strcpy (p, ns_name[(ind-1) &0x0f]);
|
|
} else {
|
|
sprintf (p, "N-UNKNOWN NS(%02x)", ind);
|
|
}
|
|
break;
|
|
case DSIG_ID: /* SIG REQ */
|
|
encode_sig_req (ind, p, 0);
|
|
break;
|
|
case MAN_ID:
|
|
encode_man_req (ind, p, 0);
|
|
break;
|
|
default:
|
|
sprintf (p, "?-(%02x)", ind);
|
|
break;
|
|
}
|
|
strcat (tmp, " IND Id:");
|
|
p = &tmp[strlen(tmp)];
|
|
switch (id) {
|
|
case DSIG_ID:
|
|
strcpy (p, "DSIG_ID");
|
|
break;
|
|
case NL_ID:
|
|
strcpy (p, "NL_ID");
|
|
break;
|
|
case BLLC_ID:
|
|
strcpy (p, "BLLC_ID");
|
|
break;
|
|
case TASK_ID:
|
|
strcpy (p, "TASK_ID");
|
|
break;
|
|
case TIMER_ID:
|
|
strcpy (p, "TIMER_ID");
|
|
break;
|
|
case TEL_ID:
|
|
strcpy (p, "TEL_ID");
|
|
break;
|
|
case MAN_ID:
|
|
strcpy (p, "MAN_ID");
|
|
break;
|
|
default:
|
|
sprintf (p, "%02x", id);
|
|
break;
|
|
}
|
|
p = &tmp[strlen(tmp)];
|
|
sprintf (p, ", Ch:%02x ", ch);
|
|
p = &tmp[strlen(tmp)];
|
|
switch (val) {
|
|
case 0:
|
|
strcpy (p, "DELIVERY");
|
|
break;
|
|
case 1:
|
|
sprintf (p, "RNR=%d", rnr);
|
|
break;
|
|
case 2:
|
|
strcpy (p, "RNum=0");
|
|
break;
|
|
case 3:
|
|
strcpy (p, "COMPLETE");
|
|
break;
|
|
}
|
|
p = &tmp[strlen(tmp)];
|
|
sprintf (p, " A(%02x)", A);
|
|
fprintf(Out,"%s", tmp);
|
|
} break;
|
|
}
|
|
fprintf(Out,"\n");
|
|
return o;
|
|
}
|
|
void xlog_sig(FILE * stream, struct msg_s * message)
|
|
{
|
|
word n;
|
|
word i;
|
|
word cr;
|
|
byte msg;
|
|
n = message->length;
|
|
msg = TRUE;
|
|
*(word *)&message->info[0] = diva_word2le(*(word *)&message->info[0]);
|
|
switch(*(word *)&message->info[0]) {
|
|
case 0x0000:
|
|
fprintf(Out,"SIG-x(%03i)",n-4);
|
|
break;
|
|
case 0x0010:
|
|
case 0x0013:
|
|
fprintf(Out,"SIG-R(%03i)",n-4);
|
|
cr ^=0x8000;
|
|
break;
|
|
case 0x0020:
|
|
fprintf(Out,"SIG-X(%03i)",n-4);
|
|
break;
|
|
default:
|
|
fprintf(Out,"SIG-EVENT %04X",*(word *)&message->info[0]);
|
|
msg = FALSE;
|
|
break;
|
|
}
|
|
for(i=0; (i<n-4) && (n>4); i++)
|
|
fprintf(Out," %02X",message->info[4+i]);
|
|
fprintf(Out,"\n");
|
|
if(msg) display_q931_message(stream, message);
|
|
}
|
|
void call_failed_event(FILE * stream, struct msg_s * message, word code)
|
|
{
|
|
fprintf(Out, "EVENT: Call failed in State '%s'\n", sig_state[code>>8]);
|
|
*(word *)&message->info[0] = diva_word2le(*(word *)&message->info[0]);
|
|
switch(*(word *)&message->info[0]) {
|
|
case 0x0000:
|
|
case 0x0010:
|
|
case 0x0020:
|
|
display_q931_message(stream, message);
|
|
break;
|
|
case 0xff00:
|
|
fprintf(Out," ");
|
|
fprintf(Out,"Signaling Timeout %s",sig_timeout[code>>8]);
|
|
break;
|
|
case 0xffff:
|
|
fprintf(Out," ");
|
|
fprintf(Out,"Link disconnected");
|
|
switch(message->info[4]) {
|
|
case 8:
|
|
fprintf(Out,", Layer-1 error (cable or NT)");
|
|
break;
|
|
case 9:
|
|
fprintf(Out,", Layer-2 error");
|
|
break;
|
|
case 10:
|
|
fprintf(Out,", TEI error");
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
void display_q931_message(FILE * stream, struct msg_s * message)
|
|
{
|
|
word i;
|
|
word cr;
|
|
word p;
|
|
word w;
|
|
word wlen;
|
|
byte codeset,lock;
|
|
fprintf(Out," ");
|
|
cr = 0;
|
|
/* read one byte call reference */
|
|
if(message->info[5]==1) {
|
|
cr = message->info[6] &0x7f;
|
|
}
|
|
/* read two byte call reference */
|
|
if(message->info[5]==2) {
|
|
cr = message->info[7];
|
|
cr += (message->info[6] &0x7f)<<8;
|
|
}
|
|
/* read call reference flag */
|
|
if(message->info[5]) {
|
|
if(message->info[6] &0x80) cr |=0x8000;
|
|
}
|
|
for(i=0;i<PD_MAX && message->info[4]!=pd[i].code;i++);
|
|
if(i<PD_MAX) fprintf(Out,"%sCR%04x ",pd[i].name,cr);
|
|
else fprintf(Out,"PD(%02xCR%04x) ",message->info[4],cr);
|
|
p = 6+message->info[5];
|
|
for(i=0;i<MT_MAX && message->info[p]!=mt[i].code;i++);
|
|
if(i<MT_MAX) fprintf(Out,"%s",mt[i].name);
|
|
else fprintf(Out,"MT%02x",message->info[p]);
|
|
p++;
|
|
codeset = 0;
|
|
lock = 0;
|
|
while(p<message->length) {
|
|
fprintf(Out,"\n ");
|
|
/* read information element id and length */
|
|
w = message->info[p];
|
|
if(w & 0x80) {
|
|
w &=0xf0;
|
|
wlen = 1;
|
|
}
|
|
else {
|
|
wlen = message->info[p+1]+2;
|
|
}
|
|
if(lock & 0x80) lock &=0x7f;
|
|
else codeset = lock;
|
|
if(w==0x90) {
|
|
codeset = message->info[p];
|
|
if(codeset &8) fprintf(Out,"SHIFT %02x",codeset &7);
|
|
else fprintf(Out,"SHIFT LOCK %02x",codeset &7);
|
|
if(!(codeset & 0x08)) lock = (byte)(codeset & 7);
|
|
codeset &=7;
|
|
lock |=0x80;
|
|
}
|
|
else {
|
|
w |= (codeset<<8);
|
|
for(i=0;i<IE_MAX && w!=ie[i].code;i++);
|
|
if(i<IE_MAX) fprintf(Out,"%s",ie[i].name);
|
|
else fprintf(Out,"%01x/%02x ",codeset,(byte)w);
|
|
if((p+wlen) > message->length) {
|
|
fprintf(Out,"IE length error");
|
|
}
|
|
else {
|
|
if(wlen>1) display_ie(stream,message->info[4],w,&message->info[1+p]);
|
|
}
|
|
}
|
|
/* check if length valid (not exceeding end of packet) */
|
|
p+=wlen;
|
|
}
|
|
}
|
|
void display_ie(FILE * stream, byte pd, word w, byte * ie)
|
|
{
|
|
word i;
|
|
switch(w) {
|
|
case 0x08:
|
|
for(i=0;i<ie[0];i++) fprintf(Out," %02x",ie[1+i]);
|
|
switch(pd) {
|
|
case 0x08:
|
|
for(i=0; i<ie[0] && !(ie[1+i]&0x80); i++);
|
|
fprintf(Out, " '%s'",cau_q931[ie[2+i]&0x7f]);
|
|
break;
|
|
case 0x41:
|
|
if(ie[0]) fprintf(Out, " '%s'",cau_1tr6[ie[1]&0x7f]);
|
|
else fprintf(Out, " '%s'",cau_1tr6[0]);
|
|
break;
|
|
}
|
|
break;
|
|
case 0x0c:
|
|
case 0x6c:
|
|
case 0x6d:
|
|
case 0x70:
|
|
case 0x71:
|
|
for(i=0; i<ie[0] && !(ie[1+i]&0x80); i++)
|
|
fprintf(Out, " %02x",ie[1+i]);
|
|
fprintf(Out, " %02x",ie[1+i++]);
|
|
fprintf(Out," '");
|
|
for( ; i<ie[0]; i++) fprintf(Out, "%c",ie[1+i]);
|
|
fprintf(Out,"'");
|
|
break;
|
|
case 0x2c:
|
|
case 0x603:
|
|
fprintf(Out," '");
|
|
for(i=0 ; i<ie[0]; i++) fprintf(Out, "%c",ie[1+i]);
|
|
fprintf(Out,"'");
|
|
break;
|
|
default:
|
|
for(i=0;i<ie[0];i++) fprintf(Out," %02x",ie[1+i]);
|
|
break;
|
|
}
|
|
}
|
|
void spid_event(FILE * stream, struct msg_s * message, word code)
|
|
{
|
|
word i;
|
|
switch(code>>8) {
|
|
case 1:
|
|
fprintf(Out, "EVENT: SPID rejected");
|
|
break;
|
|
case 2:
|
|
fprintf(Out, "EVENT: SPID accepted");
|
|
break;
|
|
case 3:
|
|
fprintf(Out, "EVENT: Timeout, resend SPID");
|
|
break;
|
|
case 4:
|
|
fprintf(Out, "EVENT: Layer-2 failed, resend SPID");
|
|
break;
|
|
case 5:
|
|
fprintf(Out, "EVENT: Call attempt on inactive SPID");
|
|
break;
|
|
}
|
|
fprintf(Out, " '");
|
|
for(i=0;i<message->info[0];i++) fprintf(Out,"%c",message->info[1+i]);
|
|
fprintf(Out, "'");
|
|
}
|
|
static void rc2str (byte rc, char* p) {
|
|
if ((rc & 0xf0) == 0xf0) {
|
|
switch (rc) {
|
|
case OK_FC:
|
|
strcpy (p, "OK_FC");
|
|
break;
|
|
case READY_INT:
|
|
strcpy (p, "READY_INT");
|
|
break;
|
|
case TIMER_INT:
|
|
strcpy (p, "TIMER_INT");
|
|
break;
|
|
case OK:
|
|
strcpy (p, "OK");
|
|
break;
|
|
default:
|
|
sprintf (p, "%02x", rc);
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
if (rc & 0xe0) {
|
|
switch (rc) {
|
|
case ASSIGN_RC:
|
|
strcpy (p, "ASSIGN_RC");
|
|
break;
|
|
case ASSIGN_OK:
|
|
strcpy (p, "ASSIGN_OK");
|
|
return;
|
|
default:
|
|
sprintf (p, "%02x", rc);
|
|
return;
|
|
}
|
|
}
|
|
strcat (p, " | ");
|
|
p = p+strlen(p);
|
|
switch (rc & 0x1f) {
|
|
case UNKNOWN_COMMAND:
|
|
strcpy (p, "UNKNOWN_COMMAND");
|
|
break;
|
|
case WRONG_COMMAND:
|
|
strcpy (p, "WRONG_COMMAND");
|
|
break;
|
|
case WRONG_ID:
|
|
strcpy (p, "WRONG_ID");
|
|
break;
|
|
case WRONG_CH:
|
|
strcpy (p, "WRONG_CH");
|
|
break;
|
|
case UNKNOWN_IE:
|
|
strcpy (p, "UNKNOWN_IE");
|
|
break;
|
|
case WRONG_IE:
|
|
strcpy (p, "WRONG_IE");
|
|
break;
|
|
case OUT_OF_RESOURCES:
|
|
strcpy (p, "OUT_OF_RESOURCES");
|
|
break;
|
|
case N_FLOW_CONTROL:
|
|
strcpy (p, "N_FLOW_CONTROL");
|
|
break;
|
|
case ASSIGN_RC:
|
|
strcpy (p, "ASSIGN_RC");
|
|
break;
|
|
case ASSIGN_OK:
|
|
strcpy (p, "ASSIGN_OK");
|
|
break;
|
|
default:
|
|
sprintf (p, "%02x", rc);
|
|
break;
|
|
}
|
|
}
|
|
static void encode_sig_req (byte code, char* p, int is_req) {
|
|
strcpy (p, "S-");
|
|
p = p+strlen(p);
|
|
switch (code) {
|
|
case CALL_REQ: /* 1 call request */
|
|
/* CALL_CON 1 call confirmation */
|
|
if (is_req) {
|
|
strcpy(p, "CALL_REQ");
|
|
} else {
|
|
strcpy(p, "CALL_CON");
|
|
}
|
|
break;
|
|
case LISTEN_REQ: /* 2 listen request */
|
|
/* CALL_IND 2 incoming call connected */
|
|
if (is_req) {
|
|
strcpy (p, "LISTEN_REQ");
|
|
} else {
|
|
strcpy (p, "CALL_IND");
|
|
}
|
|
break;
|
|
case HANGUP: /* 3 hangup request/indication */
|
|
strcpy(p, "HANGUP");
|
|
break;
|
|
case SUSPEND: /* 4 call suspend request/confirm */
|
|
strcpy (p, "SUSPEND");
|
|
break;
|
|
case RESUME: /* 5 call resume request/confirm */
|
|
strcpy (p, "RESUME");
|
|
break;
|
|
case SUSPEND_REJ: /* 6 suspend rejected indication */
|
|
strcpy (p, "SUSPEND_REJ");
|
|
break;
|
|
case USER_DATA: /* 8 user data for user to user signaling */
|
|
strcpy (p, "USER_DATA");
|
|
break;
|
|
case CONGESTION: /* 9 network congestion indication */
|
|
strcpy (p, "CONGESTION");
|
|
break;
|
|
case INDICATE_REQ: /* 10 request to indicate an incoming call */
|
|
/* INDICATE_IND 10 indicates that there is an incoming call */
|
|
if (is_req) {
|
|
strcpy (p, "INDICATE_REQ");
|
|
} else {
|
|
strcpy (p, "INDICATE_IND");
|
|
}
|
|
break;
|
|
case CALL_RES: /* 11 accept an incoming call */
|
|
strcpy (p, "CALL_RES");
|
|
break;
|
|
case CALL_ALERT: /* 12 send ALERT for incoming call */
|
|
strcpy (p, "CALL_ALERT");
|
|
break;
|
|
case INFO_REQ: /* 13 INFO request */
|
|
/* INFO_IND 13 INFO indication */
|
|
if (is_req) {
|
|
strcpy (p, "INFO_REQ");
|
|
} else {
|
|
strcpy (p, "INFO_IND");
|
|
}
|
|
break;
|
|
case REJECT: /* 14 reject an incoming call */
|
|
strcpy (p, "REJECT");
|
|
break;
|
|
case RESOURCES: /* 15 reserve B-Channel hardware resources */
|
|
strcpy (p, "RESOURCES");
|
|
break;
|
|
case TEL_CTRL: /* 16 Telephone control request/indication */
|
|
strcpy (p, "TEL_CTRL");
|
|
break;
|
|
case STATUS_REQ: /* 17 Request D-State (returned in INFO_IND) */
|
|
strcpy (p, "STATUS_REQ");
|
|
break;
|
|
case FAC_REG_REQ: /* 18 connection idependent fac registration */
|
|
strcpy (p, "FAC_REG_REQ");
|
|
break;
|
|
case FAC_REG_ACK: /* 19 fac registration acknowledge */
|
|
strcpy (p, "FAC_REG_ACK");
|
|
break;
|
|
case FAC_REG_REJ: /* 20 fac registration reject */
|
|
strcpy (p, "FAC_REG_REJ");
|
|
break;
|
|
case CALL_COMPLETE: /* 21 send a CALL_PROC for incoming call */
|
|
strcpy (p, "CALL_COMPLETE");
|
|
break;
|
|
case FACILITY_REQ: /* 22 send a Facility Message type */
|
|
/* FACILITY_IND 22 Facility Message type indication */
|
|
if (is_req) {
|
|
strcpy (p, "FACILITY_REQ");
|
|
} else {
|
|
strcpy (p, "FACILITY_IND");
|
|
}
|
|
break;
|
|
case SIG_CTRL: /* 29 Control for signalling hardware */
|
|
strcpy (p, "SIG_CTRL");
|
|
break;
|
|
case DSP_CTRL: /* 30 Control for DSPs */
|
|
strcpy (p, "DSP_CTRL");
|
|
break;
|
|
case LAW_REQ: /* 31 Law config request for (returns info_i) */
|
|
strcpy (p, "LAW_REQ");
|
|
break;
|
|
case UREMOVE:
|
|
strcpy (p, "UREMOVE");
|
|
break;
|
|
case REMOVE:
|
|
strcpy (p, "REMOVE");
|
|
break;
|
|
default:
|
|
sprintf (p, "UNKNOWN(%02x)", code);
|
|
break;
|
|
}
|
|
}
|
|
static void encode_man_req (byte code, char* p, int is_req) {
|
|
strcpy (p, "M-");
|
|
p = p+strlen(p);
|
|
switch (code) {
|
|
case ASSIGN: /* 1 */
|
|
strcpy (p, "ASSIGN");
|
|
break;
|
|
case MAN_READ: /* 2 */
|
|
/* MAN_INFO_IND 2 */
|
|
strcpy (p, is_req ? "MAN_READ" : "MAN_INFO_IND");
|
|
break;
|
|
case MAN_WRITE: /* 3 */
|
|
/* MAN_EVENT_IND 3 */
|
|
strcpy (p, is_req ? "MAN_WRITE" : "MAN_EVENT_IND");
|
|
break;
|
|
case MAN_EXECUTE: /* 4 */
|
|
/* MAN_TRACE_IND 4 */
|
|
strcpy (p, is_req ? "MAN_EXECUTE" : "MAN_TRACE_IND");
|
|
break;
|
|
case MAN_EVENT_ON:/* 5 */
|
|
strcpy (p, "MAN_EVENT_ON");
|
|
break;
|
|
case MAN_EVENT_OFF:/*6 */
|
|
strcpy (p, "MAN_EVENT_OFF");
|
|
break;
|
|
case MAN_LOCK: /* 7 */
|
|
strcpy (p, "MAN_LOCK");
|
|
break;
|
|
case MAN_UNLOCK: /* 8 */
|
|
strcpy (p, "MAN_UNLOCK");
|
|
break;
|
|
case REMOVE:
|
|
strcpy (p, "REMOVE");
|
|
break;
|
|
case UREMOVE:
|
|
strcpy (p, "UREMOVE");
|
|
break;
|
|
default:
|
|
sprintf (p, "UNKNOWN(%02x)", code);
|
|
break;
|
|
}
|
|
}
|
|
#define MAKEWORD(a, b) ((word)(((byte)(a)) | ((word)((byte)(b))) << 8))
|
|
#define LOBYTE(w) ((byte)(w))
|
|
#define HIBYTE(w) ((byte)(((word)(w) >> 8) & 0xFF))
|
|
word diva_word2le (word w) {
|
|
if (diva_convert_be2le) {
|
|
return (MAKEWORD(HIBYTE(w), LOBYTE(w)));
|
|
}
|
|
return (w);
|
|
}
|