with CALENDAR ; use CALENDAR ; separate (NETWORK_PROTOCOLS) package body PROTOCOL_INDEPENDENT_UTILITIES is UNACCEPTABLE_TYPE_ERROR : exception ; function LOW_BYTE_OF_SUM ( BLOCK : BYTE_STRING ) return BYTE is TOTAL : INTEGER ; begin -- add values of all bytes in block, assuming less than 256 bytes -- (so total will fit in 16 bits) TOTAL := 0 ; for I in BLOCK'RANGE loop TOTAL := TOTAL + BYTE'POS(BLOCK(I)) ; end loop ; -- return byte whose "value" is the low byte of the total return BYTE'VAL ( TOTAL mod 256 ) ; end LOW_BYTE_OF_SUM ; procedure RS_READ_WITH_TIMEOUT ( C : out BYTE ; GOT_ONE : out BOOLEAN ; RETURN_AFTER : DURATION := 0.0 ) is GOTONE : BOOLEAN ; STOP_TIME : TIME ; begin STOP_TIME := CLOCK + RETURN_AFTER ; loop RS_READ (C,GOTONE,RETURN_AFTER) ; exit when GOTONE or else CLOCK > STOP_TIME ; end loop ; GOT_ONE := GOTONE ; end RS_READ_WITH_TIMEOUT ; procedure RS_READ_BLOCK_WITH_TIMEOUT ( Data : in out Byte_String ; Limit : in Duration ; Complete : out Boolean ; Last : out Integer ) is Received_Char : Boolean ; -- This procedure uses RS_READ_WITH_TIMEOUT to read a complete block of -- data. It returns a boolean value called Complete that tells the -- calling program if the entire block was read. Also an integer -- called Last is returned and it holds the byte number of the last -- byte read. begin Last := Data'First - 1 ; for I in Data'Range loop RS_READ_WITH_TIMEOUT ( Data ( I ), Received_Char, Limit ) ; exit when not Received_Char ; Last := I ; end loop ; Complete := Received_Char ; end RS_READ_BLOCK_WITH_TIMEOUT ; procedure F_WRITE_BLOCK ( Data : in Byte_String ) is -- This procedure writes a complete block of data to disk using F_WRITE. begin for I in Data'Range loop F_WRITE ( Data ( I ) ) ; end loop ; end F_WRITE_BLOCK ; procedure F_READ_BLOCK ( Data : in out Byte_String ; End_of_File : out Boolean ; Last : out Integer ) is NUL : constant Byte := Byte'Val ( Character'Pos ( ASCII.NUL ) ) ; EOF : Boolean ; -- This procedure reads a complete block from disk. It returns a -- boolean value called End_of_File which tells the calling program if -- the end of file was reached. In the case of an end of file the rest -- of the block is filled with NUL. Also an integer called last is -- returned and holds the number of the last byte in the block that was -- read. begin Last := Data'First - 1 ; for I in Data'Range loop F_READ ( Data ( I ), EOF ) ; if EOF then for J in I .. Data'Last loop Data ( J ) := NUL ; end loop ; exit ; end if ; Last := I ; end loop ; End_of_File := EOF ; end F_READ_BLOCK ; procedure RS_WRITE_BLOCK ( Data : in out Byte_String ) is -- This procedure uses RS_WRITE to write a whole block to the RS-232 port. begin for I in Data'Range loop RS_WRITE ( Data ( I ) ) ; end loop ; end RS_WRITE_BLOCK ; procedure Long_Read ( Error_Cnt : in out Integer ; Hold : out Byte ; Errlim : in Integer ; Limit : in Duration ) is Received_Char : Boolean ; -- This procedure reads a response from the RS-232 port. It is called -- long read because it will attempt to read many times ( while the -- error count is less than the error limit of 10 ). Thus the longest -- that this procedure could wait for a response is 100 seconds. begin while Error_Cnt < Errlim loop RS_READ_WITH_TIMEOUT ( Hold, Received_Char, Limit ) ; exit when Received_Char ; Error_Cnt := Error_Cnt + 1 ; end loop ; end Long_Read ; procedure Write_Read_With_Expected_Response ( Error_Cnt : in out Integer ; Errlim : in Integer ; Hold : out Byte ; Write : in Byte ; Limit : in Duration ; Response : in Byte ) is Received_Char : Boolean ; Temp : Byte ; -- This procedure is a lot like Long_Read with a few changes. This -- procedure writes a byte out first then waits for the correct -- response. Again the longest that this procedure could wait for the -- correct response is 100 seconds. begin while Error_Cnt < Errlim loop RS_WRITE ( Write ) ; RS_READ_WITH_TIMEOUT ( Temp, Received_Char, Limit ) ; if Received_Char and then Temp = Response then exit ; elsif Received_Char then loop RS_READ_WITH_TIMEOUT ( Temp, Received_Char, 5.0 ) ; exit when not Received_Char ; end loop ; end if ; Error_Cnt := Error_Cnt + 1 ; end loop ; Hold := Temp ; end Write_Read_With_Expected_Response ; procedure Get_Byte ( Hold : out Byte ; Limit : in Duration ) is Received_Char : Boolean ; -- This procedure reads one byte from the RS-232 port and is local to -- the receive procedure. If a byte is not available to be read the -- read error exception will be raised. begin RS_READ_WITH_TIMEOUT ( Hold, Received_Char, Limit ) ; if not Received_Char then raise Read_Error ; end if ; end Get_Byte ; begin -- insure that BYTE supports 8-bit unsigned values and that INTEGER -- supports 16-bit signed values if BYTE'POS(BYTE'FIRST) > 0 or BYTE'POS(BYTE'LAST) < 255 then raise UNACCEPTABLE_TYPE_ERROR ; end if ; if INTEGER'LAST <= 65535 then raise UNACCEPTABLE_TYPE_ERROR ; end if ; end PROTOCOL_INDEPENDENT_UTILITIES ;