The VisionAppster Engine comes with an I/O driver that communicates with external I/O servers using a simple text-based protocol. The protocol described here is agnostic to the socket type being used. The I/O driver implementation (I/O protocol client) in the VisionAppster Engine currently supports local, TCP and SSL sockets. The I/O driver is used through ReadDigitalInputTool and WriteDigitalOutputTool.
An I/O server may or may not support multiple simultaneous connections. If multiple connections are not supported, the server refuses further connection attempts once one connection has been accepted.
The protocol does not provide facilities for configuring I/O devices. It is assumed that I/O channel configuration is handled by the server as it sees fit.
Depending on the configuration of the I/O device, a change in an I/O channel may be detected in different ways. For example, an I/O interrupt may be generated on the rising or falling edge of an input signal, or both. Alternatively, the I/O device may poll its inputs in regular intervals and detect level changes. The I/O protocol does not provide a way to configure such behavior; it merely specifies a way of listening to changes. It is the server’s task to implement change detection in a suitable manner.
The VisionAppster SDK contains a reference implementation of an I/O
server that supports UNIX domain sockets and TCP sockets. The source
code and build instructions can be found in
va-ioserver/ under the
VisionAppster SDK installation directory.
The I/O protocol uses the following commands:
Query information about I/O channels.
Retrieve current value of a channel.
Set value of an output channel.
Add a channel to monitored inputs.
Remove a channel from monitored inputs.
Start listening to changes.
Stop listening to changes.
Explicitly shut down connection.
All messages are encoded as UTF-8. The ASCII subset is used for everything except human-readable error messages returned by the server, which basically means you can safely treat every byte as a character everywhere except in error messages. In error messages, the rest of the line following an error code is a UTF-8 -encoded string.
Each command is terminated with a line feed character (ASCII
'\n'). The server replies with zero or more lines, each
terminated by an
LF character. The end of a message is indicated by
an empty line.
All numbers are non-negative base-10 integers, represented as text
The maximum length of a line, including the newline character is 1024 bytes.
A connection is established by opening a socket (UNIX domain socket, TCP socket or SSL socket) to a listening I/O server. When connected to, the server responds with a single line that contains an identification string “VAIO”, a space and an integer that specifies the protocol version:
⇐ VAIO 1 <LF>
In this document, messages from the server are indicated by a
left-pointing arrow (
⇐) and messages sent by the client by a
right-pointing arrow (
⇒). All lines are terminated with an
which is not written out explicitly unless the line is empty.
The server may require authentication. If this is the case, the initial
response will be an error code 4 (see below). The client must then use
C command to authenticate itself.
Query channel info🔗
Q command returns information about all I/O channels, sorted
according to the (zero-based) channel index. The format of each line of
the reply depends on the type of the channel.
<max> parameter is a positive integer that specifies the maximum
value a channel can take. An example:
⇒ Q ⇐ I 1 I 1 O 1 O 1 I 15 O 65535 <LF>
This device has two digital inputs (channels 0-1), two digital outputs (channels 2-3), one four-bit input (e.g. A/D input, channel 4) and a 16-bit output (e.g. D/A output, channel 5).
Note that an output channel with a maximum value larger than one can represent any analog-like outputs such as PWM (pulse width modulated) outputs. From the protocol’s perspective they work the same way.
Get channel value🔗
I <channel> command retrieves the current value of a specific
input channel. The zero-based channel index is given as an argument. If
<channel> is omitted, the server returns the current values of all
Each response line contains a channel index and the current value. Depending on the device, it may be possible to read the value of an output channel. If the channel is not readable, the server responds with error code 2.
⇒ I 0 ⇐ 0 1 <LF> ⇒ I ⇐ 0 1 1 0 4 12 <LF>
Set output channel value🔗
O <channel> <value> command sets an output channel to the
specified value. The server responds with an empty message. It is an
error (error code 2) to set the value of an input channel. Exceeding the
maximum value of a channel will also cause error 2.
⇒ O 0 1 ⇐ <LF> ⇒ O 5 12345 ⇐ <LF>
Manage monitored inputs🔗
A <channel> command adds an input channel to the list of
channels that are monitored for changes. If the channel is omitted, all
input channels will be monitored. The server responds with an empty
message. It is an error (code 2) to start monitoring an output channel.
R <channel> command works the same way, but removes the given
channel or all channels from monitored input channels. Removing a
monitored input does not remove already queued change events; the next
L command may still receive events that were queued before the
Changes in all monitored input channels will be queued up to an
implementation-specific maximum number of items. Queued events will be
sent out when the client starts listening to input events using the
L command. The format is the same as that of the
command: each line contains a channel index and the latest value.
L command is special in that it may not receive a response
immediately and does not terminate automatically, but must be canceled
S command. Sending any other command while listening, or
S command in other situations is an error (code 3).
A typical communication sequence is as follows:
⇒ A ⇐ <LF> ⇒ L ⇐ 0 1 0 0 0 1 1 0 ⇒ S ⇐ <LF>
Note that the client may receive input events after the
S command if
the events are already in transmission when the
S command is
received by the server. This is possible:
⇒ L ⇒ S ⇐ 0 1 0 0 0 1 1 0 <LF>
Authentication may not be needed if the client and the server communicate through a local socket. If the communication happens over the network, authentication may be necessary. In this case the server responds immediately with error code 4 to require authentication.
C <credentials> command is used to send authentication
credentials to the server. If the server accepts the credentials, it
responds with an empty message. Otherwise, it responds with error code 4
to all commands. The
C command must be the first command, and it
will be rejected with error 3 if tried after it is accepted once.
An illustrative conversation:
⇐ E 4 Authentication required ⇒ C secret pasword ⇐ E 4 Authentication required ⇒ C secret password ⇐ VAIO 1 <LF>
The easiest way to shut down a connection is to just close it on the
client side. The
X command provides a way to request the server to
close the connection. On success, the server closes the connection and
sends no response. This may be useful when manually interacting with a
server. If the server requires authentication,
X is the only command
accepted before the
C <credentials> command.
If a command causes an error on the server side, the server replies with
E followed by a space, an error code and optionally another space
and a human-readable explanation of the error. The error message must
be encoded in UTF-8.
not exceed the maximum line length (counting “E”, error code and spaces).
not contain linefeed characters.
⇒ S ⇐ E 3 Not listening
If the server runs out of output buffer space or is unable to queue more input events, it may choose to terminate the connection instead of sending an error message.
Note that error responses are not terminated by an empty line.
Invalid argument to command.
Command not accepted.
I/O device error.
It is common to wire digital I/O pins so that they are connected to the ground in the active state. Usually, the I/O driver also sees a zero in the I/O register in this case. It is important to notice that the protocol always treats “0” as the inactive state for all inputs and outputs. Thus, the driver may need to invert the I/O control register if the I/O lines are configured to an active low state.
socat program can be used to connect to and control an I/O
server from the command line:
# Connect to a TCP (IPv4 or IPv6) socket $ socat - TCP:192.168.2.3:1234 # Connect to a UNIX domain socket $ socat - UNIX-CONNECT:/run/va-ioserver.sock