Implementation notes Edwin Olson, eolson@mit.edu, 11/17/03 The serial port connection to the orc board performs two distinct operations. It implements a Command-Response protocol, and it asynchronously broadcasts events. It is a bit difficult to efficiently deal with both, so orcd demultiplexes the two streams and provides separate interfaces for both. Command-response transactions are implemented on one TCP port, and asynchronous operations are sent on another. This simplifies the implementation of the client. Following a suggestion by Edward Faulkner: a background thread does nothing but read from the serial port, parsing input into lines and routing the data into one of two pipes: one for responses to commands, and another for asynchronous messages. A single thread takes asynchronous messages and attempts to send messages to the current subscribers. However, we don't want to block all threads if one subscriber is unresponsive. Thus, if a write is partially completed, we remember that particular message and try to send it again the next time we process an event. Thus, each client receives complete messages (never garbage), but messages may be dropped for slow clients. The command-response service requires a listener thread to make connections, and a per-client thread. The client threads perform blocking reads on the TCP input, then acquire exclusive access to the serial port to perform the transaction. The transaction result is then sent back to the TCP client. The actual serial port transaction includes a timeout mechanism, ensuring that a client will *always* receive a response. Thus, the clients need not implement a timeout mechanism. Troubleshooting: If you seem to be dropping characters, make sure UDMA is enabled on your harddisk, hdparm -c1 -d1 -u1 /dev/hda