Google
 

Trailing-Edge - PDP-10 Archives - BB-P363B-SM_1985 - t20/nmlt20/nmlcnv.bli
There is 1 other file named nmlcnv.bli in the archive. Click here to see a list.
!<MCINTEE>NMLCNV.BLI.4,  7-Sep-83 12:58:19, Edit by MCINTEE
!
! Ident 05. 
!   Dot bug in RESPONSE_TO_V3
!
!<MCINTEE>NMLCNV.BLI.3, 19-Aug-83 07:57:19, Edit by MCINTEE
!
! Ident 04.
!   Fix infinite loop bug in COMMAND_TO_V3
!
!<MCINTEE.WORK>NMLCNV.BLI.2, 19-Jul-83 12:57:49, Edit by MCINTEE
!
! Ident 03.
!   Put subentity type in entity type in request block in COMMAND_TO_V3
!   
!<MCINTEE.WORK>NMLCNV.BLI.2, 15-Jun-83 11:40:53, Edit by MCINTEE
!
! Ident 02.
!   COMMAND_TO_V3 assumes that the request block
!   entry for NICE_ENTITY_TYPE is set up. Instead, use the option
!   byte to get entity type.
!
%title 'NMLCNV -- NICE Version compatibility'
module NMLCNV (                         ! NICE conversion utilities
		ident = 'X04.05'
		) =
begin
!
! COPYRIGHT (C) 1980, 1981, 1982, 1983
! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS  01754
!
! THIS SOFTWARE IS FURNISHED  UNDER A LICENSE FOR USE ONLY ON A SINGLE
! COMPUTER  SYSTEM AND  MAY BE  COPIED ONLY 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
! EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO AGREES TO THESE LICENSE
! TERMS.  TITLE TO AND  OWNERSHIP OF THE  SOFTWARE  SHALL AT ALL TIMES
! REMAIN IN DEC.
!
! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
! AND SHOULD  NOT BE CONSTRUED  AS A COMMITMENT  BY DIGITAL  EQUIPMENT
! CORPORATION.
!
! DEC ASSUMES  NO  RESPONSIBILITY  FOR  THE USE OR  RELIABILITY OF ITS
! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC.
!

!++
! Facility: LSG DECnet Network Management
!
! Abstract: This module provides routines to adjust NICE command,
!           response, and event messages for differences in NML
!           versions.
!
! Environment: TOPS10/TOPS20 user mode, MCB RSX task level
!
! Author: Alan D. Peckham, Creation date: 9-Jun-83
!
!--
!
! Include files
!

library 'NMLLIB';			! All needed definitions

!
! Global routines
!

forward routine
    NML$CNV_CHECK_VERSION,
    NML$CNV_COMMAND,
    NML$CNV_EVENT,
    NML$CNV_RESPONSE,
    COMMAND_TO_V3,                      ! V4 commands to V3
    INCOMPATIBLE,
    RESPONSE_TO_V3;                     ! V4 responses to V3

!
! External references
!

external routine
    NML$DATA_TYPE,
    NML$ENTITY_DATA_SKIP,
    NML$NICE_RESPONSE: novalue,
    NML$PARAMETER_DATA_SKIP,
    NML$GET_SUBENTITY_ID,
    NMU$NETWORK_LOCAL;

external
    NMLVER;

!
! Equated symbols
!
!       NONE
!
! Own variables
!

own
    NICE_DATA: vector [ch$allocation (255, 8)];
%global_routine ('NML$CNV_CHECK_VERSION', VERSION) =

!++
! Functional description:
!
!	Check if version is supported.
!
! Formal parameters:
!
!	.VERSION   Version number to check.
!
! Routine value: $true is supported, otherwise $false.
!
! Side effects: None
!
!--

    begin
    if .VERSION gtr .NMLVER
    then $true
    else selectone .VERSION of
             set
             [3 to 4]: $true;
             [otherwise]: $false;
             tes
    end;                                ! End of NML$CNV_CHECK_VERSION
%global_routine ('NML$CNV_COMMAND', REQ: ref REQUEST_BLOCK) =

