309 lines
9.3 KiB
C
309 lines
9.3 KiB
C
/*
|
|
|
|
PrivL0serial.h
|
|
|
|
*/
|
|
|
|
#ifndef PRIVL0SERIAL_H
|
|
#define PRIVL0SERIAL_H
|
|
|
|
#include <NET\L0Serial.h>
|
|
|
|
/*
|
|
* universal multiplayer library level 0 header file
|
|
* transport layer: serial PC-windows 95
|
|
*/
|
|
|
|
#if !defined(__L0SERIALPCWIN95_TYPES__)
|
|
#define __L0SERIALPCWIN95_TYPES__
|
|
|
|
#if !defined(ONLY_TYPES)
|
|
#define L0SERIALPCWIN95_UNDEF
|
|
#define ONLY_TYPES
|
|
#endif /* !ONLY_TYPES */
|
|
|
|
/*
|
|
* include here any other include files you need
|
|
*/
|
|
#include <windows.h>
|
|
|
|
#include "L0GlDef.h"
|
|
|
|
|
|
#if defined(L0SERIALPCWIN95_UNDEF)
|
|
#undef ONLY_TYPES
|
|
#undef L0SERIALPCWIN95_UNDEF
|
|
#endif /* !L0SERIALPCWIN95_UNDEF */
|
|
|
|
/*
|
|
* number of bytes the buffer must be able to store between two
|
|
* consecutive calls to the net engine. a 1Kb value enables to call
|
|
* the engine about every 5 frames with a continuous flow of data
|
|
* at 115Kbps.
|
|
*/
|
|
#define C_uwMaxAsyncLength 1024
|
|
|
|
M_BeginDeclareEnumerate(tdeNetL0PCWin95SerialBaudStatus)
|
|
E_Net_L0SerialBaud_Default,
|
|
E_Net_L0SerialBaud_Set,
|
|
E_Net_L0SerialBaud_Ok,
|
|
E_Net_L0SerialBaud_Invalid
|
|
|
|
M_EndDeclareEnumerate(tdeNetL0PCWin95SerialBaudStatus, unsigned char)
|
|
|
|
/* length of send buffer */
|
|
/* should correspond to the amount of data that can be sent between two calls to vNetEngine */
|
|
|
|
#define C_usSerialBufferSize ((unsigned short)300)
|
|
|
|
/*
|
|
* template name for all structures
|
|
*/
|
|
|
|
/*
|
|
* structures of transmission data blocks
|
|
*/
|
|
|
|
/* number of useful bytes in a send slot */
|
|
#define BLOCKSIZE 30
|
|
|
|
/* identifier for invalid slot */
|
|
#define INVALID_SLOT ((unsigned char)-1)
|
|
|
|
/* byte used to mark the beginning of packets */
|
|
#define STARTMARK 0xa3
|
|
|
|
/* structure of the data packets sent over the line */
|
|
|
|
#pragma pack(push)
|
|
#pragma pack(1)
|
|
|
|
typedef struct {
|
|
unsigned char ucStartMark; /* mark the beginning of the packet */
|
|
unsigned short usChecksum; /* redundancy checksum */
|
|
unsigned char ucSeqn; /* sequence number */
|
|
unsigned char ucAckn; /* acknowledgement sequence number */
|
|
unsigned char ucSize; /* number of meaningful bytes in the packet */
|
|
char acData[BLOCKSIZE]; /* data to transmit */
|
|
} tdstPacket;
|
|
|
|
#pragma pack(pop)
|
|
|
|
/* slots used to store packets to send and received packets */
|
|
typedef struct {
|
|
unsigned long ulDate; /* date of send request / date of reception */
|
|
unsigned char ucSeqn; /* sequence number */
|
|
unsigned char ucState; /* state of slot */
|
|
unsigned char ucSize; /* number of meaningful bytes acData */
|
|
char acData[BLOCKSIZE]; /* content of the packet */
|
|
} tdstSlot;
|
|
|
|
/* slot state */
|
|
typedef enum {
|
|
FREE, /* slot not used */
|
|
TO_SEND, /* slot waiting to be sent */
|
|
SENT, /* slot sent not yet acknowledged */
|
|
TIMED_OUT, /* slot sent, not acknowledged, whose timer has timed out */
|
|
ACK, /* slot sent and acknowledged / slot received and acknowledged */
|
|
RECVD /* slot received, not yet acknowledged */
|
|
} tdeState;
|
|
|
|
/* array of slots */
|
|
typedef struct {
|
|
tdstSlot *pstSlot; /* array of slots*/
|
|
int iSize; /* number of elements in the array */
|
|
unsigned long ulTimeout; /* limit to consider when computing the timeout of the slots of the array */
|
|
} tdstWindow;
|
|
|
|
/*
|
|
* link buffer structure
|
|
*/
|
|
|
|
enum { eLinkOk, eLinkFull, eLinkEmpty }; /* error codes */
|
|
|
|
/* size of each link */
|
|
#define LINKSIZE BLOCKSIZE
|
|
|
|
/* link structure */
|
|
typedef struct {
|
|
unsigned char ucSeqN; /* sequence number */
|
|
unsigned char ucSize; /* number of meaningful bytes in acData */
|
|
int iNextIndex; /* index of next link in the list */
|
|
char acData[LINKSIZE]; /* content */
|
|
} tdstLink;
|
|
|
|
/* list of links */
|
|
typedef struct {
|
|
int iNLinks; /* total number of links */
|
|
unsigned char ucAwaitedSeqN; /* lowest sequence number not received yet */
|
|
int iHead; /* index of first link in the list */
|
|
int iFirstSequence; /* number of links in sequence starting from the head of the list */
|
|
int iNFreeLinks; /* number of links not used in the list */
|
|
unsigned long ulFirstSequenceLength; /* total number of meaningful bytes in the first sequence of links */
|
|
tdstLink *pstLink; /* array of links */
|
|
} tdstLinkBuffer;
|
|
|
|
|
|
|
|
/*
|
|
* ring buffer structure
|
|
*/
|
|
|
|
/* number of bytes in the ring */
|
|
#define RINGBUFFERSIZE C_usSerialBufferSize
|
|
|
|
typedef struct {
|
|
char acBuffer[RINGBUFFERSIZE]; /* content of the ring */
|
|
unsigned long ulLowMark; /* index of the first meaningful byte in acBuffer */
|
|
unsigned long ulHighMark; /* index of the last meaningful byte in acBuffer */
|
|
|
|
char *pcBigMsg; /* pointer to a 'big' message */
|
|
unsigned long ulSize; /* length of the big message */
|
|
unsigned long ulBottom; /* index of first byte of pcBigMsg not sent yet */
|
|
} tdstRingBuffer;
|
|
|
|
enum { eRingOk, eRingBigOk, eRingFull, eRingEmpty }; /* error codes */
|
|
|
|
/* low level functions used by both l0serial.c and l0modem.c */
|
|
|
|
void vInitWindow(tdstWindow *, int, unsigned long);
|
|
void vDeleteWindow(tdstWindow *);
|
|
void vInitLinkBuffer(tdstLinkBuffer *, int iNLinks);
|
|
void vDeleteLinkBuffer(tdstLinkBuffer *);
|
|
void vInitRingBuffer(tdstRingBuffer *);
|
|
|
|
void vAddThreadClient(tduwNetChannel);
|
|
void vRemoveThreadClient(tduwNetChannel);
|
|
|
|
/*
|
|
* channel structure
|
|
*/
|
|
|
|
typedef struct tdstL0PCWin95SerialChannel_
|
|
{
|
|
/* internal error status in case of transport layer faults */
|
|
tdeNetTransferStatus eChannelStatus;
|
|
|
|
/* number of bytes received for the currently incoming data */
|
|
unsigned long ulBytesInReadBuffer;
|
|
|
|
/* pointers to I/O buffers */
|
|
tdpPointer pCurrentReceivingBuffer;
|
|
|
|
/* message being received, and associated input point */
|
|
tdpPointer pCurrentReceivedMessage;
|
|
tdpPointer pCurrentMessageIncomingPoint;
|
|
/* number of bytes to read before the message is completely here */
|
|
unsigned long ulBytesToCompleteIncomingMessage;
|
|
|
|
/* is an I/O operation in progress ? */
|
|
unsigned char ubf1ReadInProgress : 1;
|
|
unsigned char ubf1WriteInProgress : 1;
|
|
|
|
/* can this channel be used to send broadcast messages ? */
|
|
unsigned char ubf1IsBroadcast : 1;
|
|
|
|
/* is this slot in use in the protocol's array of channels ? */
|
|
unsigned char ubf1IsSlotInUse : 1;
|
|
|
|
/* is this slot to be considered by the serial layer or by the modem layer ? */
|
|
unsigned char ubf1IsSlotForModem : 1;
|
|
|
|
/* is this slot connected to a remote end ? (useful for modem connections) */
|
|
unsigned char ubf1IsSlotConnected : 1;
|
|
|
|
/* has this slot its final baud rate*/
|
|
tdeNetL0PCWin95SerialBaudStatus eBaudStatus;
|
|
/* Max baud rate*/
|
|
unsigned long ulMaxBaudRate;
|
|
|
|
/*
|
|
* fields related to threaded sending system
|
|
*/
|
|
|
|
/* handle on a file opened on the serial port */
|
|
HANDLE hCom;
|
|
|
|
/* device's status */
|
|
DCB stChannelStatus;
|
|
|
|
tdstWindow stSendWindow; /* array of blocks to send */
|
|
tdstWindow stRecvWindow; /* array of blocks to receive */
|
|
|
|
tdstPacket stPacket; /* buffer for send operation */
|
|
|
|
unsigned char ucSeqn; /* next block sequence number */
|
|
|
|
OVERLAPPED stOverlappedRead;
|
|
|
|
OVERLAPPED stOverlappedWrite;
|
|
|
|
char acReadBuffer[sizeof(tdstPacket)*2]; /* buffer for ReadFile*/
|
|
unsigned long ulReadPos; /* where to store bytes in the previous buffer */
|
|
|
|
tdstRingBuffer stSendBuffer; /* where blocks to send are taken from */
|
|
tdstLinkBuffer stRecvBuffer; /* where incoming blocks are reassembled */
|
|
|
|
HANDLE hBufferEmpty; /* event used to signal when the send buffer is empty */
|
|
HANDLE hSlotsEmpty; /* event used to signal when the send slots have all been sent and acknowledged */
|
|
|
|
CRITICAL_SECTION stSendBufferAccess; /* mutual exclusion on stSendBuffer */
|
|
CRITICAL_SECTION stRecvBufferAccess; /* mutual exclusion on stRecvBuffer */
|
|
CRITICAL_SECTION stChannelAccess; /* mutual exclusion on channel */
|
|
} tdstL0PCWin95SerialChannel;
|
|
|
|
|
|
#endif /* !__L0SERIALPCWIN95_TYPES__ */
|
|
|
|
#if !defined(ONLY_TYPES)
|
|
|
|
#if !defined(__L0SERIALPCWIN95_VARS__)
|
|
#define __L0SERIALPCWIN95_VARS__
|
|
|
|
#undef EXTERN
|
|
#undef extern
|
|
#if !defined(GLOBALS)
|
|
#define EXTERN extern
|
|
#else /* !GLOBALS */
|
|
#define EXTERN
|
|
#endif /* !GLOBALS */
|
|
|
|
/*
|
|
* variables of the above types are here. declarations with initialization
|
|
* are of the form:
|
|
*
|
|
* <type> <variable name>
|
|
* #if defined(GLOBALS)
|
|
* = <initial values>
|
|
* #endif
|
|
* ;
|
|
*/
|
|
|
|
#endif /* !__L0SERIALPCWIN95_VARS__ */
|
|
|
|
#if !defined (__L0SERIALPCWIN95_PROTOS__)
|
|
#define __L0SERIALPCWIN95_PROTOS__
|
|
|
|
/*
|
|
Prototypes :
|
|
*/
|
|
tduwNetChannel uwL0PCWin95SerialStartChannelScan(void);
|
|
tduwNetChannel uwL0PCWin95SerialNextChannel(tduwNetChannel);
|
|
tduwNetChannel uwL0PCWin95SerialStartBroadcastChannelScan(void);
|
|
tduwNetChannel uwL0PCWin95SerialNextBroadcastChannel(tduwNetChannel);
|
|
NetLib_tdeErrorStatus eL0PCWin95SerialReadData(tduwNetChannel*,tdpPointer*);
|
|
NetLib_tdeErrorStatus eL0PCWin95SerialSendData(tduwNetChannel,tdpPointer);
|
|
NetLib_tdeErrorStatus eL0PCWin95SerialQueryChannelStatus(tduwNetChannel);
|
|
void vL0PCWin95SerialNetEngine(void);
|
|
void vL0PCWin95SerialCloseChannel(tduwNetChannel);
|
|
void vL0PCWin95SerialCloseProtocol(void);
|
|
|
|
NetLib_tdeErrorStatus eL0PCWin95SerialPurgeChannel(tduwNetChannel);
|
|
NetLib_tdeErrorStatus eL0PCWin95SerialFlushChannel(tduwNetChannel);
|
|
NetLib_tdeErrorStatus eL0PCWin95SerialResetChannel(tduwNetChannel);
|
|
#endif /* !__L0SERIALPCWIN95_PROTOS__ */
|
|
|
|
#endif /* !ONLY_TYPES */
|
|
|
|
#endif /* PRIVL0SERIAL_H */
|