reset a3, kut Charlie ;)
[tt2015.git] / a3 / code / dotgen / tcpmodel.icl
diff --git a/a3/code/dotgen/tcpmodel.icl b/a3/code/dotgen/tcpmodel.icl
new file mode 100644 (file)
index 0000000..2b73c25
--- /dev/null
@@ -0,0 +1,100 @@
+module tcpmodel
+
+import gast, ESMSpec, Graphviz
+
+derive bimap []
+derive gEq State
+derive gLess State
+derive genShow State
+derive ggen Input
+derive gEq 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 render State where
+       render Listen = "Listen"
+       render ReceivedSYN = "Received SYN"
+       render Established = "Established"
+       render Waiting = "Waiting"
+       render Closed = "Closed"
+       render WaitClose = "Awaiting Close"
+       render ConnectionError = "Connection Error"
+
+/* input (received from client) */
+:: Input = InSYN | InACK | InDATA | InRST | InFIN
+
+instance render Input where
+       render InSYN = "SYN"
+       render InACK = "ACK"
+       render InDATA = "DATA"
+       render InRST = "RST"
+       render InFIN = "FIN"
+
+/* output (sent to client) */
+:: Output = OutSYN | OutACK | OutDATA | OutFIN
+
+instance render Output where
+       render OutSYN = "SYN"
+       render OutACK = "ACK"
+       render OutDATA = "DATA"
+       render OutFIN = "FIN"
+
+/* 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]
+
+stateTrans Closed _ = [Pt [] Closed]
+stateTrans ConnectionError _ = [Pt [] ConnectionError]
+
+/* state machine thingy */
+esm :: ESM State Input Output
+esm = {s_0 = Listen, d_F = stateTrans, out = \_ _ . [], pred = \_ . []}
+
+/* build transitions */
+automaton = addTransitions 50 esm [Listen] [InSYN] {trans = [], issues = []}
+
+/* build graph */
+graph = mkDigraph "TCPModel" (automaton, Listen, [], [Closed,ConnectionError], [], [])
+
+/* write list of strings to file */
+instance <<< [String] where
+       (<<<) file [] = file
+       (<<<) file [x:xs] = file <<< x <<< xs
+
+/* testing program */
+Start world
+       # (_, file, world) = fopen "graph.dot" FWriteText world
+       # file = file <<< printDigraph graph
+       # (_, world) = fclose file world
+       = world
+