Google
 

Trailing-Edge - PDP-10 Archives - BB-P363B-SM_1985 - mcb/nml/nmlxmt.bli
There are 2 other files named nmlxmt.bli in the archive. Click here to see a list.
!NET:<BRANDT.DEVELOP>NMLXMT.BLI.1 12-Dec-82 20:34:50, Edit by BRANDT
!
!  Ident 15.
!    In CONNECT_TO_REMOTE allocate the same size response block that
!    is required in RECEIVE_RESPONSE.
!
!NET:<BRANDT.DEVELOP>NMLXMT.BLI.1  9-Dec-82 16:39:05, Edit by BRANDT
!
!  Ident 14.
!    In RECEIVE_RESPONSE  do not allocate a new response buffer if
!    one is already allocated.  Just reuse it.
!
!NET:<BRANDT.DEVELOP>NMLXMT.BLI.1  29-Sep-82 16:29:05, Edit by BRANDT
!
!  Ident 13.
!    In RECEIVE_RESPONSE put NMU$NETWORK_READ in a loop so that if a 
!    timeout occurs, the operation can be retried several times.
!    For lengthy operations (LOOP or LOAD for example) on a remote
!    executor, the response message may be slow in coming.
!
!NET:<BRANDT.DEVELOP>NMLXMT.BLI.1  19-Jan-82 09:29:05, Edit by BRANDT
!
!    Ident 12.
!    Make error detail field of $RESPONSE message null rather than 0.
!    Allow for MEMORY_GET to fail in RECEIVE_RESPONSE.
!
! NET:<PECKHAM.DEVELOPMENT>NMLXMT.BLI.3 24-May-82 12:40:13, Edit by PECKHAM
!
! Ident 11.
! Add CHECK_VERSION routine.
! Use CHECK_VERSION in CONNECT_TO_REMOTE to abort connects to V2.0 receivers.
!
!NET:<BRANDT.DEVELOP>NMLXMT.BLI.1  19-Jan-82 09:29:05, Edit by BRANDT
!
!    Ident 10.
!    Add a call to NML$REQUEST_TERMINATE in NML$TRANSMITTER to handle
!    the situation of a read response failure while in the middle of
!    a sequence of multiple responses.
!
!NET:<DECNET20-V3P1.NML>NMLXMT.BLI.8  2-Nov-81 11:29:05, Edit by WEBBER
!
!    Ident 09.
!    Add recognition of the -2 NETWORK_OPEN return code ("don't retry").
!
!NET:<DECNET20-V3P1.NML>NMLXMT.BLI.2 21-Oct-81 10:05:41, Edit by WEBBER
!
!    Ident 08.
!    Add response buffer and its length as parameters to NETWORK_OPEN.
!    NETWORK_OPEN will build a response message on an error.
!
!NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NMLXMT.BLI.8  5-Aug-81 10:42:19, Edit by JENNESS
!
!    Ident 07.
!    Fix CONNECT_TO_REMOTE to retry a limited number of times and
!    then fail the request.
!
!NET:<DECNET20-V3P1.NML>NMLXMT.BLI.4 15-Jun-81 10:39:45, Edit by GUNN
!
!    Ident 06.
!    Fix loop caused when NMU$NETWORK_READ in RECEIVE_RESPONSE fails.
!
!NET:<DECNET20-V3P1.NML>NMLXMT.BLI.2 12-Jun-81 14:20:23, Edit by GUNN
!
!    Ident 05.
!    Fix call to $NML$MAP_NODE_ID in PROCESS_ENTITY_CLASS to pass 
!    address of length not literal.
!
!NET:<DECNET20-V3P1.NML>NMLXMT.BLI.3  6-May-81 10:34:43, Edit by JENNESS
!
!    Change TASK_ERROR ('Read failure') on response read to build a
!    operation failure response message.
!
!NET:<DECNET20-V3P1.NML>NMLXMT.BLI.2  3-Apr-81 17:50:34, Edit by GUNN
!
!    Add dot to second argument to $NML$MAP_NODE_ID.
!
!NET:<DECNET20-V3P1.NML>NMLXMT.BLI.3 31-Mar-81 08:01:02, Edit by GUNN
!
!    Remove 'language (common)' from module header. $NML$MAP_NODE_ID
!    expands into system specific code.
! 
!NET:<DECNET20-V3P1.NML>NMLXMT.BLI.3 11-Mar-81 09:29:35, Edit by GUNN
!
!    Change format of node name string passed to NMU$NETWORK_OPEN in the
!    Connect Block CB_HOST field to be same as NODE entity id.
!    Add code to map EXECUTOR node address to node name.
!    Update copyright date.
!
%title 'NMLXMT -- NICE Request Transmitter'
module NMLXMT (                         ! NICE request transmitter task
		ident = 'X03.15'
		) =
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: LSG DECnet Network Management
!
! Abstract: This task takes the next request from the request
!	    queue destined for a remote node, transmits it and
!	    waits for the response.
!
! Environment: TOPS10/TOPS20 user mode, MCB RSX task level
!
! Author: Steven M. Jenness, Creation date: 1-Dec-80
!
!--
!
! Include files
!

