The public interface to this class is as follows:
RspConnection
. The constructor, provided in
two flavors. The first takes a single integer argument, the port
number to listen on. The second takes an optional string
argument, the name of a TCP/IP service to listen on (which
defaults to "or1ksim-rsp"
).
Both use the private function, rspInit
to
save the port number (0 if the service name is to be used) and
service name and set the file descriptor for the connection
(private variable clientFd
) to -1, indicating
no connection is present.
~RspConnection
. The destructor, which
closes any connection which has been established.
rspConnect ()
. This function listens for
client GDB connections over TCP/IP using the port or service
specified in the constructor. The connection is established with
a keep-alive flag (for long debug sessions) and with Nagel's
algorithm disabled. This ensures that the characters of a packet
are transmitted as a soon as they are available, rather than
being grouped for more efficient transmission. This is
appropriate for an interactive interface such as a debugger.
Once a connection is established, its file descriptor (which
cannot be negative) is stored in the private variable,
clientFd
.
The function returns false
if a catastrophic
failure occurs in setting up the connection. This will cause the
GDB server to terminate. A result of true
indicates either a successful connection, or that the connection
attempt may be retried. The two can be distinguished by use of
the isConnected
function (see below).
rspClose
. This closes the connection if it
is open and sets the file descriptor
(clientFd
) to -1. It may be safely called
without checking if the connection is still open, since it will
check the value of clientFd
before closing
it.
isConnected
. This returns
true
if a connection is established
(i.e. clientFd
is not negative) and
false
otherwise.
getPkt
. This takes a pointer to a packet
and populates it with the data from the next packet read from
the TCP/IP stream. It will continue to retry until a packet is
successfully read (i.e. is complete, fits into the packet data
structure and has a correct checksum) or the connection
fails. The packet is acknowledged back to the client.
The RSP protocol requires certain characters
('$'
, '#'
and
'}'
) in the data field of incoming packets to
be escaped. However rather than inspecting every packet for
escaped characters, it is the raw data which is stored. This is
because there is only one packet type (X
)
which can have these characters, and it is more efficient to
unescape the characters only in the handler for that packet.
The private function getRspChar
is used to
read individual characters from the socket. It will
automatically retry in the event of an interrupt.
The function returns true
if a packet is
successfully read and false
if the connection
fails.
putPkt
. This is the complement to
getPkt
, sending its argument packet back to
the client. It will continue to retry until receipt is
successfully acknowledged or the connection fails.
Unlike getPkt
, putPkt
escapes its data field. Characters '$'
,
'#'
, '*'
and
'}'
are escaped by preceding them with
'}'
and then the original character XORed
with 0x20. It makes sense to centralize escaping here, since
several commands may generate results using these characters.
The private function putRspChar
is used to
write individual characters to the socket. It will automatically
retry in the event of an interrupt.
The function returns true
if a packet is
successfully sent and false
if the connection
fails.