Google
 

Trailing-Edge - PDP-10 Archives - TOPS-20_V6.1_DECnetSrc_7-23-85 - mcb/xpt/tlinmi.bli
There is 1 other file named tlinmi.bli in the archive. Click here to see a list.
module TLINMI   (				! Network Management stuff
		ident = 'X01160'
		) =
begin
!
!                    COPYRIGHT (c) 1980, 1981, 1982
!                    DIGITAL EQUIPMENT CORPORATION
!                        Maynard, Massachusetts
!
!     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:	Transport
!
! ABSTRACT:	This is the Network Management interface for the MCB
!		implementation of the Transport Line Interface.  It
!               dispatches to a processing routine in XPTNMX.
!
! ENVIRONMENT:	MCB
!
! AUTHOR:	L. Webber,	CREATION DATE: 20-Nov-80
!
! MODIFIED BY:
!
! 1.00	L. Webber, 11-Dec-80
!	Modified the model interface template to match XPT.
!
! 1.01	L. Webber, 22-Dec-80
!	Split into XPT and TLI parts.
!
! 1.02	L. Webber, 25-Feb-81
!	NMX entries are now in process XNM.
!
! 1.03	L. Webber, 20-May-81
!	Add GIVE_CIRCUIT and TAKE_CIRCUIT to support the new DLL/Network
!	Management Interface.
!
! 1.04	L. Webber, 23-Jun-81
!	Construct EID for the $MODIFY_CIRCUIT_OWNER using TLI's PIX.
!
! 1.05	L. Webber, 9-Jul-81
!	Fix call to SHOW_ZERO_COUNTERS for zeroing to pass correct function
!	code.
!
! 1.06	L. Webber, 13-Jul-81
!	Fix linkage to SET_PARM to pass address of COSTCH.
!
! 1.07	L. Webber, 16-Sep-81
!	Fix GIVE_CIRCUIT to use the DLLLIB sub-field to get the provider PIX
!	from the function CCB.
!
! 1.08	L. Webber, 24-Sep-81
!	Change GIVE_CIRCUIT not to save the ASCII circuit ID any more.
!
! 1.09	L. Webber, 28-Sep-81
!	Fix GIVE_CIRCUIT to use the provider LIX to get the circuit ID
!	from CEX, not the PIX.
!
! 1.10	A. Peckham, 14-Apr-82
!	Move NM code from XNM to this module.  Optimize linkages.
!
! 1.11	A. Peckham, 2-May-82
!	Only modify circuit owner on first assignment.
!
! 1.12	A. Peckham, 10-Sep-82
!	Do not set initial Lcv in GIVE_CIRCUIT.
!
! 1.13	A. Peckham, 14-Sep-82
!	Display new variable "Block_size" for circuit parameter #810.
!
! 1.14	A. Peckham, 29-Sep-82
!	Fix setting of DLLhandle to fix low byte as LINEnumber in GIVE_CIRCUIT.
!
! 1.15	A. Peckham,  1-Oct-82
!	Make CLEAR CIRCUIT ALL work in CLEAR_CIRCUIT.
!
! 1.16	A. Peckham, 20-Nov-82
!	Support seconds-since-last-zeroed counter.
!
!--

!
! REQUIRED FILES
!

require 'XPTMAC';

%if %bliss (bliss16)
%then
linkage XPT_LKG_CCB = jsr (register = 4);
%else
macro XPT_LKG_CCB = bliss36c;
%fi

!
! TABLE OF CONTENTS:
!
forward routine
    TLI_NM: MCB_DB_CCB novalue,         ! Control (i.e., NM)
    CIRCUIT_COUNTERS: LINKAGE_DB novalue,       ! Get circuit counters
    CLEAR_CIRCUIT: LINKAGE_DB_CCB novalue, ! Clear a circuit parameter
    GIVE_CIRCUIT: MCB_DB_CCB novalue,   ! Grant Circuit Ownership
    SET_CIRCUIT: LINKAGE_DB_CCB novalue, ! Set a circuit parameter
    SHOW_AND_ZERO_CIRCUIT_COUNTERS: LINKAGE_DB_CCB novalue,
                                        ! Show and zero circuit counters
    SHOW_CIRCUIT: LINKAGE_DB_CCB novalue, ! Show circuit parameters
    TAKE_CIRCUIT: MCB_DB_CCB novalue,   ! Withdraw Circuit Ownership
    ZERO_CIRCUIT_COUNTERS: LINKAGE_DB_CCB novalue; ! Zero circuit counters

