Remote I/OπŸ”—

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.

CommandsπŸ”—

The I/O protocol uses the following commands:

Command

Description

Q

Query information about I/O channels.

I <channel>

Retrieve current value of a channel.

O <channel> <value>

Set value of an output channel.

A <channel>

Add a channel to monitored inputs.

R <channel>

Remove a channel from monitored inputs.

L

Start listening to changes.

S

Stop listening to changes.

C <credentials>

Send credentials.

X

Explicitly shut down connection.

Message formatπŸ”—

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 LF, hex code 0A, '\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 (ASCII characters '0'-'9').

The maximum length of a line, including the newline character is 1024 bytes.

ConnectπŸ”—

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 LF, 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 the C command to authenticate itself.

Query channel infoπŸ”—

The 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.

  • Input: I <max>

  • Output: O <max>

The <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πŸ”—

The 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 input channels.

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πŸ”—

The 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πŸ”—

The 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.

The 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 R command.

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 I <channel> command: each line contains a channel index and the latest value.

The L command is special in that it may not receive a response immediately and does not terminate automatically, but must be canceled with the S command. Sending any other command while listening, or sending the 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>

Authenticate clientπŸ”—

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.

The 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>

DisconnectπŸ”—

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.

ErrorsπŸ”—

If a command causes an error on the server side, the server replies with an 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.

Error codes

Code

Description

1

Invalid command.

2

Invalid argument to command.

3

Command not accepted.

4

Authentication required.

5

I/O device error.

6

Non-categorized error.

I/O statesπŸ”—

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.

Command-line accessπŸ”—

The 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