!++
! Functional description:
!
!	Convert a V4 nice command to be acceptable to remote receiver.
!
! Formal parameters:
!
!	.REQ	Request block pointing to command to be translated.
!
! Routine value: $false
!
! Side effects:
!
!       Command message modified to be compatible with version RB[RB_VERSION].
!       On failure, IMV response is set up in request block.
!
!--

    begin

    if .REQ[RB_VERSION] geq .NMLVER then return $true;

    if .REQ[RB_VERSION] geq 4 then return $true;

    if not COMMAND_TO_V3 (.REQ) then return INCOMPATIBLE (.REQ);

    if .REQ[RB_VERSION] geq 3 then return $true;

    $false
    end;                                ! End of NML$CNV_COMMAND
%global_routine ('NML$CNV_EVENT', REQ: ref REQUEST_BLOCK) =

!++
! Functional description:
!
!	Convert a V4 event to be acceptable to a remote receiver.
!       (currently unsupported)
!
! Formal parameters:
!
!	.REQ	Request block pointing to event to be translated.
!
! Routine value: $false
!
! Side effects:
!
!       Event message modified to be compatible with remote version.
!       On failure, IMV response is set up in request block.
!
!--

    begin
    INCOMPATIBLE (.REQ)
    end;                                ! End of NML$CNV_EVENT
%global_routine ('NML$CNV_RESPONSE', REQ: ref REQUEST_BLOCK) =

!++
! Functional description:
!
!	Convert a V4 response to be acceptable to remote transmitter.
!
! Formal parameters:
!
!	.REQ	Request block pointing to response to be translated.
!
! Routine value: $false
!
! Side effects:
!
!       Response message modified to be compatible with remote version.
!       On failure, IMV response is set up in request block.
!
!--

    begin

    if .REQ[RB_VERSION] geq .NMLVER then return $true;

    if .REQ[RB_VERSION] geq 4 then return $true;

    if not RESPONSE_TO_V3 (.REQ) then return INCOMPATIBLE (.REQ);

    if .REQ[RB_VERSION] geq 3 then return $true;

    $false
    end;                                ! End of NML$CNV_RESPONSE
%routine ('COMMAND_TO_V3', REQ: ref REQUEST_BLOCK) =