!
! MACROS:
!

!
! EQUATED SYMBOLS:
!

!
! OWN STORAGE:
!

!
! EXTERNAL REFERENCES:
!
external routine
    CKTOFF: LINKAGE_DB_CCB novalue,
    CKTON: LINKAGE_DB_CCB novalue;
%sbttl 'Network Management'
global routine TLI_NM (XPTDB,CCB): MCB_DB_CCB novalue =

!++
! FUNCTIONAL DESCRIPTION:
!	This routine is activated by a control request from
!	Network Management.
!
! FORMAL PARAMETERS:
!
!	CCB	CCB to pass to handler routine
!
! IMPLICIT INPUTS:
!	CCB Contents
!
! IMPLICIT OUTPUTS:
!	None
!
! ROUTINE VALUE:
! COMPLETION CODES:
!	None
!
! SIDE EFFECTS:
!	None
!--

    begin

    require 'XPTSYM';

    map
	CCB: ref block field (C_NM_FIELDS);

    selectone .CCB [C_NM_ENTITY] of
	set
	[NMX$ENT_ckt]: 		! NM function for circuit parameter
		case .CCB [C_NM_FUNC] from NMX$FNC_lo to NMX$FNC_hi of
		    set 			! *** CIRCUIT ***
		    [NMX$FNC_set]: 		! Set parameters
			SET_CIRCUIT (.XPTDB,.CCB);
		    [NMX$FNC_clr]: 		! Clear parameters
			CLEAR_CIRCUIT (.XPTDB,.CCB);
		    [NMX$FNC_zro]: 		! Zero counters
			ZERO_CIRCUIT_COUNTERS (.XPTDB,.CCB);
		    [NMX$FNC_sho]: 		! Show selected items
			SHOW_CIRCUIT (.XPTDB,.CCB);
		    [NMX$FNC_szc]: 		! Show and zero counters
			SHOW_AND_ZERO_CIRCUIT_COUNTERS (.XPTDB,.CCB);
		    [NMX$FNC_ret]: 		! Return selected items
			CCB [C_STS] = $NM$ERR_MPE;
		    [inrange, outrange]: CCB [C_STS] = $NM$ERR_MPE;
		    tes;
	    [otherwise]: CCB [C_STS] = $NM$ERR_URC;
	    tes;

    if .CCB[C_STS] neq 0 then begin
	CCB [C_FNC] = FC_CCP;
	$MCB_SCHEDULE_CCB (.CCB);
	end;
    end;
routine CIRCUIT_COUNTERS (LINEb): LINKAGE_DB novalue =

!++
! FUNCTIONAL DESCRIPTION:
!	This routine inserts the counters for the specified circuit
!       in the NM buffer.
!
! FORMAL PARAMETERS:
!
!	LINEb	Line data base pointer
!
! IMPLICIT INPUTS:
!	None
!
! IMPLICIT OUTPUTS:
!	None
!
! ROUTINE VALUE:
! COMPLETION CODES:
!	None
!
! SIDE EFFECTS:
!	None
!--

    begin
    require 'XPTSYM';
    COUNTER_16_TIME(0,Time_circuit_zeroed);     ! Seconds since last zeroed
    COUNTER_32(800,Arriving_Packets);   ! Terminating Packets Received
    COUNTER_32(801,Departing_Packets);  ! Originating Packets Sent
    COUNTER_16(802,End_Congestion);     ! Terminating Congestion Loss
    COUNTER_32(810,Transit_In);         ! Transit Packets Received
    COUNTER_32(811,Transit_Out);        ! Transit Packets Sent
    COUNTER_16(812,Transit_Congestion); ! Transit Congestion Loss
    COUNTER_8(820,Line_Downs);          ! Circuit Down's
    COUNTER_8(821,Init_Fails);          ! Circuit Initialization Failures
    end;                                ! of CIRCUIT_COUNTERS
routine CLEAR_CIRCUIT (XPTDB,CCB): LINKAGE_DB_CCB novalue =

