/*
 ******************************************************************************
 *  Copyright 1995 DeltaLink bv. All Rights Reserved.
 ******************************************************************************
 *
 * File: serial.h
 *
 * This file contains the serial communication definitions under OS/2
 *
 */

#ifndef _serial0_def
#define _serial0_def

#include <critic0.h>

#ifdef NT

  #define NOGDI
  typedef void * SERIAL_HANDLE;
  typedef void * SEMA_HANDLE;
  #ifndef HANDLE

  typedef void * HANDLE;
  #endif  

  #ifndef _DWORD_DEFINED
  typedef unsigned long DWORD;
  #endif
      
  #ifndef _WINBASE_
  typedef struct _OVERLAPPED {
      DWORD   Internal;
      DWORD   InternalHigh;
      DWORD   Offset;
      DWORD   OffsetHigh;
      HANDLE  hEvent;
  } OVERLAPPED, *LPOVERLAPPED;
  #endif

  #define SER_ONESTOPBIT         0
  #define SER_ONE5STOPBIT        1
  #define SER_TWOSTOPBIT         2

  #define SER_NONE               0
  #define SER_EVEN               1
  #define SER_ODD                2
  #define SER_SPACE              3
  #define SER_MARK               4
#endif

#ifdef WIN

typedef HANDLE SERIAL_HANDLE;
#endif

#ifdef OS2

typedef HANDLE SERIAL_HANDLE;
#endif

#ifdef UNIX

typedef HANDLE SERIAL_HANDLE;
#endif

#define SEND_TIMEOUT_CHAR   50         /* serial time in 100th of seconds */
#define SEND_TIMEOUT       100         /* internal time out for sending */

#define SER_SEND_LIMIT     5         /* retries before seinding is aborted */
#define SER_NO_DATA        0
#define SER_DATA           1

#define SER_WAIT_READ      0
#define SER_ABORT_READ     1
#define SER_ABORT_ALLOWED  1

#define NO_ACTION         -1

/*
 * Error codes for serial communicatin errors
 */

#define  SER_GOOD          0      /* Success */

#define  SER_E_OPEN        1      /* Open function returned OS error code */
#define  SER_E_CLOSE       2      /* Close function returned OS error code */
#define  SER_E_GET         3      /* Error retrieving port settings */
#define  SER_E_SET         4      /* Error setting port settings */
#define  SER_E_MEM         5      /* Memory allocation error, rx or tx buffer */
#define  SER_E_READ        6      /* Read error serial device */
#define  SER_E_WRITE       7      /* Write error serial device */
#define  SER_E_RTIMEOUT    8      /* Read timeout */
#define  SER_E_GTIME       9      /* Error reading time out values for device */
#define  SER_E_STIME      10      /* Error setting time out values for device */
#define  SER_E_MODE       11      /* Invalid mode for deivce */
#define  SER_E_BREAK      12      /* Hardware break condition */
#define  SER_E_FRAME      13      /* Framing error */
#define  SER_E_IO         14      /* Hardware IO error */
#define  SER_E_OVERRUN    15      /* Overrun error input buffer */
#define  SER_E_PARITY     16      /* Parity error */
#define  SER_E_RXOVER     17      /* Receive buffer overflow */
#define  SER_E_TXOVER     18      /* Transmit buffer overflow */
#define  SER_E_SEMA_CRE   19      /* Error creating semaphore */
#define  SER_E_SEMA_REL   20      /* Error releasing semaphore */
#define  SER_E_SEMA_CLO   21      /* Error closing semaphore */
#define  SER_E_SEMA_TIM   22      /* Timeout waiting for lock on device */
#define  SER_E_SEMA_UNK   23      /* OS error locking serial device */
#define  SER_E_COMMBREAK  24      /* Error executing break state */
#define  SER_E_PORT       25      /* Port not yet initialised */

/*
 * defines for serial semaphore
 */
#define SER_SEMA_START   0            /* initial value of the semaphore */  
#define SER_SEMA_COUNT   1            /* increment, for release fo seamphore */
#define SER_SEMA_MAX     1            /* maximum count for semaphore */
#define SER_SEMA_TIMEOUT 10000        /* internal time out, waiting for a lock */
#define SER_SEMA_NAME    "Serial_Semaphore_"
#define SER_SEMA_RPURGE  "Serial_Semaphore_Read_"

#define SERIAL_END       5
#define SERIAL_DEBUG_LEN 1024


typedef struct  _comdef {             /* serial communications set up */

  char           name[ 80];            /* Communication port name */
  unsigned long  baudrate;             /* baudrate */
  unsigned char  data;                 /* data bits */
  unsigned char  parity;               /* parity */
  unsigned char  stop;                 /* stop bits */
  unsigned char  rts_cts;              /* Use RTS/CTS */
  unsigned char  dtr_dsr;              /* Use DTR/DSR */
  unsigned char  xon_xoff;             /* Use XON/XOFF */
  unsigned char  xon;                  /* XON character */
  unsigned char  xoff;                 /* XOFF character */

  unsigned short read_time;            /* time out value [milli seconds] */
  unsigned short read_multi;           /* time out for one char [milli seconds] */
  unsigned short read_interval;        /* interval time [milli seconds] */

} COMDEF;


