2054 lines
60 KiB
C
2054 lines
60 KiB
C
/*******************************************************************************
|
||
* Copyright (c) 1997 Gemplus developpement
|
||
*
|
||
* Name : GNTSER.C (Gemplus Win NT SERial port management)
|
||
*
|
||
* Description : This module holds the functions needed for a communication on a
|
||
* serial line.
|
||
*
|
||
* Compiler : Microsoft DDK for Windows NT
|
||
*
|
||
* Host : IBM PC and compatible machines under Windows NT4
|
||
*
|
||
* Release : 1.00.002
|
||
*
|
||
* Last Modif : 01/12/97: V1.00.002 (TFB)
|
||
* - Change IOCTL_SMARTCARD_WRITE and IOCTL_SMARTCARD_READ in
|
||
* respectively GTSER_IOCTL_WRITE and GTSER_IOCTL_READ.
|
||
* 07/07/97: V1.00.001 (GPZ)
|
||
* - Start of development.
|
||
*
|
||
********************************************************************************
|
||
*
|
||
* Warning :
|
||
*
|
||
* Remark :
|
||
*
|
||
*******************************************************************************/
|
||
/*------------------------------------------------------------------------------
|
||
Include section:
|
||
- stdio.h: standards definitons.
|
||
- ntddk.h: DDK Windows NT general definitons.
|
||
- ntddser.h: DDK Windows NT serial management definitons.
|
||
------------------------------------------------------------------------------*/
|
||
#include <stdio.h>
|
||
#include <ntddk.h>
|
||
#include <ntddser.h>
|
||
|
||
/*------------------------------------------------------------------------------
|
||
- smclib.h: smart card library definitions.
|
||
------------------------------------------------------------------------------*/
|
||
#define SMARTCARD_POOL_TAG 'cGCS'
|
||
#include <smclib.h>
|
||
|
||
/*------------------------------------------------------------------------------
|
||
- gemcore.h: Gemplus general definitions for the GemCore smart card reader.
|
||
- gntser.h is used to define general macros and values for serial management.
|
||
- gntscr09.h: public interface definition for the reader.
|
||
- gioctl09.h: public interface definition for IOCTL functions.
|
||
------------------------------------------------------------------------------*/
|
||
#include "gemcore.h"
|
||
#include "gntscr09.h"
|
||
#include "gioctl09.h"
|
||
#include "gntser.h"
|
||
|
||
|
||
/*------------------------------------------------------------------------------
|
||
Type section:
|
||
TPORT_CONFIG:
|
||
- WaitRelease holds the timeout for the release of the semaphore.
|
||
- Counter holds the number of opened session. If its value is 0, the port is
|
||
closed.
|
||
- Error holds Rx over state.
|
||
- TimeOut holds the character level time out.
|
||
- TxSize memorises the transmit buffer size.
|
||
- RxSize memorises the reception buffer size.
|
||
- InitRts memorises the initial Rts signal state.
|
||
- InitDtr memorises the initial Dtr signal state.
|
||
- Access is TRUE if the access is free, else FALSE if the channel access
|
||
is locked.
|
||
- pSerialPortDevice is a pointer on the serial Device Object.
|
||
- pSerialFileObject is a pointer on the serial FileObject. Is needed to
|
||
close the connection to the serial port.
|
||
- GTSER_IOCTL_WRITE io control to write a buffer on a serial port.
|
||
- GTSER_IOCTL_READ io control to read a buffer on a serial port.
|
||
------------------------------------------------------------------------------*/
|
||
typedef struct
|
||
{
|
||
PIRP Irp;
|
||
KEVENT Event;
|
||
IO_STATUS_BLOCK IoStatus;
|
||
KDPC Dpc;
|
||
} CARD_STATUS;
|
||
|
||
typedef struct
|
||
{
|
||
DWORD WaitRelease;
|
||
WORD16 Counter;
|
||
INT16 Error;
|
||
WORD16 TimeOut;
|
||
WORD16 TxSize;
|
||
WORD16 RxSize;
|
||
WORD16 InitRts;
|
||
WORD16 InitDtr;
|
||
INT32 Access;
|
||
PDEVICE_OBJECT pSerialPortDevice;
|
||
PFILE_OBJECT pSerialFileObject;
|
||
PKMUTEX pExchangeMutex;
|
||
} TPORT_CONFIG;
|
||
|
||
#define GTSER_DEF_WAIT_RELEASE 2000
|
||
#define GTSER_IOCTL_WRITE SCARD_CTL_CODE(1001)
|
||
#define GTSER_IOCTL_READ SCARD_CTL_CODE(1000)
|
||
|
||
/*------------------------------------------------------------------------------
|
||
Macro section:
|
||
- CTRL_BAUD_RATE control the baud rate parameter.
|
||
- WORD_LEN, PARITY and STOP retreive the configuration values to pass to
|
||
Windows to configure the port.
|
||
------------------------------------------------------------------------------*/
|
||
#define WORD_LEN(x) (BYTE)(((x) & 0x03) + 5)
|
||
#define PARITY(x) (BYTE)(parity[((BYTE)(x) >> 3) & 3])
|
||
#define STOP(x) (BYTE)(stop[((x) >> 2) & 1])
|
||
|
||
/*------------------------------------------------------------------------------
|
||
Global variable section:
|
||
- port_config is an array of TPORT_CONFIG which memorises the port
|
||
configuration at each time.
|
||
------------------------------------------------------------------------------*/
|
||
TPORT_CONFIG
|
||
port_config[HGTSER_MAX_PORT] =
|
||
{
|
||
{0,0,0,0,0,0,0,0,TRUE,NULL,NULL},
|
||
{0,0,0,0,0,0,0,0,TRUE,NULL,NULL},
|
||
{0,0,0,0,0,0,0,0,TRUE,NULL,NULL},
|
||
{0,0,0,0,0,0,0,0,TRUE,NULL,NULL}
|
||
};
|
||
|
||
static WORD16
|
||
parity[] = {NO_PARITY,
|
||
ODD_PARITY,
|
||
NO_PARITY,
|
||
EVEN_PARITY};
|
||
static WORD16
|
||
stop[] = {STOP_BIT_1,
|
||
STOP_BITS_2};
|
||
|
||
/*------------------------------------------------------------------------------
|
||
Local function definition section:
|
||
------------------------------------------------------------------------------*/
|
||
static NTSTATUS GDDKNT_SetupComm
|
||
(
|
||
const INT16 Handle,
|
||
const ULONG InSize,
|
||
const ULONG OutSize
|
||
);
|
||
static NTSTATUS GDDKNT_GetCommStatus
|
||
(
|
||
const INT16 Handle,
|
||
SERIAL_STATUS *SerialStatus
|
||
);
|
||
static NTSTATUS GDDKNT_ResetComm
|
||
(
|
||
const INT16 Handle
|
||
);
|
||
static NTSTATUS GDDKNT_PurgeComm
|
||
(
|
||
const INT16 Handle,
|
||
const ULONG Select
|
||
);
|
||
/*******************************************************************************
|
||
* INT16 G_SerPortOpen
|
||
* (
|
||
* const TGTSER_PORT *Param
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine opens a serial port and initializes it according to the
|
||
* parameters found in Param.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* Param holds the following parameters:
|
||
* - Port indicates the selected port: G_COM1 (1), G_COM2 (2), G_COM3 (3) or
|
||
* G_COM4 (4).
|
||
* - BaudRate is used to set port baud rate: 110, 150, 300, 600, 1200, 2400,
|
||
* 4800, 9600, 19200, 38400 or 57600.
|
||
* A value greater than 57600 is reduced to 57600 !
|
||
* - Mode gathers
|
||
* * word size WORD_5 (0), WORD_6 (1), WORD_7 (2) or WORD_8 (3),
|
||
* * stop bit number STOP_BIT_1 (0) or STOP_BIT_2 (4) and
|
||
* * parity NO_PARITY (0), ODD_PARITY (8) or EVEN_PARITY (24).
|
||
* - TimeOut indicates the time out value, in milli-seconds, at character level.
|
||
* - TxSize is the transmit buffer size, in bytes.
|
||
* - RxSize is the reception buffer size, in mbytes.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is OK:
|
||
* - a handle on the port channel (>= 0).
|
||
* If an error condition is raised:
|
||
* - GE_HOST_PORT_ABS (- 401) if port is not found on host or is locked by
|
||
* another device.
|
||
* - GE_HOST_PORT_OPEN (- 411) if the port is already opened.
|
||
* - GE_HOST_MEMORY (- 420) if a memory allocation fails.
|
||
* - GE_HOST_PARAMETERS(- 450) if one of the given parameters is out of the
|
||
* allowed range or is not supported by hardware.
|
||
* - GE_UNKNOWN_PB (-1000) if an unexpected problem is encountered.
|
||
*
|
||
Extern var :
|
||
-------------
|
||
Nothing.
|
||
|
||
Global var :
|
||
-------------
|
||
com_name gives the DOS level port name
|
||
device_ctrl is used to hold the string requred by BuildCommDCB.
|
||
parity gives the DOS level parity name
|
||
port_config is set with the selected configuration.
|
||
|
||
*******************************************************************************/
|
||
INT16 G_SerPortOpen(const TGTSER_PORT *Param)
|
||
{
|
||
/*------------------------------------------------------------------------------
|
||
Local variables:
|
||
- Handle holds the handle associated to the given port. It is calculated
|
||
by the following formula Port - 1.
|
||
- response holds the called function responses.
|
||
- current_dcb is used to set parameters in the device control block.
|
||
------------------------------------------------------------------------------*/
|
||
INT16
|
||
Handle = (INT16)(Param->Port - 1);
|
||
NTSTATUS
|
||
status;
|
||
PSMARTCARD_EXTENSION
|
||
SmartcardExtension;
|
||
SERIAL_READER_CONFIG
|
||
SerialConfig;
|
||
PREADER_EXTENSION
|
||
pReaderExtension;
|
||
|
||
/*------------------------------------------------------------------------------
|
||
Controls the given parameters:
|
||
<= Test the port number (G_COM1 .. G_COM4): GE_HOST_PARAMETERS
|
||
------------------------------------------------------------------------------*/
|
||
if ((Handle < 0) || (Handle >= HGTSER_MAX_PORT))
|
||
{
|
||
return (GE_HOST_PARAMETERS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Test the port access state : GE_HOST_PORT_LOCKED
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Handle].Access == FALSE)
|
||
{
|
||
return (GE_HOST_PORT_LOCKED);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Test the port state (Counter field null): GE_HOST_PORT_OPEN
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Handle].Counter != 0)
|
||
{
|
||
return (GE_HOST_PORT_OPEN);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Retrieve the SmartcardExtension structure of the current device.
|
||
------------------------------------------------------------------------------*/
|
||
SmartcardExtension = (PSMARTCARD_EXTENSION)(Param->pSmartcardExtension);
|
||
pReaderExtension = SmartcardExtension->ReaderExtension;
|
||
port_config[Handle].pSerialPortDevice = pReaderExtension->ConnectedSerialPort;
|
||
port_config[Handle].pSerialFileObject = pReaderExtension->SerialFileObject;
|
||
port_config[Handle].pExchangeMutex = &pReaderExtension->ExchangeMutex;
|
||
|
||
/*------------------------------------------------------------------------------
|
||
The current port state is read and stored in current_dcb structure by
|
||
calling GetCommState function.
|
||
If the reading is possible (GetCommState return 0)
|
||
Then
|
||
The current_dcb structure is updated with the given parameter (baud
|
||
rate, ByteSize, Parity, StopBits).
|
||
The modified state is written by calling SetCommState.
|
||
------------------------------------------------------------------------------*/
|
||
status = GDDKNT_GetCommState(Handle,&SerialConfig);
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
status = GDDKNT_SetupComm(Handle,4096L,4096L);
|
||
/*------------------------------------------------------------------------------
|
||
Set the serial port communication parameters
|
||
------------------------------------------------------------------------------*/
|
||
SerialConfig.BaudRate.BaudRate = Param->BaudRate;
|
||
SerialConfig.LineControl.WordLength = WORD_LEN(Param->Mode);
|
||
SerialConfig.LineControl.Parity = PARITY(Param->Mode);
|
||
SerialConfig.LineControl.StopBits = STOP(Param->Mode);
|
||
SerialConfig.WaitMask = SERIAL_EV_RXCHAR;
|
||
/*------------------------------------------------------------------------------
|
||
Set timeouts
|
||
------------------------------------------------------------------------------*/
|
||
SerialConfig.Timeouts.ReadIntervalTimeout = 1000;
|
||
SerialConfig.Timeouts.ReadTotalTimeoutConstant = 5000;
|
||
SerialConfig.Timeouts.ReadTotalTimeoutMultiplier = 50;
|
||
/*------------------------------------------------------------------------------
|
||
Set special characters
|
||
------------------------------------------------------------------------------*/
|
||
SerialConfig.SerialChars.ErrorChar = 0;
|
||
SerialConfig.SerialChars.EofChar = 0;
|
||
SerialConfig.SerialChars.EventChar = 0;
|
||
SerialConfig.SerialChars.XonChar = 0;
|
||
SerialConfig.SerialChars.XoffChar = 0;
|
||
SerialConfig.SerialChars.BreakChar = 0xFF;
|
||
/*------------------------------------------------------------------------------
|
||
Set handflow
|
||
------------------------------------------------------------------------------*/
|
||
SerialConfig.HandFlow.XonLimit = 0;
|
||
SerialConfig.HandFlow.XoffLimit = 0;
|
||
SerialConfig.HandFlow.FlowReplace = SERIAL_XOFF_CONTINUE ;
|
||
SerialConfig.HandFlow.ControlHandShake = 0;
|
||
status = GDDKNT_SetCommState(Handle,&SerialConfig);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Else
|
||
response is set with IE_DEFAULT error value.
|
||
------------------------------------------------------------------------------*/
|
||
else
|
||
{
|
||
return (GE_HOST_PARAMETERS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Treats system error codes:
|
||
If an error has occured (response < 0)
|
||
Then
|
||
switch response value:
|
||
IE_OPEN, IE_BAD_ID and IE_HARDWARE
|
||
<= GE_HOST_PORT_ABS
|
||
IE_MEMORY
|
||
<= GE_HOST_MEMORY
|
||
IE_BAUDRATE, IE_BYTESIZE, IE_DEFAULT
|
||
<= GE_HOST_PARAMETERS
|
||
default
|
||
<= GE_UNKNOWN_PB
|
||
------------------------------------------------------------------------------*/
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
switch (status)
|
||
{
|
||
case STATUS_INSUFFICIENT_RESOURCES:
|
||
{
|
||
return (GE_HOST_MEMORY);
|
||
}
|
||
case STATUS_BUFFER_TOO_SMALL:
|
||
{
|
||
return (GE_HOST_PARAMETERS);
|
||
}
|
||
default :
|
||
{
|
||
return (GE_UNKNOWN_PB);
|
||
}
|
||
}
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Memorises the given parameters in port_config structure.
|
||
Counter, Error, TimeOut, TxSize and RxSize fields are updated.
|
||
------------------------------------------------------------------------------*/
|
||
port_config[Handle].Counter = 1;
|
||
port_config[Handle].Error = 0;
|
||
port_config[Handle].TimeOut = Param->TimeOut;
|
||
port_config[Handle].TxSize = Param->TxSize;
|
||
port_config[Handle].RxSize = Param->RxSize;
|
||
/*------------------------------------------------------------------------------
|
||
<= the handle value.
|
||
------------------------------------------------------------------------------*/
|
||
return (Handle);
|
||
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* INT16 G_SerPortAddUser
|
||
* (
|
||
* const INT16 Port
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* Add a new user on a port. This function return the handle of a previously
|
||
* opened port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* When this function is successful, it is mandatory to call G_SerPortClose
|
||
* to decrement the user number.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Port indicates the selected port: G_COM2 (1), G_COM2 (2), G_COM3 (3) or
|
||
* G_COM4 (4).
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is OK:
|
||
* a handle on the port channel (>= 0)
|
||
* If an error condition is raised:
|
||
* - GE_HOST_PORT_CLOSE (-412) if port is closed.
|
||
* - GE_HOST_RESOURCES (-430) if too many users hold the port.
|
||
* - GE_HOST_PARAMETERS (-450) if the given handle is out of the allowed range.
|
||
*
|
||
Extern var :
|
||
-------------
|
||
Nothing.
|
||
|
||
Global var :
|
||
-------------
|
||
port_config memorises the port configuration.
|
||
|
||
*******************************************************************************/
|
||
INT16 G_SerPortAddUser
|
||
(
|
||
const INT16 Port
|
||
)
|
||
{
|
||
/*------------------------------------------------------------------------------
|
||
Controls the given parameters:
|
||
<= Test the port handle (0 <= Handle < HGTSER_MAX_PORT): GE_HOST_PARAMETERS.
|
||
------------------------------------------------------------------------------*/
|
||
if ((Port < G_COM1) || (Port > G_COM4))
|
||
{
|
||
return (GE_HOST_PARAMETERS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Test the port state (Counter > 0): GE_HOST_PORT_CLOSE.
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Port - 1].Counter == 0)
|
||
{
|
||
return (GE_HOST_PORT_CLOSE);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Test port_config.Counter [!= 65535): GE_HOST_RESOURCES
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Port - 1].Counter == 65535lu)
|
||
{
|
||
return (GE_HOST_RESOURCES);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Increments the port_config.Counter.
|
||
------------------------------------------------------------------------------*/
|
||
port_config[Port - 1].Counter += 1;
|
||
|
||
/*------------------------------------------------------------------------------
|
||
<= Port number.
|
||
------------------------------------------------------------------------------*/
|
||
return (Port - 1);
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* INT16 G_SerPortClose
|
||
* (
|
||
* const INT16 Handle
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine closes a previously opened serial port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* When port is shared, the close will be effective only when all clients will
|
||
* have closed the port.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Handle holds the port handle.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is OK:
|
||
* - G_OK ( 0).
|
||
* If an error condition is raised:
|
||
* - GE_HOST_PORT_CLOSE (-412) if the selected port is already closed.
|
||
* - GE_HOST_PARAMETERS (-450) if the given handle is out of the allowed range.
|
||
*
|
||
Extern var :
|
||
-------------
|
||
Nothing.
|
||
|
||
Global var :
|
||
-------------
|
||
port_config is updated to closed state.
|
||
|
||
*******************************************************************************/
|
||
INT16 G_SerPortClose (const INT16 Handle)
|
||
{
|
||
/*------------------------------------------------------------------------------
|
||
Local variables:
|
||
- response holds the called function responses.
|
||
------------------------------------------------------------------------------*/
|
||
INT16
|
||
response;
|
||
|
||
/*------------------------------------------------------------------------------
|
||
Controls the given parameters:
|
||
<= Test the port handle (0 <= Handle < HGTSER_MAX_PORT): GE_HOST_PARAMETERS.
|
||
------------------------------------------------------------------------------*/
|
||
if ((Handle < 0) || (Handle >= HGTSER_MAX_PORT))
|
||
{
|
||
return (GE_HOST_PORT_ABS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Test the port state (Counter > 0): GE_HOST_PORT_CLOSE.
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Handle].Counter == 0)
|
||
{
|
||
return (GE_HOST_PORT_CLOSE);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Decrements the port_config.Counter field.
|
||
If is the last connection on the port
|
||
Then
|
||
Set the access state to TRUE.
|
||
------------------------------------------------------------------------------*/
|
||
port_config[Handle].Counter -= 1;
|
||
if (port_config[Handle].Counter == 0)
|
||
{
|
||
port_config[Handle].Access = TRUE;
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Closes really the port for the last user:
|
||
If port_config.Counter = 0
|
||
Then
|
||
The queues are flushed by calling PurgeComm function.
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Handle].Counter == 0)
|
||
{
|
||
GDDKNT_PurgeComm(Handle,SERIAL_PURGE_TXCLEAR | SERIAL_PURGE_TXABORT);
|
||
}
|
||
else
|
||
{
|
||
response = G_OK;
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Last Response
|
||
------------------------------------------------------------------------------*/
|
||
return (response);
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* INT16 G_SerPortWrite
|
||
* (
|
||
* const INT16 Handle,
|
||
* const WORD16 Length,
|
||
* const BYTE Buffer[]
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine writes bytes on a previously opened serial port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* WARNING: Application must verify that it remains enough place to send all the
|
||
* bytes.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Handle holds the port handle.
|
||
* - Length holds the number of bytes to write.
|
||
* - Buffer holds the bytes to write.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is OK:
|
||
* - G_OK ( 0).
|
||
* If an error condition is raised:
|
||
* - GE_HI_LEN (-311) if there is not enough available space is in Tx
|
||
* queue.
|
||
* - GE_HOST_PORT_BREAK (-404) if the bytes cannot be sent.
|
||
* - GE_HOST_PORT_CLOSE (-412) if port is closed.
|
||
* - GE_HOST_PARAMETERS (-450) if the given handle is out of the allowed range.
|
||
*
|
||
Extern var :
|
||
-------------
|
||
Nothing.
|
||
|
||
Global var :
|
||
-------------
|
||
port_config memorises the port configuration.
|
||
|
||
*******************************************************************************/
|
||
INT16 G_SerPortWrite
|
||
(
|
||
const INT16 Handle,
|
||
const WORD16 Length,
|
||
const BYTE Buffer[]
|
||
)
|
||
{
|
||
/*------------------------------------------------------------------------------
|
||
Local variables:
|
||
------------------------------------------------------------------------------*/
|
||
NTSTATUS
|
||
status;
|
||
SERIAL_STATUS
|
||
SerialStatus;
|
||
WORD16
|
||
LengthOut;
|
||
|
||
ASSERT(Buffer != NULL);
|
||
/*------------------------------------------------------------------------------
|
||
Controls the given parameters:
|
||
<= Test the port handle (0 <= Handle < HGTSER_MAX_PORT): GE_HOST_PARAMETERS.
|
||
------------------------------------------------------------------------------*/
|
||
if ((Handle < 0) || (Handle >= HGTSER_MAX_PORT))
|
||
{
|
||
return (GE_HOST_PORT_ABS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Test the port state (Counter > 0): GE_HOST_PORT_CLOSE.
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Handle].Counter == 0)
|
||
{
|
||
return (GE_HOST_PORT_CLOSE);
|
||
}
|
||
|
||
/*------------------------------------------------------------------------------
|
||
Control if the write can be made in one time:
|
||
- The windows port status is read by calling GetCommError to know how many
|
||
bytes remain in Tx queue (port_config.Error field is updated if needed).
|
||
- If the write length is greater than the available space in Tx queue
|
||
Then
|
||
<= GE_HI_LEN
|
||
------------------------------------------------------------------------------*/
|
||
GDDKNT_GetCommStatus(Handle,&SerialStatus);
|
||
port_config[Handle].Error |= (WORD16)(SERIAL_ERROR_OVERRUN & SerialStatus.Errors);
|
||
if (Length > ( port_config[Handle].TxSize - SerialStatus.AmountInOutQueue))
|
||
{
|
||
return (GE_HI_LEN);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Writes the given byte in Tx queue by calling the WriteComm function.
|
||
If an error occurs during this operation
|
||
Then
|
||
The ClearCommError function is called to unblock the port
|
||
(port_config.Error field is updated if needed).
|
||
<= GE_HOST_PORT_BREAK
|
||
------------------------------------------------------------------------------*/
|
||
LengthOut = 0;
|
||
status = GDDKNT_SerPortIoRequest(Handle,
|
||
GTSER_IOCTL_WRITE,
|
||
500UL,
|
||
Length,
|
||
Buffer,
|
||
&LengthOut,
|
||
NULL);
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
GDDKNT_GetCommStatus(Handle,&SerialStatus);
|
||
port_config[Handle].Error |= (WORD16)(SERIAL_ERROR_OVERRUN & SerialStatus.Errors);
|
||
GDDKNT_ResetComm(Handle);
|
||
return (GE_HOST_PORT_BREAK);
|
||
}
|
||
return (G_OK);
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* INT16 G_SerPortRead
|
||
* (
|
||
* const INT16 Handle,
|
||
* WORD16 *Length,
|
||
* BYTE Buffer[]
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine reads bytes on a previously opened serial port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* It ends when required length = read length or when a character level timeout
|
||
* is detected.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Handle holds the port handle.
|
||
* - Length holds the number of bytes to read.
|
||
* - Buffer is a free area of, at least, Length bytes.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* - Length holds the real number of read bytes.
|
||
* - Buffer holds the read bytes.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is OK:
|
||
* - G_OK ( 0).
|
||
* If an error condition is raised:
|
||
* - GE_IFD_MUTE (-201) if a character timeout is detected.
|
||
* - GE_HI_COMM (-300) if a communication error occurs.
|
||
* - GE_HI_PARITY (-301) if a parity error is encountered.
|
||
* - GE_HI_PROTOCOL (-310) if a frame error is encountered.
|
||
* - GE_HOST_PORT_CLOSE (-412) if port is closed.
|
||
* - GE_HOST_PARAMETERS (-450) if the given handle is out of the allowed range.
|
||
*
|
||
Extern var :
|
||
-------------
|
||
Nothing.
|
||
|
||
Global var :
|
||
-------------
|
||
port_config memorises the port configuration.
|
||
|
||
*******************************************************************************/
|
||
INT16 G_SerPortRead
|
||
(
|
||
const INT16 Handle,
|
||
WORD16 *Length,
|
||
BYTE Buffer[]
|
||
)
|
||
{
|
||
/*------------------------------------------------------------------------------
|
||
Local variables:
|
||
- end_tick is used to manage timeout.
|
||
- ptr point on the next position in buffer. The HUGE modifier is used to avoid
|
||
wraparound.
|
||
- status will hold Windows port status.
|
||
- nb_of_read_byte memorises the number of read bytes.
|
||
- byte_to read holds the number of bytes to read in one loop.
|
||
- read_byte holds the number of bytes which have been really read in a loop.
|
||
- response holds called function responses.
|
||
------------------------------------------------------------------------------*/
|
||
NTSTATUS
|
||
status;
|
||
WORD32
|
||
end_tick;
|
||
INT16
|
||
response,i;
|
||
DWORD
|
||
error;
|
||
TIME
|
||
CurrentTime;
|
||
SERIAL_STATUS
|
||
SerialStatus;
|
||
|
||
ASSERT(Buffer != NULL);
|
||
/*------------------------------------------------------------------------------
|
||
Controls the given parameters:
|
||
<= Test the port Handle (0 <= Handle < HGTSER_MAX_PORT): GE_HOST_PARAMETERS.
|
||
------------------------------------------------------------------------------*/
|
||
if ((Handle < 0) || (Handle >= HGTSER_MAX_PORT))
|
||
{
|
||
return (GE_HOST_PORT_ABS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Test the port state (Counter > 0): GE_HOST_PORT_CLOSE.
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Handle].Counter == 0)
|
||
{
|
||
*Length = 0;
|
||
return (GE_HOST_PORT_CLOSE);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Try to read the bytes.
|
||
------------------------------------------------------------------------------*/
|
||
status = GDDKNT_SerPortIoRequest(Handle,
|
||
GTSER_IOCTL_READ,
|
||
port_config[Handle].TimeOut,
|
||
0,
|
||
NULL,
|
||
Length,
|
||
Buffer);
|
||
/*------------------------------------------------------------------------------
|
||
If an error occurs (response == FALSE)
|
||
Then
|
||
VCOMM_GetLastError
|
||
According to the detected error, a status is returned:
|
||
CE_RXPARITY
|
||
<= GE_HI_PARITY
|
||
CE_FRAME
|
||
<= GE_HI_PROTOCOL
|
||
other cases
|
||
<= GE_HI_COMM
|
||
------------------------------------------------------------------------------*/
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
GDDKNT_GetCommStatus(Handle,&SerialStatus);
|
||
error = (WORD16)(SerialStatus.Errors);
|
||
if (error & SERIAL_ERROR_PARITY)
|
||
{
|
||
return (GE_HI_PARITY);
|
||
}
|
||
else if (error & SERIAL_ERROR_FRAMING)
|
||
{
|
||
return (GE_HI_PROTOCOL);
|
||
}
|
||
else
|
||
{
|
||
return (GE_HI_COMM);
|
||
}
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Else
|
||
Then
|
||
Length is updated with the number of read byte.
|
||
<= GE_IFD_MUTE
|
||
------------------------------------------------------------------------------*/
|
||
else
|
||
{
|
||
if (*Length == 0)
|
||
{
|
||
return (GE_IFD_MUTE);
|
||
}
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= G_OK
|
||
------------------------------------------------------------------------------*/
|
||
return (G_OK);
|
||
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* INT16 G_SerPortFlush
|
||
* (
|
||
* const INT16 Handle,
|
||
* const WORD16 Select
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This function clears Tx and Rx buffers.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* When RX_QUEUE is selected, the RX_OVER flag is reseted.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Handle holds the port handle.
|
||
* - Select holds the buffers to clear:
|
||
* HGTSER_TX_QUEUE
|
||
* HGTSER_RX_QUEUE
|
||
* HGTSER_TX_QUEUE | HGTSER_RX_QUEUE
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is OK:
|
||
* - G_OK ( 0).
|
||
* If an error condition is raised:
|
||
* - GE_HOST_PORT_CLOSE (-412) if port is closed.
|
||
* - GE_HOST_PARAMETERS (-450) if the given handle is out of the allowed range.
|
||
* - GE_HOST_PORT_BREAK (-404) if the port cannot be flush.
|
||
*
|
||
Extern var :
|
||
-------------
|
||
Nothing.
|
||
|
||
Global var :
|
||
-------------
|
||
port_config memorises the port configuration.
|
||
|
||
*******************************************************************************/
|
||
INT16 G_SerPortFlush
|
||
(
|
||
const INT16 Handle,
|
||
const WORD16 Select
|
||
)
|
||
{
|
||
NTSTATUS
|
||
status;
|
||
|
||
/*------------------------------------------------------------------------------
|
||
Controls the given parameters:
|
||
<= Test the port handle (0 <= Handle < HGTSER_MAX_PORT): GE_HOST_PARAMETERS.
|
||
------------------------------------------------------------------------------*/
|
||
if ((Handle < 0) || (Handle >= HGTSER_MAX_PORT))
|
||
{
|
||
return (GE_HOST_PORT_ABS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Test the port state (Counter > 0): GE_HOST_PORT_CLOSE.
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Handle].Counter == 0)
|
||
{
|
||
return (GE_HOST_PORT_CLOSE);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Clears the selected queues:
|
||
If HGTSER_TX_QUEUE is selected
|
||
Then
|
||
Flushes the Tx queue by calling FlushComm.
|
||
------------------------------------------------------------------------------*/
|
||
if (Select & HGTSER_TX_QUEUE)
|
||
{
|
||
status = GDDKNT_PurgeComm(Handle,SERIAL_PURGE_TXCLEAR);
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
return (GE_HOST_PORT_BREAK);
|
||
}
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
If HGTSER_RX_QUEUE is selected
|
||
Then
|
||
Flushes the Rx queue by calling FlushComm.
|
||
Reset port_config.error field.
|
||
------------------------------------------------------------------------------*/
|
||
if (Select & HGTSER_RX_QUEUE)
|
||
{
|
||
status = GDDKNT_PurgeComm(Handle,SERIAL_PURGE_RXCLEAR);
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
return (GE_HOST_PORT_BREAK);
|
||
}
|
||
port_config[Handle].Error = 0;
|
||
}
|
||
return(G_OK);
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* INT16 G_SerPortStatus
|
||
* (
|
||
* const INT16 Handle,
|
||
* WORD16 *TxLength,
|
||
* WORD16 *RxLength,
|
||
* TGTSER_STATUS *Status
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* Return information about communication state.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* Handle holds the port handle.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* - TxLength holds the used Tx buffer length.
|
||
* - RxLength holds the used Rx buffer length.
|
||
* - Status can hold the following flags:
|
||
* HGTSER_RX_OVER when a character has been lost since last call to this
|
||
* function.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is OK:
|
||
* - G_OK ( 0).
|
||
* If an error condition is raised:
|
||
* - GE_HOST_PORT_CLOSE (-412) if port is closed.
|
||
* - GE_HOST_PARAMETERS (-450) if the given handle is out of the allowed range.
|
||
*
|
||
Extern var :
|
||
-------------
|
||
Nothing.
|
||
|
||
Global var :
|
||
-------------
|
||
port_config memorises the port configuration.
|
||
|
||
*******************************************************************************/
|
||
INT16 G_SerPortStatus
|
||
(
|
||
const INT16 Handle,
|
||
WORD16 *TxLength,
|
||
WORD16 *RxLength,
|
||
TGTSER_STATUS *Status
|
||
)
|
||
{
|
||
/*------------------------------------------------------------------------------
|
||
Local variables:
|
||
- status will hold Windows port status.
|
||
------------------------------------------------------------------------------*/
|
||
NTSTATUS
|
||
status;
|
||
SERIAL_STATUS
|
||
SerialStatus;
|
||
|
||
ASSERT(TxLength != NULL);
|
||
ASSERT(RxLength != NULL);
|
||
ASSERT(Status != NULL);
|
||
/*------------------------------------------------------------------------------
|
||
Controls the given parameters:
|
||
<= Test the port Handle (0 <= Handle < HGTSER_MAX_PORT): GE_HOST_PARAMETERS.
|
||
------------------------------------------------------------------------------*/
|
||
if ((Handle < 0) || (Handle >= HGTSER_MAX_PORT))
|
||
{
|
||
return (GE_HOST_PORT_ABS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Test the port state (Counter > 0): GE_HOST_PORT_CLOSE.
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Handle].Counter == 0)
|
||
{
|
||
return (GE_HOST_PORT_CLOSE);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Updates the given parameters:
|
||
The current windows state is read and port_config.Error field is updated.
|
||
------------------------------------------------------------------------------*/
|
||
status = GDDKNT_GetCommStatus(Handle,&SerialStatus);
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
return (GE_HOST_PORT_BREAK);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
TxLength, RxLength and Status parameter fields are updated.
|
||
------------------------------------------------------------------------------*/
|
||
*TxLength = (WORD16)SerialStatus.AmountInOutQueue;
|
||
*RxLength = (WORD16)SerialStatus.AmountInInQueue;
|
||
*Status = 0;
|
||
/*------------------------------------------------------------------------------
|
||
The Error field is reseted.
|
||
------------------------------------------------------------------------------*/
|
||
port_config[Handle].Error = 0;
|
||
/*------------------------------------------------------------------------------
|
||
<= G_OK
|
||
------------------------------------------------------------------------------*/
|
||
return (G_OK);
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* INT16 G_SerPortGetState
|
||
* (
|
||
* TGTSER_PORT *Param,
|
||
* WORD16 *UserNb
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine read the currently in use parameters for an opened serial port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* The following field of Param must be filled:
|
||
* - Port indicates the selected port: G_COM1 (1), G_COM2 (2), G_COM3 (3) or
|
||
* G_COM4 (4).
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* The following fields of Param are updated by the call:
|
||
* - BaudRate holds the currently selected port baud rate: 110, 150, 300, 600,
|
||
* 1200, 2400, 4800, 9600, 19200, 38400 or 57600.
|
||
* - Mode gathers
|
||
* * word size WORD_5 (0), WORD_6 (1), WORD_7 (2) or WORD_8 (3),
|
||
* * stop bit number STOP_BIT_1 (0) or STOP_BIT_2 (4) and
|
||
* * parity NO_PARITY (0), ODD_PARITY (8) or EVEN_PARITY (24).
|
||
* - TimeOut indicates the time out value, in milli-seconds, at character level.
|
||
* - TxSize is the transmit buffer size, in bytes.
|
||
* - RxSize is the reception buffer size, in mbytes.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is OK:
|
||
* - G_OK ( 0).
|
||
* If an error condition is raised:
|
||
* - GE_HOST_PORT_OS (-410) if a unexpected value has been returned by the
|
||
* operating system.
|
||
* - GE_HOST_PORT_CLOSE (-412) if the selected port is closed.
|
||
* - GE_HOST_PARAMETERS (-450) if the given handle is out of the allowed range.
|
||
*
|
||
Extern var :
|
||
-------------
|
||
Nothing.
|
||
|
||
Global var :
|
||
-------------
|
||
port_config is read.
|
||
|
||
*******************************************************************************/
|
||
INT16 G_SerPortGetState
|
||
(
|
||
TGTSER_PORT *Param,
|
||
WORD16 *UserNb
|
||
)
|
||
{
|
||
/*------------------------------------------------------------------------------
|
||
Local variables:
|
||
- handle holds the handle associated to the given port. It is calculated by the
|
||
following formula Port - 1.
|
||
- response holds the called function responses.
|
||
- current_dcb is used to read parameters in the device control block.
|
||
------------------------------------------------------------------------------*/
|
||
NTSTATUS
|
||
status;
|
||
INT16
|
||
Handle = (INT16)(Param->Port - 1);
|
||
SERIAL_READER_CONFIG
|
||
SerialConfig;
|
||
|
||
ASSERT(Param != NULL);
|
||
ASSERT(UserNb != NULL);
|
||
/*------------------------------------------------------------------------------
|
||
Controls the given parameters:
|
||
<= Test the port Handle (0 <= Handle < HGTSER_MAX_PORT): GE_HOST_PARAMETERS.
|
||
------------------------------------------------------------------------------*/
|
||
if ((Handle < 0) || (Handle >= HGTSER_MAX_PORT))
|
||
{
|
||
return (GE_HOST_PORT_ABS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Test the port state (Counter > 0): GE_HOST_PORT_CLOSE.
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Handle].Counter == 0)
|
||
{
|
||
return (GE_HOST_PORT_CLOSE);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
The current port state is read and stored in current_dcb structure by calling
|
||
GetCommState function.
|
||
If an error has occured (response < 0)
|
||
Then
|
||
<= GE_HOST_PORT_OS
|
||
------------------------------------------------------------------------------*/
|
||
status = GDDKNT_GetCommState(Handle,&SerialConfig);
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
return (GE_HOST_PORT_OS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
The parameters are updated with the read values.
|
||
------------------------------------------------------------------------------*/
|
||
Param->BaudRate = SerialConfig.BaudRate.BaudRate;
|
||
/*------------------------------------------------------------------------------
|
||
If the byte size is not supported
|
||
Then
|
||
<= GE_HOST_PORT_OS
|
||
------------------------------------------------------------------------------*/
|
||
switch (SerialConfig.LineControl.WordLength)
|
||
{
|
||
case 5:
|
||
Param->Mode = HGTSER_WORD_5;
|
||
break;
|
||
case 6:
|
||
Param->Mode = HGTSER_WORD_6;
|
||
break;
|
||
case 7:
|
||
Param->Mode = HGTSER_WORD_7;
|
||
break;
|
||
case 8:
|
||
Param->Mode = HGTSER_WORD_8;
|
||
break;
|
||
default:
|
||
return (GE_HOST_PORT_OS);
|
||
}
|
||
|
||
/*------------------------------------------------------------------------------
|
||
If the parity is not supported
|
||
Then
|
||
<= GE_HOST_PORT_OS
|
||
------------------------------------------------------------------------------*/
|
||
switch (SerialConfig.LineControl.Parity)
|
||
{
|
||
case NO_PARITY:
|
||
Param->Mode |= HGTSER_NO_PARITY;
|
||
break;
|
||
case ODD_PARITY:
|
||
Param->Mode |= HGTSER_ODD_PARITY;
|
||
break;
|
||
case EVEN_PARITY:
|
||
Param->Mode |= HGTSER_EVEN_PARITY;
|
||
break;
|
||
case SERIAL_PARITY_MARK:
|
||
case SERIAL_PARITY_SPACE:
|
||
default:
|
||
return (GE_HOST_PORT_OS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
If the stop bit number is not supported
|
||
Then
|
||
<= GE_HOST_PORT_OS
|
||
------------------------------------------------------------------------------*/
|
||
switch (SerialConfig.LineControl.StopBits)
|
||
{
|
||
case STOP_BIT_1:
|
||
Param->Mode |= HGTSER_STOP_BIT_1;
|
||
break;
|
||
case STOP_BITS_2:
|
||
Param->Mode |= HGTSER_STOP_BIT_2;
|
||
break;
|
||
case STOP_BITS_1_5:
|
||
default:
|
||
return (GE_HOST_PORT_OS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Updates the library fields ITNumber, TimeOut, TxSize and RxSize.
|
||
------------------------------------------------------------------------------*/
|
||
Param->ITNumber = DEFAULT_IT;
|
||
Param->TimeOut = port_config[Handle].TimeOut;
|
||
Param->TxSize = port_config[Handle].TxSize;
|
||
Param->RxSize = port_config[Handle].RxSize;
|
||
/*------------------------------------------------------------------------------
|
||
The UserNb parameter is filled with the port_config.Counter.
|
||
------------------------------------------------------------------------------*/
|
||
*UserNb = port_config[Handle].Counter;
|
||
/*------------------------------------------------------------------------------
|
||
<= G_OK
|
||
------------------------------------------------------------------------------*/
|
||
return (G_OK);
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* INT16 G_SerPortSetState
|
||
* (
|
||
* TGTSER_PORT *Param
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine alters the currently in use parameters for an opened serial port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* The following field of Param must be filled:
|
||
* - Port indicates the selected port: G_COM1 (1), G_COM2 (2), G_COM3 (3) or
|
||
* G_COM4 (4).
|
||
* - BaudRate holds the currently selected port baud rate: 110, 150, 300, 600,
|
||
* 1200, 2400, 4800, 9600, 19200, 38400 or 57600.
|
||
* - Mode gathers
|
||
* * word size WORD_5 (0), WORD_6 (1), WORD_7 (2) or WORD_8 (3),
|
||
* * stop bit number STOP_BIT_1 (0) or STOP_BIT_2 (4) and
|
||
* * parity NO_PARITY (0), ODD_PARITY (8) or EVEN_PARITY (24).
|
||
* - TimeOut indicates the time out value, in milli-seconds, at character level.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* The following fields of Param are updated by the call:
|
||
* - TxSize is the transmit buffer size, in bytes.
|
||
* - RxSize is the reception buffer size, in mbytes.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is OK:
|
||
* - G_OK ( 0).
|
||
* If an error condition is raised:
|
||
* - GE_HOST_PORT_ABS (- 401) if port is not found on host or is locked by
|
||
* another device.
|
||
* - GE_HOST_PORT_OS (- 410) if a unexpected value has been returned by the
|
||
* operating system.
|
||
* - GE_HOST_PORT_CLOSE (- 412) if the selected port is closed.
|
||
* - GE_HOST_MEMORY (- 420) if a memory allocation fails.
|
||
* - GE_HOST_PARAMETERS (- 450) if one of the given parameters is out of the
|
||
* allowed range or is not supported by hardware.
|
||
* - GE_UNKNOWN_PB (-1000) if an unexpected problem is encountered.
|
||
*
|
||
Extern var :
|
||
-------------
|
||
Nothing.
|
||
|
||
Global var :
|
||
-------------
|
||
port_config is set with the selected configuration.
|
||
|
||
*******************************************************************************/
|
||
INT16 G_SerPortSetState
|
||
(
|
||
TGTSER_PORT *Param
|
||
)
|
||
{
|
||
NTSTATUS
|
||
status;
|
||
INT16
|
||
response = G_OK,
|
||
Handle = (INT16)(Param->Port - 1);
|
||
SERIAL_READER_CONFIG
|
||
SerialConfig;
|
||
DWORD
|
||
error = 0;
|
||
|
||
ASSERT(Param != NULL);
|
||
/*------------------------------------------------------------------------------
|
||
Controls the given parameters:
|
||
<= Test the port handle (0 <= Handle < HGTSER_MAX_PORT): GE_HOST_PARAMETERS.
|
||
------------------------------------------------------------------------------*/
|
||
if ((Handle < 0) || (Handle >= HGTSER_MAX_PORT))
|
||
{
|
||
return (GE_HOST_PORT_ABS);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
<= Test the port state (Counter > 0): GE_HOST_PORT_CLOSE.
|
||
------------------------------------------------------------------------------*/
|
||
if (port_config[Handle].Counter == 0)
|
||
{
|
||
return (GE_HOST_PORT_CLOSE);
|
||
}
|
||
|
||
status = GDDKNT_GetCommState(Handle,&SerialConfig);
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
SerialConfig.BaudRate.BaudRate = Param->BaudRate;
|
||
SerialConfig.LineControl.WordLength = WORD_LEN(Param->Mode);
|
||
SerialConfig.LineControl.Parity = PARITY(Param->Mode);
|
||
SerialConfig.LineControl.StopBits = STOP(Param->Mode);
|
||
status = GDDKNT_SetCommState(Handle,&SerialConfig);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Else
|
||
error is set with GE_HOST_PARAMETERS error value.
|
||
------------------------------------------------------------------------------*/
|
||
else
|
||
{
|
||
return(GE_HOST_PARAMETERS);
|
||
}
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
switch (status)
|
||
{
|
||
case STATUS_BUFFER_TOO_SMALL:
|
||
case STATUS_INVALID_PARAMETER:
|
||
response = GE_HOST_PARAMETERS;
|
||
break;
|
||
default :
|
||
response = GE_UNKNOWN_PB;
|
||
break;
|
||
}
|
||
}
|
||
return(response);
|
||
}
|
||
/*******************************************************************************
|
||
* INT32 G_SerPortLockComm
|
||
* (
|
||
* const INT16 Handle,
|
||
* const DWORD WaitRelease
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* Take the mutex for a serial port communication if is free or wait
|
||
* the release
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* Handle hold the port handle
|
||
* WaitRelease old the new time to wait the release
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is OK: TRUE
|
||
* else FALSE
|
||
*
|
||
Extern var :
|
||
-------------
|
||
Nothing.
|
||
|
||
Global var :
|
||
-------------
|
||
Nothing
|
||
|
||
*******************************************************************************/
|
||
INT32 G_SerPortLockComm
|
||
(
|
||
const INT16 Handle,
|
||
const DWORD WaitRelease
|
||
)
|
||
{
|
||
NTSTATUS
|
||
status;
|
||
LARGE_INTEGER
|
||
timeout;
|
||
|
||
/*------------------------------------------------------------------------------
|
||
Controls the given parameters:
|
||
<= Test the port handle (0 <= Handle < HGTSER_MAX_PORT): GE_HOST_PARAMETERS.
|
||
------------------------------------------------------------------------------*/
|
||
if ((Handle < 0) || (Handle >= HGTSER_MAX_PORT))
|
||
{
|
||
return (FALSE);
|
||
}
|
||
/*------------------------------------------------------------------------------
|
||
Wait the release of the mutex
|
||
------------------------------------------------------------------------------*/
|
||
timeout.QuadPart = -((LONGLONG)(
|
||
port_config[Handle].WaitRelease > GTSER_DEF_WAIT_RELEASE ?
|
||
port_config[Handle].WaitRelease : GTSER_DEF_WAIT_RELEASE)*10*1000);
|
||
status = KeWaitForMutexObject(
|
||
port_config[Handle].pExchangeMutex,
|
||
Executive,
|
||
KernelMode,
|
||
FALSE,
|
||
&timeout
|
||
);
|
||
if (status != STATUS_SUCCESS)
|
||
{
|
||
return(FALSE);
|
||
}
|
||
else
|
||
{
|
||
port_config[Handle].WaitRelease = WaitRelease;
|
||
return(TRUE);
|
||
}
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* void G_SerPortUnlockComm
|
||
* (
|
||
* const INT16 Handle
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* Release the mutex for a serial port communication.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In : Handle hold the port handle
|
||
* -------------
|
||
* Nothing
|
||
*
|
||
* Out :
|
||
* -------------
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* Nothing
|
||
*
|
||
Extern var :
|
||
-------------
|
||
Nothing.
|
||
|
||
Global var :
|
||
-------------
|
||
Nothing
|
||
|
||
*******************************************************************************/
|
||
void G_SerPortUnlockComm
|
||
(
|
||
const INT16 Handle
|
||
)
|
||
{
|
||
NTSTATUS
|
||
status;
|
||
|
||
/*------------------------------------------------------------------------------
|
||
Controls the given parameters:
|
||
------------------------------------------------------------------------------*/
|
||
if ((Handle >= 0) && (Handle < HGTSER_MAX_PORT))
|
||
{
|
||
status = KeReleaseMutex(port_config[Handle].pExchangeMutex,FALSE);
|
||
}
|
||
}
|
||
/******************************************************************************
|
||
* NTSTATUS GDDKNT_SerPortIoRequest
|
||
* (
|
||
* IN CONST INT16 Handle,
|
||
* IN CONST ULONG SerialIoControlCode,
|
||
* IN CONST ULONG CmdTimeout,
|
||
* IN CONST WORD16 LengthIn,
|
||
* IN CONST BYTE *BufferIn,
|
||
* IN OUT WORD16 *pLengthOut,
|
||
* OUT BYTE *BufferOut
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This function sends IOCTL's to the serial driver. It waits on for their
|
||
* completion, and then returns.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Handle holds the port handle.
|
||
* - CmdTimeout is the current command timeout.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is Ok:
|
||
* STATUS_SUCCESS ( 0).
|
||
*
|
||
*******************************************************************************/
|
||
NTSTATUS GDDKNT_SerPortIoRequest
|
||
(
|
||
IN CONST INT16 Handle,
|
||
IN CONST ULONG SerialIoControlCode,
|
||
IN CONST ULONG CmdTimeout,
|
||
IN CONST WORD16 LengthIn,
|
||
IN CONST BYTE *BufferIn,
|
||
IN OUT WORD16 *pLengthOut,
|
||
OUT BYTE *BufferOut
|
||
)
|
||
{
|
||
NTSTATUS
|
||
status;
|
||
PIRP
|
||
irp;
|
||
PIO_STACK_LOCATION
|
||
irpNextStack;
|
||
IO_STATUS_BLOCK
|
||
ioStatus;
|
||
KEVENT
|
||
event;
|
||
LARGE_INTEGER
|
||
timeout;
|
||
|
||
KeInitializeEvent(&event,NotificationEvent,FALSE);
|
||
/*------------------------------------------------------------------------------
|
||
Build an Irp to be send to serial driver
|
||
------------------------------------------------------------------------------*/
|
||
irp = IoBuildDeviceIoControlRequest
|
||
(
|
||
SerialIoControlCode,
|
||
port_config[Handle].pSerialPortDevice,
|
||
(PVOID)BufferIn,
|
||
(ULONG)LengthIn,
|
||
(PVOID)BufferOut,
|
||
(ULONG)(*pLengthOut),
|
||
FALSE,
|
||
&event,
|
||
&ioStatus
|
||
);
|
||
|
||
if (irp == NULL)
|
||
{
|
||
return STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
irpNextStack = IoGetNextIrpStackLocation(irp);
|
||
|
||
switch (SerialIoControlCode)
|
||
{
|
||
case GTSER_IOCTL_WRITE:
|
||
irpNextStack->MajorFunction = IRP_MJ_WRITE;
|
||
irpNextStack->Parameters.Write.Length = (ULONG)LengthIn;
|
||
break;
|
||
|
||
case GTSER_IOCTL_READ:
|
||
irpNextStack->MajorFunction = IRP_MJ_READ;
|
||
irpNextStack->Parameters.Read.Length = (ULONG)(*pLengthOut);
|
||
break;
|
||
}
|
||
|
||
status = IoCallDriver(port_config[Handle].pSerialPortDevice,irp);
|
||
|
||
if (status == STATUS_PENDING)
|
||
{
|
||
timeout.QuadPart = -((LONGLONG) CmdTimeout*10*1000);
|
||
status = KeWaitForSingleObject(&event,
|
||
Suspended,
|
||
KernelMode,
|
||
FALSE,
|
||
&timeout);
|
||
if (status == STATUS_TIMEOUT)
|
||
{
|
||
IoCancelIrp(irp);
|
||
KeWaitForSingleObject(&event,
|
||
Suspended,
|
||
KernelMode,
|
||
FALSE,
|
||
NULL);
|
||
}
|
||
}
|
||
|
||
status = ioStatus.Status;
|
||
|
||
switch (SerialIoControlCode)
|
||
{
|
||
case GTSER_IOCTL_WRITE:
|
||
if (ioStatus.Status == STATUS_TIMEOUT)
|
||
{
|
||
// STATUS_TIMEOUT isn't correctly mapped
|
||
// to a WIN32 error, that's why we change it here to STATUS_IO_TIMEOUT
|
||
status = STATUS_IO_TIMEOUT;
|
||
}
|
||
break;
|
||
|
||
case GTSER_IOCTL_READ:
|
||
if (ioStatus.Status == STATUS_TIMEOUT)
|
||
{
|
||
// STATUS_TIMEOUT isn't correctly mapped
|
||
// to a WIN32 error, that's why we change it here to STATUS_IO_TIMEOUT
|
||
status = STATUS_IO_TIMEOUT;
|
||
*pLengthOut = 0;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
*pLengthOut = (WORD16)(ioStatus.Information);
|
||
break;
|
||
}
|
||
return status;
|
||
}
|
||
|
||
/******************************************************************************
|
||
* NTSTATUS GDDKNT_SetCommState
|
||
* (
|
||
* const INT16 Handle,
|
||
* SERIAL_READER_CONFIG *SerialConfig
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine will appropriately configure the serial port.
|
||
* It makes synchronous calls to the serial port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Handle holds the port handle.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is Ok:
|
||
* STATUS_SUCCESS ( 0).
|
||
*
|
||
*******************************************************************************/
|
||
NTSTATUS GDDKNT_SetCommState
|
||
(
|
||
const INT16 Handle,
|
||
SERIAL_READER_CONFIG *SerialConfig
|
||
)
|
||
{
|
||
NTSTATUS
|
||
status = STATUS_SUCCESS;
|
||
USHORT
|
||
i;
|
||
ULONG
|
||
SerialIoControlCode;
|
||
WORD16
|
||
LengthIn,
|
||
LengthOut;
|
||
PUCHAR
|
||
pBufferIn;
|
||
|
||
ASSERT(SerialConfig != NULL);
|
||
for (i=0; NT_SUCCESS(status); i++)
|
||
{
|
||
switch (i)
|
||
{
|
||
case 0:
|
||
// Set up baudrate
|
||
SerialIoControlCode = IOCTL_SERIAL_SET_BAUD_RATE;
|
||
pBufferIn = (PUCHAR)&SerialConfig->BaudRate;
|
||
LengthIn = sizeof(SERIAL_BAUD_RATE);
|
||
break;
|
||
|
||
case 1:
|
||
// Set up line control parameters
|
||
SerialIoControlCode = IOCTL_SERIAL_SET_LINE_CONTROL;
|
||
pBufferIn = (PUCHAR)&SerialConfig->LineControl;
|
||
LengthIn = sizeof(SERIAL_LINE_CONTROL);
|
||
break;
|
||
|
||
case 2:
|
||
// Set serial special characters
|
||
SerialIoControlCode = IOCTL_SERIAL_SET_CHARS;
|
||
pBufferIn = (PUCHAR)&SerialConfig->SerialChars;
|
||
LengthIn = sizeof(SERIAL_CHARS);
|
||
break;
|
||
|
||
case 3:
|
||
// Set up timeouts
|
||
SerialIoControlCode = IOCTL_SERIAL_SET_TIMEOUTS;
|
||
pBufferIn = (PUCHAR)&SerialConfig->Timeouts;
|
||
LengthIn = sizeof(SERIAL_TIMEOUTS);
|
||
break;
|
||
|
||
case 4:
|
||
// Set flowcontrol and handshaking
|
||
SerialIoControlCode = IOCTL_SERIAL_SET_HANDFLOW;
|
||
pBufferIn = (PUCHAR)&SerialConfig->HandFlow;
|
||
LengthIn = sizeof(SERIAL_HANDFLOW);
|
||
break;
|
||
|
||
case 5:
|
||
// Set break off
|
||
SerialIoControlCode = IOCTL_SERIAL_SET_BREAK_OFF;
|
||
LengthIn = 0;
|
||
break;
|
||
|
||
case 6:
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
LengthOut = 0;
|
||
status = GDDKNT_SerPortIoRequest(Handle,
|
||
SerialIoControlCode,
|
||
500UL,
|
||
LengthIn,
|
||
pBufferIn,
|
||
&LengthOut,
|
||
NULL);
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
/******************************************************************************
|
||
* NTSTATUS GDDKNT_GetCommState
|
||
* (
|
||
* const INT16 Handle,
|
||
* SERIAL_READER_CONFIG *SerialConfig
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine will appropriately configure the serial port.
|
||
* It makes synchronous calls to the serial port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Handle holds the port handle.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is Ok:
|
||
* STATUS_SUCCESS ( 0).
|
||
*
|
||
*******************************************************************************/
|
||
NTSTATUS GDDKNT_GetCommState
|
||
(
|
||
const INT16 Handle,
|
||
SERIAL_READER_CONFIG *SerialConfig
|
||
)
|
||
{
|
||
NTSTATUS
|
||
status = STATUS_SUCCESS;
|
||
USHORT
|
||
i;
|
||
ULONG
|
||
SerialIoControlCode;
|
||
WORD16
|
||
LengthOut;
|
||
PUCHAR
|
||
pBufferOut;
|
||
|
||
ASSERT(SerialConfig != NULL);
|
||
for (i=0; NT_SUCCESS(status); i++)
|
||
{
|
||
switch (i)
|
||
{
|
||
|
||
case 0:
|
||
// Get up baudrate
|
||
SerialIoControlCode = IOCTL_SERIAL_GET_BAUD_RATE;
|
||
pBufferOut = (PUCHAR)&SerialConfig->BaudRate;
|
||
LengthOut = sizeof(SERIAL_BAUD_RATE);
|
||
break;
|
||
|
||
case 1:
|
||
// Get up line control parameters
|
||
SerialIoControlCode = IOCTL_SERIAL_GET_LINE_CONTROL;
|
||
pBufferOut = (PUCHAR)&SerialConfig->LineControl;
|
||
LengthOut = sizeof(SERIAL_LINE_CONTROL);
|
||
break;
|
||
|
||
case 2:
|
||
// Get serial special characters
|
||
SerialIoControlCode = IOCTL_SERIAL_GET_CHARS;
|
||
pBufferOut = (PUCHAR)&SerialConfig->SerialChars;
|
||
LengthOut = sizeof(SERIAL_CHARS);
|
||
break;
|
||
|
||
case 3:
|
||
// Get up timeouts
|
||
SerialIoControlCode = IOCTL_SERIAL_GET_TIMEOUTS;
|
||
pBufferOut = (PUCHAR)&SerialConfig->Timeouts;
|
||
LengthOut = sizeof(SERIAL_TIMEOUTS);
|
||
break;
|
||
|
||
case 4:
|
||
// Get flowcontrol and handshaking
|
||
SerialIoControlCode = IOCTL_SERIAL_GET_HANDFLOW;
|
||
pBufferOut = (PUCHAR)&SerialConfig->HandFlow;
|
||
LengthOut = sizeof(SERIAL_HANDFLOW);
|
||
break;
|
||
|
||
case 5:
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
status = GDDKNT_SerPortIoRequest(Handle,
|
||
SerialIoControlCode,
|
||
500UL,
|
||
0,
|
||
NULL,
|
||
&LengthOut,
|
||
pBufferOut);
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
/******************************************************************************
|
||
* NTSTATUS GDDKNT_SetupComm
|
||
* (
|
||
* const INT16 Handle,
|
||
* const ULONG InSize,
|
||
* const ULONG OutSize
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine will appropriately resize the driver's internal typeahead
|
||
* and input buffers of the serial port.
|
||
* It makes synchronous calls to the serial port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Handle holds the port handle.
|
||
* - InSize is the input buffer size.
|
||
* - OutSize is the output buffer size.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is Ok:
|
||
* STATUS_SUCCESS ( 0).
|
||
*
|
||
*******************************************************************************/
|
||
static NTSTATUS GDDKNT_SetupComm
|
||
(
|
||
const INT16 Handle,
|
||
const ULONG InSize,
|
||
const ULONG OutSize
|
||
)
|
||
{
|
||
NTSTATUS
|
||
status = STATUS_SUCCESS;
|
||
SERIAL_QUEUE_SIZE
|
||
SerialQueueSize;
|
||
WORD16
|
||
LengthOut = 0;
|
||
|
||
// Set up queue size
|
||
SerialQueueSize.InSize = InSize;
|
||
SerialQueueSize.OutSize = OutSize;
|
||
|
||
status = GDDKNT_SerPortIoRequest(Handle,
|
||
IOCTL_SERIAL_SET_QUEUE_SIZE,
|
||
500UL,
|
||
sizeof(SERIAL_QUEUE_SIZE),
|
||
(PUCHAR)&SerialQueueSize,
|
||
&LengthOut,
|
||
NULL);
|
||
|
||
return status;
|
||
}
|
||
|
||
/******************************************************************************
|
||
* NTSTATUS GDDKNT_GetCommStatus
|
||
* (
|
||
* const INT16 Handle,
|
||
* SERIAL_STATUS *SerialStatus
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine will appropriately get status information of the serial port.
|
||
* It makes synchronous calls to the serial port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Handle holds the port handle.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* - SerialStatus is the pointer to the status information returned.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is Ok:
|
||
* STATUS_SUCCESS ( 0).
|
||
*
|
||
*******************************************************************************/
|
||
static NTSTATUS GDDKNT_GetCommStatus
|
||
(
|
||
const INT16 Handle,
|
||
SERIAL_STATUS *SerialStatus
|
||
)
|
||
{
|
||
NTSTATUS
|
||
status = STATUS_SUCCESS;
|
||
WORD16
|
||
LengthOut;
|
||
|
||
ASSERT(SerialStatus != NULL);
|
||
LengthOut = sizeof(SERIAL_STATUS);
|
||
status = GDDKNT_SerPortIoRequest(Handle,
|
||
IOCTL_SERIAL_GET_COMMSTATUS,
|
||
500UL,
|
||
0,
|
||
NULL,
|
||
&LengthOut,
|
||
(PUCHAR)SerialStatus);
|
||
|
||
return status;
|
||
}
|
||
|
||
/******************************************************************************
|
||
* NTSTATUS GDDKNT_ResetComm
|
||
* (
|
||
* const INT16 Handle
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine will appropriately get status information of the serial port.
|
||
* It makes synchronous calls to the serial port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Handle holds the port handle.
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is Ok:
|
||
* STATUS_SUCCESS ( 0).
|
||
*
|
||
*******************************************************************************/
|
||
static NTSTATUS GDDKNT_ResetComm
|
||
(
|
||
const INT16 Handle
|
||
)
|
||
{
|
||
NTSTATUS
|
||
status = STATUS_SUCCESS;
|
||
WORD16
|
||
LengthOut = 0;
|
||
|
||
status = GDDKNT_SerPortIoRequest(Handle,
|
||
IOCTL_SERIAL_RESET_DEVICE,
|
||
500UL,
|
||
0,
|
||
NULL,
|
||
&LengthOut,
|
||
NULL);
|
||
|
||
return status;
|
||
}
|
||
|
||
/******************************************************************************
|
||
* NTSTATUS GDDKNT_PurgeComm
|
||
* (
|
||
* const INT16 Handle,
|
||
* const ULONG Select
|
||
* )
|
||
*
|
||
* Description :
|
||
* -------------
|
||
* This routine flush the data in the serial port.
|
||
*
|
||
* Remarks :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* In :
|
||
* -------------
|
||
* - Handle holds the port handle.
|
||
* - Select holds the buffers to clear:
|
||
* SERIAL_PURGE_TXCLEAR
|
||
* SERIAL_PURGE_RXCLEAR
|
||
* SERIAL_PURGE_TXCLEAR | SERIAL_PURGE_RXCLEAR
|
||
*
|
||
* Out :
|
||
* -------------
|
||
* Nothing.
|
||
*
|
||
* Responses :
|
||
* -------------
|
||
* If everything is Ok:
|
||
* STATUS_SUCCESS ( 0).
|
||
*
|
||
*******************************************************************************/
|
||
static NTSTATUS GDDKNT_PurgeComm
|
||
(
|
||
const INT16 Handle,
|
||
const ULONG Select
|
||
)
|
||
{
|
||
NTSTATUS
|
||
status = STATUS_SUCCESS;
|
||
ULONG
|
||
PurgeMask = Select;
|
||
WORD16
|
||
LengthOut = 0;
|
||
|
||
status = GDDKNT_SerPortIoRequest(Handle,
|
||
IOCTL_SERIAL_PURGE,
|
||
500UL,
|
||
sizeof(PurgeMask),
|
||
(PUCHAR)&PurgeMask,
|
||
&LengthOut,
|
||
NULL);
|
||
|
||
return status;
|
||
}
|