Symbian Developer Library

SYMBIAN OS V6.1 EDITION FOR C++

[Index] [Glossary] [Previous] [Next]



Setting up handshaking

In general, the speed at which data is transmitted is deliberately set to be faster than the speed with which it can be processed by the receiver. This results in a highly efficient utilisation of the available bandwidth — data transfers complete faster — and when data is being transmitted over phone lines, this translates into a direct saving of connect time and therefore of money.

Consequently, input buffers linked to reliable flow control mechanisms are essential for effective communications, as the receiver needs a mechanism for throttling back the transmitter and telling it to stop sending data. The TCommConfig package enables flow control to be configured at the driver level, relieving application software of the burden of handling this chore. Since multiple handshaking mechanisms may be active simultaneously, the various possibilities are implemented via a bitmapped integer (iHandshake) and various sets of individually enumerated bitmasks.


Flow control when sending

The first four of the handshaking bitmasks control what type of flow control is obeyed when we are sending data. We can set up any combination of hardware flow control (where we stop transmitting when any specified permutation of the modem input line CTS, DSR or DCD are low and we then wait for the relevant lines to go high before resuming) and software flow control (where we suspend transmission when we receive a configurable XOFF character and don’t resume until we receive a corresponding XON character).

[Top]


Flow control when receiving

The next three of the handshaking bitmasks controls the type of flow control we implement when receiving data, in the expectation that the transmitter will stop sending when told to. Again, we can set up any combination of hardware flow control (where we drop the signal levels on one or both of the modem outputs DTR and RTS to stop the incoming data and then raise the signals again to restart) or software flow control (where we transmit our XOFF character to stop the incoming data and then transmit XON when we are ready to resume). Software flow control is enforced by setting the KConfigSendXoff bit of iHandshake, while hardware flow control is enabled by setting either one or both of the KConfigFreeRTS and KConfigFreeDTR bits, which indicate whether or not the RTS and DTR outputs are under driver control or follow the user-defined settings  — see SetSignals() for more information.

[Top]


Flow control thresholds

Since the rate at which data is being placed in the input buffer can exceed the rate at which it is being taken out, it is probable that the buffer will gradually fill up. When a particular point (the high water mark), is reached and a suitable handshaking mode is enabled, a flow control event is triggered. This could be the transmission of an XOFF character or the lowering of either the RTS or DTR output signals, or any combination of these events. Whatever action is taken will be taken as a signal by the transmitter, which will stop sending. The inward flow of data will then stop, and the buffer will begin to empty. When a particular point (the low water mark) is reached, a matching flow control event is triggered, which could be the transmission of an XON character or the raising of the RTS or DTR signals, or any combination of these events.

[Top]


Handshaking latency and buffer sizes

It takes a finite amount of time to respond to flow control and other handshaking events. The term latency is generally used in this context to refer to the time taken between the occurrence of a particular event and the response to it. The maximum handshaking latency in ultimately depends on the frequency of the system clock.

However, the high and low watermarks for inward flow control need to allow for the response times of the systems with which our serial port is communicating rather than the latency associated with our own responses. Suppose it takes one second for a system to which we are connected to respond to a request to stop sending data, and supposed our serial port is running at 38400 bps. This means that we should have at least 3840 bytes free in our buffer when the high water mark. is reached, otherwise we may lose incoming data if our buffer overflows.

The input buffer levels at which these flow control events occur are not something that can be altered. Instead, the recommended way of adjusting the precise times at which flow control events will occur is to alter the size of the receive buffer using the member function SetReceiveBufferLength(). In the situation just described, we would need to set a receive buffer size of around 16K to guarantee no data loss .

(In practise, it may well be possible to get away with a smaller buffer than this even when the sending system takes one second to respond, as we will almost certainly be removing data from the buffer during the latency period. However, the precise calculations would clearly depend on the processing requirements of the receiving application.)

[Top]


Internal FIFO buffer control

As well as the buffers in the serial port drivers, the components used to implement many RS232 ports include a small internal FIFO buffer which can be switched on or off. The presence of such an internal buffer is signified by the iFifo byte in TCommCaps being set, and the FIFO can be enabled or disabled by setting or clearing the iFifo byte in TCommConfig as appropriate. The default state is for any FIFOs to be automatically enabled, as even a 16 byte FIFO (the usual size) significantly reduces the load on the processor during serial i/o operations, and applications should not disable this without good reason.

[Top]


Software flow control and data transparency

Software flow control presents particular problems of data transparency, since the characters used to suspend and resume the data flow may also occur as valid data bytes. There is no ideal method of handling this situation. For this reason, hardware flow control is the preferred handshaking method whenever there is a requirement for the transfer of binary data in either direction.

Different policies are adopted for solving data transparency issues, depending on the direction in which the handshaking operates.

[Top]


Changing software flow control characters

It is possible to change the characters that are used for software flow control with the TCommConfig package simply by changing the values in iXonChar and iXoffChar. However, you would normally need compelling reasons to change the defaults of the ASCII DC1 (decimal 17) for XON and DC3 (decimal 19) for XOFF respectively. In particular, you should note that disabling flow control must be done through iHandshake. Setting iXonChar and iXoffChar to zero is neither necessary nor desirable, and is liable to have extremely unpredictable effects.

[Top]


Cancellation of reads and writes

The next three of the handshaking bitmasks are all of the form KConfigFailxxx, and can be used to set up the conditions under which pending data transfers are automatically cancelled. Examples of the sort of situation this is designed to handle would be attempts to send data over a cable that had been pulled out, or disconnection of a modem during a file download.

An RComm i/o request can be set to terminate early with a KErrCommsLineFail error if any specified combination of the control lines fail. All you need to do is set the appropriate handshaking bits defined as KConfigFailCTS, KConfigFailDSR, and KConfigFailDCD. If multiple failure conditions are enabled, it may be necessary for an application to use the Signals() function to ascertain what the exact reason for the comms line failure might have been.

[Top]


Handshaking capability checks

As with the speed and data format, it is possible to use Caps() to find out whether a specified handshaking mode is supported or not. A matching set of enumerated bitmasks can be used with the iHandshake byte in TCommCaps to isolate specific capabilities of the port.