typedef struct  _comport {            /* serial communications device */

  SERIAL_HANDLE  handle;              /* comport handle recieved form OS */
  int            action;              /* purge release specifier */
  int            block;               /* block purging */
  
  SEMA_HANDLE    sema;                /* semaphore for locking the serial device */
  SEMA_HANDLE    r_purge;             /* semaphore for purging the read */
  OVERLAPPED     O_Lap;               /* Overlapped structure */

  COMDEF         def;                 /* serial communications set up */

  unsigned char  *rx_buffer;          /* receive buffer */
  unsigned       rx_length;           /* atual length receive buffer */
  unsigned       rx_size;             /* atual size receive buffer */

  unsigned char  *tx_buffer;          /* transmit buffer */
  unsigned       tx_length;           /* atual length transmit buffer */
  unsigned       tx_size;             /* atual size send buffer */

  void           *user;               /* user data pointer */

  char           debug[ SERIAL_DEBUG_LEN];
  int            debug_len;
  unsigned char  debug_end[ SERIAL_END];
  unsigned char  debug_endlen;
} COMPORT;


extern  int    Serial_Debug;
extern  int    Serial_ASCII;
extern  int    Serial_Debug_Len;
extern  long   Serial_Sema_Timeout;
extern  FILE   *Serial_File;

/* macros */
#define Serial_Set_Name( c, n)          ( strcpy(((COMPORT *)c)->def.name, (char *)n))
#define Serial_Get_Name( c)             ( ((COMPORT *)c)->def.name)
#define Serial_Set_Baudrate( c, l)      ( ((COMPORT *)c)->def.baudrate = (unsigned long)l)
#define Serial_Set_Stopbits( c, l)      ( ((COMPORT *)c)->def.stop = (unsigned char)l)
#define Serial_Set_Databits( c, l)      ( ((COMPORT *)c)->def.data = (unsigned char)l)
#define Serial_Set_Parity( c, l)        ( ((COMPORT *)c)->def.parity = (unsigned char)l)
#define Serial_Set_RTS_CTS( c, l)       ( ((COMPORT *)c)->def.rts_cts = (unsigned char)l)
#define Serial_Set_DTR_DSR( c, l)       ( ((COMPORT *)c)->def.dtr_dsr = (unsigned char)l)
#define Serial_Set_XON_XOFF( c, l)      ( ((COMPORT *)c)->def.xon_xoff = (unsigned char)l)
#define Serial_Set_XON( c, l)           ( ((COMPORT *)c)->def.xon = (unsigned char)l)
#define Serial_Set_XOFF( c, l)          ( ((COMPORT *)c)->def.xoff = (unsigned char)l)
#define Serial_Set_Multi_Time( c, l)    ( ((COMPORT *)c)->def.read_multi = (short)l)
#define Serial_Set_Out_Time( c, l)      ( ((COMPORT *)c)->def.read_time = (short)l)
#define Serial_Set_Interval_Time( c, l) ( ((COMPORT *)c)->def.read_interval = (short)l)

#define Serial_Set_RX_Length( c, l)     ( ((COMPORT *)c)->rx_length = (unsigned)l)
#define Serial_Set_TX_Length( c, l)     ( ((COMPORT *)c)->tx_length = (unsigned)l)

#define Serial_Set_UPointer( c, p)      ( ((COMPORT *)c)->user = (void *)p)
#define Serial_Get_UPointer( c)         ( ((COMPORT *)c)->user)
#define Serial_Reset_UPointer( c)       ( ((COMPORT *)c)->user = NULL)

#define Serial_Reset_Handle( c)         ( ((COMPORT *)c)->handle = NULL)
#define Serial_Reset_Semaphore( c)      ( ((COMPORT *)c)->sema = NULL)
#define Serial_Reset_Read_Abort( c)     ( ((COMPORT *)c)->r_purge = NULL)

#define Serial_Block_Purge( c)          ( ((COMPORT *)c)->block = 1) 
#define Serial_Release_Purge( c)        ( ((COMPORT *)c)->block = 0) 

#define Serial_Initialised( c)          ( ((COMPORT *)c)->handle != NULL) 
#define Serial_Get_Block( c)            ( ((COMPORT *)c)->block) 

#define Serial_Debug_On()               ( Serial_Debug = 1)
#define Serial_Debug_Off()              ( Serial_Debug = 0)
#define Serial_Debug_File( f)           ( Serial_File = f)

#define Serial_Set_Sema_Timeout(t)     ( Serial_Sema_Timeout = t)


/* prototypes of serial functions */

int  Serial_Init         ( COMPORT *);
int  Serial_Exit         ( COMPORT *);

int  Serial_TX_Clear     ( COMPORT *);
int  Serial_RX_Clear     ( COMPORT *);

int  Serial_TX_Purge     ( COMPORT *);
int  Serial_RX_Purge     ( COMPORT *);

int  Serial_TX           ( COMPORT *, unsigned short, char *);
int  Serial_RX           ( COMPORT *, unsigned short *);

int  Serial_Set_Packet   ( COMPORT *, unsigned short, char *);
int  Serial_Get_Packet   ( COMPORT *, unsigned short, unsigned short *, char *);

int  Serial_CommBreak    ( COMPORT *, unsigned short);

int  Serial_TimeOut      ( COMPORT *, long);
int  Serial_Lock         ( COMPORT *, int, int);
int  Serial_UnLock       ( COMPORT *);

void Serial_Set_Debug    ( COMPORT *, unsigned char);
void Serial_Debug_ASCII  ( int);
#endif