library 'NMLLIB';			! All needed definitions

!
! Global routines
!

forward routine
    NML$TRANSMITTER : novalue;		! Main routine for transmitter task

!
! Local routines
!

forward routine
    LOCK_REMOTE_NODE : novalue,    ! Place lock to insure request sequentiality
    CONNECT_TO_REMOTE,             ! Make connection to remote NICE process
    CHECK_VERSION,                 ! Validate network management version
    RECEIVE_RESPONSE,              ! Read next response message
    UNLOCK_REMOTE_NODE : novalue;  ! Unlock node

!
! External references
!

external routine
    NML$REQUEST_MANAGER,           ! Central NICE request handler
    NMU$NETWORK_UTILITIES,         ! DECnet logical link interface
    NMU$MEMORY_MANAGER,            ! Memory management routines
    NMU$SCHED_MANAGER;             ! Scheduler interface

external
    NMLVER,                        ! Version of Network Management
    DECECO,                        ! Digital's ECO number
    USRECO;                        ! User's ECO number

!
! Equated symbols
!

literal
    FIVE_SECONDS = 5,
    TEN_SECONDS = 10,
    NICE_BUFFER_LENGTH = 300,					! Bytes
    NICE_BUFFER_SIZE = ch$allocation (NICE_BUFFER_LENGTH, 8),   ! Words
    NICE_BUFFER_ALLOCATION = NICE_BUFFER_SIZE * %upval;         ! Units

!
! Own variables
!

own
   XMTR_RETRIES : initial (5);
%global_routine ('NML$TRANSMITTER', TB, TR) : novalue =

!++
! Functional description:
!
!	This task runs forever (almost) removing remote requests
!	from the request queue and sending them to the appropriate
!	remote node for processing.
!
! Formal parameters:
!
!	.TB	Task block address
!	.TR	Task resource address
!
! Routine value: none
! Side effects: none
!
!--

    begin

    local
	REQ : ref REQUEST_BLOCK,
	LINK_ID;

    while $true do
	begin
!
! Get next request to send to the remote node
!
	REQ = NML$REQUEST_NEXT (RT$REMOTE);
!
! Lock node to guarantee command sequentiality
!
	LOCK_REMOTE_NODE (.REQ);
!
! Connect to remote NICE processor.
!

	if (LINK_ID = CONNECT_TO_REMOTE (.REQ)) gtr 0
        then
            begin

            !
            ! Send the request
            !

            NMU$NETWORK_WRITE (.LINK_ID, $true,
                               .REQ [RB_NICE_LENGTH],
                               ch$ptr (.REQ [RB_NICE],, 8));
            !
            ! Receive all response messages to the request
            !

            do
              begin
              if not RECEIVE_RESPONSE (.LINK_ID, .REQ)
              then
                  begin
                  if not NML$REQUEST_FINISH (.REQ)
                  then NML$REQUEST_TERMINATE (.REQ) ; ! If not done, Abort it
                  exitloop;
                  end;
              end
            until NML$REQUEST_FINISH (.REQ);

            !
            ! Discard the link (done with the request)
            !

            NMU$NETWORK_CLOSE (.LINK_ID, 0, 0);

            end
        else
            !
            ! Finish off request that failed to connect
            !

            NML$REQUEST_FINISH (.REQ);

        !
        ! Unlock node to allow other requests to be sent
        ! to the node.
        !

        UNLOCK_REMOTE_NODE (.REQ);
        end;
    end;					! End of NML$TRANSMITTER