!++
! Functional description:
!
!	Convert a V4 nice command to a V3 nice command.
!       This involves locating all node numbers and removing the area
!       number if the area = homearea.
!
! Formal parameters:
!
!	.REQ	Request block pointing to command to be translated.
!
! Routine value: NICE success or error code
!
! Side effects:
!
!       Command message modified to be compatible with version 3.
!       On failure, IMV response is set up in request block.
!
!--

    begin

    local
	ENTITY_TYPE : FULL_ENTITY,    	! Entity type
        END_PTR,                        ! Pointer to end of NICE message
        LOCAL_ADDRESS,                  ! Local node address
        NICE_PTR;                       ! Pointer into NICE message

    NICE_PTR = ch$ptr (.REQ[RB_NICE],, 8);
    END_PTR = ch$plus (.NICE_PTR, .REQ[RB_NICE_LENGTH]);
    LOCAL_ADDRESS = NMU$NETWORK_LOCAL ();       ! Get local address
    LOCAL_ADDRESS = GETW (LOCAL_ADDRESS);       ! for access to homearea.
    begin

    local
	OPTION : block [1] field (TEST_OPTIONS), ! Option byte
        SKIP_ACCESS;

    SKIP_ACCESS = $false;

    case GETB (NICE_PTR) from LOAD_ to SYSTEM_SPECIFIC_ of
        set
        [LOAD_, DUMP_, TRIGGER_, ZERO_]:
	    OPTION = GETB (NICE_PTR);
        [TEST_]:
            begin
            OPTION = GETB (NICE_PTR);
            if .OPTION [TO_ACCESS_CONTROL] then SKIP_ACCESS = $true;
            end;
	[CHANGE_, READ_]:
	    begin
	    local CNT,PTR;
	    OPTION = GETB (NICE_PTR);

	    PTR = .NICE_PTR;		! Get subentity id if needed
    	    CNT = ch$rchar_a (PTR);	
    	    ENTITY_TYPE [ENTITY_SUB] = NML$GET_SUBENTITY_ID (.CNT, .PTR);
	    end;

        [SYSTEM_SPECIFIC_]:
            return $true;
        tes;								       
    ENTITY_TYPE [ENTITY_MAIN] = .OPTION [TO_ENTITY_TYPE]; ! Get entity type
    begin
    local PTR;

    PTR = .NICE_PTR;			! Get subentity id

    if .ENTITY_TYPE [ENTITY_MAIN] eql ENTITY_NODE
    then if GETB (PTR) eql 0            ! Zap area if = homearea
         then begin
              PTR = GETW (PTR);         ! node entity address.
              if .PTR<10,6> eql .LOCAL_ADDRESS<10,6>    ! If areas match
              then ch$wchar ((ch$rchar (ch$plus (.NICE_PTR, 2)) and %b'11'),
                             ch$plus (.NICE_PTR, 2));   ! then ZAP area
              end;

    NML$ENTITY_DATA_SKIP (.ENTITY_TYPE, NICE_PTR);
    end;

    if .SKIP_ACCESS                     ! If access-control included
    then begin                          ! then bypass it.

         local
             LENGTH;

         LENGTH = GETB (NICE_PTR);      ! USER
         NICE_PTR = ch$plus (.NICE_PTR, .LENGTH);
         LENGTH = GETB (NICE_PTR);      ! PASSWORD
         NICE_PTR = ch$plus (.NICE_PTR, .LENGTH);
         LENGTH = GETB (NICE_PTR);      ! ACCOUNTING
         NICE_PTR = ch$plus (.NICE_PTR, .LENGTH);
         end;

    end;

    while ch$diff (.END_PTR, .NICE_PTR) lss 0
    do begin

       local
           DATA_TYPE: block [1] field (DATA_TYPE_FIELDS),
           PARAMETER;

       PARAMETER = GETW (NICE_PTR);
       DATA_TYPE = NML$DATA_TYPE (.ENTITY_TYPE, .PARAMETER);

       if (.DATA_TYPE[DT_CODED] neq 0) and
          (.DATA_TYPE[DT_FIELDS] neq 0)
       then selectone .DATA_TYPE[DT_NUMBER] of
                set
                [CMN]:
                    begin
                    local PTR;
                    PTR = .NICE_PTR;
                    if GETB (PTR) eql 0
                    then begin
                         PTR = GETW (PTR);      ! node entity address.

                         if .PTR<10,6> eql .LOCAL_ADDRESS<10,6>  ! If areas match
                         then ch$wchar ((ch$rchar (ch$plus (.NICE_PTR, 2)) and %b'11'),
                                        ch$plus (.NICE_PTR, 2)); ! then ZAP area
                         end;
                    end;
                [CME, CMU]:
                    begin
                    local PTR;
                    PTR = .NICE_PTR;
                    if GETB (PTR) eql ENTITY_NODE
                    then if GETB (PTR) eql 0
                         then begin
                              PTR = GETW (PTR); ! node entity address.
                              if .PTR<10,6> eql .LOCAL_ADDRESS<10,6>    ! If areas match
                              then ch$wchar ((ch$rchar (ch$plus (.NICE_PTR, 3)) and %b'11'),
                                             ch$plus (.NICE_PTR, 3));      ! then ZAP area
                              end;
                    end;
                tes;

       NML$PARAMETER_DATA_SKIP (.ENTITY_TYPE, .PARAMETER, NICE_PTR);
                                        ! Skip over the data
       end;

    $true
    end;                                ! End of COMMAND_TO_V3
%routine ('INCOMPATIBLE', REQ: ref REQUEST_BLOCK) =

