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).
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 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 api.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.
As described below, many packets are `acknowledged'. It means that upon reception, the server sends either:
BRLPACKET_ACK
packet, with no data, which means the operation
corresponding to the received packet was successful,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:
BRLPACKET_ERROR
packet.The connection between the client and the server can be in either of the four following modes:
BRLPACKET_AUTHKEY
packet
will be accepted, which makes the connection enter normal mode;
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.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.BRLPACKET_KEY
or BRLPACKET_COMMAND
packets to signal key presses;
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.BRLPACKET_PACKET
packets to give received packets
from the terminal to the client.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.