%routine ('LOCK_REMOTE_NODE', REQUEST : ref REQUEST_BLOCK) : novalue =

!++
! Functional description:
!
!
! Formal parameters: none
!
! Routine value: none
! Side effects: none
!
!--

    begin
	$true
    end;					! End of LOCK_REMOTE_NODE
%routine ('UNLOCK_REMOTE_NODE', REQUEST : ref REQUEST_BLOCK) : novalue =

!++
! Functional description:
!
!
! Formal parameters: none
!
! Routine value: none
! Side effects: none
!
!--

    begin
	$true
    end;					! End of UNLOCK_REMOTE_NODE
%routine ('CONNECT_TO_REMOTE', REQUEST : ref REQUEST_BLOCK) =

!++
! Functional description:
!
!	This routine connects to the NICE listener on the
!	host specified in the request.  It does not return
!	until the connection is made (or determined to be
!	next to impossible).
!
! Formal parameters:
!
!	.REQUEST    Address of request block
!
! Routine value:
!
!	Link id of DECnet link to remote NICE listener
!
! Side effects: none
!
!--

    begin
    local
	CONN_BLK : CONNECT_BLOCK,
	NODE_PTR,
	DATA_PTR,
	LINK_ID,
        ATTEMPTS_LEFT,
	CONNECTED;

    CONNECTED = $false;
    ATTEMPTS_LEFT = .XMTR_RETRIES;

    while not .CONNECTED
    do
	begin
        local
             LENGTH ;                   ! Length temporary for MAPping

	CONN_BLK [CB_OBJECT] = NICE_OBJECT;
	CONN_BLK [CB_DESCRIPTOR_LENGTH] = 0;
	CONN_BLK [CB_TASK_LENGTH] = 0;

	NODE_PTR = ch$ptr (.REQUEST [RB_EXECUTOR],, 8);
	CONN_BLK [CB_HOST] = .NODE_PTR;

	CONN_BLK [CB_HOST_LENGTH] = ch$rchar (ch$plus (.NODE_PTR, 2));

	!
	! Attempt to map node address to node number
	!

        LENGTH = NODE_ID_BUFFER_LENGTH ; ! Get buffer length
        $NML$MAP_NODE_ID (LENGTH,
                          .NODE_PTR) ;

	CONN_BLK [CB_USERID_LENGTH] = .REQUEST [RB_USER_LENGTH];
	CONN_BLK [CB_USERID] = .REQUEST [RB_USER];

	CONN_BLK [CB_ACCOUNT_LENGTH] = .REQUEST [RB_ACCOUNT_LENGTH];
	CONN_BLK [CB_ACCOUNT] = .REQUEST [RB_ACCOUNT];

	CONN_BLK [CB_PASSWORD_LENGTH] = .REQUEST [RB_PASSWORD_LENGTH];
	CONN_BLK [CB_PASSWORD] = .REQUEST [RB_PASSWORD];

	CONN_BLK [CB_DATA_LENGTH] = 3;
	DATA_PTR = ch$ptr (CONN_BLK [CB_DATA_BUFFER],, 8);
	CONN_BLK [CB_DATA] = .DATA_PTR;
	ch$wchar_a (.NMLVER, DATA_PTR);
	ch$wchar_a (.DECECO, DATA_PTR);
	ch$wchar_a (.USRECO, DATA_PTR);

        if .REQUEST [RB_RESPONSE] eqla 0    ! If no response buffer is
        then				    ! allocated yet, set one up.
            begin
            REQUEST [RB_RESPONSE_ALLOCATION] = NICE_BUFFER_ALLOCATION;
            REQUEST [RB_RESPONSE] =
              NMU$MEMORY_GET (.REQUEST [RB_RESPONSE_ALLOCATION]);
	    end;

	if (LINK_ID = NMU$NETWORK_OPEN (SOURCE_LINK, CONN_BLK, 
	    ch$ptr(.REQUEST[RB_RESPONSE],,8), REQUEST[RB_RESPONSE_LENGTH],
	    NICE$_LCF))
	lss 0
	then
            if ((.LINK_ID neq -2) and
	    ((ATTEMPTS_LEFT = .ATTEMPTS_LEFT - 1) gtr 0))
            then
                NMU$SCHED_SLEEP (TEN_SECONDS)
            else
                return 0
	else
            begin
            local RESULT;

            if (RESULT = CHECK_VERSION (CONN_BLK)) neq 0
            then
                begin
                NMU$NETWORK_ABORT (.LINK_ID, $SC$ERR_UAB, 0, 0);
                REQUEST[RB_RESPONSE_LENGTH] = $RESPONSE (ch$ptr(.REQUEST[RB_RESPONSE],,8), .RESULT);
                return 0;
                end;

            CONNECTED = $true
            end;

	end;

    .LINK_ID
    end;					! End of CONNECT_TO_REMOTE
