/**************************************************************************** * Data Buffer for the Real-time BBC Codec/Modem * **************************************************************************** * William L. Bahn * * Academy Center for Information Security * * Department of Computer Science * * United States Air Force Academy * * USAFA, CO 80840 * **************************************************************************** * FILE:............ buffer.h * * DATE CREATED:.... 01 SEP 07 * * DATE MODIFIED:... 01 SEP 07 * **************************************************************************** * * REVISION HISTORY * **************************************************************************** * * DESCRIPTION * * The data buffer stores packet data between the codec and the modem. * * In the receiver, the buffer accepts packet data from the codec and * feeds that data to the modem. In the transmitter, it accepts data from * the modem and feeds it to the codec. While the modem, by its nature, * generally produces and consumes data at a uniform rate, the codec * can be quite erratic in its data rate. Therefore the buffer must be * sized sufficiently large to allow for the resulting ebb and flow. * This is particularly important in the case of the receiver since, if * the buffer can't accommodate the data as the modem delivers it, data * will be lost. This is not as critical with the transmitter, depending * on the nature of the data source and its buffering strategy, since it * will normally only reduce the effective data rate as opposed to causing * dropped packets. * * The data is stored in a circular buffer with the following variables: * * buffer: Pointer to the block of memory where the buffer starts. * read: Index of the first byte of the present packet. * write: Index of the next unused buffer location. * margin: How many bytes are in buffer beyond the scope of the decoder. * unused: How many unused bytes are available in the buffer. * * The buffer is seen by two functions, the one that is demodulating the * data packet and the one that is decoding the resulting data. The * demodulating function writes to the buffer at a nominally constant * rate dictated by the communications link. In this application, this is * simulated by reading the stored waveform data from a file and querying * the clock to determine how many bytes to add to the buffer each time * the function is called. The decoding function, on the other hand, always * to decodes eight packets each time it is called provided sufficient data * is available. Specifically, it decodes the eight packets that start with * the bits in the byte stored at the "read" pointer. Since it can't decode * packets that are not completely contained in the buffer, the decoding * function first checks to see if "fill" is non-negative. If it isn't, then * it returns immediately. At the other end of the spectrum, the demodulator * may run out of unused memory to write to. If this happens, data is going * to be lost. It is cleaner to throw away old data instead of introducing * a gap in present data, therefore the demodulator will push the "read" * pointer forward as it overwrites the beginning of the existing packet * data. * */ #ifndef BUFFERdotH #define BUFFERdotH //------------------------------------------------------------------------ // REQUIRED INCLUDES //------------------------------------------------------------------------ #include "config.h" #include "dirtyd.h" //------------------------------------------------------------------------ // STRUCTURE DECLARATIONS //------------------------------------------------------------------------ typedef struct BUFFER BUFFER; //------------------------------------------------------------------------ // STRUCTURE DEFINITIONS //------------------------------------------------------------------------ // NOTE: Normally the structure definition would be in the *.c file to make // the structure members inaccessible to outside functions except through // public function calls. But for the real-time code it has been decided // to make the structure members directly visible to the functions that // manipulate them. struct BUFFER { size_t size; // Allocated size of buffer (in bytes) size_t minsize; // Minimum acceptable buffer size (in bytes) BYTE *buffer; // Pointer to the actual buffer DWORD read; // Index of next position to be read. DWORD write; // Index of next position to be written. DWORD scope; // The number of bytes recipient must. SDWORD margin; // Number of bytes beyond scope of recipient DWORD empty; // Number of bytes available for new data. DWORD ready; // Number of bytes ready for modulation. DWORD buffermask; // The used bits in the buffer size DWORD overflows; // Number of data pushes into read pointer. }; //------------------------------------------------------------------------ // PUBLIC FUNCTION PROTOTYPES //------------------------------------------------------------------------ BUFFER *BUFFER_Del(BUFFER *p); BUFFER *BUFFER_New(CONFIG *c, DWORD *errcode); //------------------------------------------------------------------------ #endif