1e9b4b6b86309d7fb20f63d61c5d65915005b999
[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 the
57 channels, starts the synchronization \gls{Task} (\CI{synFun}), makes sure the
58 errors are handled when needed and runs a processing function in parallel to
59 react on the incoming messages. Moreover, it sends a specification request to
60 the device in question to determine the details of the device and updates the
61 record to contain the top-level \gls{Task}-id. All device functionality
62 heavily depends on the specific \CI{deviceShare} function that generates an
63 \gls{SDS} for a specific device. This allows giving an old device record to the
64 function and still update the latest instance. Listing~\ref{lst:connectDevice}
65 shows the connection function.
66
67 \begin{lstlisting}[label={lst:connectDevice},%
68 caption={Connect a device}]
69 connectDevice :: (MTaskDevice (Shared Channels) -> Task ()) MTaskDevice -> Task Channels
70 connectDevice procFun device = set ([], [], False) ch
71 >>| appendTopLevelTask 'DM'.newMap True
72 ( procFun device ch -||- catchAll (getSynFun device.deviceData ch) errHdl)
73 >>= \tid->upd (\d->{d&deviceTask=Just tid,deviceError=Nothing}) (deviceShare device)
74 >>| upd (\(r,s,ss)->(r,s++[MTSpec],ss)) ch
75 where
76 errHdl e = upd (\d->{d & deviceTask=Nothing, deviceError=Just e}) (deviceShare device) @! ()
77 ch = channels device
78 \end{lstlisting}
79
80 Figure~\ref{fig:handshake} shows the connection diagram. The client responds to
81 the server with their device specification. This is detected by the processing
82 function and the record is updated accordingly.
83
84 \begin{figure}[H]
85 \centering
86 \begin{sequencediagram}
87 \newthread{s}{Server}
88 \newinst[4]{c}{Client}
89 \begin{call}{s}{MTSpec}{c}{MTDevSpec}
90 \end{call}
91 \end{sequencediagram}
92 \caption{Connect a device}\label{fig:handshake}
93 \end{figure}
94
95 \subsection{\glspl{Task} \& \glspl{SDS}}
96 When a \gls{Task} is sent to the device it is added to the device record
97 without an identifier. The actual identifier is added to the record when the
98 acknowledgement of the \gls{Task} by the device is received. The connection
99 diagram is shown in Figure~\ref{fig:tasksend}.
100
101 \begin{figure}[H]
102 \centering
103 \begin{sequencediagram}
104 \newthread{s}{Server}
105 \newinst[4]{c}{Client}
106 \begin{call}{s}{MTSDS}{c}{MTSDSAck}
107 \end{call}
108 \begin{call}{s}{MTTask}{c}{MTTaskAck}
109 \end{call}
110 \end{sequencediagram}
111 \caption{Sending a \gls{Task} to a device}\label{fig:tasksend}
112 \end{figure}
113
114 The function for sending a \gls{Task} to the device is shown in
115 Listing~\ref{lst:sendtask}. First the \gls{Task} is compiled into messages. The
116 details of the compilation process are given in Section~\ref{sec:compiler}.
117 The new \glspl{SDS} that were generated during compilation are merged with the
118 existing device's \glspl{SDS}. Furthermore the messages are placed in the
119 channel \gls{SDS} of the device. This will result in sending the actual
120 \gls{SDS} specification and \gls{Task} specifications to the device. A
121 \gls{Task} record is created with the identifier $-1$ to denote a \gls{Task}
122 not yet acknowledged. Finally the device itself is updated with the new state
123 and with the new \gls{Task}. After waiting for the acknowledgement the device
124 is updated again and the \gls{Task} returns.
125
126 \begin{lstlisting}[label={lst:sendtask},%
127 caption={Sending a \gls{Task} to a device}]
128 makeTask :: String Int -> Task MTaskTask
129 makeTask name ident = get currentDateTime @ \dt->{MTaskTask | name=name, ident=ident, dateAdded=dt}
130
131 makeShare :: String Int BCValue -> MTaskShare
132 makeShare withTask identifier value = {MTaskShare | withTask=[withTask], identifier=identifier, value=value}
133
134 sendTaskToDevice :: String (Main (ByteCode a Stmt)) (MTaskDevice, MTaskInterval) -> Task MTaskTask
135 sendTaskToDevice wta mTask (device, timeout)
136 # (msgs, newState=:{sdss}) = toMessages timeout mTask device.deviceState
137 # shares = [makeShare wta "" sdsi sdsval\\{sdsi,sdsval}<-sdss, (MTSds sdsi` _)<-msgs | sdsi == sdsi`]
138 = updateShares device ((++) shares)
139 >>| sendMessages msgs device
140 >>| makeTask wta -1
141 >>= \t->upd (addTaskUpState newState t) (deviceShare device)
142 >>| wait "Waiting for task to be acked" (taskAcked t) (deviceShare device)
143 >>| treturn t
144 where
145 addTaskUpState :: BCState MTaskTask MTaskDevice -> MTaskDevice
146 addTaskUpState st task device = {MTaskDevice | device & deviceState=st, deviceTasks=[task:device.deviceTasks]}
147 taskAcked t d = maybe True (\t->t.ident <> -1) $ find (eq t) d.deviceTasks
148 eq t1 t2 = t1.dateAdded == t2.dateAdded && t1.MTaskTask.name == t2.MTaskTask.name
149 \end{lstlisting}
150
151 \subsection{Miscellaneous Messages}
152 One special type of message is available which is sent to the device only when
153 it needs to reboot. When the server wants to stop the bond with the device it
154 sends the \CI{MTShutdown} message. The device will then clear its memory, thus
155 losing all the \glspl{SDS} and \glspl{Task} that were stored and reset itself.
156 Shortly after the shutdown message a new server can connect to the device
157 because the device is back in listening mode.
158
159 \subsection{Integration}
160 When the system starts up, the devices from the previous execution still
161 residing in the \gls{SDS} must be cleaned up. It might be the case that they
162 contain \glspl{Task}, \glspl{SDS} or errors that are no longer applicable in
163 this run. A user or programmer can later choose to reconnect to some devices.
164
165 \begin{lstlisting}[caption={Starting up the devices},%
166 label={lst:startupdevs}]
167 startupDevices :: Task [MTaskDevice]
168 startupDevices = upd (map reset) deviceStoreNP
169 where reset d = {d & deviceTask=Nothing, deviceTasks=[], deviceError=Nothing}
170 \end{lstlisting}
171
172 The system's management is done through the interface of a single \gls{Task}
173 called \CI{mTaskManager}. To manage the system, a couple of different
174 functionalities are necessary and are launched. An image of the management
175 interface is shown in Figure~\ref{lst:manage}. The left sidebar of the
176 interface shows the list of example \glspl{Task} that are present in the
177 system. When clicking a \gls{Task}, a dialog opens in which a device can be
178 selected to send the \gls{Task} to. The dialog might contain user specified
179 variables. All example \gls{mTask}-\glspl{Task} are of the type \CI{Task (Main
180 (ByteCode () Stmt))} and can thus ask for user input first if needed for
181 parameterized \gls{mTask}-\glspl{Task}. The bottom panel shows the device
182 information. In this panel, the devices can be created and modified. Moreover,
183 this panel allows the user to reconnect with a device after a restart of the
184 server application.
185
186 \begin{figure}[H]
187 \centering
188 \includegraphics[width=\linewidth]{manage}
189 \caption{The device management interface}\label{lst:manage}
190 \end{figure}