%routine ('CHECK_VERSION', CBLK) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	This routine checks to see if the Network Management
!	version match.  If they don't, an error code is returned.
!
! FORMAL PARAMETERS
!
!	CBLK - Address of connect block
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	Zero if ok, a non-zero error code if failed test
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
       CBLK: ref CONNECT_BLOCK;

    local
         DATA_PTR,
         VERSION;

!
! Create pointer to data supplied with connect request
!

    DATA_PTR = .CBLK[CB_DATA];

!
! Check for enough data available.  If not, return
! Invalid Identification error.
!

%( N.B. - If no version number is provided then assume 2.0.0 and
          continue with checking. )%

    if .CBLK[CB_DATA_LENGTH] lss 3
    then return $NICE$ERR_IID           ! Is this the right code to return ??
    else begin

!
! Check version number against ours, if it is older
! it is incompatible with us.
!

         VERSION = GETB (DATA_PTR);
         if .VERSION lss .NMLVER
         then return $NICE$ERR_IMV
         else begin

!
! Check the Digital ECO number, if it is non-zero,
! it is incompatible with us.
!
!	      VERSION = GETB (DATA_PTR);
!
!	      if .VERSION gtr 0
!             then return NICE$_IMV
!             else return 0
!
! For now accept any 2.x.y version of Network Management
!

              return 0;
              end
         end

    end;				! End of CHECK_VERSION
%routine ('RECEIVE_RESPONSE', LINK_ID, REQUEST : ref REQUEST_BLOCK) =

!++
! Functional description:
!
!	This routine receives the response from a NICE processor
!	at the other end of a DECnet logical link.
!
! Formal parameters:
!
!	.LINK_ID    Identifier for DECnet logical link
!	.REQUEST    Address of request block
!
! Routine value: TRUE, if response received OK.
!                FALSE, otherwise.
! Side effects: none
!
!--

    begin
    local
	TEXT,
	TIMES;

    if .REQUEST [RB_RESPONSE] eqla 0    ! If no response buffer is
    then				! allocated yet, set one up.
        begin
        REQUEST [RB_RESPONSE_ALLOCATION] = NICE_BUFFER_ALLOCATION;
        REQUEST [RB_RESPONSE] =
            NMU$MEMORY_GET (.REQUEST [RB_RESPONSE_ALLOCATION]);
	end;

    REQUEST [RB_RESPONSE_LENGTH] = 0;

    TIMES = (if ((.REQUEST[RB_NICE_FUNCTION] eql LOAD_) or
		 (.REQUEST[RB_NICE_FUNCTION] eql TEST_))
	     then 3			! Wait longer for LOAD and LOOP
	     else 1);

    incr N from 1 to .TIMES do
	begin
	if (REQUEST [RB_RESPONSE_LENGTH] =
		NMU$NETWORK_READ (.LINK_ID,
			          NICE_BUFFER_LENGTH,
				  ch$ptr (.REQUEST [RB_RESPONSE],, 8)))
	    gtr 0
	then
	    return $TRUE;		! If read successful, all done!

	if .REQUEST [RB_RESPONSE_LENGTH] eql -1  ! Indicates timeout
	then
	    TEXT = CH$ASCIZ('Timed out waiting for response')
	else
	    begin
	    TEXT = CH$ASCIZ('Response read failed');
	    exitloop;			! Break now to signal failure
	    end;
	end;

    REQUEST [RB_RESPONSE_LENGTH] =
           $RESPONSE (ch$ptr (.REQUEST [RB_RESPONSE],, 8),
                      NICE$_OPF, , '%A', .TEXT);
    return $FALSE;
	
    end;				! End of RECEIVE_RESPONSE
end					! End of module NMLXMT

eludom