!++
! FUNCTIONAL DESCRIPTION:
!	This routine clears a circuit parameter
!
! FORMAL PARAMETERS:
!
!	CCB	CCB to pass to handler routine
!
! IMPLICIT INPUTS:
!	CCB Contents
!
! IMPLICIT OUTPUTS:
!	None
!
! ROUTINE VALUE:
! COMPLETION CODES:
!	None
!
! SIDE EFFECTS:
!	None
!--

    begin
    map CCB: ref block field(C_NM_FIELDS);
    local LINEb;
    require 'XPTSYM';

!
! Determine the entity whose parameter is to be set
!

    CCB [C_STS] = $NM$ERR_PNA;

    selectone
        begin
        if .CCB[C_CNT] eql 0
        then 2600
        else begin
             pointer PTR;
             MAPBUF(.CCB,PTR);
             getw(PTR)
             end
        end
    of
        set
[2600]:		begin			! Circuit node-type
    CCB [C_STS] = $NM$ERR_CWS;
    if (LINEb = $TLI_GET_LINE_DB(.CCB [C_LIN])) neqa 0
    then begin
        Ph2only = false;                !     to "automatic"
        CCB [C_STS] = NM$SUC;
	end;
		end;

[otherwise]:	0;                      ! Invalid parameter type
tes;
    end;                                ! of CLEAR_CIRCUIT
global
routine GIVE_CIRCUIT (XPTDB,CCB): MCB_DB_CCB novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
! Processes a "Grant Circuit Ownership" function.  If this is the
! first time the circuit has been mentioned, a data base entry is
! allocated for it.  Network Management is informed of the change
! in circuit owner.  If the circuit's Network Management state is ON,
! the circuit is initialized.
!
! FORMAL PARAMETERS
!
!	CCB	Function CCB
!
!		CCB[C_LIN]	0, if ownership of the circuit is being
!				given Transport for the first time.  Other-
!				wise, the index of the data base entry
!				allocated for the circuit.
!
!			If C_LIN is 0:
!
!		CCB[C_PRM1]
!		  subfield DLL$B_PROVIDER_PROCESS_INDEX
!				Provider PIX for the DLL process for the
!				circuit.
!		  subfield DLL$B_PROVIDER_LINE_INDEX
!				Provider LIX for the circuit.
!		CCB[C_PRM2]	Pointer to an unmapped image field which
!				represents the ASCII line ID.
!		CCB[C_PRM3]	Circuit characteristics:
!
!				........ .......x	1 if the circuit is a
!							DTE adjacent to a KL.
!				xxxxxxxx xxxxxxx.	Reserved.
!				
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
! COMPLETION CODES:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

begin
map CCB: ref block field(C_fields);
local LINEb;
require 'XPTSYM';
local P,Q,LEN;

!
!  Set up a line data base entry if required.
!

if .CCB[C_LIN] eql 0 then begin
    bind DLL_FLAG = CCB [C_PRM3]: block field (DLL$V_DTE_CIRCUIT);
         
    incr J from 1 to NLN do begin		!   Scan for a
	LINEb = $TLI_GET_LINE_DB(.J);           !   free line data
	if .DLLhandle eql 0 then		!   base entry
	    exitloop(CCB [C_LIN] = .J);
	end;
    if .CCB [C_LIN] eql 0 then			! Not found -
	SIGNAL_STOP(CE_ERR);			!   bomb
    DLLhandle = (.CCB[C_PRM1] and not %o'377') + .LINEnumber;
    DTEcircuit = false;
    if .DLL_FLAG [DLL$V_DTE_CIRCUIT]    ! If the circuit is a DTE,
    then begin
         DTEcircuit = true;		!   remember the fact.
         Intercept = true;
         end;
    Hello_timer = Default_Hello_timer;
    Listen_timer = Default_Listen_timer;
    $NM_TIME(Time_circuit_zeroed);

!
!  Inform Network Management of the new circuit owner
!

    begin
    local
        NMX_ID,
        SAVE_MAP;
    SMAP$(SAVE_MAP);
    MAP$(.CCB[C_BIAS]);
    NMX$MODIFY_CIRCUIT_OWNER (PD_NMX,		! NMX's PIX
                              .CCB [C_ADDR],	! ASCII ID
                              PD_TLI^8+.CCB[C_LIN],! EID
                              NMX_ID);		! Circuit's NMXID (returned)
    MAP$(.SAVE_MAP);
    NMXID = .NMX_ID;
    end;
    end
