+++ /dev/null
-module tcpmodel
-
-import gast, TCPIP
-
-derive bimap []
-derive gEq State
-derive gLess State
-derive genShow State
-derive ggen Input
-derive genShow Input
-derive gEq Output
-derive genShow Output
-
-/* connection settings */
-hostIP = "192.168.0.14"
-hostPort = 1203
-
-/* states */
-:: State = Listen | ReceivedSYN | Established | Waiting | Closed | WaitClose | ConnectionError
-
-instance == State where
- (==) Listen Listen = True
- (==) ReceivedSYN ReceivedSYN = True
- (==) Established Established = True
- (==) Waiting Waiting = True
- (==) Closed Closed = True
- (==) WaitClose WaitClose = True
- (==) ConnectionError ConnectionError = True
- (==) _ _ = False
-
-/* input (received from client) */
-:: Input = InSYN | InACK | InDATA | InRST | InFIN
-
-instance toString Input where
- toString InSYN = "SYN"
- toString InACK = "ACK"
- toString InRST = "RST"
- toString InFIN = "FIN"
- toString InDATA = "DATA"
-
-/* output (sent to client) */
-:: Output = OutSYN | OutACK | OutDATA | OutFIN
-
-toOutput :: String -> [Output]
-toOutput "SYN-ACK" = [OutSYN, OutACK]
-toOutput "ACK" = [OutACK]
-toOutput "DATA" = [OutDATA]
-toOutput "TO" = []
-
-/* state transitions */
-stateTrans :: State Input -> [Trans Output State]
-stateTrans Listen InSYN = [Pt [OutSYN, OutACK] ReceivedSYN]
-stateTrans Listen InFIN = [Pt [] ConnectionError]
-stateTrans Listen InACK = [Pt [] ConnectionError]
-stateTrans Listen InDATA = [Pt [] ConnectionError]
-stateTrans Listen InRST = [Pt [] ConnectionError]
-
-stateTrans ReceivedSYN InSYN = [Pt [OutSYN,OutACK] ConnectionError]
-stateTrans ReceivedSYN InRST = [Pt [] Listen]
-stateTrans ReceivedSYN InACK = [Pt [] Established]
-stateTrans ReceivedSYN InFIN = [Pt [OutACK] Closed]
-stateTrans ReceivedSYN InDATA = [Pt [OutACK] Established]
-
-stateTrans Established InSYN = [Pt [] ConnectionError, Pt [OutACK] ConnectionError, Pt [OutDATA] ConnectionError] // connection error returns whatever it wants?
-stateTrans Established InDATA = [Pt [OutACK] Waiting, Pt [OutDATA] Established, Pt [] Established] // last one resend?
-stateTrans Established InRST = [Pt [] ConnectionError, Pt [OutACK] ConnectionError, Pt [OutDATA] ConnectionError] // connection error returns whatever it wants?
-stateTrans Established InFIN = [Pt [OutACK] Closed, Pt [] WaitClose]
-stateTrans Established InACK = [Pt [] ConnectionError]
-
-stateTrans Waiting InACK = [Pt [] Established]
-stateTrans Waiting _ = [Pt [] ConnectionError, Pt [OutACK] ConnectionError, Pt [OutDATA] ConnectionError]
-
-stateTrans WaitClose InACK = [Pt [OutACK] Closed]
-stateTrans WaitClose _ = [Pt [] ConnectionError]
-
-/* sut state */
-:: *SutState :== (StringSChannel, StringRChannel, *World)
-
-/* adapter for SUT communication */
-adapter :: *SutState Input -> ([Output], *SutState)
-adapter (s, r, world) i
- # (s, world) = send (toString i) s world
- # (cmd, r, world) = receive r world
- = (toOutput cmd, (s, r, world))
-
-/* reset SUT */
-reset :: *SutState -> *SutState
-reset (s, r, world)
- # (s, world) = send "SUT-RESET" s world
- = (s, r, world)
-
-/* all endstates */
-endstate :: [State] -> Bool
-endstate sts = isMember Closed sts || isMember ConnectionError sts
-
-/* testing options */
-options = [Nsequences 9000, Stop endstate]
-
-/* testing program */
-Start world
- /* open console */
- # (console, world) = stdio world
- /* setup connection with adapter */
- # (Just adr, world) = lookupIPAddress hostIP world
- # (to, mcon, world) = connectTCP_MT Nothing (adr, hostPort) world
- | to <> TR_Success
- # console = console <<< "ERROR: can't connect to SUT!\n"
- # (_, world) = fclose console world
- = world
- # (Just con) = mcon
- /* open files */
- # (_, file, world) = fopen "testOut.txt" FWriteText world
- /* perform testing */
- # st = (toStringSChannel con.sChannel, toStringRChannel con.rChannel, world)
- # ((_, _, world), console, file) = testConfSM options stateTrans Listen adapter st reset console file
- /* close connection */
- /* close files */
- # (_, world) = fclose file world
- # (_, world) = fclose console world
- /* done */
- = world
-