BrlAPI Reference manual: Protocol reference

Next Previous Contents

## 6. Protocol reference

Under some circumstances, it may be preferable to communicate directly with BrlAPI's server.avoid rather than using BrlAPI's library. Here are the needed details to be able to do this. This chapter is also of interest if a precise understanding of how the communication stuff works is desired, to be sure to understand how to write multithreaded clients, for instance.

In all the following, integer will mean an unsigned 32 bits integer in network byte order (ie most significant bytes first).

## 6.1 Reliable packet transmission channel

The protocol between BrlAPI's server and clients is based on exchanges of packets. So as to avoid locks due to packet loss, these exchanges are supposed reliable, and ordering must be preserved, thus BrlAPI needs a reliable packet transmission channel.

To achieve this, BrlAPI uses a TCP-based connection, on which packets are transmitted this way:

- the size in bytes of the packet is transmitted first as an integer,
- then the type of the packet, as an integer,
- and finally the packet data.

The size does not include the { size, type } header, so that packets which don't need any data have a size of 0 byte. The type of the packet can be either of `BRLPACKET_*` constants defined in `brlapi.h`. Each type of packet will be further discussed below.

BrlAPI's library ships two functions to achieve packets sending and receiving using this protocol: `brlapi_writePacket` and `brlapi_readPacket`. It is a good idea to use instead of rewriting them, since this protocol might change one day in favor of a real reliable packet transmission protocol such as the experimental RDP.

## 6.2 Responses from the server