else						! "Old" circuit:
    LINEb = $TLI_GET_LINE_DB(.CCB[C_LIN]);      !   address line data base

!
!  Change the ownership state.
!

if not .OWNED                           ! Attempt to grant ownership
then CKTON(.LINEb, .CCB)                ! of the circuit
else SIGNAL_STOP(CE_ERR);		! otherwise there is a mixup

end;				!End of GIVE_CIRCUIT
routine SET_CIRCUIT (XPTDB,CCB): LINKAGE_DB_CCB novalue =

!++
! FUNCTIONAL DESCRIPTION:
!	This routine sets a circuit parameter
!
! FORMAL PARAMETERS:
!
!	CCB	CCB to pass to handler routine
!
! IMPLICIT INPUTS:
!	CCB Contents
!
! IMPLICIT OUTPUTS:
!	None
!
! ROUTINE VALUE:
! COMPLETION CODES:
!	None
!
! SIDE EFFECTS:
!	None
!--

    begin
    map CCB: ref block field(C_NM_FIELDS);
    local LINEb;
    require 'XPTSYM';

!
! Determine the entity whose parameter is to be set
!

if (LINEb = $TLI_GET_LINE_DB(.CCB [C_LIN])) neqa 0
then
    begin
    local PNUM,PVAL;
    begin
    pointer PTR;
    MAPBUF(.CCB,PTR);
    PNUM = getw(PTR);
    PVAL = getw(PTR);
    end;

    selectone .PNUM of
        set

        [0]:                            ! STATE
    selectoneu (PVAL = .PVAL<0,8>) of
         set
         [0]: begin                     ! Set line ON:
	NMstate = ON;			!   Change the line state
	selectone .LINEstate of
            set
            [TC,RU]:                    ! If not running
                0;                      ! then
            [otherwise]:                ! initialize the line.
                if .DLLstate neq DLL_FREE
                then CALL$L(INI_LIN,.LINEb);
            tes;
	CCB [C_STS] = NM$SUC;
	end;
         [1]: begin                     ! Set line OFF:
	NMstate = OFF;			!   Change the line state
        selectone .LINEstate of
            set
            [OFF,HA]:                   ! If not stopped
                0;                      ! then
            [otherwise]:                ! stop this line.
                if .DLLstate neq DLL_FREE
                then CALL$L(TERM_LIN,.LINEb);
            tes;
	CCB [C_STS] = NM$SUC;
        end;
         [otherwise]:
        CCB [C_STS] = $NM$ERR_IPV;
         tes;

[900]:					! COST
    selectoneu (PVAL = .PVAL<0,8>) of
        set
        [1 to 25]:
            begin
            CALL$E(COSTCH,(PD_XPE),.CCB [C_LIN],.PVAL);
            CCB [C_STS] = NM$SUC;
            end;
        [otherwise]:
            CCB [C_STS] = $NM$ERR_IPV;
        tes;
[906]:                                  ! HELLO TIMER
    selectoneu .PVAL of
        set
        [1 to 65535]:
            begin
            Hello_timer = .PVAL;
            if .Hello_clock gtr .Hello_timer
            then Hello_clock = .Hello_timer;
            CCB [C_STS] = NM$SUC;
            end;
        [otherwise]:
            CCB [C_STS] = $NM$ERR_IPV;
        tes;
[907]:                                  ! LISTEN TIMER
    selectoneu .PVAL of
        set
        [1 to 65535]:
            begin
            Listen_timer = .PVAL;
            if .Listen_clock gtr .Listen_timer
            then Listen_clock = .Listen_timer;
            CCB [C_STS] = NM$SUC;
            end;
        [otherwise]:
            CCB [C_STS] = $NM$ERR_IPV;
        tes;
[2600]:					! NODE TYPE
	selectoneu (PVAL = .PVAL<0,8>) of
            set
            [2]: begin                  !   Set parameter
	    Ph2only = true;             !    to "Phase II only"
            CCB [C_STS] = NM$SUC;
                 end;
            [otherwise]:
            CCB [C_STS] = $NM$ERR_IPV;
            tes;

