Trailing-Edge
-
PDP-10 Archives
-
BB-X117B-SB_1986
-
10,7/nml/nmllbk.bli
There are 2 other files named nmllbk.bli in the archive. Click here to see a list.
! UPD ID= 258, SNARK:<6.1.NML>NMLLBK.BLI.11, 10-Feb-85 14:49:28 by GLINDELL
! Remove definitions of STATE/SUBSTATE/SERVICE values.
! Change all LINK_ to CIRCUIT_
!
! UPD ID= 255, SNARK:<6.1.NML>NMLLBK.BLI.10, 8-Feb-85 15:16:51 by PALMIERI
! Return updated byte pointer in NODE_ACCESS when loop length exceeded
! UPD ID= 206, SNARK:<6.1.NML>NMLLBK.BLI.9, 10-Dec-84 15:27:17 by HALPIN
! Get MONSYM Library file out of default directory, not BLI:
!
! UPD ID= 180, SNARK:<6.1.NML>NMLLBK.BLI.8, 7-Dec-84 08:21:44 by HALPIN
! Add PSI arguemts in call to $NMU_DLX_OPEN.
!
! UPD ID= 153, SNARK:<6.1.NML>NMLLBK.BLI.7, 1-Nov-84 15:26:39 by GUNN
! Fix dot '.' bug in code which builds PHYSICAL ADDRESS. Found in
! debugging NMLDTL.
!
! UPD ID= 149, SNARK:<6.1.NML>NMLLBK.BLI.6, 30-Oct-84 17:38:58 by GUNN
! Ident 40.
! In LOOP_CIRCUIT, leave response pointer pointing to end of
! response message built by NMU$DLX_READ. This prevents
! higher level routines from overwriting the response built
! by NMU$KLNI_READ which contains the PHYSICAL ADDRESS parameter
! of the Ethernet node responding to a multicast loop request.
!
! UPD ID= 140, SNARK:<6.1.NML>NMLLBK.BLI.5, 29-Oct-84 11:14:42 by GUNN
! Ident 39.
! Make LOOP CIRCUIT NI-0-0 NODE foobar work.
! Fix GET_LOOP_PARAMETERS to set up defaults based on entity. LOOP NODE
! parameters COUNT, LENGTH, and WITH are EXECUTOR NODE parameters.
! Change calls to NML$GET_VDB_PARAMETER to use the LOCAL (EXECUTOR)
! node id, not the LOOP entity as it had done.
! Add PB_HARDWARE_ADDR field to PB.
! Add code to produce Ethernet physical address from node number.
! Get HARDWARE ADDRESS parameter from VDB if NODE parameter is included.
!
! UPD ID= 134, SNARK:<6.1.NML>NMLLBK.BLI.4, 19-Oct-84 16:01:54 by GUNN
! Ident 38.
! Fix GET_LOOP_PARAMETERS to ensure that PHYSICAL ADDRESS and
! LOOP ASSISTANT PHYSICAL ADDRESS parameters are HI-6 fields.
!
! UPD ID= 113, SLICE:<6.1.NML>NMLLBK.BLI.3, 24-Sep-84 10:19:05 by GUNN
!
! Ident 37.
! Fix zero length response message bug. Code that calls CH$DIFF to set
! RB_RESPONSE_LENGTH in NML$TEST had pointers in wrong order.
!
! Change all routine declarations to use %routine macro.
!
! UPD ID= 88, SLICE:<6.1.NML>NMLLBK.BLI.2, 18-Sep-84 15:05:07 by GUNN
!
! Ident 36.
! Add code to handle returning Ethernet Physical Address in response
! message.
!
! WORK:<GUNN.NML>NMLLBK.BLI.25 21-Aug-84 12:10:22, Edit by GUNN
!
! Ident 35.
! Add support for Ethernet LOOP CIRCUIT. Change name of some routines
! they are misleading. Change: LOOPBACK_ACCESS to NODE_ACCESS
! LINE_ACCESS to CIRCUIT_ACCESS
! LOOP_LINE to LOOP_CIRCUIT
!
! The new names more nearly reflect the function of the routines.
!
! Change to accomodate new LIBRARY conventions. MONSYM.L36 and JLNKG.L36
! are now explicity declared here rather than in NMULIB.
!
!<MCINTEE.WORK>NMLLBK.BLI.2, 14-Jun-83 14:07:59, Edit by MCINTEE
!
! Ident 34.
! New style entity type names
!
! NET:<PECKHAM.DEVELOPMENT>NMLLBK.BLI.2 4-Oct-82 07:39:16, Edit by PECKHAM
!
! Ident 33.
! Fix bug introduced to LOOP_LINE by last edit.
!
! NET:<PECKHAM.DEVELOPMENT>NMLLBK.BLI.2 3-Oct-82 14:59:41, Edit by PECKHAM
!
! Ident 32.
! It was found that in-house VAXes returned a MOP loopback response code
! of 25 - it will take too long to get them to fix it, so accomodate it.
! Hack up LOOP_LINE to recognize it as valid message.
!
! <BRANDT.DEVELOPMENT>NMLLBK.BLI.1 14-Sep-82 11:43:23, Edit by BRANDT
!
! Ident 31.
! In NML$TEST, include an entity id in the response message. Include
! the data field only for specific errors.
!
! NET:<PECKHAM.DEVELOPMENT>NMLLBK.BLI.2 23-Jun-82 11:37:06, Edit by PECKHAM
!
! Ident 30.
! Check RB_PRV_* bits in request block before performing requests.
!
! NET:<PECKHAM.DEVELOPMENT>NMLLBK.BLI.3 14-Jun-82 13:43:13, Edit by PECKHAM
!
! Ident 29.
! Handle the MOP prompt message (ENTER MOP MODE) as a one byte message.
! This conforms to the VMS/RSX agreed-upon protocol.
!
! NET:<PECKHAM.DEVELOPMENT>NMLLBK.BLI.2 22-May-82 17:37:27, Edit by PECKHAM
!
! Ident 28.
! Check CIRCUIT STATE, SUBSTATE, and SERVICE in LINE_ACCESS
! for service interlocks.
!
! NET:<PECKHAM.DEVELOPMENT>NMLLBK.BLI.2 10-May-82 15:54:38, Edit by PECKHAM
!
! Ident 27.
! Fix linkage for BLISS-36
!
! NET:<PECKHAM.DEVELOPMENT>NMLLBK.BLI.13 5-May-82 11:09:50, Edit by PECKHAM
!
! Ident 26.
! Disallow LOOP LINE in NML$TEST.
! Add Loop Request Parameter Block and use (for better code efficiency).
! Optimize linkages around the parameter block.
!
! NET:<PECKHAM.DEVELOPMENT>NMLLBK.BLI.2 28-Apr-82 12:45:27, Edit by PECKHAM
!
! Ident 25.
! Change NMU$DLX_* routine references to $NMU_DLX_* macro references.
! Add receive timeout values where needed.
!
! NET:<PECKHAM.DEVELOPMENT>NMLLBK.BLI.7 8-Mar-82 13:36:45, Edit by PECKHAM
!
! Ident 24.
! Do not send ENTER MOP MODE message on LOOP LINE initialization
! in LINE_ACCESS. Add retry code in LOOP_LINE.
!
! NET:<BRANDT.DEVELOP>NMLLBK.BLI.1 14-Dec-81 16:43:23, Edit by BRANDT
!
! Ident 23.
! Change call to NML$SET_VDB_PARAMETER so that the address of the
! data is passed, not the value. Add literal defs from NMLDLW for
! circuit parameter numbers and substate values.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.4 21-Oct-81 09:13:23, Edit by WEBBER
!
! Ident 22.
! Modify interface to NETWORK_OPEN to pass the response buffer and its
! length.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.3 16-Jun-81 17:05:02, Edit by GUNN
!
! Ident 21.
! Make check for looped message in LINE_ACCESS allow both
! function code LOOPBACK_TEST and LOOPED_DATA.
! Allow for reflected ENTER-MOP-MODE message.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.15 16-Jun-81 12:30:15, Edit by GUNN
!
! Ident 20.
! Fix response handling in LOOP_LINE.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.12 15-Jun-81 10:04:26, Edit by GUNN
!
! Ident 19.
! Fix retrieval of response code from response buffer after calling
! LINE_ACCESS.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.8 12-Jun-81 10:50:01, Edit by GUNN
!
! Ident 18.
! Change default LENGTH parameter to 127. Makes default work with
! DECnet-M.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.7 11-Jun-81 17:45:07, Edit by GUNN
!
! Ident 17.
! Build response message if LINE_ACCESS fails.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.6 11-Jun-81 16:07:08, Edit by GUNN
!
! Ident 16.
! Release MOP buffer in LINE_ACCESS.
! Put call to NML$SET_VDB_PARAMETER in comment.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.5 8-Jun-81 10:16:54, Edit by GUNN
!
! Ident 15.
! Add code in LINE_ACCESS to write ENTER-MOP-MODE message and
! read MOP-MODE-RUNNING message.
! Add code to handle read errors.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.12 28-May-81 10:45:42, Edit by GUNN
!
! Ident 14.
! Set RB_RESPONSE_LENGTH from response message buffer after calling
! LINE_ACCESS.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.11 28-May-81 09:23:50, Edit by GUNN
!
! Ident 13.
! Change test for completion of NMU$DLX_OPEN to geq 0.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.10 28-May-81 06:21:35, Edit by GUNN
!
! Ident 12.
! Add definition for RESPONSE_BUFFER_ALLOCATION.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.9 28-May-81 06:11:12, Edit by GUNN
!
! Ident 11.
! Allocate a response message buffer in NML$TEST.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.8 27-May-81 15:58:49, Edit by GUNN
!
! Ident 10.
! Add external declarations for NMU$DLX_xxx routines.
! Remove reference to structure REQ in LOOP_NODE and LOOP_LINE.
! Pass repsonse pointer instead.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.6 27-May-81 15:03:15, Edit by GUNN
!
! Ident 09.
! Add code to perform loop line/circuit.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.5 31-Mar-81 07:59:24, Edit by GUNN
!
! Release send and receive buffers in LOOP_NODE.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.3 11-Mar-81 08:57:37, Edit by GUNN
!
! Change format of node id string passed to NMU$NETWORK_OPEN in the
! Connect Block CB_HOST field to be same as NODE entity id.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.2 9-Mar-81 08:54:21, Edit by GUNN
!
! Change test loop limit so extra loop not taken.
! Change default length to 255.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.7 13-Feb-81 10:06:16, Edit by GUNN
!
! Add CIRCUIT entity in NML$TEST.
!
! NET:<DECNET20-V3P1.NML>NMLLBK.BLI.6 12-Feb-81 15:27:19, Edit by GUNN
!
! Update copyright date.
! Change GET_LOOP_PARAMETERS to return NICE error return code on first
! invalid parameter detected.
! Change GENERATE_LOOP_MESSAGE to return NICE error code if LOOP WITH
! parameter value is invalid.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NMLLBK.BLI.36 10-Feb-81 13:49:06, Edit by JENNESS
! Make sure that connect data has zero length in connect block!!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NMLLBK.BLI.35 9-Feb-81 12:43:12, Edit by GUNN
! Remove check for version skew.
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NMLLBK.BLI.33 3-Feb-81 10:34:00, Edit by JENNESS
! Remove literal definition for MIRROR_OBJECT ... now in NMARCH.
%title 'NMLLBK -- Network Management Loopback Processor'
module NMLLBK (
ident = 'X04.40'
) =
begin
!
! COPYRIGHT (c) 1980, 1981, 1984 BY
! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
!
! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
! ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
! INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
! COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
! OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
! TRANSFERRED.
!
! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
! AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
! CORPORATION.
!
! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
!
!++
! FACILITY: DECnet-10/20 V4.0 Network Management Layer (NML)
!
! ABSTRACT:
!
! Performs loopback test function.
!
! ENVIRONMENT: TOPS-10/20 & MCB/RSX11 User mode under NML
!
! AUTHOR: Dale C. Gunn , CREATION DATE: 12-Nov-80
!
! MODIFIED BY:
!
! , : VERSION
! 01 -
!--
!
! INCLUDE FILES:
!
library 'NMLLIB' ; ! All required definitions
%if $TOPS20
%then
library 'MONSYM'; ! Monitor symbols
library 'JLNKG'; ! JSYS linkage definitions
%fi
require 'NMLEXT'; ! External routine declarations
!
! TABLE OF CONTENTS
!
%if %bliss (bliss16)
%then linkage NML_LKG_PB = jsr (register = 5);
%else macro NML_LKG_PB = bliss36c %;
%fi
forward routine
NML$TEST, ! Perform loopback test
GET_LOOP_PARAMETERS: NML_LKG_PB, ! Get parameters from NICE test msg
NODE_ACCESS: NML_LKG_PB, ! NODE loopback access routine
CIRCUIT_ACCESS: NML_LKG_PB, ! CIRCUIT loopback access routine
LOOP_NODE: NML_LKG_PB, ! Perform NODE loop test
LOOP_CIRCUIT: NML_LKG_PB, ! Perform CIRCUIT loop test
GENERATE_LOOP_MESSAGE: NML_LKG_PB, ! Build LOOP data message
VERIFY_LOOP_MESSAGE: NML_LKG_PB; ! Check validity of LOOPED message
!
! MACROS:
!
macro
CH$HEX [ ] =
ch$ptr (uplit (X_CHAR(%explode(%remaining))),,8) %;
macro
X_CHAR [B1,B2,B3,B4,B5,B6,B7,B8] =
((%X B1 ^ (%bpval-4))
%if not %null(B2)
%then
or (%X B2 ^ (%bpval-8))
%if not %null(B3)
%then
or (%X B3 ^ (%bpval-12))
%if not %null(B4)
%then
or (%X B4 ^ (%bpval-16))
%if not %null(B5)
%then
or (%X B5 ^ (%bpval-20))
%if not %null(B6)
%then
or (%X B6 ^ (%bpval-24))
%if not %null(B7)
%then
or (%X B7 ^ (%bpval-28))
%if not %null(B8)
%then
or (%X B8 ^ (%bpval-32))
%fi %fi %fi %fi %fi %fi %fi) %;
!
! EQUATED SYMBOLS:
!
! Loop Request Block
!
$show (fields); ! Turn on XPORT field display
$show (literals); ! Turn on XPORT literal display
$field
PARAMETER_FIELDS =
set
PB_BASE = [$sub_block (0)],
PB_RESPONSE_PTR = [$pointer],
PB_REQ_ADR = [$address],
PB_LINK_HANDLE = [$short_integer],
PB_ASST_NODE = ! Node parameter 156
[$sub_block (NODE_ID_BUFFER_LENGTH)],
PB_ASST_PHY_ADDR = [$pointer], ! Node parameter 153
PB_COUNT = [$integer], ! Node parameter 150
PB_HARDWARE_ADDR = [$pointer], ! Node parameter 114
PB_HELP = [$integer], ! Node parameter 154
PB_LENGTH = [$integer], ! Node parameter 151
PB_NODE = ! Node parameter 155
[$sub_block (NODE_ID_BUFFER_LENGTH)],
PB_PHY_ADDR = [$pointer], ! Node parameter 10
PB_WITH = [$integer] ! Node parameter 152
tes;
literal
PARAMETER_BLOCK_SIZE = $field_set_size,
PARAMETER_BLOCK_ALLOCATION = $field_set_units;
macro
PARAMETER_BLOCK = block [PARAMETER_BLOCK_SIZE] field (PARAMETER_FIELDS) %;
$show (none); ! Turn off XPORT display
!
! STATE/SUBSTATE/SERVICE definitions
!
literal
CPARM_STATE = 0,
CPARM_SUBSTATE = 1,
CPARM_SERVICE = 100;
literal
RESPONSE_BUFFER_LENGTH = 76, ! NICE response buffer in bytes
RESPONSE_BUFFER_SIZE = ch$allocation (RESPONSE_BUFFER_LENGTH,8),
RESPONSE_BUFFER_ALLOCATION = RESPONSE_BUFFER_SIZE * %upval ;
bind
LOOP_ASST_MULTICAST = CH$HEX ('CF0000000000'),
DEFAULT_PHY_ADDR = LOOP_ASST_MULTICAST;
literal
HELP_FULL = 2;
literal ! Defaults for test
DEFAULT_LENGTH = 127, ! Length of test data in bytes
DEFAULT_COUNT = 1, ! Same as RSX and VAX
DEFAULT_WITH = 2, ! MIXED ones and zeroes
DEFAULT_HELP = HELP_FULL; ! Both XMT & RCV assistance
!
! OWN STORAGE:
!
!
! EXTERNAL REFERENCES:
!
external
NMLVER, ! Network Managment version number
DECECO, ! Digital ECO number
USRECO ; ! User ECO number
external routine
NML$NICE_RESPONSE,
NML$CLR_VDB_PARAMETER,
NML$GET_VDB_PARAMETER,
NML$SET_VDB_PARAMETER,
NMU$NETWORK_UTILITIES;
%global_routine ('NML$TEST', REQ) =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine performs the NICE test request function. Either
! a NODE or CIRCUIT loopback test is performed based on the
! entity type in the test request message. If the NODE loop test
! is requested the NICE message may specify optional access
! control information to be used when connecting to the remote
! loopback mirror. Optional test parameters may also be included.
!
! FORMAL PARAMETERS
!
! REQ - The address of the NML Request Block.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NICE return code.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
REQ: ref REQUEST_BLOCK; ! NICE RB structure
local
PB: PARAMETER_BLOCK, ! For centralized data base
RTN_COD; ! NICE return code
selectone .REQ[RB_NICE_ENTITY_TYPE] of
set
[ENTITY_CIRCUIT, ENTITY_LINE] : ! Too dangerous
if not .REQ[RB_PRV_SERVICE] then return NICE$_PRV;
[otherwise]: ! Okay
0;
tes;
!
! Allocate NICE response buffer.
!
REQ[RB_RESPONSE_ALLOCATION] = RESPONSE_BUFFER_ALLOCATION;
REQ[RB_RESPONSE] = NMU$MEMORY_GET (.REQ[RB_RESPONSE_ALLOCATION]);
!
! Set up the parameter block
!
PB [PB_REQ_ADR] = .REQ; ! Get Request Block address
REQ[RB_RESPONSE_LENGTH] = 0; ! Initialize response length to zero
PB [PB_RESPONSE_PTR] = ch$ptr (.REQ[RB_RESPONSE],, 8);
!
! Get the LOOP test parameters from NICE message.
!
if (RTN_COD = GET_LOOP_PARAMETERS (PB[PB_BASE])) lss 0
then return .RTN_COD ;
!
! Perform either NODE or CIRCUIT loop test based on entity
!
begin
local PBBASE;
PBBASE = PB[PB_BASE];
selectone .REQ[RB_NICE_ENTITY_TYPE] of
set
[ENTITY_NODE]: ! NODE loopback test
RTN_COD = NODE_ACCESS (.PBBASE); ! Call loopback access routine
[ENTITY_CIRCUIT]: ! CIRCUIT loopback test
RTN_COD = CIRCUIT_ACCESS (.PBBASE); ! Call circuit access routine
[ENTITY_LINE]:
RTN_COD = NICE$_UFO;
[otherwise]: ! Internal error
RTN_COD = NICE$_MPE;
tes;
end;
if .RTN_COD lss 0
then begin
local EID_PTR, EID_LEN;
! If the preceding entity access routine did not build a NICE
! response message using the PB_RESPONSE_PTR, build a standard
! response using the RTN_COD value returned from the access routine.
if ch$diff (.PB[PB_RESPONSE_PTR],ch$ptr (.REQ[RB_RESPONSE],,8)) leq 0
then
PB[PB_RESPONSE_PTR] = ch$plus (.PB[PB_RESPONSE_PTR],
$RESPONSE (.PB[PB_RESPONSE_PTR],
.RTN_COD));
! PB_RESPONSE_PTR now points to the ENTITY ID field of the NICE
! response message. Build the ENTITY ID into the response message.
EID_PTR = .REQ[RB_NICE_ENTITY]; ! include an entity ID
if .REQ[RB_NICE_ENTITY_TYPE] eql NODE_E
then ! NODE has special format
begin
local
NODE_ID_PTR,
LOCAL_NODE_PTR;
LOCAL_NODE_PTR = NMU$NETWORK_LOCAL (); ! Local node id
NODE_ID_PTR = .PB[PB_RESPONSE_PTR]; ! Make copy of current pointer
EID_LEN = ch$rchar (ch$plus (.EID_PTR,2)) + 3;
PB[PB_RESPONSE_PTR] = ch$move (.EID_LEN,
.EID_PTR,
.PB[PB_RESPONSE_PTR]);
!
! If node addresses are equal this is the executor node,
! so set bit 7 in length byte to indicate this fact.
!
if GETB (NODE_ID_PTR) eql GETB (LOCAL_NODE_PTR)
then if GETB (NODE_ID_PTR) eql GETB (LOCAL_NODE_PTR)
then ch$wchar ((ch$rchar (.NODE_ID_PTR) or (1 ^ 7)), .NODE_ID_PTR);
end
else
begin
EID_LEN = ch$rchar (.EID_PTR) + 1;
PB[PB_RESPONSE_PTR] = ch$move (.EID_LEN,
.EID_PTR,
.PB[PB_RESPONSE_PTR]);
end;
selectone .RTN_COD of ! Include TEST DATA field in response
set ! message, for appropriate errors
[$NICE$ERR_LCE,
$NICE$ERR_BLR,
$NICE$ERR_OPF,
$NICE$ERR_IPV]:
PUTW ((PB[PB_COUNT]),PB[PB_RESPONSE_PTR]);
[otherwise]: ! No data field supplied
0;
tes;
end
else begin
! If the preceding entity access routine did not build a NICE
! response message using the PB_RESPONSE_PTR, build a standard
! response using the NICE success return code.
if ch$diff (.PB[PB_RESPONSE_PTR],ch$ptr (.REQ[RB_RESPONSE],,8)) leq 0
then
PB[PB_RESPONSE_PTR] = ch$plus (.PB[PB_RESPONSE_PTR],
$RESPONSE (.PB[PB_RESPONSE_PTR],
NICE$_SUC));
! Set the response message length in the request block
REQ[RB_RESPONSE_LENGTH] = ch$diff (.PB[PB_RESPONSE_PTR],
ch$ptr (.REQ[RB_RESPONSE],,8));
NML$REQUEST_FINISH (.REQ) ; ! Queue request for completion
end;
return .RTN_COD
end; !End of NML$TEST
%routine ('GET_LOOP_PARAMETERS', PB) : NML_LKG_PB =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine extracts the optional parameters that may be
! supplied with the NICE test request message. If any of the
! parameters are not supplied in the test request, appropriate
! defaults are returned.
!
! FORMAL PARAMETERS
!
! PB - The address of the parameter block.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! 1, if successful;
! NICE return code otherwise.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
PB : ref PARAMETER_BLOCK;
bind
REQ = .PB[PB_REQ_ADR]: REQUEST_BLOCK; ! NICE RB structure
!
! Preset the default values. LOOP HELP/LENGTH/WITH parameters are
! set up in the EXECUTOR node's Volatile Data Base (VDB). Get them
! from there as first priority. If not there use a local default.
if not NML$GET_VDB_PARAMETER (ENTITY_NODE,
NMU$NETWORK_LOCAL(),
150, ! LOOP COUNT
PB[PB_COUNT])
then PB[PB_COUNT] = DEFAULT_COUNT;
if not NML$GET_VDB_PARAMETER (ENTITY_NODE,
NMU$NETWORK_LOCAL(),
151, ! LOOP LENGTH
PB[PB_LENGTH])
then PB[PB_LENGTH] = DEFAULT_LENGTH;
if not NML$GET_VDB_PARAMETER (ENTITY_NODE,
NMU$NETWORK_LOCAL(),
152, ! LOOP WITH
PB[PB_WITH])
then PB[PB_WITH] = DEFAULT_WITH;
selectone .REQ[RB_NICE_ENTITY_TYPE] of
set
[ENTITY_NODE]: ! NODE loopback test
;
[ENTITY_CIRCUIT]: ! CIRCUIT loopback test
begin
PB[PB_HELP] = DEFAULT_HELP;
PB[PB_HARDWARE_ADDR] = 0;
PB[PB_PHY_ADDR] = DEFAULT_PHY_ADDR;
end;
[ENTITY_LINE]: ! LINE loopback test
;
[otherwise]: ! Internal error
return $NICE$ERR_MPE;
tes;
!
! If parameters were provided pick up their values.
!
if .REQ[RB_NICE_PARAMETERS] neq 0
then begin
local PARPTR,PAREND;
PARPTR = .REQ[RB_NICE_PARAMETERS];
PAREND = ch$plus (ch$ptr(.REQ[RB_NICE],,8), .REQ[RB_NICE_LENGTH]);
while ch$diff (.PAREND, .PARPTR) gtr 0
do begin
local PAR_NO, PAR_VAL;
PAR_NO = GETW (PARPTR) ; ! Get parameters number
selectone .PAR_NO of
set
[150]: ! LOOP COUNT
selectoneu (PAR_VAL = GETW (PARPTR)) of
set
[1 to 65535]:
PB[PB_COUNT] = .PAR_VAL;
[otherwise]:
return $NICE$ERR_IPV;
tes;
[151]: ! LOOP LENGTH
selectoneu (PAR_VAL = GETW (PARPTR)) of
set
[1 to 65535]:
PB[PB_LENGTH] = .PAR_VAL;
[otherwise]:
return $NICE$ERR_IPV;
tes;
[152]: ! LOOP WITH
selectoneu (PAR_VAL = GETB (PARPTR)) of
set
[0, 1, 2]:
PB[PB_WITH] = .PAR_VAL;
[otherwise]:
return $NICE$ERR_IPV;
tes;
[10]: ! LOOP PHYSICAL ADDRESS
begin
if GETB (PARPTR) neq 6 ! It must be HI-6
then return $NICE$ERR_IMF;
PB[PB_PHY_ADDR] = .PARPTR; ! Save pointer to data
GETW (PARPTR); ! Eat up the string
GETW (PARPTR);
GETW (PARPTR);
end;
[153]: ! LOOP ASSISTANT PHYSICAL ADDRESS
begin
if GETB (PARPTR) neq 6 ! It must be HI-6
then return $NICE$ERR_IMF;
PB[PB_ASST_PHY_ADDR] = .PARPTR; ! Save pointer to data
GETW (PARPTR); ! Eat up the string
GETW (PARPTR);
GETW (PARPTR);
end;
[154]: ! LOOP HELP
selectoneu (PAR_VAL = GETB (PARPTR)) of
set
[0, 1, 2]:
PB[PB_HELP] = .PAR_VAL;
[otherwise]:
return $NICE$ERR_IPV;
tes;
[155]: ! LOOP NODE
begin
local
L,
ADDRESS,
NOD_LEN: $SIGNED_BYTE_VALUE, ! Signed length
NOD_PTR,
NOD_ADR;
!
! Get NODE NAME and ADDRESS
!
NOD_ADR = PB[PB_NODE];
NOD_PTR = ch$ptr (.NOD_ADR,,8);
NOD_LEN = GETB (PARPTR); ! Fetch format byte
NOD_LEN = .NOD_LEN[VALUE]; ! Pick up the id length
L = NODE_ID_BUFFER_LENGTH;
if .NOD_LEN[VALUE] eql 0
then begin ! NODE address format
ADDRESS = GETW (PARPTR); ! Get node address value
if .ADDRESS eql 0
then return $NICE$ERR_IPV ! EXECUTOR Node illegal
else begin
PUTW (ADDRESS, NOD_PTR); ! Store node address
PUTB (0, NOD_PTR); ! Zero length node name
NOD_PTR = ch$ptr (.NOD_ADR,,8);
$NML$MAP_NODE_ID (L, .NOD_PTR);
end;
end
else begin
if .NOD_LEN[VALUE] gtr 0
then begin ! NODE name format
ADDRESS = 0; ! Node address is zero
PUTW (ADDRESS, NOD_PTR); ! Store node address
PUTB (.NOD_LEN[VALUE], NOD_PTR); ! And length
ch$move (.NOD_LEN[VALUE], ! Move node name
.PARPTR,
.NOD_PTR);
PARPTR = ch$plus (.PARPTR,.NOD_LEN[VALUE]);
NOD_PTR= ch$ptr (.NOD_ADR,,8);
if not $NML$MAP_NODE_ID (L, .NOD_PTR)
then return $NICE$ERR_URC;
ADDRESS = GETW (NOD_PTR);
end
else return $NICE$ERR_IPV; ! Class illegal
end;
if .PB[PB_PHY_ADDR] neq DEFAULT_PHY_ADDR
then return $NICE$ERR_IPG; ! Can't have together
!
! Get HARDWARE ADDRESS from NODE Data Base. If
! not defined set to null.
!
if not NML$GET_VDB_PARAMETER (ENTITY_NODE,
ch$ptr (PB[PB_NODE],,8),
114, ! HARDWARE ADDRESS
PB[PB_HARDWARE_ADDR])
then PB[PB_HARDWARE_ADDR] = 0;
!
! Play GUTS!!!!!
! Build Ethernet physical address for this node
! in the NODE Id buffer in the PB.
! Hope no one will need the NODE ID again.
!
NOD_PTR = ch$ptr (.NOD_ADR,,8);
NOD_PTR = ch$move (4, ! Move HI-Order Ethernet address
CH$HEX ('AA000400'),
.NOD_PTR);
PUTW (ADDRESS, NOD_PTR);
PB[PB_PHY_ADDR] = ch$ptr (.NOD_ADR,,8);
end;
[156]: ! LOOP ASSISTANT NODE
begin
local
L,
ADDRESS,
NOD_LEN: $SIGNED_BYTE_VALUE, ! Signed length
NOD_PTR,
NOD_ADR;
!
! Get NODE NAME and ADDRESS
!
NOD_ADR = PB[PB_ASST_NODE];
NOD_PTR = ch$ptr (.NOD_ADR,,8);
NOD_LEN = GETB (PARPTR); ! Fetch format byte
NOD_LEN = .NOD_LEN[VALUE]; ! Pick up the id length
L = NODE_ID_BUFFER_LENGTH;
if .NOD_LEN[VALUE] eql 0
then begin ! NODE address format
ADDRESS = GETW (PARPTR); ! Get node address value
if .ADDRESS eql 0
then return $NICE$ERR_IPV ! EXECUTOR Node illegal
else begin
PUTW (ADDRESS, NOD_PTR); ! Store node address
PUTB (0, NOD_PTR); ! Zero length node name
NOD_PTR = ch$ptr (.NOD_ADR,,8);
$NML$MAP_NODE_ID (L, .NOD_PTR);
end;
end
else begin
if .NOD_LEN[VALUE] gtr 0
then begin ! NODE name format
ADDRESS = 0; ! Node address is zero
PUTW (ADDRESS, NOD_PTR); ! Store node address
PUTB (.NOD_LEN[VALUE], NOD_PTR);
ch$move (.NOD_LEN[VALUE], ! Move node name
.PARPTR,
.NOD_PTR);
PARPTR = ch$plus (.PARPTR,.NOD_LEN[VALUE]);
NOD_PTR= ch$ptr (.NOD_ADR,,8);
if not $NML$MAP_NODE_ID (L, .NOD_PTR)
then return $NICE$ERR_URC;
ADDRESS = GETW (NOD_PTR);
end
else return $NICE$ERR_IPV; ! Class illegal
end;
if .PB[PB_ASST_PHY_ADDR] neq DEFAULT_PHY_ADDR
then return $NICE$ERR_IPG; ! Can't have together
!
! Get HARDWARE ADDRESS from NODE Data Base. If
! not defined set to null.
!
if not NML$GET_VDB_PARAMETER (ENTITY_NODE,
ch$ptr (PB[PB_ASST_NODE],,8),
114, ! HARDWARE ADDRESS
PB[PB_HARDWARE_ADDR])
then PB[PB_HARDWARE_ADDR] = 0;
!
! Play GUTS!!!!!
! Build Ethernet physical address for this node
! in the NODE Id buffer in the PB.
! Hope no one will need the NODE ID again.
!
NOD_PTR = ch$ptr (.NOD_ADR,,8);
NOD_PTR = ch$move (4, ! Move HI-Order Ethernet address
CH$HEX ('AA000400'),
.NOD_PTR);
PUTW (ADDRESS, NOD_PTR);
PB[PB_ASST_PHY_ADDR] = ch$ptr (.NOD_ADR,,8);
end;
[otherwise]: ! Invalid parameter for LOOP
return $NICE$ERR_UPT ;
tes;
end;
if .PARPTR neq .PAREND then return $NICE$ERR_IMF;
end;
return 1 ; ! Return NICE success code
end; !End of GET_LOOP_PARAMETERS
%routine ('NODE_ACCESS', PB) : NML_LKG_PB =
!++
! FUNCTIONAL DESCRIPTION:
!
! This is the loopback access routine for the NODE loopback
! test.
!
! FORMAL PARAMETERS
!
! PB - The address of the parameter block.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NICE return code.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
PB: ref PARAMETER_BLOCK;
bind
REQ = .PB[PB_REQ_ADR]: REQUEST_BLOCK ; ! NICE RB structure
local
CBLK: CONNECT_BLOCK, ! DECnet link connect block
LSBLK: LINK_STATUS_BLOCK, ! DECnet link status block
RTN_COD ; ! NICE return
!
! Set up the DECnet link connect block for loopback mirror
! at node specified in NCP command
!
CBLK[CB_OBJECT] = MIRROR_OBJECT ; ! Loopback mirror object number
CBLK[CB_DESCRIPTOR_LENGTH] = 0 ; ! No descriptor
CBLK[CB_TASK_LENGTH] = 0 ; ! No task name
!
! Entity id specifies the node to mirror the loopback test messages
!
CBLK[CB_HOST] = .REQ[RB_NICE_ENTITY] ;
CBLK[CB_HOST_LENGTH] = .REQ[RB_NICE_ENTITY_ID_LENGTH] ;
!
! Copy access control fields from request block
!
CBLK[CB_USERID_LENGTH] = .REQ[RB_USER_LENGTH] ;
CBLK[CB_USERID] = .REQ[RB_USER];
CBLK[CB_ACCOUNT_LENGTH] = .REQ[RB_ACCOUNT_LENGTH] ;
CBLK[CB_ACCOUNT] = .REQ[RB_ACCOUNT];
CBLK[CB_PASSWORD_LENGTH] = .REQ[RB_PASSWORD_LENGTH] ;
CBLK[CB_PASSWORD] = .REQ[RB_PASSWORD];
CBLK[CB_DATA_LENGTH] = 0;
!
! Now make network connection to Loopback Mirror
!
REQ[RB_RESPONSE_LENGTH] = RESPONSE_BUFFER_LENGTH;
if (PB[PB_LINK_HANDLE] = NMU$NETWORK_OPEN (SOURCE_LINK, CBLK,
.PB[PB_RESPONSE_PTR], REQ[RB_RESPONSE_LENGTH], NICE$_MCF))
gtr 0
then begin
local
MESSAGE_DATA_SIZE ; ! Maximum data size of mirror
!
! Check that mirror returned its maximum data buffer length
! and get it.
!
if .CBLK[CB_DATA_LENGTH] neq 2
then return $NICE$ERR_MPE ;
MESSAGE_DATA_SIZE = GETW (CBLK[CB_DATA]) ; ! Get mirror's data length
!
! Go ahead and test if our length is not over mirrors maximum.
!
if .PB[PB_LENGTH] leq .MESSAGE_DATA_SIZE
then RTN_COD = LOOP_NODE (PB[PB_BASE]) ! Loop messages to node
else begin
RTN_COD = NICE$_IPV;
PB[PB_RESPONSE_PTR] = ch$plus (.PB[PB_RESPONSE_PTR],
$RESPONSE (.PB[PB_RESPONSE_PTR], .RTN_COD, N$LLTH));
PB[PB_COUNT] = .MESSAGE_DATA_SIZE;
end;
NMU$NETWORK_CLOSE (.PB[PB_LINK_HANDLE], 0, 0);
end
else RTN_COD = $NICE$ERR_MCF; ! Say mirror connect failed
return .RTN_COD
end; !End of NODE_ACCESS
%routine ('CIRCUIT_ACCESS', PB) : NML_LKG_PB =
!++
! FUNCTIONAL DESCRIPTION:
!
! This is the access routine for the CIRCUIT loopback test.
!
! FORMAL PARAMETERS
!
! PB - The address of the parameter block.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NICE return code.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
PB: ref PARAMETER_BLOCK;
bind
REQ = .PB[PB_REQ_ADR]: REQUEST_BLOCK; ! NICE RB structure
local
RTN_COD ; ! NICE return
!
! STATE must be ON or SERVICE
!
begin
local CIRCUIT_STATE;
if not NML$GET_VDB_PARAMETER (.REQ[RB_NICE_ENTITY_TYPE],
.REQ[RB_NICE_ENTITY],
CPARM_STATE,
CIRCUIT_STATE)
then CIRCUIT_STATE = CIRCUIT_ON;
selectone .CIRCUIT_STATE of
set
[CIRCUIT_ON, CIRCUIT_SERVICE]:
;
[otherwise]:
begin
RTN_COD = NICE$_CWS;
$RESPONSE (.PB[PB_RESPONSE_PTR], .RTN_COD, CIRCUIT_);
return .RTN_COD;
end;
tes;
end;
!
! SERVICE must be ENABLED
!
begin
local CIRCUIT_SERVICE;
if not NML$GET_VDB_PARAMETER (.REQ[RB_NICE_ENTITY_TYPE],
.REQ[RB_NICE_ENTITY],
CPARM_SERVICE,
CIRCUIT_SERVICE)
then CIRCUIT_SERVICE = CIRCUIT_DISABLED;
selectone .CIRCUIT_SERVICE of
set
[CIRCUIT_ENABLED]:
;
[otherwise]:
begin
RTN_COD = NICE$_CWS;
$RESPONSE (.PB[PB_RESPONSE_PTR], .RTN_COD, CIRCUIT_);
return .RTN_COD;
end;
tes;
end;
!
! substate must not be set.
!
begin
local CIRCUIT_SUBSTATE;
if not NML$GET_VDB_PARAMETER (.REQ[RB_NICE_ENTITY_TYPE],
.REQ[RB_NICE_ENTITY],
CPARM_SUBSTATE,
CIRCUIT_SUBSTATE)
then CIRCUIT_SUBSTATE = CIRCUIT_NO_SUBSTATE;
selectone .CIRCUIT_SUBSTATE of
set
[CIRCUIT_NO_SUBSTATE]:
;
[otherwise]:
begin
RTN_COD = NICE$_CWS;
$RESPONSE (.PB[PB_RESPONSE_PTR], .RTN_COD, CIRCUIT_);
return .RTN_COD;
end;
tes;
end;
!
! Open the DLX data link for loopback use.
!
if (RTN_COD = $NMU_DLX_OPEN (DLX_LOOP,
CIRCUIT_,
.REQ[RB_NICE_ENTITY],
.PB[PB_PHY_ADDR],
.PB[PB_RESPONSE_PTR])) geq 0
then begin ! DLX open, got DLX link handle
PB[PB_LINK_HANDLE] = .RTN_COD;
!
! Set Data Link Substate to LOOPING.
!
NML$SET_VDB_PARAMETER (.REQ[RB_NICE_ENTITY_TYPE],
.REQ[RB_NICE_ENTITY],
CPARM_SUBSTATE,
uplit (CIRCUIT_LOOPING)) ;
RTN_COD = LOOP_CIRCUIT (PB[PB_BASE]); ! Loop messages to data link
NML$CLR_VDB_PARAMETER (.REQ[RB_NICE_ENTITY_TYPE],
.REQ[RB_NICE_ENTITY],
CPARM_SUBSTATE);
$NMU_DLX_CLOSE (.PB[PB_LINK_HANDLE]); ! Close the DLX link
end;
return .RTN_COD
end; !End of CIRCUIT_ACCESS
%routine ('LOOP_NODE', PB) : NML_LKG_PB =
!++
! FUNCTIONAL DESCRIPTION:
!
! Performs the loopback function to the loopback mirror at
! a remote node.
!
! FORMAL PARAMETERS
!
! PB - The address of the parameter block.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NICE return code.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
PB: ref PARAMETER_BLOCK;
label
AND_RETURN_BUFFERS;
literal
EOM = 1 ; ! End of message flag
local
BUFFER_ADR, ! Address of receive buffer
BUFFER_PTR, ! Pointer to looped test message
MESSAGE_ADR, ! Address of test message buffer
MESSAGE_PTR, ! Pointer to test message
RTN_COD ; ! NICE return code
bind
LOOP_BUFFER_ALLOCATION = ch$allocation((.PB[PB_LENGTH] + 1),8) * %upval ;
!
! Get buffers for send and receive loop messages
!
BUFFER_ADR = NMU$MEMORY_GET (LOOP_BUFFER_ALLOCATION) ;
BUFFER_PTR = ch$ptr (.BUFFER_ADR,,8) ; ! Pointer to buffer
MESSAGE_ADR = NMU$MEMORY_GET (LOOP_BUFFER_ALLOCATION) ;
MESSAGE_PTR = ch$ptr (.MESSAGE_ADR,,8) ; ! Pointer to buffer
AND_RETURN_BUFFERS:
begin ! AND_RETURN_BUFFERS
!
! Build a loop message to test with, function code is zero.
!
RTN_COD = GENERATE_LOOP_MESSAGE (PB[PB_BASE], %O'0', .MESSAGE_PTR) ;
if .RTN_COD lss 0 then leave AND_RETURN_BUFFERS;
until .PB[PB_COUNT] eql 0 ! Loop all messages
do begin
if not NMU$NETWORK_WRITE (.PB[PB_LINK_HANDLE],
EOM,
.PB[PB_LENGTH] + 1, ! 1 Overhead byte
.MESSAGE_PTR)
then begin
RTN_COD = NICE$_MLD;
$RESPONSE(.PB[PB_RESPONSE_PTR], .RTN_COD, 10);
leave AND_RETURN_BUFFERS
end;
RTN_COD = NMU$NETWORK_READ (.PB[PB_LINK_HANDLE],
.PB[PB_LENGTH] + 1,
.BUFFER_PTR);
if .RTN_COD lss 0 then leave AND_RETURN_BUFFERS;
if not VERIFY_LOOP_MESSAGE (PB[PB_BASE], 1, .MESSAGE_PTR, .BUFFER_PTR)
then begin
RTN_COD = $NICE$ERR_BLR;
leave AND_RETURN_BUFFERS
end;
PB[PB_COUNT] = .PB[PB_COUNT] - 1 ; ! Another message looped
end;
$RESPONSE (.PB[PB_RESPONSE_PTR], NICE$_SUC);
RTN_COD = NICE$_SUC;
end; ! AND_RETURN_BUFFERS
!
! Release buffers
!
NMU$MEMORY_RELEASE (.MESSAGE_ADR,LOOP_BUFFER_ALLOCATION) ;
NMU$MEMORY_RELEASE (.BUFFER_ADR,LOOP_BUFFER_ALLOCATION) ;
return .RTN_COD ; ! Return results
end; !End of LOOP_NODE
%routine ('LOOP_CIRCUIT', PB) : NML_LKG_PB =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
! PB - The address of the parameter block.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
PB: ref PARAMETER_BLOCK;
label
AND_RETURN_BUFFERS;
local
BUFFER_ADR, ! Address of receive buffer
BUFFER_PTR, ! Pointer to looped test message
MESSAGE_ADR, ! Address of test message buffer
MESSAGE_PTR, ! Pointer to test message
RTN_COD ; ! NICE return code
bind
LOOP_BUFFER_ALLOCATION = ch$allocation((.PB[PB_LENGTH] + 1),8) * %upval ;
!
! Get buffers for send and receive loop messages
!
BUFFER_ADR = NMU$MEMORY_GET (LOOP_BUFFER_ALLOCATION) ;
BUFFER_PTR = ch$ptr (.BUFFER_ADR,,8) ; ! Pointer to buffer
MESSAGE_ADR = NMU$MEMORY_GET (LOOP_BUFFER_ALLOCATION) ;
MESSAGE_PTR = ch$ptr (.MESSAGE_ADR,,8) ; ! Pointer to buffer
AND_RETURN_BUFFERS:
begin ! AND_RETURN_BUFFERS
!
! Build a loop message to test with, function code LOOPBACK_TEST.
!
RTN_COD = GENERATE_LOOP_MESSAGE (PB[PB_BASE], LOOPBACK_TEST, .MESSAGE_PTR) ;
if .RTN_COD lss 0 then leave AND_RETURN_BUFFERS;
until .PB[PB_COUNT] eql 0 ! Loop all messages
do begin
decru CNT from NMU$K_MOP_RETRY_LIMIT to 1
do begin
if not (RTN_COD = $NMU_DLX_WRITE (.PB[PB_LINK_HANDLE],
DLX_OTHER, ! Not doing load/dump
.MESSAGE_PTR,
.PB[PB_LENGTH] + 1, ! 1 Overhead byte
.PB[PB_RESPONSE_PTR]))
then begin
if .RTN_COD geq 0
then begin
ch$wchar(0, .PB[PB_RESPONSE_PTR]);
RTN_COD = $NICE$ERR_LCE;
end;
leave AND_RETURN_BUFFERS
end;
RTN_COD = $NMU_DLX_READ (.PB[PB_LINK_HANDLE],
DLX_OTHER, ! Not doing load/dump
.BUFFER_PTR, .PB[PB_LENGTH] + 1,,
.PB[PB_RESPONSE_PTR]);
if .RTN_COD gtr 0 then exitloop;
ch$wchar(0, .PB[PB_RESPONSE_PTR]);
if .RTN_COD neq -2
then begin
RTN_COD = $NICE$ERR_LCE;
leave AND_RETURN_BUFFERS
end;
RTN_COD = $NICE$ERR_LCE;
end;
if .RTN_COD lss 0 then leave AND_RETURN_BUFFERS;
selectone ch$rchar (.BUFFER_PTR) of
set
[LOOPED_DATA, 25, LOOPBACK_TEST]:
if VERIFY_LOOP_MESSAGE (PB[PB_BASE],
ch$rchar (.BUFFER_PTR),
.MESSAGE_PTR,
.BUFFER_PTR)
then PB[PB_COUNT] = .PB[PB_COUNT] - 1
else begin
RTN_COD = $NICE$ERR_BLR;
leave AND_RETURN_BUFFERS
end;
[MOP_MODE_RUNNING]:
if .RTN_COD geq 8
then if (ch$rchar (ch$plus (.BUFFER_PTR, 7)) and 1^2) eql 0
then begin
RTN_COD = $NICE$ERR_OPF;
leave AND_RETURN_BUFFERS
end;
[otherwise]:
begin
RTN_COD = $NICE$ERR_BLR;
leave AND_RETURN_BUFFERS
end;
tes;
end;
! $RESPONSE (.PB[PB_RESPONSE_PTR], NICE$_SUC);
!
! Leave response pointer at end of response message
!
PB[PB_RESPONSE_PTR] = ch$plus (.PB[PB_RESPONSE_PTR],
($RESPONSE_LENGTH (.PB[PB_RESPONSE_PTR])));
PB[PB_RESPONSE_PTR] = ch$plus (.PB[PB_RESPONSE_PTR],
(GETB (PB[PB_RESPONSE_PTR])));
PB[PB_RESPONSE_PTR] = ch$plus (.PB[PB_RESPONSE_PTR],
(GETB (PB[PB_RESPONSE_PTR])));
RTN_COD = NICE$_SUC;
end; ! AND_RETURN_BUFFERS
!
! Release buffers
!
NMU$MEMORY_RELEASE (.MESSAGE_ADR,LOOP_BUFFER_ALLOCATION) ;
NMU$MEMORY_RELEASE (.BUFFER_ADR,LOOP_BUFFER_ALLOCATION) ;
return .RTN_COD ; ! Return results
end; !End of LOOP_CIRCUIT
%routine ('GENERATE_LOOP_MESSAGE', PB, FUNC_CODE, MESSAGE_PTR) : NML_LKG_PB =
!++
! FUNCTIONAL DESCRIPTION:
!
! Generates a NICE test message of requested length and
! contents determined by the LOOP WITH parameter value
! passed as an argument.
!
! FORMAL PARAMETERS
!
! PB - The address of the parameter block.
! FUNC_CODE - A value to be used as the first byte (function code)
! of the test message.
! MESSAGE_PTR - A character sequence pointer to the buffer in which
! the NICE test message will be built.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! 1, if successful;
! NICE return code if failed.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
PB: ref PARAMETER_BLOCK;
local
LOOP_CHAR ;
!
! Set up the data pattern to be used in loop message
!
LOOP_CHAR = (case .PB[PB_WITH] from 0 to 2 of
set
[0]: ! All zeroes
%B'00000000' ;
[1]: ! All ones
%B'11111111' ;
[2]: ! Mixed ones and zeroes
%B'10101010' ;
[inrange, ! Default to mixed
outrange]:
return $NICE$ERR_IPV ; ! Error return
tes);
!
! Write loop function code and fill message with appropriate pattern
!
ch$wchar_a (.FUNC_CODE,MESSAGE_PTR) ; ! Write function code
ch$fill (.LOOP_CHAR,
.PB[PB_LENGTH],
.MESSAGE_PTR) ;
return 1 ; ! Success
end; !End of GENERATE_LOOP_MESSAGE
%routine ('VERIFY_LOOP_MESSAGE', PB, FUNC_CODE, TRANSMIT_PTR,
RECEIVE_PTR) : NML_LKG_PB =
!++
! FUNCTIONAL DESCRIPTION:
!
! Determines the validity of a NICE test message response after
! being looped to the target node. The first byte of the message
! must contain the NICE success return code.
!
! FORMAL PARAMETERS
!
! PB - The address of the parameter block.
! FUNC_CODE - A value to be used as the first byte (function code)
! of the test message.
! TRANSMIT_PTR - A character sequence pointer to the NICE test
! message sent to the loopback mirror.
! RECEIVE_PTR - A character sequence pointer to the NICE test
! received from the loopback mirror.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! TRUE, if the looped message is valid;
! FALSE, otherwise.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
begin
map
PB: ref PARAMETER_BLOCK;
if ch$rchar_a (RECEIVE_PTR) neq .FUNC_CODE
then $false
else ch$eql (.PB[PB_LENGTH],
.RECEIVE_PTR,
.PB[PB_LENGTH],
ch$plus (.TRANSMIT_PTR, 1))
end; !End of VERIFY_LOOP_MESSAGE
end !End of Module NMLLBK
eludom
! Local Modes:
! Mode:BLISS
! Auto Save Mode:1
! Comment Column:40
! Comment Rounding:+1
! End: