clean up and fix lstlistoflistings indentation
[msc-thesis1617.git] / arch.communication.tex
1 The communication from the server to the client and vice versa is just a
2 character stream containing encoded \gls{mTask} messages. The \CI{synFun}
3 belonging to the device is responsible for sending the content in the left
4 channel and putting received messages in the right channel. Moreover, the
5 boolean flag in the channel type should be set to \CI{True} when the connection
6 is terminated. The specific encoding of the messages is visible in
7 Appendix~\ref{app:communication-protocol}. The type holding the messages is
8 shown in Listing~\ref{lst:avmsg}. Detailed explanation about the message types
9 and according actions will be given in the following subsections.
10
11 \begin{lstlisting}[label={lst:avmsg},caption={Available messages}]
12 :: MTaskId :== Int
13 :: MSDSId :== Int
14 :: MTaskFreeBytes :== Int
15 :: MTaskMSGRecv
16 = MTTaskAck MTaskId MTaskFreeBytes | MTTaskDelAck MTaskId
17 | MTSDSAck MSDSId | MTSDSDelAck MSDSId
18 | MTPub MSDSId BCValue | MTMessage String
19 | MTDevSpec MTaskDeviceSpec | MTEmpty
20
21 :: MTaskMSGSend
22 = MTTask MTaskInterval String | MTTaskDel MTaskId
23 | MTShutdown | MTSds MSDSId BCValue
24 | MTUpd MSDSId BCValue | MTSpec
25
26 :: MTaskInterval = OneShot | OnInterval Int | OnInterrupt Int
27 \end{lstlisting}
28
29 \subsection{Device Specification}
30 The server stores a description for every device available in a record type.
31 From the macro settings in the client --- in the interface file--- a profile
32 is created that describes the specification of the device. When the connection
33 between the server and a client is established, the server will send a request
34 for specification. The client serializes its specification and send it to the
35 server so that the server knows what the client is capable of. The exact
36 specification is shown in Listing~\ref{lst:devicespec} and stores the
37 peripheral availability, the memory available for storing \glspl{Task} and
38 \glspl{SDS} and the size of the stack. Not all peripheral flags are shown for
39 brevity.
40
41 \begin{lstlisting}[label={lst:devicespec},
42 caption={Device specification for \gls{mTask}-\glspl{Task}}]
43 :: MTaskDeviceSpec =
44 { haveLed :: Bool
45 , haveLCD :: Bool
46 , have...
47 , bytesMemory :: Int
48 , stackSize :: Int
49 , aPins :: Int
50 , dPins :: Int
51 }
52 \end{lstlisting}
53
54 \subsection{Add a device}
55 A device can be added by filling in the \CI{MTaskDevice} record as much as
56 possible and running the \CI{connectDevice} function. This function grabs and
57 clears the channels, starts the synchronization \gls{Task} (\CI{synFun}), makes
58 sure the errors are handled when needed and runs a processing function in
59 parallel to react on the incoming messages. Moreover, it sends a specification
60 request to the device in question to determine the details of the device and
61 updates the record to contain the top-level \gls{Task}-id. All device
62 functionality heavily depends on the specific \CI{deviceShare} function that
63 generates an \gls{SDS} for a specific device. This allows giving an old device
64 record to the function and still update the latest instance.
65 Listing~\ref{lst:connectDevice} shows the connection function.
66
67 \begin{lstlisting}[label={lst:connectDevice},%
68 caption={Connect a device}]
69 process :: MTaskDevice (Shared Channels) -> Task ()
70 process device ch = forever $ wait "process" (not o isEmpty o fst3) ch
71 >>= \(r,s,ss)->upd (appFst3 (const [])) ch >>| proc r
72 where
73 proc :: [MTaskMSGRecv] -> Task ()
74 proc [] = treturn ()
75 proc [m:ms] = (case m of
76 MTPub i val = updateShareFromPublish device i val @! ()
77 ...
78 MTDevSpec s = deviceAddSpec device s @! ()
79 ) >>| proc ms
80
81 connectDevice :: MTaskDevice -> Task Channels
82 connectDevice device = set ([], [], False) ch
83 >>| appendTopLevelTask 'DM'.newMap True
84 ( process device ch -||- catchAll (getSynFun device.deviceData ch) errHdl)
85 >>= \tid->upd (\d->{d&deviceTask=Just tid,deviceError=Nothing}) (deviceShare device)
86 >>| set (r,[MTSpec],ss) ch
87 >>| treturn device
88 where
89 errHdl e = upd (\d->{d & deviceTask=Nothing, deviceError=Just e}) (deviceShare device) @! ()
90 ch = channels device
91 \end{lstlisting}
92
93 Figure~\ref{fig:handshake} shows the connection diagram. The client responds to
94 the server with their device specification. This is detected by the processing
95 function and the record is updated accordingly.
96
97 \begin{figure}[H]
98 \centering
99 \begin{sequencediagram}
100 \newthread{s}{Server}
101 \newinst[4]{c}{Client}
102 \begin{call}{s}{MTSpec}{c}{MTDevSpec}
103 \end{call}
104 \end{sequencediagram}
105 \caption{Connect a device}\label{fig:handshake}
106 \end{figure}
107
108 \subsection{\glspl{Task} \& \glspl{SDS}}
109 When a \gls{Task} is sent to the device it is added to the device record
110 without an identifier. The actual identifier is added to the record when the
111 acknowledgement of the \gls{Task} by the device is received. The connection
112 diagram is shown in Figure~\ref{fig:tasksend}.
113
114 \begin{figure}[H]
115 \centering
116 \begin{sequencediagram}
117 \newthread{s}{Server}
118 \newinst[4]{c}{Client}
119 \begin{call}{s}{MTSDS}{c}{MTSDSAck}
120 \end{call}
121 \begin{call}{s}{MTTask}{c}{MTTaskAck}
122 \end{call}
123 \end{sequencediagram}
124 \caption{Sending a \gls{Task} to a device}\label{fig:tasksend}
125 \end{figure}
126
127 The function for sending a \gls{Task} to the device is shown in
128 Listing~\ref{lst:sendtask}. First the \gls{Task} is compiled into messages. The
129 details of the compilation process are given in Section~\ref{sec:compiler}.
130 The new \glspl{SDS} that were generated during compilation are merged with the
131 existing device's \glspl{SDS}. Furthermore the messages are placed in the
132 channel \gls{SDS} of the device. This will result in sending the actual
133 \gls{SDS} specification and \gls{Task} specifications to the device. A
134 \gls{Task} record is created with the identifier $-1$ to denote a \gls{Task}
135 not yet acknowledged. Finally the device itself is updated with the new state
136 and with the new \gls{Task}. After waiting for the acknowledgement the device
137 is updated again and the \gls{Task} returns.
138
139 \begin{lstlisting}[label={lst:sendtask},%
140 caption={Sending a \gls{Task} to a device}]
141 makeTask :: String Int -> Task MTaskTask
142 makeTask name ident = get currentDateTime @ \dt->{MTaskTask | name=name, ident=ident, dateAdded=dt}
143
144 makeShare :: String Int BCValue -> MTaskShare
145 makeShare withTask identifier value = {MTaskShare | withTask=[withTask], identifier=identifier, value=value}
146
147 sendTaskToDevice :: String (Main (ByteCode a Stmt)) (MTaskDevice, MTaskInterval) -> Task (MTaskTask, [MTaskShare])
148 sendTaskToDevice wta mTask (device, timeout)
149 # (msgs, newState=:{sdss}) = toMessages timeout mTask device.deviceState
150 # shares = [makeShare wta "" sdsi sdsval\\{sdsi,sdsval}<-sdss, (MTSds sdsi` _)<-msgs | sdsi == sdsi`]
151 = updateShares device ((++) shares)
152 >>| sendMessages msgs device
153 >>| makeTask wta -1
154 >>= \t->upd (addTaskUpState newState t) (deviceShare device)
155 >>| wait "Waiting for task to be acked" (taskAcked t) (deviceShare device)
156 >>| treturn (t, shares)
157 where
158 addTaskUpState :: BCState MTaskTask MTaskDevice -> MTaskDevice
159 addTaskUpState st task device = {MTaskDevice | device & deviceState=st, deviceTasks=[task:device.deviceTasks]}
160 taskAcked t d = maybe True (\t->t.ident <> -1) $ find (eq t) d.deviceTasks
161 eq t1 t2 = t1.dateAdded == t2.dateAdded && t1.MTaskTask.name == t2.MTaskTask.name
162 \end{lstlisting}
163
164 \subsection{Miscellaneous Messages}
165 One special type of message is available which is sent to the device only when
166 it needs to reboot. When the server wants to stop the bond with the device it
167 sends the \CI{MTShutdown} message. The device will then clear its memory, thus
168 losing all the \glspl{SDS} and \glspl{Task} that were stored and reset itself.
169 Shortly after the shutdown message a new server can connect to the device
170 because the device is back in listening mode.
171
172 \subsection{Integration}
173 When the system starts up, the devices from the previous execution still
174 residing in the \gls{SDS} must be cleaned up. It might be the case that they
175 contain \glspl{Task}, \glspl{SDS} or errors that are no longer applicable in
176 this run. A user or programmer can later choose to reconnect to some devices.
177
178 \begin{lstlisting}[caption={Starting up the devices},%
179 label={lst:startupdevs}]
180 startupDevices :: Task [MTaskDevice]
181 startupDevices = upd (map reset) deviceStoreNP
182 where reset d = {d & deviceTask=Nothing, deviceTasks=[], deviceError=Nothing}
183 \end{lstlisting}
184
185 The system's management is done through the interface of a single \gls{Task}
186 called \CI{mTaskManager}. To manage the system, a couple of different
187 functionalities are necessary and are launched. An image of the management
188 interface is shown in Figure~\ref{lst:manage}. The left sidebar of the
189 interface shows the list of example \glspl{Task} that are present in the
190 system. When clicking a \gls{Task}, a dialog opens in which a device can be
191 selected to send the \gls{Task} to. The dialog might contain user specified
192 variables. All example \gls{mTask}-\glspl{Task} are of the type
193 \CI{Task (Main (ByteCode () Stmt))} and can thus ask for user input first if
194 needed for parameterized \gls{mTask}-\glspl{Task}. The bottom panel shows the
195 device information. In this panel, the devices can be created and modified.
196 Moreover, this panel allows the user to reconnect with a device after a restart
197 of the server application.
198
199 \begin{figure}[H]
200 \centering
201 \includegraphics[width=\linewidth]{manage}
202 \caption{The device management interface}\label{lst:manage}
203 \end{figure}