[otherwise]:	CCB [C_STS] = $NM$ERR_PNA;      ! Invalid parameter type
tes;
end
else CCB [C_STS] = $NM$ERR_URC;

    end;                                ! of SET_CIRCUIT
routine SHOW_AND_ZERO_CIRCUIT_COUNTERS (XPTDB,CCB): LINKAGE_DB_CCB novalue =

!++
! FUNCTIONAL DESCRIPTION:
!	This routine show the counters for the specified circuit
!       and then zeroes them.
!
! FORMAL PARAMETERS:
!
!	CCB	CCB to pass to handler routine
!
! IMPLICIT INPUTS:
!	CCB Contents
!
! IMPLICIT OUTPUTS:
!	None
!
! ROUTINE VALUE:
! COMPLETION CODES:
!	None
!
! SIDE EFFECTS:
!	None
!--

    begin
    map CCB: ref block field(C_NM_FIELDS);
    local LINEb;
    require 'XPTSYM';

    CCB [C_STS] = $NM$ERR_URC;          ! Default to "unrecognized component"
    if (LINEb = $TLI_GET_LINE_DB(.CCB[C_LIN])) eqla 0
    then return;                        ! invalid LIX - error

!
!  Map in the return buffer
!

    $NM_RESPONSE_BEGIN(.CCB);
    CIRCUIT_COUNTERS (.LINEb);
    $NM_RESPONSE_END(.CCB);
    begin
    local STS_SAVE;
    STS_SAVE = .CCB [C_STS];
    ZERO_CIRCUIT_COUNTERS (.XPTDB,.CCB);
    CCB [C_STS] = .STS_SAVE;
    end;
    end;                                ! of SHOW_AND_ZERO_CIRCUIT_COUNTERS
routine SHOW_CIRCUIT (XPTDB,CCB): LINKAGE_DB_CCB novalue =

!++
! FUNCTIONAL DESCRIPTION:
!	This routine shows circuit parameters
!
! FORMAL PARAMETERS:
!
!	CCB	CCB to pass to handler routine
!
! IMPLICIT INPUTS:
!	CCB Contents
!
! IMPLICIT OUTPUTS:
!	None
!
! ROUTINE VALUE:
! COMPLETION CODES:
!	None
!
! SIDE EFFECTS:
!	None
!--

    begin
    map CCB: ref block field(C_NM_FIELDS);
    local PLIST: ref vector;
    local LINEb;
    require 'XPTSYM';

    CCB [C_STS] = $NM$ERR_URC;          ! Default to "unrecognized component"
    if (LINEb = $TLI_GET_LINE_DB(.CCB[C_LIN])) eqla 0
    then return;                        ! invalid LIX - error

!
!  Determine the entity whose data are to be shown
!

    $NM_RESPONSE_BEGIN(.CCB);		! Initialize response buffer

    case .CCB[C_NM_SELECT]              ! Select
    from NMX$SEL_lo to NMX$SEL_hi of    !   parameter list
        set                             !   based on selector value
	[NMX$SEL_sta]: PLIST = plit(0,1,800,810);
	[NMX$SEL_sum]: PLIST = plit(0,1,800);
	[NMX$SEL_cha]: PLIST = plit(900,905,906,907,910,920,921,930,2600);
        [NMX$SEL_cou]: PLIST = plit(-1);
        tes;

