Once all layers in a device have been brought into data transfer state, full-duplex communication can begin. Data is read from and written to the topmost service in the device. These operations are shown in the ExchangeData() function in the sample program.
Data is written by calling either lgo_Write() or lgo_WriteSpecial(). lgo_WriteSpecial() is used to pass protocol-specific information which can be transmitted with the data, such as the M-bit, Q-bit and D-bit in the X.25 layer.
The application may attempt to regulate the flow of data from the remote system using lgo_Xoff() to request a temporary suspension of data transmission and lgo_Xon() to request resumption of data transmission. If the remote system sends an xoff request , the API will enter data transfer xoff state. In this state, the application will receive an error if it attempts to write. However, the application may still read, issue a disconnect request or send flow control requests to the remote system.
Note that protocol layers may initiate flow control measures on their own to prevent the system from being flooded with data. For instance, when the number of system buffers available to receive data falls to 0, the physical layer must attempt to stop transmission from the remote site or start dropping data. In this case, it may issue an xoff request. (If the user also issues an xoff request, the xoff remains in effect at least until the user issues an xon request. Similarly, the LAPB link layer may initiate flow control when the number of buffers available for receiving data falls below a critical value defined for the buffer pool. It does this by sending an RNR frame. When the number of buffers rises to a safe level, it sends an RR frame to resume data transmission. For details, see System Buffer Pool in the LayGO Configuration Manual.
Data is read by calling lgo_Read(), lgo_ReadNext(), or lgo_ReadSpecial(). Like lgo_WriteSpecial(), lgo_ReadSpecial() provides access to protocol-specific information attached to data packets. lgo_ReadNext() lets an application read data from the next CID on which data is waiting.
Both data and control events arrive on a queue from below and must be processed in order. lgo_Poll() can be used to find out if any event is waiting and, if so, what kind of event it is and what size buffer will be needed to hold any data arriving with it. If the event is a data event, the application must use lgo_Read() or lgo_ReadSpecial() to dequeue it or lgo_DiscardData() to discard it. If it is a control event, the application must call lgo_Event() to dequeue it.
If a device consists solely of a physical protocol, it may receive 3 special kinds of data events. These are:
These events are filtered out when higher level protocols are used. When a higher layer protocol is not used, they are passed to the application. Since in each case, the data is of questionable value, the application has the choice of simply discarding the data by calling lgo_DiscardData(). Any data event may be discarded, for instance, if the application has run out of disk space. However, control events must be processed using lgo_Event().