-
-
Notifications
You must be signed in to change notification settings - Fork 374
/
Copy pathsock-protocol.txt
316 lines (216 loc) · 9.05 KB
/
sock-protocol.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
Driver/server socket protocol
=============================
Here's a brief explanation of the text-based protocol which is used
between the drivers and server.
The drivers may send things on the socket at any time. They will send
out changes to their local storage immediately, without any sort of
prompting from the server. As a result, the server must always check on
any driver sockets for activity.
In terms of communications, each driver is a server on the Unix socket
(or Windows named pipe) which it creates, and the data server `upsd` is
a client which knows where to find such sockets, how they are named,
and connects to all of them to send commands and receive data updates.
During development, it is possible to use tools like `socat` to connect
to the socket (you may want to enable `NOBROADCAST` mode soon), e.g.
socat - UNIX-CONNECT:/var/state/ups/dummy-ups-UPS1
For more insight, NUT provides an optional tool of its own (not built
by default): the `sockdebug` which is built when `configure --with-dev`
is in effect, or can be requested from the root directory of the build
workspace:
make sockdebug && \
./server/sockdebug dummy-ups-UPS1
Formatting
----------
All parsing on either side of the socket is done by parseconf, so the
same rules about escaping characters and "quoting multi-word elements"
apply here. Values which may contain odd characters are typically
sent through pconf_encode to apply \ characters where necessary.
The "" construct is used throughout to force a multi-word value to stay
together on its way to the other end.
Commands used by the drivers
----------------------------
These commands (or semantically responses to server commands in some cases)
can be sent by drivers to the data server over the socket protocol.
SETINFO
~~~~~~~
SETINFO <varname> "<value>"
SETINFO ups.status "OB LB"
There is no "ADDINFO" -- if a given variable does not exist, it is
created upon receiving the first SETINFO command.
DELINFO
~~~~~~~
DELINFO <varname>
DELINFO ups.temperature
ADDENUM
~~~~~~~
ADDENUM <varname> "<value>"
ADDENUM input.transfer.low "95"
DELENUM
~~~~~~~
DELENUM <varname> "<value>"
DELENUM input.transfer.low "98"
ADDRANGE
~~~~~~~~
ADDRANGE <varname> <minvalue> <maxvalue>
ADDRANGE input.transfer.low 95 100
DELRANGE
~~~~~~~~
DELRANGE <varname> <minvalue> <maxvalue>
DELRANGE input.transfer.low 95 100
SETAUX
~~~~~~
SETAUX <varname> <numeric value>
SETAUX ups.id 8
This overrides any previous value. The auxiliary value is presently
used as a length byte for read-write variables that are strings.
SETFLAGS
~~~~~~~~
SETFLAGS <varname> <flag>...
SETFLAGS ups.id RW STRING
Note that this command takes a variable number of arguments, as multiple
flags are supported. Also note that they are not crammed together in
"" quotes, since "RW STRING" would mean something completely different.
This also replaces any previous flags for a given variable.
Currently supported flags include `IMMUTABLE`, `RW`, `STRING` and `NUMBER`
(detailed in the NUT Network Protocol documentation); unrecognized values
are quietly ignored.
ADDCMD
~~~~~~
ADDCMD <cmdname>
ADDCMD load.off
DELCMD
~~~~~~
DELCMD <cmdname>
DELCMD load.on
DUMPDONE
~~~~~~~~
DUMPDONE
This is only used to tell the server that every possible item has been
transmitted in response to its DUMPALL request. Once this has been
received by the server, it can be sure that it knows everything that the
driver does.
PONG
~~~~
PONG
This is sent in response to a PING from the server. It is only used as
a sanity check to make sure that the driver has not gotten stuck
somewhere.
DATAOK
~~~~~~
DATAOK
This means that the driver is able to communicate with the UPS, and the
data should be treated as usable. It is always sent at the end of the
dump if the data is not stale. It may also be sent at other times.
DATASTALE
~~~~~~~~~
DATASTALE
This is sent by the driver to inform any listeners that the data is no
longer usable. This usually means that the driver is unable to get any
sort of meaningful response from the UPS. You must not rely on any
status information once this has been sent.
This will be sent in the beginning of a dump if the data is stale, and
may be repeated. It is cleared by DATAOK.
TRACKING
~~~~~~~~
TRACKING <id> <value>
This is sent in response to an INSTCMD or SET VAR that includes a TRACKING,
upon completion of request execution by the driver. <value> is the integer
return value from the driver handlers instcmd and setvar (see
drivers/upshandler.h). The server is in charge of translating these codes into
strings, as per docs/net-protocol.txt GET TRACKING.
Commands sent by the server
---------------------------
The data server `upsd` (or technically any client that connects to a Unix
socket or Windows named pipe provided by each NUT driver) can send the
following commands to the driver:
PING
~~~~
PING
This is sent to check on the health of a driver. The server should only
send this when it hasn't heard anything valid from a driver recently.
Some drivers have very little to say in terms of updates, and this may
be the only communications they have with the server on a normal basis.
If a driver does not respond with the PONG within a few seconds at the
most, it should be treated as dead/unavailable. Data stored in the
server must not be passed on to the clients when this happens.
NOTE: For the `upsd` data server, the MAXAGE setting in upsd.conf controls
how long since the last message from the driver it is considered stale.
At 1/3 of this time the server sends a `PING` command to the driver, so
there is some time for a `PONG` to arrive and reset the timer (any other
message would serve that goal as well).
INSTCMD
~~~~~~~
INSTCMD <cmdname> [<cmdparam>] [TRACKING <id>]
INSTCMD panel.test.start
INSTCMD load.off 10
INSTCMD load.on 10 TRACKING 1bd31808-cb49-4aec-9d75-d056e6f018d2
NOTE:
* <cmdparam> is an additional and optional parameter for the command,
* "TRACKING <id>" can be provided to track commands execution status, if
TRACKING was set to ON on upsd. In this case, driver will later return
the execution status, using TRACKING.
SET
~~~
SET <varname> "<value>" [TRACKING <id>]
SET ups.id "Data room"
SET ups.id "Data room" TRACKING 2dedb58a-3b91-4fab-831f-c8af4b90760a
NOTE:
* "TRACKING <id>" can be provided to track commands execution status, if
TRACKING was set to ON on upsd. In this case, driver will later return
the execution status, using TRACKING.
DUMPALL
~~~~~~~
DUMPALL
The server uses this to request a complete copy of everything the driver
knows. This is returned in the form of the same commands (SETINFO,
etc.) that would be used if they were being updated normally. As a
result, the same parsing happens either way.
The server can tell when it has a full copy of the data by waiting for
DUMPDONE. That special response from the driver is sent once the entire
set has been transmitted.
NOBROADCAST
~~~~~~~~~~~
This connection does not want to receive broadcast messages (implemented
by `send_to_all()` method in `dstate.c`). Default is to receive everything.
BROADCAST (NUM)
~~~~~~~~~~~~~~~
This connection specified whether it wants to receive broadcast messages
(implemented by `send_to_all()` method in `dstate.c`), and by default
enables that -- unless disabled by providing an optional zero or negative
numeric argument. Note that initial default is to receive everything, so
this command may be useful for connections that disabled broadcasts at
some point.
Design notes
------------
Requests
~~~~~~~~
There is no way to request just one variable. This was done on purpose
to limit the complexity of the drivers. Their job is to send out
updates and handle a few simple requests. DUMPALL is provided to give
the server a known foundation.
To track a limited set of variables, a server just needs to do DUMPALL,
then only have handlers that remember values for the variables that
matter. Anything else should be ignored.
Access/Security
~~~~~~~~~~~~~~~
There are no access controls in the drivers. Anything that can connect
to their sockets can make requests, including SET and INSTCMD if
supported by the driver and hardware. These sockets must be kept
secure. If your operating system does not honor permissions or modes on
sockets, then you must store them in a directory with suitable
permissions to limit access.
Command limitations
~~~~~~~~~~~~~~~~~~~
As parseconf is used to handle decoding and chunking of the data, there
are some limits on what may be used. These default to 32 arguments of
512 characters each, which should be more than enough for everything
which is currently needed by the software.
These limits are strictly for sanity purposes, and may be raised if
necessary. parseconf itself can handle vast numbers of arguments and
characters, with some speed penalty as things get really big.
Re-establishing communications
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the server loses its connection to the driver and later reconnects,
it must flush any local storage and start again with DUMPALL. The
driver may have changed the internal state considerably during that
time, and any other approach could leave old elements behind.