!++
! Functional description:
!
!	Declare a protocol conversion incompatible
!
! Formal parameters:
!
!	.REQ	Request block pointing to command to be rejected.
!
! Routine value: $false
!
! Side effects: IMV response set up in request block.
!
!--

    begin
    REQ[RB_RESPONSE_LENGTH] = 0;
    REQ[RB_RETURN_CODE] = $NICE$ERR_IMV;
    REQ[RB_ERROR_DETAIL] = -1;
    REQ[RB_ERROR_POINTER] = ch$ptr (uplit (0),, 8);
    NML$NICE_RESPONSE (.REQ);
    $false
    end;                                ! End of INCOMPATIBLE
%routine ('RESPONSE_TO_V3', REQ: ref REQUEST_BLOCK) =

!++
! Functional description:
!
!	Convert a V4 response to a V3 response.  This involves
!       locating all node numbers and removing the area number
!       if the area = homearea.
!
! Formal parameters:
!
!	.REQ	Request block pointing to response to be translated.
!
! Routine value: $true for successful conversion, otherwise $false.
!
! Side effects:
!
!       Response message modified to be compatible with version 3.
!       On failure, IMV response is set up in request block.
!
!--

    begin

    local
        END_PTR,                        ! Pointer to end of NICE message
        LOCAL_ADDRESS,                  ! Local node address
        RESPONSE_PTR;                   ! Pointer into NICE message

    bind
	ENTITY_TYPE = REQ[RB_NICE_ENTITY_TYPE] : FULL_ENTITY; ! Full entity type

    LOCAL_ADDRESS = NMU$NETWORK_LOCAL ();       ! Get local address
    LOCAL_ADDRESS = GETW (LOCAL_ADDRESS);       ! for access to homearea.

    if .REQ[RB_RESPONSE_LENGTH] leq 1 + 2 + 1 then return $true;

    RESPONSE_PTR = ch$ptr (.REQ[RB_RESPONSE],, 8);
    END_PTR = ch$plus (.RESPONSE_PTR, .REQ[RB_RESPONSE_LENGTH]);
    RESPONSE_PTR = ch$plus (.RESPONSE_PTR, 1 + 2 + 1 + ch$rchar (ch$plus (.RESPONSE_PTR, 3)));

    if 0 %(plural entities)% or
       (selectone ch$rchar (ch$ptr (.REQ[RB_NICE],, 8)) of
            set
            [READ_] : $true;
            [ZERO_] :
                begin
                local OPTION: block [1] field (ZERO_OPTIONS);
                OPTION = ch$rchar (ch$ptr (.REQ[RB_NICE], 1, 8));
                if (.OPTION[ZO_READ_AND_ZERO] eql 1)
                then $true
                else $false
                end;
            [otherwise] : $false;
            tes)
    then case .ENTITY_TYPE [ENTITY_MAIN] from ENTITY_LO to ENTITY_HI of
             set
             [ENTITY_NODE] :
                 begin
                 local CNT;
                 CNT = GETW (RESPONSE_PTR);

                 if .CNT<10,6> eql .LOCAL_ADDRESS<10,6>
                 then begin
                      CNT<10,6> = 0;
                      RESPONSE_PTR = ch$plus (.RESPONSE_PTR, -2);
                      PUTW (CNT, RESPONSE_PTR);
                      end;

                 CNT = ch$rchar_a (RESPONSE_PTR);
                 RESPONSE_PTR = ch$plus (.RESPONSE_PTR, .CNT<0,7>);
                 end;
             [ENTITY_LINE, ENTITY_CIRCUIT, ENTITY_MODULE] :
                 begin
                 local CNT;
                 CNT = ch$rchar_a (RESPONSE_PTR);
                 RESPONSE_PTR = ch$plus (.RESPONSE_PTR, .CNT);
                 end;
             [ENTITY_LOGGING, ENTITY_AREA] :
                 RESPONSE_PTR = ch$plus (.RESPONSE_PTR, 1);
             tes;

    selectone ch$rchar (ch$ptr (.REQ[RB_NICE],, 8)) of
        set
        [READ_] : 0;
        [ZERO_] :
            begin
            local OPTION: block [1] field (ZERO_OPTIONS);
            OPTION = ch$rchar (ch$ptr (.REQ[RB_NICE], 1, 8));
            if (.OPTION[ZO_READ_AND_ZERO] eql 0)
            then return $true;
            end;
        [otherwise] :  return $true;
        tes;

    while ch$diff (.END_PTR, .RESPONSE_PTR) neq 0
    do begin

       local
           DATA_ID: block [1] field (DATA_ID_FIELDS);

       DATA_ID = GETW (RESPONSE_PTR);

       if (.DATA_ID[DI_TYPE] eql 0)
       then begin                       ! Parameter data

            local
                CM_COUNT: block [1] field (DATA_TYPE_FIELDS),
                CM_TYPE: block [1] field (DATA_TYPE_FIELDS);

            CM_TYPE = NML$DATA_TYPE (.ENTITY_TYPE, .DATA_ID[DI_PARMNO]);

            if (.CM_TYPE[DT_CODED] eql 1) and
               (.CM_TYPE[DT_FIELDS] eql 1)
            then begin
                 CM_TYPE = .CM_TYPE[DT_NUMBER];
                 CM_COUNT = GETB (RESPONSE_PTR);
                 CM_COUNT = .CM_COUNT[DT_NUMBER];
                 end
            else begin
                 CM_TYPE = 0;
                 CM_COUNT = 1;
                 end;

            do begin

               local
                   DATA_TYPE: block [1] field (DATA_TYPE_FIELDS);

               DATA_TYPE = GETB (RESPONSE_PTR);

               if (.DATA_TYPE[DT_CODED] eql 0)
               then begin
                    if (.DATA_TYPE[DT_FTYPE] eql 0)
                    then begin
                         local CNT;

                         if .CM_TYPE neq 0
                         then if .DATA_TYPE eql (0^7 + 0^6 + 0^4 + 2)   ! DU-2
                              then selectone .CM_TYPE of
                                       set
                                       [CMN, CMU, CME]:
                                           begin
                                           local ADDRESS;
                                           ADDRESS = .RESPONSE_PTR;
                                           ADDRESS = GETW (ADDRESS);
                                           if .ADDRESS<10,6> eql .LOCAL_ADDRESS<10,6>   ! If areas match
                                           then ch$wchar ((ch$rchar (ch$plus (.RESPONSE_PTR, 1)) and %b'11'),
                                                          ch$plus (.RESPONSE_PTR, 1));  ! then ZAP area
                                           end;
                                       [otherwise]: 0;
                                       tes;

                         if (CNT = .DATA_TYPE[DT_LENGTH]) eql 0
                         then CNT = GETB (RESPONSE_PTR);
                         RESPONSE_PTR = ch$plus (.RESPONSE_PTR, .CNT);
                         end
                    else begin
                         local CNT;
                         CNT = GETB (RESPONSE_PTR);
                         RESPONSE_PTR = ch$plus (.RESPONSE_PTR, .CNT);
                         end;
                    end
               else begin
                    if (.DATA_TYPE[DT_FIELDS] eql 0)
                    then begin
                         local CNT;
                         if (CNT = .DATA_TYPE[DT_LENGTH]) eql 0
                         then CNT = GETB (RESPONSE_PTR);
                         RESPONSE_PTR = ch$plus (.RESPONSE_PTR, .CNT);
                         end
                    else 0;             ! Can't get here!
                    end;

               end
            while (CM_COUNT = .CM_COUNT - 1) neq 0;
            end
       else begin                       ! Counter data
            if (.DATA_ID[DI_MAPPED] eql 1)
            then RESPONSE_PTR = ch$plus (.RESPONSE_PTR, 2);
            RESPONSE_PTR = ch$plus (.RESPONSE_PTR,
                (case .DATA_ID[DI_WIDTH] from 0 to 3 of
                     set
                     [1] : 1;           !  8 bits
                     [2] : 2;           ! 16 bits
                     [3] : 4;           ! 32 bits
                     [inrange] : 0;     ! reserved
                     tes));
            end;

       end;

    NICE$_SUC
    end;                                ! End of RESPONSE_TO_V3
end					! End of module NMLCNV

eludom