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