As described below, many packets are `acknowledged'. It means that upon reception, the server sends either:

- a `BRLPACKET_ACK` packet, with no data, which means the operation corresponding to the received packet was successful,
- or a `BRLPACKET_ERROR` packet, the data being an integer which should be one of `BRLERR_*` constants. This means the operation corresponding to the received packet failed.

Some other packets need some information as a response. Upon reception, the server will send either:

- a packet of the same type, its data being the response,
- or a `BRLPACKET_ERROR` packet.

## 6.3 Operating modes

The connection between the client and the server can be in either of the four following modes:

- authentication mode: this is the initial mode, when the client hasn't authenticated itself to the server yet. Only one `BRLPACKET_AUTHKEY` packet will be accepted, which makes the connection enter normal mode;
- normal mode: the client is authenticated, but didn't ask for a tty or raw mode. The client can send either of these types of packet:
  - `BRLPACKET_GETDRIVERID`, `BRLPACKET_GETDRIVERNAME` or `BRLPACKET_GETDISPLAYSIZE` to get pieces of information from the server,
  - `BRLPACKET_GETTTY` to enter tty handling mode,
  - `BRLPACKET_GETRAW` to enter raw mode,
  - `BRLPACKET_BYE` to tell the server it wants to close the connection.
  ;
- tty handling mode: the client holds the control of a tty: brltty has no power on it any more, masked keys excepted. It's up to the client to manage display and keypresses. For this, it can send either of these types of packet:
  - `BRLPACKET_GETTTY` to switch to another tty, but how key presses should be sent mustn't change,
  - `BRLPACKET_LEAVETTY` to leave tty handling mode and go back to normal mode,
  - `BRLPACKET_MASKKEY` or `BRLPACKET_UNMASKKEY` to mask and unmask keys,
  - `BRLPACKET_WRITE` or `BRLPACKET_STATUSWRITE` to display text on this tty,
  - `BRLPACKET_GETRAW` to enter raw mode,
  - `BRLPACKET_GETDRIVERID`, `BRLPACKET_GETDRIVERNAME` or `BRLPACKET_GETDISPLAYSIZE` to get pieces of information from the server,
  - `BRLPACKET_BYE` to tell the server it wants to close the connection.
  And the server might send either `BRLPACKET_KEY` or `BRLPACKET_COMMAND` packets to signal key presses;
- raw mode: the client wants to exchange packets directly with the braille terminal. Only these types of packet will be accepted:
  - `BRLPACKET_LEAVERAW` to get back to previous mode, either normal or tty handling mode.
  - `BRLPACKET_PACKET` to send a packet to the braille terminal.
  - `BRLPACKET_BYE` to tell the server it wants to close the connection.
  And the server might send `BRLPACKET_PACKET` packets to give received packets from the terminal to the client.

## 6.4 Details for each type of packet

Here is described the semantics of each type of packet. Most of them are directly linked to some of BrlAPI's library's functions. Reading their online manual page as well will hence be of good help for understanding.

### `BRLPACKET_AUTHKEY` (see brlapi_loadAuthKey())

This must be the first packet ever transmitted from the client to the server. It lets the client authenticate itself to the server. Data is the authentication key itself.

If the authentication key matches the servers', it is acknowledged, and other types of packets might be used, other `BRLPACKET_AUTHKEY` shouldn't be sent by the client.

If the authentication key doesn't match, the server sends a `BRLERR_CONNREFUSED` and closes the connection.

### `BRLPACKET_BYE` (see brlapi_closeConnection())

This should be sent by the client when it doesn't need server's services any more, just before disconnecting from it. The server will acknowledge this packet and close the connection. It will also clean up things like the tty which was got by the application, as well as raw mode, by sending a special reset event to the braille device, if the `brltty` driver implements it. But this shouldn't prevent clients from cleanly leaving ttys and raw mode before issuing `BRLPACKET_BYE` !

### `BRLPACKET_GETDRIVERID` (see brlapi_getDriverId())

This should be sent by the client when it needs the 2-char identifier of the current `brltty` driver. The returned string is \0 terminated.

### `BRLPACKET_GETDRIVERNAME` (see brlapi_getDriverName())

This should be sent by the client when it needs the full name of the current `brltty` driver. The returned string is \0 terminated.

### `BRLPACKET_GETDISPLAYSIZE` (see brlapi_getDisplaySize())

This should be sent by the client when it needs to know the braille display size. The returned data are two integers: width and then height.

### `BRLPACKET_GETTTY` (see brlapi_getTty())

This should be sent by the client to get control of a tty. Sent data are two integers: the number of the tty to get control of (it mustn't be 0), and how key presses should be sent: either `BRLKEYCODES` or `BRLCOMMANDS`. This packet is then acknowledged by the server.

### `BRLPACKET_KEY` and `BRLPACKET_COMMAND` (see brlapi_readKey()and brlapi_readCommand())

As soon as the client got a tty, it must be prepared to handle either `BRLPACKET_KEY` or `BRLPACKET_COMMAND` incoming packets (depending on the parameter given in the `BRLPACKET_GETTTY` packet), at any time (as soon as the key was pressed on the braille terminal, hopefuly). The data holds the key press code as an integer, either a raw key code in `BRLPACKET_KEY` packets, or a `brltty` command code in `BRLPACKET_COMMAND` packets.

### `BRLPACKET_LEAVETTY` (see brlapi_leaveTty())

This should be sent to free the tty and masked keys lists. This is acknowledged by the server.

### `BRLPACKET_MASKKEYS` and `BRLPACKET_UNMASKKEYS` (seebrlapi_ignoreKeys() and brlapi_unignoreKeys())

If the client doesn't want every key press to be signaled to it, but some of them to be given to `brltty` for normal processing, it can send `BRLPACKET_MASKKEYS` packets to tell ranges of key codes which shouldn't be sent to it, but given to `brltty`, and `BRLPACKET_UNMASKKEYS` packets to tell ranges of key codes which should be sent to it, and not given to `brltty`. The server keeps a dynamic list of ranges, so that arbitrary sequences of such packets can be sent. Data are 2 integers: the lower and the upper boundaries; lower and upper must be equal to tell one key, for instance.

### `BRLPACKET_WRITE` (see brlapi_writeBrl())

To display text on the braille terminal and set the position of the cursor, the client can send a `BRLPACKET_WRITE` packet. This packet holds the cursor position as an integer, and then the text to display, one byte per caracter. The text must exactly fit the braille display, ie hold height*width bytes, where height and width must be get by sending a `BRLPACKET_GETDISPLAYSIZE` packet. Moreover, characters are expected to be encoded in latin-1. This packet is acknowledged by the server.

### `BRLPACKET_WRITEDOTS` (see brlapi_writeBrlDots())

Is used the same way as `BRLPACKET_WRITE`, the only difference being that characters are encoded in braille dots.

### `BRLPACKET_STATWRITE`

Some braille terminals have a special status display, whose text is independant from normal display's. To display text on it, the client can send a `BRLPACKET_STATWRITE` packet, just like `BRLPACKET_WRITE` packets.

### `BRLPACKET_STATWRITEDOTS`

Is used the same way as `BRLPACKET_STATWRITE`, the only difference being that characters are encoded in braille dots.

### `BRLPACKET_GETRAW` (see brlapi_getRaw())

To enter raw mode, the client must send a `BRLPACKET_GETRAW` packet, which is acknowledged. Once in raw mode, no other packet than `BRLPACKET_LEAVERAW` or `BRLPACKET_PACKET` will be accepted. The data must hold the special value `BRLRAW_MAGIC`: `0xdeadbeef`, to avoid erroneous raw mode activating.

### `BRLPACKET_LEAVERAW` (see brlapi_leaveRaw())

To leave raw mode, the client must send a `BRLPACKET_LEAVERAW` packet, which is acknowledged.

### `BRLPACKET_PACKET` (see brlapi_sendRaw() andbrlapi_recvRaw())

While in raw mode, only `BRLPACKET_PACKET` packets can be exchanged between the client and the server: to send a packet to the braille terminal, the client merely sends a `BRLPACKET_PACKET` packet, its data being the packet to send to the terminal. Whenever its receives a packet from the terminal, the server does exactly the same, so that packet exchanges between the terminal and the server are exactly reproduced between the server and the client.

Packets' content depend on the braille driver, so that the client should check for its id or name thanks to a `BRLPACKET_GETDRIVERID` packet or a `BRLPACKET_GETDRIVERNAME` packet, prior to sending any `BRLPACKET_GETRAW` packet.

Next Previous Contents