mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-07-26 10:38:47 +02:00
8175ad07bc
Compiling Hercules with gcc 10 produces many warnings like this one:
```
CC hao.lo
In file included from /usr/include/ctype.h:97,
from hstdinc.h:117,
from hao.c:17:
hao.c: In function 'hao_message':
hao.c:812:37: warning: array subscript has type 'char' [-Wchar-subscripts]
812 | if (isdigit(p[2]))
| ^
```
Gcc should really present these as compile time errors, since each and every
one represents a potential case of Undefined Behaviour.
I changed (almost) all of these calls, except a few where the parameter was an
int that just came from a getc()-type function.
666 lines
23 KiB
C
666 lines
23 KiB
C
/* MPC.C (C) Copyright Jan Jaeger, 2010-2012 */
|
|
/* (C) Copyright Ian Shorter, 2011-2012 */
|
|
/* (C) Copyright Harold Grovesteen, 2011-2012 */
|
|
/* MPC (Multi-Path Channel) functions */
|
|
/* */
|
|
/* Released under "The Q Public License Version 1" */
|
|
/* (http://www.hercules-390.org/herclic.html) as modifications to */
|
|
/* Hercules. */
|
|
|
|
/* This implementation is based on the S/390 Linux implementation */
|
|
|
|
#include "hstdinc.h"
|
|
|
|
#define _MPC_C_
|
|
#define _HENGINE_DLL_
|
|
|
|
#include "hercules.h"
|
|
#include "mpc.h"
|
|
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_point_ipa(): */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT MPC_IPA* mpc_point_ipa( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH )
|
|
{
|
|
MPC_PH* pMPC_PH;
|
|
MPC_IPA* pMPC_IPA;
|
|
U32 uOffData;
|
|
U16 uOffPH;
|
|
|
|
UNREFERENCED( pDEVBLK );
|
|
|
|
// Point to the MPC_PH.
|
|
FETCH_HW( uOffPH, pMPC_RRH->offph );
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
|
|
|
|
// Get the length of and point to the data referenced by the
|
|
// MPC_PH. The data contain a MPC_IPA.
|
|
FETCH_FW( uOffData, pMPC_PH->offdata );
|
|
pMPC_IPA = (MPC_IPA*)((BYTE*)pMPC_TH + uOffData);
|
|
|
|
return pMPC_IPA;
|
|
} /* End function mpc_point_ipa() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_point_puk(): */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT MPC_PUK* mpc_point_puk( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH )
|
|
{
|
|
MPC_PH* pMPC_PH;
|
|
MPC_PUK* pMPC_PUK;
|
|
U32 uOffData;
|
|
U16 uOffPH;
|
|
|
|
UNREFERENCED( pDEVBLK );
|
|
|
|
// Point to the MPC_PH.
|
|
FETCH_HW( uOffPH, pMPC_RRH->offph );
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
|
|
|
|
// Get the length of and point to the data referenced by the
|
|
// MPC_PH. The data contain a MPC_PUK and one or more MPC_PUSs.
|
|
FETCH_FW( uOffData, pMPC_PH->offdata );
|
|
pMPC_PUK = (MPC_PUK*)((BYTE*)pMPC_TH + uOffData);
|
|
|
|
return pMPC_PUK;
|
|
} /* End function mpc_point_puk() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_point_pus(): */
|
|
/*--------------------------------------------------------------------*/
|
|
/* Return a pointer to the MPC_PUS of the required type. If the */
|
|
/* required type is not found a null pointer is returned. Although */
|
|
/* never seen, if multiple MPC_PUS of the required type exist, only */
|
|
/* the first MPC_PUS of the required type will ever be returned. */
|
|
DLL_EXPORT MPC_PUS* mpc_point_pus( DEVBLK* pDEVBLK, MPC_PUK* pMPC_PUK, BYTE bType )
|
|
{
|
|
MPC_PUS* pMPC_PUS;
|
|
int iTotLenPUS;
|
|
U16 uTotLenPUS;
|
|
U16 uLenPUS;
|
|
U16 uLenPUK;
|
|
|
|
UNREFERENCED( pDEVBLK );
|
|
|
|
/* Get the length of the MPC_PUK, the total length of the */
|
|
/* following MPC_PUSs, then point to the first MPC_PUS. */
|
|
FETCH_HW( uLenPUK, pMPC_PUK->length );
|
|
FETCH_HW( uTotLenPUS, pMPC_PUK->lenpus );
|
|
iTotLenPUS = uTotLenPUS;
|
|
pMPC_PUS = (MPC_PUS*)((BYTE*)pMPC_PUK + uLenPUK);
|
|
|
|
/* Find the required MPC_PUS. */
|
|
while( iTotLenPUS > 0 )
|
|
{
|
|
/* Ensure there are at least the first 4-bytes of an MPC_PUS. */
|
|
if( iTotLenPUS < 4 )
|
|
return NULL;
|
|
|
|
/* Get the length of the MPC_PUS. */
|
|
FETCH_HW( uLenPUS, pMPC_PUS->length );
|
|
if( uLenPUS == 0 ) /* Better safe than sorry */
|
|
return NULL;
|
|
|
|
/* Ensure there is the whole of the MPC_PUS. */
|
|
if( iTotLenPUS < uLenPUS )
|
|
return NULL;
|
|
|
|
/* Check for the required MPC_PUS. */
|
|
if( pMPC_PUS->type == bType )
|
|
return pMPC_PUS;
|
|
|
|
/* Point to the next MPC_PUS. */
|
|
pMPC_PUS = (MPC_PUS*)((BYTE*)pMPC_PUS + uLenPUS);
|
|
iTotLenPUS -= uLenPUS;
|
|
}
|
|
|
|
return NULL;
|
|
} /* End function mpc_point_pus() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_description(): */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT void mpc_display_description( DEVBLK* pDEVBLK, char* pDesc )
|
|
{
|
|
|
|
/* Display description, if one has been provided. */
|
|
if( pDesc )
|
|
{
|
|
if( pDEVBLK )
|
|
{
|
|
// HHC03983 "%1d:%04X %s: %s
|
|
WRMSG(HHC03983, "D", SSID_TO_LCSS(pDEVBLK->ssid), pDEVBLK->devnum, pDEVBLK->typname, pDesc );
|
|
}
|
|
else
|
|
{
|
|
// HHC03984 "%s"
|
|
WRMSG(HHC03984, "D", pDesc );
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* End function mpc_display_description() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_stuff() */
|
|
/*--------------------------------------------------------------------*/
|
|
/* Function to display storage. */
|
|
DLL_EXPORT void mpc_display_stuff( DEVBLK* pDEVBLK, char* cWhat, BYTE* pAddr, int iLen, BYTE bDir )
|
|
{
|
|
int offset;
|
|
unsigned int i;
|
|
u_char c = '\0';
|
|
u_char e = '\0';
|
|
char print_ascii[17];
|
|
char print_ebcdic[17];
|
|
char print_line[64];
|
|
char tmp[32];
|
|
|
|
for( offset = 0; offset < iLen; )
|
|
{
|
|
memset( print_ascii, ' ', sizeof(print_ascii)-1 ); /* set to spaces */
|
|
print_ascii[sizeof(print_ascii)-1] = '\0'; /* with null termination */
|
|
memset( print_ebcdic, ' ', sizeof(print_ebcdic)-1 ); /* set to spaces */
|
|
print_ebcdic[sizeof(print_ebcdic)-1] = '\0'; /* with null termination */
|
|
memset( print_line, 0, sizeof( print_line ) );
|
|
|
|
MSGBUF( print_line, "+%4.4X%c ", offset, bDir );
|
|
|
|
for( i = 0; i < 16; i++ )
|
|
{
|
|
c = *pAddr++;
|
|
|
|
if( offset < iLen )
|
|
{
|
|
MSGBUF(tmp, "%2.2X", c );
|
|
tmp[sizeof(tmp)-1] = '\0';
|
|
STRLCAT( print_line, tmp );
|
|
|
|
print_ebcdic[i] = print_ascii[i] = '.';
|
|
e = guest_to_host( c );
|
|
|
|
if( isprint( (unsigned char)e ) )
|
|
print_ebcdic[i] = e;
|
|
if( isprint( (unsigned char)c ) )
|
|
print_ascii[i] = c;
|
|
}
|
|
else
|
|
{
|
|
STRLCAT( print_line, " " );
|
|
}
|
|
|
|
offset++;
|
|
if( ( offset & 3 ) == 0 )
|
|
{
|
|
STRLCAT( print_line, " " );
|
|
}
|
|
}
|
|
|
|
if( pDEVBLK )
|
|
{
|
|
// HHC03981 "%1d:%04X %s: %s: %s %s %s"
|
|
WRMSG(HHC03981, "D", SSID_TO_LCSS(pDEVBLK->ssid), pDEVBLK->devnum, pDEVBLK->typname,
|
|
cWhat, print_line, print_ascii, print_ebcdic );
|
|
}
|
|
else
|
|
{
|
|
// HHC03982 "%s: %s %s %s"
|
|
WRMSG(HHC03982, "D", cWhat, print_line, print_ascii, print_ebcdic );
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* End function mpc_display_stuff() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_th(): Display Transport Header (MPC_TH) */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT void mpc_display_th( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, BYTE bDir )
|
|
{
|
|
U32 uOffRRH;
|
|
|
|
// Display the MPC_TH.
|
|
FETCH_FW( uOffRRH, pMPC_TH->offrrh );
|
|
mpc_display_stuff( pDEVBLK, "TH ", (BYTE*)pMPC_TH, uOffRRH, bDir );
|
|
|
|
return;
|
|
} /* End function mpc_display_th() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_rrh(): Display Request/Response Header (MPC_RRH) */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT void mpc_display_rrh( DEVBLK* pDEVBLK, MPC_RRH* pMPC_RRH, BYTE bDir )
|
|
{
|
|
U16 uOffPH;
|
|
|
|
// Display the MPC_RRH.
|
|
FETCH_HW( uOffPH, pMPC_RRH->offph );
|
|
mpc_display_stuff( pDEVBLK, "RRH", (BYTE*)pMPC_RRH, uOffPH, bDir );
|
|
|
|
return;
|
|
} /* End function mpc_display_rrh() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_ph(): Display Protocol Data Unit Header (MPC_PH) */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT void mpc_display_ph( DEVBLK* pDEVBLK, MPC_PH* pMPC_PH, BYTE bDir )
|
|
{
|
|
|
|
// Display the MPC_PH.
|
|
mpc_display_stuff( pDEVBLK, "PH ", (BYTE*)pMPC_PH, SIZE_PH, bDir );
|
|
|
|
return;
|
|
} /* End function mpc_display_ph() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_rrh_and_puk(): */
|
|
/*--------------------------------------------------------------------*/
|
|
/* In all cases that have been seen, on both OSA and PTP, when */
|
|
/* MPC_RRH->proto == PROTOCOL_UNKNOWN (0x7E), the MPC_RRH is followed */
|
|
/* by a single MPC_PH, which is followed by a single MPC_PUK, which */
|
|
/* is followed by up to four MPC_PUSs. */
|
|
DLL_EXPORT void mpc_display_rrh_and_puk( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH, BYTE bDir )
|
|
{
|
|
MPC_PH* pMPC_PH;
|
|
MPC_PUK* pMPC_PUK;
|
|
MPC_PUS* pMPC_PUS;
|
|
int iTotLenPUS;
|
|
U32 uOffData;
|
|
U16 uTotLenPUS;
|
|
U16 uLenPUS;
|
|
U16 uLenPUK;
|
|
U16 uOffPH;
|
|
|
|
// Display the MPC_RRH.
|
|
FETCH_HW( uOffPH, pMPC_RRH->offph );
|
|
mpc_display_stuff( pDEVBLK, "RRH", (BYTE*)pMPC_RRH, uOffPH, bDir );
|
|
|
|
// Point to and display the MPC_PH.
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
|
|
mpc_display_stuff( pDEVBLK, "PH ", (BYTE*)pMPC_PH, SIZE_PH, bDir );
|
|
|
|
// Get the length of and point to the data referenced by the
|
|
// MPC_PH. The data contain a MPC_PUK and one or more MPC_PUSs.
|
|
FETCH_FW( uOffData, pMPC_PH->offdata );
|
|
pMPC_PUK = (MPC_PUK*)((BYTE*)pMPC_TH + uOffData);
|
|
|
|
// Display the MPC_PUK.
|
|
FETCH_HW( uLenPUK, pMPC_PUK->length );
|
|
mpc_display_stuff( pDEVBLK, "PUK", (BYTE*)pMPC_PUK, uLenPUK, bDir );
|
|
|
|
// Get the total length of the following MPC_PUSs, then point to
|
|
// the first MPC_PUS.
|
|
FETCH_HW( uTotLenPUS, pMPC_PUK->lenpus );
|
|
iTotLenPUS = uTotLenPUS;
|
|
pMPC_PUS = (MPC_PUS*)((BYTE*)pMPC_PUK + uLenPUK);
|
|
|
|
// Display all of the MPC_PUSs.
|
|
while( iTotLenPUS > 0 )
|
|
{
|
|
// Ensure there are at least the first 4-bytes of the MPC_PUS.
|
|
if( iTotLenPUS < 4 )
|
|
{
|
|
mpc_display_stuff( pDEVBLK, "???", (BYTE*)pMPC_PUS, iTotLenPUS, bDir );
|
|
break;
|
|
}
|
|
|
|
// Get the length of the MPC_PUS.
|
|
FETCH_HW( uLenPUS, pMPC_PUS->length );
|
|
if( uLenPUS == 0 ) /* Better safe than sorry */
|
|
{
|
|
mpc_display_stuff( pDEVBLK, "???", (BYTE*)pMPC_PUS, iTotLenPUS, bDir );
|
|
break;
|
|
}
|
|
|
|
// Ensure there is the whole of the MPC_PUS.
|
|
if( iTotLenPUS < uLenPUS )
|
|
{
|
|
mpc_display_stuff( pDEVBLK, "???", (BYTE*)pMPC_PUS, iTotLenPUS, bDir );
|
|
break;
|
|
}
|
|
|
|
// Display the MPC_PUS.
|
|
mpc_display_stuff( pDEVBLK, "PUS", (BYTE*)pMPC_PUS, uLenPUS, bDir );
|
|
|
|
// Point to the next MPC_PUS
|
|
pMPC_PUS = (MPC_PUS*)((BYTE*)pMPC_PUS + uLenPUS);
|
|
iTotLenPUS -= uLenPUS;
|
|
}
|
|
|
|
return;
|
|
} /* End function mpc_display_rrh_and_puk() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_rrh_and_pix(): */
|
|
/*--------------------------------------------------------------------*/
|
|
/* In all cases that have been seen, only on PTP, when MPC_RRH->type */
|
|
/* == RRH_TYPE_IPA (0xC1) and MPC_RRH->proto == PROTOCOL_LAYER2 */
|
|
/* (0x08), the MPC_RRH is followed by a single MPC_PH, which is */
|
|
/* followed by a single MPC_PIX. */
|
|
DLL_EXPORT void mpc_display_rrh_and_pix( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH, BYTE bDir )
|
|
{
|
|
MPC_PH* pMPC_PH;
|
|
MPC_PIX* pMPC_PIX;
|
|
U32 uOffData;
|
|
U32 uLenData;
|
|
U16 uOffPH;
|
|
|
|
// Display the MPC_RRH.
|
|
FETCH_HW( uOffPH, pMPC_RRH->offph );
|
|
mpc_display_stuff( pDEVBLK, "RRH", (BYTE*)pMPC_RRH, uOffPH, bDir );
|
|
|
|
// Point to and display the MPC_PH.
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
|
|
mpc_display_stuff( pDEVBLK, "PH ", (BYTE*)pMPC_PH, SIZE_PH, bDir );
|
|
|
|
// Point to and display the MPC_PIX.
|
|
FETCH_F3( uLenData, pMPC_PH->lendata );
|
|
FETCH_FW( uOffData, pMPC_PH->offdata );
|
|
pMPC_PIX = (MPC_PIX*)((BYTE*)pMPC_TH + uOffData);
|
|
mpc_display_stuff( pDEVBLK, "PIX", (BYTE*)pMPC_PIX, uLenData, bDir );
|
|
|
|
return;
|
|
} /* End function mpc_display_rrh_and_pix() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_rrh_and_ipa(): */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT void mpc_display_rrh_and_ipa( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH, BYTE bDir )
|
|
{
|
|
MPC_PH* pMPC_PH;
|
|
MPC_IPA* pMPC_IPA;
|
|
BYTE* pMPC_IPA_CMD;
|
|
U32 uOffData;
|
|
U32 uLenData;
|
|
U16 uOffPH;
|
|
int iLenIPA;
|
|
int iLenCmd;
|
|
|
|
// Display the MPC_RRH.
|
|
FETCH_HW( uOffPH, pMPC_RRH->offph );
|
|
mpc_display_stuff( pDEVBLK, "RRH", (BYTE*)pMPC_RRH, uOffPH, bDir );
|
|
|
|
// Point to and display the MPC_PH.
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
|
|
mpc_display_stuff( pDEVBLK, "PH ", (BYTE*)pMPC_PH, SIZE_PH, bDir );
|
|
|
|
/* Point to and display the MPC_IPA (and commands, if any). */
|
|
FETCH_F3( uLenData, pMPC_PH->lendata );
|
|
FETCH_FW( uOffData, pMPC_PH->offdata );
|
|
if( uLenData > sizeof(MPC_IPA) )
|
|
{
|
|
iLenIPA = sizeof(MPC_IPA);
|
|
iLenCmd = uLenData - sizeof(MPC_IPA);
|
|
}
|
|
else
|
|
{
|
|
iLenIPA = uLenData;
|
|
iLenCmd = 0;
|
|
}
|
|
pMPC_IPA = (MPC_IPA*)((BYTE*)pMPC_TH + uOffData);
|
|
mpc_display_stuff( pDEVBLK, "IPA", (BYTE*)pMPC_IPA, iLenIPA, bDir );
|
|
if( iLenCmd )
|
|
{
|
|
pMPC_IPA_CMD = (BYTE*)pMPC_IPA + iLenIPA;
|
|
mpc_display_stuff( pDEVBLK, "Cmd", (BYTE*)pMPC_IPA_CMD, iLenCmd, bDir );
|
|
}
|
|
|
|
return;
|
|
} /* End function mpc_display_rrh_and_ipa() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_rrh_and_pkt(): */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT void mpc_display_rrh_and_pkt( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH, BYTE bDir, int iLimit )
|
|
{
|
|
MPC_PH* pMPC_PH;
|
|
U16 uNumPH;
|
|
U16 uOffPH;
|
|
int iForPH;
|
|
int iDone;
|
|
U32 uLenData;
|
|
U32 uOffData;
|
|
BYTE* pData;
|
|
|
|
/* Display the MPC_RRH.*/
|
|
FETCH_HW( uOffPH, pMPC_RRH->offph );
|
|
mpc_display_stuff( pDEVBLK, "RRH", (BYTE*)pMPC_RRH, uOffPH, bDir );
|
|
|
|
/* Display the MPC_PH(s). */
|
|
FETCH_HW( uNumPH, pMPC_RRH->numph );
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
|
|
for( iForPH = 1; iForPH <= uNumPH; iForPH++ )
|
|
{
|
|
mpc_display_stuff( pDEVBLK, "PH ", (BYTE*)pMPC_PH, SIZE_PH, bDir );
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_PH + SIZE_PH);
|
|
}
|
|
|
|
/* Display the data referenced by the MPC_PH(s). */
|
|
/* if limit is negative or a silly number, don't display the */
|
|
/* data. If limit is zero, display all of the data, otherwise */
|
|
/* limit the length of the data displayed. */
|
|
iDone = 0;
|
|
if( iLimit >= 0 && iLimit <= 65535 )
|
|
{
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
|
|
for( iForPH = 1; iForPH <= uNumPH; iForPH++ )
|
|
{
|
|
FETCH_F3( uLenData, pMPC_PH->lendata );
|
|
FETCH_FW( uOffData, pMPC_PH->offdata );
|
|
pData = (BYTE*)pMPC_TH + uOffData;
|
|
if( iLimit > 0 )
|
|
{
|
|
if( iDone >= iLimit )
|
|
break;
|
|
if( (int)uLenData > ( iLimit - iDone ) )
|
|
uLenData = ( iLimit - iDone );
|
|
iDone += uLenData;
|
|
}
|
|
mpc_display_stuff( pDEVBLK, "Pkt", pData, uLenData, bDir );
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_PH + SIZE_PH);
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* End function mpc_display_rrh_and_pkt() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_rrh_and_pdu(): */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT void mpc_display_rrh_and_pdu( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, MPC_RRH* pMPC_RRH, BYTE bDir, int iLimit )
|
|
{
|
|
MPC_PH* pMPC_PH;
|
|
U16 uNumPH;
|
|
U16 uOffPH;
|
|
int iForPH;
|
|
int iDone;
|
|
U32 uLenData;
|
|
U32 uOffData;
|
|
BYTE* pData;
|
|
|
|
/* Display the MPC_RRH.*/
|
|
FETCH_HW( uOffPH, pMPC_RRH->offph );
|
|
mpc_display_stuff( pDEVBLK, "RRH", (BYTE*)pMPC_RRH, uOffPH, bDir );
|
|
|
|
/* Display the MPC_PH(s). */
|
|
FETCH_HW( uNumPH, pMPC_RRH->numph );
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
|
|
for( iForPH = 1; iForPH <= uNumPH; iForPH++ )
|
|
{
|
|
mpc_display_stuff( pDEVBLK, "PH ", (BYTE*)pMPC_PH, SIZE_PH, bDir );
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_PH + SIZE_PH);
|
|
}
|
|
|
|
/* Display the data referenced by the MPC_PH(s). */
|
|
/* if limit is negative or a silly number, don't display the */
|
|
/* data. If limit is zero, display all of the data, otherwise */
|
|
/* limit the length of the data displayed. */
|
|
iDone = 0;
|
|
if( iLimit >= 0 && iLimit <= 65535 )
|
|
{
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_RRH + uOffPH);
|
|
for( iForPH = 1; iForPH <= uNumPH; iForPH++ )
|
|
{
|
|
FETCH_F3( uLenData, pMPC_PH->lendata );
|
|
FETCH_FW( uOffData, pMPC_PH->offdata );
|
|
pData = (BYTE*)pMPC_TH + uOffData;
|
|
if( iLimit > 0 )
|
|
{
|
|
if( iDone >= iLimit )
|
|
break;
|
|
if( (int)uLenData > ( iLimit - iDone ) )
|
|
uLenData = ( iLimit - iDone );
|
|
iDone += uLenData;
|
|
}
|
|
mpc_display_stuff( pDEVBLK, "PDU", pData, uLenData, bDir );
|
|
pMPC_PH = (MPC_PH*)((BYTE*)pMPC_PH + SIZE_PH);
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* End function mpc_display_rrh_and_pdu() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_osa_iea(): */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT void mpc_display_osa_iea( DEVBLK* pDEVBLK, MPC_IEA* pMPC_IEA, BYTE bDir, int iSize )
|
|
{
|
|
|
|
/* Display MPC_IEA. */
|
|
mpc_display_stuff( pDEVBLK, "IEA", (BYTE*)pMPC_IEA, iSize, bDir );
|
|
|
|
return;
|
|
} /* End function mpc_display_osa_iea() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_osa_iear(): */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT void mpc_display_osa_iear( DEVBLK* pDEVBLK, MPC_IEAR* pMPC_IEAR, BYTE bDir, int iSize )
|
|
{
|
|
|
|
/* Display MPC_IEAR. */
|
|
mpc_display_stuff( pDEVBLK, "IEAR", (BYTE*)pMPC_IEAR, iSize, bDir );
|
|
|
|
return;
|
|
} /* End function mpc_display_osa_iear() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_osa_th_etc(): */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT void mpc_display_osa_th_etc( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, BYTE bDir, int iLimit )
|
|
{
|
|
MPC_RRH* pMPC_RRH;
|
|
int iForRRH;
|
|
U32 uOffRRH;
|
|
U16 uNumRRH;
|
|
|
|
/* Display MPC_TH. */
|
|
mpc_display_th( pDEVBLK, pMPC_TH, bDir );
|
|
|
|
/* Get the number of MPC_RRHs and the displacement from */
|
|
/* the start of the MPC_TH to the first (or only) MPC_RRH. */
|
|
FETCH_HW( uNumRRH, pMPC_TH->numrrh );
|
|
FETCH_FW( uOffRRH, pMPC_TH->offrrh );
|
|
|
|
/* Process each of the MPC_RRHs. */
|
|
for( iForRRH = 1; iForRRH <= uNumRRH; iForRRH++ )
|
|
{
|
|
|
|
/* Point to the first or subsequent MPC_RRH. */
|
|
pMPC_RRH = (MPC_RRH*)((BYTE*)pMPC_TH + uOffRRH);
|
|
|
|
/* Display the MPC_RRH etc. */
|
|
if( pMPC_RRH->type == RRH_TYPE_CM ||
|
|
pMPC_RRH->type == RRH_TYPE_ULP )
|
|
{
|
|
|
|
/* Display MPC_RRH and following MPC_PUK etc. */
|
|
mpc_display_rrh_and_puk( pDEVBLK, pMPC_TH, pMPC_RRH, bDir );
|
|
|
|
}
|
|
else if( pMPC_RRH->type == RRH_TYPE_IPA )
|
|
{
|
|
|
|
/* Display MPC_RRH and following MPC_IPA etc. */
|
|
mpc_display_rrh_and_ipa( pDEVBLK, pMPC_TH, pMPC_RRH, bDir );
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Display MPC_RRH and following PDU. */
|
|
mpc_display_rrh_and_pdu( pDEVBLK, pMPC_TH, pMPC_RRH, bDir, iLimit );
|
|
|
|
}
|
|
|
|
/* Get the displacement from the start of the MPC_TH to the */
|
|
/* next MPC_RRH. pMPC_RRH->offrrh will contain zero if this */
|
|
/* is the last MPC_RRH. */
|
|
FETCH_FW( uOffRRH, pMPC_RRH->offrrh );
|
|
|
|
}
|
|
|
|
return;
|
|
} /* End function mpc_display_osa_th_etc() */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/* mpc_display_ptp_th_etc(): */
|
|
/*--------------------------------------------------------------------*/
|
|
DLL_EXPORT void mpc_display_ptp_th_etc( DEVBLK* pDEVBLK, MPC_TH* pMPC_TH, BYTE bDir, int iLimit )
|
|
{
|
|
MPC_RRH* pMPC_RRH;
|
|
int iForRRH;
|
|
U32 uOffRRH;
|
|
U16 uNumRRH;
|
|
|
|
/* Display MPC_TH. */
|
|
mpc_display_th( pDEVBLK, pMPC_TH, bDir );
|
|
|
|
/* Get the number of MPC_RRHs and the displacement from */
|
|
/* the start of the MPC_TH to the first (or only) MPC_RRH. */
|
|
FETCH_HW( uNumRRH, pMPC_TH->numrrh );
|
|
FETCH_FW( uOffRRH, pMPC_TH->offrrh );
|
|
|
|
/* Process each of the MPC_RRHs. */
|
|
for( iForRRH = 1; iForRRH <= uNumRRH; iForRRH++ )
|
|
{
|
|
|
|
/* Point to the first or subsequent MPC_RRH. */
|
|
pMPC_RRH = (MPC_RRH*)((BYTE*)pMPC_TH + uOffRRH);
|
|
|
|
/* Display the MPC_RRH etc. */
|
|
if( pMPC_RRH->proto == PROTOCOL_LAYER2 &&
|
|
pMPC_RRH->type == RRH_TYPE_CM )
|
|
{
|
|
/* Display MPC_RRH and following packet data. */
|
|
mpc_display_rrh_and_pkt( pDEVBLK, pMPC_TH, pMPC_RRH, bDir, iLimit );
|
|
}
|
|
else if( pMPC_RRH->proto == PROTOCOL_LAYER2 &&
|
|
pMPC_RRH->type == RRH_TYPE_IPA )
|
|
{
|
|
/* Display MPC_RRH and following MPC_PIX etc. */
|
|
mpc_display_rrh_and_pix( pDEVBLK, pMPC_TH, pMPC_RRH, bDir );
|
|
}
|
|
else if( pMPC_RRH->proto == PROTOCOL_UNKNOWN )
|
|
{
|
|
/* Display MPC_RRH and following MPC_PUK etc. */
|
|
mpc_display_rrh_and_puk( pDEVBLK, pMPC_TH, pMPC_RRH, bDir );
|
|
}
|
|
else
|
|
{
|
|
/* Display MPC_RRH */
|
|
mpc_display_rrh( pDEVBLK, pMPC_RRH, bDir );
|
|
}
|
|
|
|
/* Get the displacement from the start of the MPC_TH to the */
|
|
/* next MPC_RRH. pMPC_RRH->offrrh will contain zero if this */
|
|
/* is the last MPC_RRH. */
|
|
FETCH_FW( uOffRRH, pMPC_RRH->offrrh );
|
|
|
|
}
|
|
|
|
return;
|
|
} /* End function mpc_display_ptp_th_etc() */
|
|
|