The networking code
uses ASIO.
ASIO handles low level socket IO and calls call backs into the user code
asynchronously when network events need processing. The ASIO library is a very very difficult library to learn and
use. The networking code was written so that it should never have to be touched
except to add more network message types. This document will explain what parts
of the networking code need to be edited to add a new network message type.
The files that contain the networking code are: controlWindow/Downlink.h Client side IO, exists to send commands to
the robot. controlWindow/Downlink.cc main/Uplink.h Server, runs on the robot. Calls into the robot code to
notify subscribers of network events and pass data around. main/Uplink.cc common/Network.h Network message types.
There is extensive documentation in the header files listed above.
The most important thing to realize is that the callback functions (documented
in the code) don't run in the same thread as the class was constructed
in. The packets are parsed immediately when they arrive, that means that when
notification is given to the rest of the robot of new data, those
notifications are also being called from another thread. When a class
subscribes to the robot to receive network data notifications it is the
subscribers responsibility to make sure that anything it does during the
notification is thread safe and happens very quickly, since the callback holds
up the network thread if it takes too long.
Packet format
Packet ID
unsigned char
Packet data length
unsigned int
Packet data
${Packet data length} bytes.
These packets are stringed together over a socket with no separating data.
Adding network message types
The first thing to do is open the Network.h file and add an enumeration that
defines the new packet type. Then edit either the Uplink.cc or Downlink.cc
files to either send or receive that packet type, depending on the direction
of the packet. For example, joystick data is sent from the client to the
robot. So Downlink.cc gets a send joystick data function, and the parsing code
for Uplink.cc gets parsing and notification code for new joystick data.
Sender gets a new public function to send the data. The sending function takes
the input data and formats a new packet. This means the first byte is the new
packet ID, then the packet length (can vary across packets, even for the same
type) followed by the packet data. This new packet data buffer (vector <
char>) is then added to the outgoing queue. Both classes have function to add
packets to the out queue, never edit these variables yourself, they are used
by multiple threads.
On the receiving end there is a switch for each packet type. Add your type and
parse your data. once your data is parsed call the subscribers with the
boost::signals library. You can add public functions for subscribers to add
themselves. There are examples of this too in the code.