!
!  Build the buffer
!

    incr I from 0 to .PLIST[-1]-1 do
        begin
        local PARM;
        PARM = .PLIST[.I];
        selectone .PARM of
            set

            [0]:	begin           ! Line state:
	local VALUE;
        VALUE = 0;                      ! is ON
	if .LINEstate eql HA then VALUE = .VALUE + 1;   ! or OFF
	if .DLLstate neq DLL_FREE       !   Line is ours
	then PARAMETER_C_1(0,VALUE);	!     display the state
		end;

    [1]:	begin			! Line substate:
	if .DLLstate neq DLL_FREE       !   Line is ours
        then case .LINEstate from HA to RU of
                 set
                 [TI,TV,TC]:		!	STARTING
                     PARAMETER_C_1(.PARM,uplit(0));
                 [LR,DS]:		!	SYNCHRONIZING
                     PARAMETER_C_1(.PARM,uplit(10));
                 [DT,OFF]:              !       FAILED
                     PARAMETER_C_1(.PARM,uplit(11));
                 [inrange]:             ! 	(no substate)
                 tes;
		end;

    [800]:	begin			! Adjacent node:
	if ((.LINEstate eql RU) or	!   Do only if line
	(.LINEstate eql TC)) then	!     state is ON
            selectone .Nty of
                set
                [PHtwo,TOPS20]:
                    begin
                    PARAMETER_CM(.PARM,2);
                    PARAMETER_DU_2(,Nid);
                    PARAMETER_AI(,.Nnml,byt$ptr(Nnm));
                    end;
                [otherwise]:
                    begin
                    PARAMETER_CM(.PARM,1);
                    PARAMETER_DU_2(,Nid);
                    end;
                tes;
		end;

    [810]:	begin			! Circuit (DLL) Block Size:
	if ((.LINEstate eql RU) or	!   Do only if line
	(.LINEstate eql TC))            !     state is ON
        then PARAMETER_DU_2(.PARM,Block_size);
		end;

    [900]:	begin			! Circuit Cost:
	PARAMETER_DU_2(.PARM,Lcv);
		end;

    [906]:	begin			! Hello Timer:
	PARAMETER_DU_2(.PARM,Hello_timer);
		end;

    [907]:	begin			! Listen Timer:
	PARAMETER_DU_2(.PARM,Listen_timer);
		end;

    [2600]:	begin			! Circuit Node-type: either
	bind TWO = uplit(2);		!   "Phase II only" or not given
	if .Ph2only then begin
	    PARAMETER_C_1(.PARM,TWO);
	    end;
		end;
    [-1]:       begin
        CIRCUIT_COUNTERS (.LINEb);
                end;
    tes
    end;

!
!  Update buffer count
!
    $NM_RESPONSE_END(.CCB);
    end;                                ! of SHOW_CIRCUIT
global
routine TAKE_CIRCUIT (XPTDB,CCB): MCB_DB_CCB novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
! Processes a "Withdraw Circuit Ownership" function.  If the circuit's
! Network Management state is ON, the circuit must be brought down.
!
! FORMAL PARAMETERS
!
!	CCB	Function CCB
!
!		CCB[C_LIN]	Transport line index for circuit to
!				be taken away.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
! COMPLETION CODES:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

begin

local LINEb;
require 'XPTSYM';
require 'MCBCOM';

LINEb = $TLI_GET_LINE_DB(.CCB[C_LIN]);  ! Address line data base entry

if .OWNED                               ! Circuit owned:
then CKTOFF(.LINEb, .CCB)               !   release circuit
else SIGNAL_STOP(CE_ERR);               !   otherwise bomb

end;				!End of TAKE_CIRCUIT
routine ZERO_CIRCUIT_COUNTERS (XPTDB,CCB): LINKAGE_DB_CCB novalue =

!++
! FUNCTIONAL DESCRIPTION:
!	This routine zeroes counters for the specified circuit
!
! FORMAL PARAMETERS:
!
!	CCB	CCB to pass to handler routine
!
! IMPLICIT INPUTS:
!	CCB Contents
!
! IMPLICIT OUTPUTS:
!	None
!
! ROUTINE VALUE:
! COMPLETION CODES:
!	None
!
! SIDE EFFECTS:
!	None
!--

    begin
    map CCB: ref block field(C_NM_FIELDS);
    local LINEb;
    require 'XPTSYM';

    CCB [C_STS] = $NM$ERR_URC;          ! Default to "unrecognized component"
    if (LINEb = $TLI_GET_LINE_DB(.CCB[C_LIN])) eqla 0
    then return;                        ! invalid LIX - error

    $NM_TIME(Time_circuit_zeroed);
    zeroq(Arriving_Packets);
    zeroq(Departing_Packets);
    End_Congestion = 0;
    zeroq(Transit_In);
    zeroq(Transit_Out);
    Transit_Congestion = 0;
    Line_Downs = 0;
    Init_Fails = 0;

    CCB [C_STS] = NM$SUC;
    end;                                ! of ZERO_CIRCUIT_COUNTERS

end
eludom			! End of module TLINMI