serial: got rid of most the warning message with MAKE_BUILD_TYPE=Release

winpr-comm: consolidated _set_handflow()/_get_handflow()
winpr-comm: introduced a permissive mode
winpr-comm: implementation of IOCTL_SERIAL_WAIT_ON_MASK still in progress
This commit is contained in:
Emmanuel Ledoux 2014-05-19 16:53:57 +02:00 committed by Emmanuel Ledoux
parent 8179affea9
commit baf4896a38
9 changed files with 293 additions and 356 deletions

View File

@ -125,12 +125,18 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp)
if (!serial->hComm || (serial->hComm == INVALID_HANDLE_VALUE))
{
DEBUG_WARN("CreateFile failure: %s last-error: Ox%x\n", serial->device.name, GetLastError());
DEBUG_WARN("CreateFile failure: %s last-error: Ox%lX\n", serial->device.name, GetLastError());
irp->IoStatus = STATUS_UNSUCCESSFUL;
goto error_handle;
}
/* FIXME: Appeared to be useful to setup some devices. Guess
* the device driver asked to setup some unsupported feature
* that were not eventually used. TODO: collecting more
* details, a command line argument? */
/* _comm_set_permissive(serial->hComm, TRUE); */
/* FIXME: this stinks, see also IOCTL_SERIAL_PURGE */
_comm_set_ReadIrpQueue(serial->hComm, serial->ReadIrpQueue);
@ -208,7 +214,7 @@ static void serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp)
}
/* MSRDPESP 3.2.5.1.4: If the Offset field is not set to 0, the value MUST be ignored
/* MS-RDPESP 3.2.5.1.4: If the Offset field is not set to 0, the value MUST be ignored
* assert(Offset == 0);
*/
@ -257,6 +263,7 @@ static void serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp)
}
}
DEBUG_SVC("%lu bytes read from %s", nbRead, serial->device.name);
error_handle:
@ -284,7 +291,12 @@ static void serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp)
Stream_Read_UINT64(irp->input, Offset); /* Offset (8 bytes) */
Stream_Seek(irp->input, 20); /* Padding (20 bytes) */
assert(Offset == 0); /* not implemented otherwise */
/* MS-RDPESP 3.2.5.1.5: The Offset field is ignored
* assert(Offset == 0);
*
* Using a serial printer, noticed though this field could be
* set.
*/
DEBUG_SVC("writing %lu bytes to %s", Length, serial->device.name);
@ -296,7 +308,6 @@ static void serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp)
else
{
DEBUG_SVC("write failure to %s, nbWritten=%d, last-error: 0x%0.8x", serial->device.name, nbWritten, GetLastError());
switch(GetLastError())
{
case ERROR_INVALID_HANDLE:
@ -337,6 +348,7 @@ static void serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp)
irp->Complete(irp);
}
static void serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp)
{
UINT32 IoControlCode;
@ -367,7 +379,7 @@ static void serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp)
Stream_Read(irp->input, InputBuffer, InputBufferLength);
DEBUG_SVC("CommDeviceIoControl: IoControlCode=[0x%x] %s", IoControlCode, _comm_serial_ioctl_name(IoControlCode));
DEBUG_SVC("CommDeviceIoControl: CompletionId=%d, IoControlCode=[0x%x] %s", irp->CompletionId, IoControlCode, _comm_serial_ioctl_name(IoControlCode));
/* FIXME: CommDeviceIoControl to be replaced by DeviceIoControl() */
if (CommDeviceIoControl(serial->hComm, IoControlCode, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, &BytesReturned, NULL))
@ -424,6 +436,8 @@ static void serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp)
error_handle:
assert(OutputBufferLength == BytesReturned);
Stream_Write_UINT32(irp->output, BytesReturned); /* OutputBufferLength (4 bytes) */
if (BytesReturned > 0)
@ -541,6 +555,7 @@ static void* serial_thread_func(void* arg)
return NULL;
}
static void serial_irp_request(DEVICE* device, IRP* irp)
{
SERIAL_DEVICE* serial = (SERIAL_DEVICE*) device;

View File

@ -524,6 +524,13 @@ static const _SERIAL_IOCTL_NAME _SERIAL_IOCTL_NAMES[] =
*/
const char* _comm_serial_ioctl_name(ULONG number);
/**
* FIXME: got a proper function name and place
*
* permissive mode is disabled by default.
*/
BOOL _comm_set_permissive(HANDLE hDevice, BOOL permissive);
void _comm_set_ReadIrpQueue(HANDLE hComm, wMessageQueue* ReadIrpQueue);

View File

@ -1029,7 +1029,7 @@ HANDLE CommCreateFileA(LPCSTR lpDeviceName, DWORD dwDesiredAccess, DWORD dwShare
if (dwDesiredAccess != (GENERIC_READ | GENERIC_WRITE))
{
DEBUG_WARN("unexpected access to the device: 0x%x", dwDesiredAccess);
DEBUG_WARN("unexpected access to the device: 0x%lX", dwDesiredAccess);
}
if (dwShareMode != 0)
@ -1043,7 +1043,7 @@ HANDLE CommCreateFileA(LPCSTR lpDeviceName, DWORD dwDesiredAccess, DWORD dwShare
if (lpSecurityAttributes != NULL)
{
DEBUG_WARN("unexpected security attributes: 0x%x", lpSecurityAttributes);
DEBUG_WARN("unexpected security attributes, nLength=%lu", lpSecurityAttributes->nLength);
}
if (dwCreationDisposition != OPEN_EXISTING)
@ -1067,14 +1067,14 @@ HANDLE CommCreateFileA(LPCSTR lpDeviceName, DWORD dwDesiredAccess, DWORD dwShare
if (!S_ISCHR(deviceStat.st_mode))
{
DEBUG_WARN("bad device %d", devicePath);
DEBUG_WARN("bad device %s", devicePath);
SetLastError(ERROR_BAD_DEVICE);
return INVALID_HANDLE_VALUE;
}
if (dwFlagsAndAttributes != 0)
{
DEBUG_WARN("unexpected flags and attributes: 0x%x", dwFlagsAndAttributes);
DEBUG_WARN("unexpected flags and attributes: 0x%lX", dwFlagsAndAttributes);
}
if (hTemplateFile != NULL)
@ -1146,7 +1146,7 @@ HANDLE CommCreateFileA(LPCSTR lpDeviceName, DWORD dwDesiredAccess, DWORD dwShare
/* upcomingTermios.c_cflag &= ~(CSIZE | PARENB); */
/* upcomingTermios.c_cflag |= CS8; */
/* About missing missing flags recommended by termios(3)
/* About missing flags recommended by termios(3):
*
* IGNBRK and IXON, see: IOCTL_SERIAL_SET_HANDFLOW
* CSIZE, PARENB and CS8, see: IOCTL_SERIAL_SET_LINE_CONTROL

View File

@ -46,6 +46,17 @@ struct winpr_comm
WINPR_HANDLE_DEF();
int fd;
/* permissive mode on errors if TRUE (default is FALSE).
*
* Since not all features are supported, some devices and applications
* can still be functional on such errors.
*
* TODO: command line switch or getting rid of it.
*/
BOOL permissive;
REMOTE_SERIAL_DRIVER_ID remoteSerialDriverId;
wMessageQueue* ReadIrpQueue; /* considered as optional since it is
@ -55,7 +66,7 @@ struct winpr_comm
COMMTIMEOUTS timeouts;
struct serial_icounter_struct counters;
ULONG waitMask;
ULONG waitMask; /* TMP: to be renamed EventMask */
ULONG pendingEvents;
/* NB: CloseHandle() has to free resources */

View File

@ -34,6 +34,27 @@
#include "comm.h"
BOOL _comm_set_permissive(HANDLE hDevice, BOOL permissive)
{
WINPR_COMM* pComm = (WINPR_COMM*) hDevice;
if (hDevice == INVALID_HANDLE_VALUE)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (!pComm || pComm->Type != HANDLE_TYPE_COMM || !pComm->fd )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
pComm->permissive = permissive;
return TRUE;
}
/* Computes Tmax in deciseconds (m and Tcare in milliseconds) */
static UCHAR _tmax(DWORD N, ULONG m, ULONG Tc)
{
@ -200,10 +221,10 @@ BOOL CommReadFile(HANDLE hDevice, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
if (nbRead < 0)
{
DEBUG_WARN("CommReadFile failed, ReadIntervalTimeout=%d, ReadTotalTimeoutMultiplier=%d, ReadTotalTimeoutConstant=%d VMIN=%d, VTIME=%d",
DEBUG_WARN("CommReadFile failed, ReadIntervalTimeout=%lu, ReadTotalTimeoutMultiplier=%lu, ReadTotalTimeoutConstant=%lu VMIN=%u, VTIME=%u",
pTimeouts->ReadIntervalTimeout, pTimeouts->ReadTotalTimeoutMultiplier, pTimeouts->ReadTotalTimeoutConstant,
currentTermios.c_cc[VMIN], currentTermios.c_cc[VTIME]);
DEBUG_WARN("CommReadFile failed, nNumberOfBytesToRead=%d, errno=[%d] %s", nNumberOfBytesToRead, errno, strerror(errno));
DEBUG_WARN("CommReadFile failed, nNumberOfBytesToRead=%lu, errno=[%d] %s", nNumberOfBytesToRead, errno, strerror(errno));
switch (errno)
{
@ -287,7 +308,7 @@ BOOL CommWriteFile(HANDLE hDevice, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite
if (nbWritten < 0)
{
DEBUG_WARN("CommWriteFile failed after %d bytes written, errno=[%d] %s\n", *lpNumberOfBytesWritten, errno, strerror(errno));
DEBUG_WARN("CommWriteFile failed after %lu bytes written, errno=[%d] %s\n", *lpNumberOfBytesWritten, errno, strerror(errno));
switch (errno)
{

View File

@ -72,22 +72,9 @@ const char* _comm_serial_ioctl_name(ULONG number)
}
/**
* FIXME: to be used through winpr-io's DeviceIoControl
*
* Any previous error as returned by GetLastError is cleared.
*
* ERRORS:
* ERROR_INVALID_HANDLE
* ERROR_INVALID_PARAMETER
* ERROR_NOT_SUPPORTED lpOverlapped is not supported
* ERROR_INSUFFICIENT_BUFFER
* ERROR_CALL_NOT_IMPLEMENTED unimplemented ioctl
*/
BOOL CommDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize,
LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
static BOOL _CommDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize,
LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
{
WINPR_COMM* pComm = (WINPR_COMM*) hDevice;
REMOTE_SERIAL_DRIVER* pRemoteSerialDriver = NULL;
@ -151,6 +138,17 @@ BOOL CommDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffe
switch (dwIoControlCode)
{
case 0x220034:
case 0X1B006C:
DEBUG_WARN("Undocumented IoControlCode: 0X%X", dwIoControlCode);
*lpBytesReturned = nOutBufferSize; /* an empty OutputBuffer will be returned */
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
if (pComm->permissive)
return FALSE;
else
return TRUE;
break;
case IOCTL_SERIAL_SET_BAUD_RATE:
{
if (pRemoteSerialDriver->set_baud_rate)
@ -467,7 +465,10 @@ BOOL CommDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffe
}
if (!pRemoteSerialDriver->wait_on_mask(pComm, pOutputMask))
{
*lpBytesReturned = sizeof(ULONG); /* TMP: TODO: all lpBytesReturned values to be reviewed on error */
return FALSE;
}
*lpBytesReturned = sizeof(ULONG);
return TRUE;
@ -511,7 +512,7 @@ BOOL CommDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffe
}
DEBUG_WARN(_T("unsupported IoControlCode=[Ox%0.8x] %s (remote serial driver: %s)"),
DEBUG_WARN(_T("unsupported IoControlCode=[0x%lX] %s (remote serial driver: %s)"),
dwIoControlCode, _comm_serial_ioctl_name(dwIoControlCode), pRemoteSerialDriver->name);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
@ -519,6 +520,53 @@ BOOL CommDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffe
}
/**
* FIXME: to be used through winpr-io's DeviceIoControl
*
* Any previous error as returned by GetLastError is cleared.
*
* ERRORS:
* ERROR_INVALID_HANDLE
* ERROR_INVALID_PARAMETER
* ERROR_NOT_SUPPORTED lpOverlapped is not supported
* ERROR_INSUFFICIENT_BUFFER
* ERROR_CALL_NOT_IMPLEMENTED unimplemented ioctl
*/
BOOL CommDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize,
LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
{
WINPR_COMM* pComm = (WINPR_COMM*) hDevice;
BOOL result;
if (hDevice == INVALID_HANDLE_VALUE)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (!pComm || pComm->Type != HANDLE_TYPE_COMM || !pComm->fd )
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
result = _CommDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize,
lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
if (pComm->permissive)
{
if (!result)
{
DEBUG_WARN("[permissive]: whereas it failed, made to succeed IoControlCode=[0x%lX] %s, last-error: 0x%lX",
dwIoControlCode, _comm_serial_ioctl_name(dwIoControlCode), GetLastError());
}
return TRUE; /* always! */
}
return result;
}
int _comm_ioctl_tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
{
int result;

View File

@ -81,7 +81,7 @@ static BOOL _set_wait_mask(WINPR_COMM *pComm, const ULONG *pWaitMask)
if (possibleMask != *pWaitMask)
{
DEBUG_WARN("Not all wait events supported (SerCx2.sys), requested events= 0X%0.4X, possible events= 0X%0.4X", *pWaitMask, possibleMask);
DEBUG_WARN("Not all wait events supported (SerCx2.sys), requested events= 0X%lX, possible events= 0X%lX", *pWaitMask, possibleMask);
/* FIXME: shall we really set the possibleMask and return FALSE? */
pComm->waitMask = possibleMask;

View File

@ -180,7 +180,7 @@ static BOOL _set_baud_rate(WINPR_COMM *pComm, const SERIAL_BAUD_RATE *pBaudRate)
newSpeed = _SERCX_SYS_BAUD_TABLE[i][0];
if (cfsetspeed(&futureState, newSpeed) < 0)
{
DEBUG_WARN("failed to set speed 0x%x (%d)", newSpeed, pBaudRate->BaudRate);
DEBUG_WARN("failed to set speed 0x%x (%lu)", newSpeed, pBaudRate->BaudRate);
return FALSE;
}
@ -188,7 +188,7 @@ static BOOL _set_baud_rate(WINPR_COMM *pComm, const SERIAL_BAUD_RATE *pBaudRate)
if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &futureState) < 0)
{
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x%0.8x", GetLastError());
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x%lX", GetLastError());
return FALSE;
}
@ -196,7 +196,7 @@ static BOOL _set_baud_rate(WINPR_COMM *pComm, const SERIAL_BAUD_RATE *pBaudRate)
}
}
DEBUG_WARN("could not find a matching speed for the baud rate %d", pBaudRate->BaudRate);
DEBUG_WARN("could not find a matching speed for the baud rate %lu", pBaudRate->BaudRate);
SetLastError(ERROR_INVALID_DATA);
return FALSE;
}
@ -231,264 +231,102 @@ static BOOL _get_baud_rate(WINPR_COMM *pComm, SERIAL_BAUD_RATE *pBaudRate)
return FALSE;
}
/* hard-coded in N_TTY */
#define TTY_THRESHOLD_THROTTLE 128 /* now based on remaining room */
#define TTY_THRESHOLD_UNTHROTTLE 128
/* FIXME: mostly copied/pasted from comm_serial_sys.c, better share this code */
static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow)
{
SERIAL_HANDFLOW SerCxHandflow;
BOOL result = TRUE;
struct termios upcomingTermios;
REMOTE_SERIAL_DRIVER* pSerialSys = SerialSys_s();
/* logical XOR */
if ((!(pHandflow->ControlHandShake & SERIAL_DTR_CONTROL) && (pHandflow->FlowReplace & SERIAL_RTS_CONTROL)) ||
((pHandflow->ControlHandShake & SERIAL_DTR_CONTROL) && !(pHandflow->FlowReplace & SERIAL_RTS_CONTROL)))
{
DEBUG_WARN("SERIAL_DTR_CONTROL cannot be different SERIAL_RTS_CONTROL, HUPCL will be set according SERIAL_RTS_CONTROL.");
result = FALSE; /* but keep on */
}
memcpy(&SerCxHandflow, pHandflow, sizeof(SERIAL_HANDFLOW));
ZeroMemory(&upcomingTermios, sizeof(struct termios));
if (tcgetattr(pComm->fd, &upcomingTermios) < 0)
{
SetLastError(ERROR_IO_DEVICE);
return FALSE;
}
/* filter out unsupported bits by SerCx.sys
*
* http://msdn.microsoft.com/en-us/library/windows/hardware/jj680685%28v=vs.85%29.aspx
*/
/* ControlHandShake */
SerCxHandflow.ControlHandShake = pHandflow->ControlHandShake & (SERIAL_DTR_CONTROL | SERIAL_DTR_HANDSHAKE | SERIAL_CTS_HANDSHAKE | SERIAL_DSR_HANDSHAKE);
SerCxHandflow.FlowReplace = pHandflow->FlowReplace & (SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE);
if (pHandflow->ControlHandShake & SERIAL_DTR_CONTROL)
if (SerCxHandflow.ControlHandShake != pHandflow->ControlHandShake)
{
upcomingTermios.c_cflag |= HUPCL;
}
else
{
upcomingTermios.c_cflag &= ~HUPCL;
if (pHandflow->ControlHandShake & SERIAL_DCD_HANDSHAKE)
{
DEBUG_WARN("SERIAL_DCD_HANDSHAKE not supposed to be implemented by SerCx.sys");
}
/* FIXME: is the DTR line also needs to be forced to a disable state? */
}
if (pHandflow->ControlHandShake & SERIAL_DSR_SENSITIVITY)
{
DEBUG_WARN("SERIAL_DSR_SENSITIVITY not supposed to be implemented by SerCx.sys");
}
if (pHandflow->ControlHandShake & SERIAL_DTR_HANDSHAKE)
{
/* DTR/DSR flow control not supported on Linux */
DEBUG_WARN("Attempt to use the unsupported SERIAL_DTR_HANDSHAKE feature.");
SetLastError(ERROR_NOT_SUPPORTED);
result = FALSE; /* but keep on */
}
if (pHandflow->ControlHandShake & SERIAL_ERROR_ABORT)
{
DEBUG_WARN("SERIAL_ERROR_ABORT not supposed to be implemented by SerCx.sys");
}
if (pHandflow->ControlHandShake & SERIAL_CTS_HANDSHAKE)
{
upcomingTermios.c_cflag |= CRTSCTS;
}
else
{
upcomingTermios.c_cflag &= ~CRTSCTS;
}
if (pHandflow->ControlHandShake & SERIAL_DSR_HANDSHAKE)
{
/* DTR/DSR flow control not supported on Linux */
DEBUG_WARN("Attempt to use the unsupported SERIAL_DSR_HANDSHAKE feature.");
SetLastError(ERROR_NOT_SUPPORTED);
result = FALSE; /* but keep on */
}
/* SERIAL_DCD_HANDSHAKE unsupported by SerCx */
if (pHandflow->ControlHandShake & SERIAL_DCD_HANDSHAKE)
{
DEBUG_WARN("Attempt to set SERIAL_DCD_HANDSHAKE (not implemented)");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
result = FALSE; /* but keep on */
result = FALSE;
}
/* SERIAL_DSR_SENSITIVITY unsupported by SerCx */
if (pHandflow->ControlHandShake & SERIAL_DSR_SENSITIVITY)
if (SerCxHandflow.FlowReplace != pHandflow->FlowReplace)
{
DEBUG_WARN("Attempt to set SERIAL_DSR_SENSITIVITY (not implemented)");
if (pHandflow->ControlHandShake & SERIAL_AUTO_TRANSMIT)
{
DEBUG_WARN("SERIAL_AUTO_TRANSMIT not supposed to be implemented by SerCx.sys");
}
if (pHandflow->ControlHandShake & SERIAL_AUTO_RECEIVE)
{
DEBUG_WARN("SERIAL_AUTO_RECEIVE not supposed to be implemented by SerCx.sys");
}
if (pHandflow->ControlHandShake & SERIAL_ERROR_CHAR)
{
DEBUG_WARN("SERIAL_ERROR_CHAR not supposed to be implemented by SerCx.sys");
}
if (pHandflow->ControlHandShake & SERIAL_NULL_STRIPPING)
{
DEBUG_WARN("SERIAL_NULL_STRIPPING not supposed to be implemented by SerCx.sys");
}
if (pHandflow->ControlHandShake & SERIAL_BREAK_CHAR)
{
DEBUG_WARN("SERIAL_BREAK_CHAR not supposed to be implemented by SerCx.sys");
}
if (pHandflow->ControlHandShake & SERIAL_XOFF_CONTINUE)
{
DEBUG_WARN("SERIAL_XOFF_CONTINUE not supposed to be implemented by SerCx.sys");
}
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
result = FALSE; /* but keep on */
}
/* SERIAL_ERROR_ABORT unsupported by SerCx */
if (pHandflow->ControlHandShake & SERIAL_ERROR_ABORT)
{
DEBUG_WARN("Attempt to set SERIAL_ERROR_ABORT (not implemented)");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
result = FALSE; /* but keep on */
}
/* FlowReplace */
/* SERIAL_AUTO_TRANSMIT unsupported by SerCx */
if (pHandflow->FlowReplace & SERIAL_AUTO_TRANSMIT)
{
DEBUG_WARN("Attempt to set SERIAL_AUTO_TRANSMIT (not implemented)");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
result = FALSE; /* but keep on */
}
/* SERIAL_AUTO_RECEIVE unsupported by SerCx */
if (pHandflow->FlowReplace & SERIAL_AUTO_RECEIVE)
{
DEBUG_WARN("Attempt to set SERIAL_AUTO_RECEIVE (not implemented)");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
result = FALSE; /* but keep on */
}
/* SERIAL_ERROR_CHAR unsupported by SerCx */
if (pHandflow->FlowReplace & SERIAL_ERROR_CHAR)
{
DEBUG_WARN("Attempt to set SERIAL_ERROR_CHAR (not implemented)");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
result = FALSE; /* but keep on */
}
/* SERIAL_NULL_STRIPPING unsupported by SerCx */
if (pHandflow->FlowReplace & SERIAL_NULL_STRIPPING)
{
DEBUG_WARN("Attempt to set SERIAL_NULL_STRIPPING (not implemented)");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
result = FALSE; /* but keep on */
}
/* SERIAL_BREAK_CHAR unsupported by SerCx */
if (pHandflow->FlowReplace & SERIAL_BREAK_CHAR)
{
DEBUG_WARN("Attempt to set SERIAL_BREAK_CHAR (not implemented)");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
result = FALSE; /* but keep on */
}
if (pHandflow->FlowReplace & SERIAL_RTS_CONTROL)
{
upcomingTermios.c_cflag |= HUPCL;
}
else
{
upcomingTermios.c_cflag &= ~HUPCL;
/* FIXME: is the RTS line also needs to be forced to a disable state? */
}
if (pHandflow->FlowReplace & SERIAL_RTS_HANDSHAKE)
{
upcomingTermios.c_cflag |= CRTSCTS;
}
else
{
upcomingTermios.c_cflag &= ~CRTSCTS;
}
/* SERIAL_XOFF_CONTINUE unsupported by SerCx */
if (pHandflow->FlowReplace & SERIAL_XOFF_CONTINUE)
{
DEBUG_WARN("Attempt to set SERIAL_XOFF_CONTINUE (not implemented)");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
result = FALSE; /* but keep on */
}
/* XonLimit */
// FIXME: could be implemented during read/write I/O
if (pHandflow->XonLimit != TTY_THRESHOLD_UNTHROTTLE)
{
DEBUG_WARN("Attempt to set XonLimit with an unsupported value: %d", pHandflow->XonLimit);
SetLastError(ERROR_NOT_SUPPORTED);
result = FALSE; /* but keep on */
}
/* XoffChar */
// FIXME: could be implemented during read/write I/O
if (pHandflow->XoffLimit != TTY_THRESHOLD_THROTTLE)
{
DEBUG_WARN("Attempt to set XoffLimit with an unsupported value: %d", pHandflow->XoffLimit);
SetLastError(ERROR_NOT_SUPPORTED);
result = FALSE; /* but keep on */
result = FALSE;
}
if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &upcomingTermios) < 0)
{
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x0.8x", GetLastError());
if (!pSerialSys->set_handflow(pComm, &SerCxHandflow))
return FALSE;
}
return result;
}
/* FIXME: mostly copied/pasted from comm_serial_sys.c, better share this code */
static BOOL _get_handflow(WINPR_COMM *pComm, SERIAL_HANDFLOW *pHandflow)
{
struct termios currentTermios;
BOOL result;
REMOTE_SERIAL_DRIVER* pSerialSys = SerialSys_s();
ZeroMemory(&currentTermios, sizeof(struct termios));
if (tcgetattr(pComm->fd, &currentTermios) < 0)
{
SetLastError(ERROR_IO_DEVICE);
return FALSE;
}
result = pSerialSys->get_handflow(pComm, pHandflow);
/* filter out unsupported bits by SerCx.sys
*
* http://msdn.microsoft.com/en-us/library/windows/hardware/jj680685%28v=vs.85%29.aspx
*/
/* ControlHandShake */
pHandflow->ControlHandShake = pHandflow->ControlHandShake & (SERIAL_DTR_CONTROL | SERIAL_DTR_HANDSHAKE | SERIAL_CTS_HANDSHAKE | SERIAL_DSR_HANDSHAKE);
pHandflow->FlowReplace = pHandflow->FlowReplace & (SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE);
pHandflow->ControlHandShake = 0;
if (currentTermios.c_cflag & HUPCL)
pHandflow->ControlHandShake |= SERIAL_DTR_CONTROL;
/* SERIAL_DTR_HANDSHAKE unsupported */
if (currentTermios.c_cflag & CRTSCTS)
pHandflow->ControlHandShake |= SERIAL_CTS_HANDSHAKE;
/* SERIAL_DSR_HANDSHAKE unsupported */
/* SERIAL_DCD_HANDSHAKE unsupported by SerCx */
/* SERIAL_DSR_SENSITIVITY unsupported by SerCx */
/* SERIAL_ERROR_ABORT unsupported by SerCx */
/* FlowReplace */
pHandflow->FlowReplace = 0;
/* SERIAL_AUTO_TRANSMIT unsupported by SerCx */
/* SERIAL_AUTO_RECEIVE unsupported by SerCx */
/* SERIAL_ERROR_CHAR unsupported by SerCx */
/* SERIAL_NULL_STRIPPING unsupported by SerCx */
/* SERIAL_BREAK_CHAR unsupported by SerCx */
if (currentTermios.c_cflag & HUPCL)
pHandflow->FlowReplace |= SERIAL_RTS_CONTROL;
if (currentTermios.c_cflag & CRTSCTS)
pHandflow->FlowReplace |= SERIAL_RTS_HANDSHAKE;
/* SERIAL_XOFF_CONTINUE unsupported by SerCx */
/* XonLimit */
pHandflow->XonLimit = TTY_THRESHOLD_UNTHROTTLE;
/* XoffLimit */
pHandflow->XoffLimit = TTY_THRESHOLD_THROTTLE;
return TRUE;
return result;
}
@ -518,7 +356,7 @@ static BOOL _set_wait_mask(WINPR_COMM *pComm, const ULONG *pWaitMask)
if (possibleMask != *pWaitMask)
{
DEBUG_WARN("Not all wait events supported (SerCx.sys), requested events= 0X%0.4X, possible events= 0X%0.4X", *pWaitMask, possibleMask);
DEBUG_WARN("Not all wait events supported (SerCx.sys), requested events= 0x%lX, possible events= 0x%lX", *pWaitMask, possibleMask);
/* FIXME: shall we really set the possibleMask and return FALSE? */
pComm->waitMask = possibleMask;

View File

@ -236,13 +236,13 @@ static BOOL _set_baud_rate(WINPR_COMM *pComm, const SERIAL_BAUD_RATE *pBaudRate)
newSpeed = _SERIAL_SYS_BAUD_TABLE[i][0];
if (cfsetspeed(&upcomingTermios, newSpeed) < 0)
{
DEBUG_WARN("failed to set speed %d (%d)", newSpeed, pBaudRate->BaudRate);
DEBUG_WARN("failed to set speed %u (%lu)", newSpeed, pBaudRate->BaudRate);
return FALSE;
}
if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &upcomingTermios) < 0)
{
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x0.8x", GetLastError());
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x%lX", GetLastError());
return FALSE;
}
@ -250,7 +250,7 @@ static BOOL _set_baud_rate(WINPR_COMM *pComm, const SERIAL_BAUD_RATE *pBaudRate)
}
}
DEBUG_WARN("could not find a matching speed for the baud rate %d", pBaudRate->BaudRate);
DEBUG_WARN("could not find a matching speed for the baud rate %lu", pBaudRate->BaudRate);
SetLastError(ERROR_INVALID_DATA);
return FALSE;
}
@ -352,7 +352,7 @@ static BOOL _set_serial_chars(WINPR_COMM *pComm, const SERIAL_CHARS *pSerialChar
result = FALSE; /* but keep on */
}
/* TMP: FIXME: Didn't find anything similar yet on Linux */
/* TMP: FIXME: Didn't find anything similar yet on Linux. What about ISIG? */
if (pSerialChars->EventChar != '\0')
{
DEBUG_WARN("EventChar='%c' (0x%x) cannot be set\n", pSerialChars->EventChar, pSerialChars->EventChar);
@ -367,7 +367,7 @@ static BOOL _set_serial_chars(WINPR_COMM *pComm, const SERIAL_CHARS *pSerialChar
if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &upcomingTermios) < 0)
{
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x0.8x", GetLastError());
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x%lX", GetLastError());
return FALSE;
}
@ -512,7 +512,7 @@ static BOOL _set_line_control(WINPR_COMM *pComm, const SERIAL_LINE_CONTROL *pLin
if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &upcomingTermios) < 0)
{
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x0.8x", GetLastError());
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x%lX", GetLastError());
return FALSE;
}
@ -572,15 +572,6 @@ static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow)
BOOL result = TRUE;
struct termios upcomingTermios;
/* logical XOR */
if ((!(pHandflow->ControlHandShake & SERIAL_DTR_CONTROL) && (pHandflow->FlowReplace & SERIAL_RTS_CONTROL)) ||
((pHandflow->ControlHandShake & SERIAL_DTR_CONTROL) && !(pHandflow->FlowReplace & SERIAL_RTS_CONTROL)))
{
DEBUG_WARN("SERIAL_DTR_CONTROL cannot be different SERIAL_RTS_CONTROL, HUPCL will be set according SERIAL_RTS_CONTROL.");
result = FALSE; /* but keep on */
}
ZeroMemory(&upcomingTermios, sizeof(struct termios));
if (tcgetattr(pComm->fd, &upcomingTermios) < 0)
{
@ -588,9 +579,18 @@ static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow)
return FALSE;
}
/* ControlHandShake */
/* HUPCL */
if (pHandflow->ControlHandShake & SERIAL_DTR_CONTROL)
/* logical XOR */
if ((!(pHandflow->ControlHandShake & SERIAL_DTR_CONTROL) && (pHandflow->FlowReplace & SERIAL_RTS_CONTROL)) ||
((pHandflow->ControlHandShake & SERIAL_DTR_CONTROL) && !(pHandflow->FlowReplace & SERIAL_RTS_CONTROL)))
{
DEBUG_WARN("SERIAL_DTR_CONTROL:%s and SERIAL_RTS_CONTROL:%s cannot be different, HUPCL will be set since it is claimed for one of the both lines.",
(pHandflow->ControlHandShake & SERIAL_DTR_CONTROL) ? "ON" : "OFF",
(pHandflow->FlowReplace & SERIAL_RTS_CONTROL) ? "ON" : "OFF");
}
if ((pHandflow->ControlHandShake & SERIAL_DTR_CONTROL) || (pHandflow->FlowReplace & SERIAL_RTS_CONTROL))
{
upcomingTermios.c_cflag |= HUPCL;
}
@ -598,9 +598,34 @@ static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow)
{
upcomingTermios.c_cflag &= ~HUPCL;
/* FIXME: is the DTR line also needs to be forced to a disable state? */
/* FIXME: is the DTR line also needs to be forced to a disable state according SERIAL_DTR_CONTROL? */
/* FIXME: is the RTS line also needs to be forced to a disable state according SERIAL_RTS_CONTROL? */
}
/* CRTSCTS */
/* logical XOR */
if ((!(pHandflow->ControlHandShake & SERIAL_CTS_HANDSHAKE) && (pHandflow->FlowReplace & SERIAL_RTS_HANDSHAKE)) ||
((pHandflow->ControlHandShake & SERIAL_CTS_HANDSHAKE) && !(pHandflow->FlowReplace & SERIAL_RTS_HANDSHAKE)))
{
DEBUG_WARN("SERIAL_CTS_HANDSHAKE:%s and SERIAL_RTS_HANDSHAKE:%s cannot be different, CRTSCTS will be set since it is claimed for one of the both lines.",
(pHandflow->ControlHandShake & SERIAL_CTS_HANDSHAKE) ? "ON" : "OFF",
(pHandflow->FlowReplace & SERIAL_RTS_HANDSHAKE) ? "ON" : "OFF");
}
if ((pHandflow->ControlHandShake & SERIAL_CTS_HANDSHAKE) || (pHandflow->FlowReplace & SERIAL_RTS_HANDSHAKE))
{
upcomingTermios.c_cflag |= CRTSCTS;
}
else
{
upcomingTermios.c_cflag &= ~CRTSCTS;
}
/* ControlHandShake */
if (pHandflow->ControlHandShake & SERIAL_DTR_HANDSHAKE)
{
/* DTR/DSR flow control not supported on Linux */
@ -610,15 +635,6 @@ static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow)
}
if (pHandflow->ControlHandShake & SERIAL_CTS_HANDSHAKE)
{
upcomingTermios.c_cflag |= CRTSCTS;
}
else
{
upcomingTermios.c_cflag &= ~CRTSCTS;
}
if (pHandflow->ControlHandShake & SERIAL_DSR_HANDSHAKE)
{
/* DTR/DSR flow control not supported on Linux */
@ -673,12 +689,10 @@ static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow)
upcomingTermios.c_iflag &= ~IXOFF;
}
// TMP: FIXME: could be implemented during read/write I/O
// TMP: FIXME: could be implemented during read/write I/O, as of today ErrorChar is necessary '\0'
if (pHandflow->FlowReplace & SERIAL_ERROR_CHAR)
{
DEBUG_WARN("Attempt to use the unsupported SERIAL_ERROR_CHAR feature. A character with a parity error or framing error will be read as \0");
/* errors will be replaced by the character '\0' */
/* errors will be replaced by the character '\0'. */
upcomingTermios.c_iflag &= ~IGNPAR;
}
else
@ -703,27 +717,6 @@ static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow)
result = FALSE; /* but keep on */
}
if (pHandflow->FlowReplace & SERIAL_RTS_CONTROL)
{
upcomingTermios.c_cflag |= HUPCL;
}
else
{
upcomingTermios.c_cflag &= ~HUPCL;
/* FIXME: is the RTS line also needs to be forced to a disable state? */
}
if (pHandflow->FlowReplace & SERIAL_RTS_HANDSHAKE)
{
upcomingTermios.c_cflag |= CRTSCTS;
}
else
{
upcomingTermios.c_cflag &= ~CRTSCTS;
}
// FIXME: could be implemented during read/write I/O
if (pHandflow->FlowReplace & SERIAL_XOFF_CONTINUE)
{
@ -738,7 +731,7 @@ static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow)
// FIXME: could be implemented during read/write I/O
if (pHandflow->XonLimit != TTY_THRESHOLD_UNTHROTTLE)
{
DEBUG_WARN("Attempt to set XonLimit with an unsupported value: %d", pHandflow->XonLimit);
DEBUG_WARN("Attempt to set XonLimit with an unsupported value: %lu", pHandflow->XonLimit);
SetLastError(ERROR_NOT_SUPPORTED);
result = FALSE; /* but keep on */
}
@ -748,7 +741,7 @@ static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow)
// FIXME: could be implemented during read/write I/O
if (pHandflow->XoffLimit != TTY_THRESHOLD_THROTTLE)
{
DEBUG_WARN("Attempt to set XoffLimit with an unsupported value: %d", pHandflow->XoffLimit);
DEBUG_WARN("Attempt to set XoffLimit with an unsupported value: %lu", pHandflow->XoffLimit);
SetLastError(ERROR_NOT_SUPPORTED);
result = FALSE; /* but keep on */
}
@ -756,7 +749,7 @@ static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow)
if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &upcomingTermios) < 0)
{
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x0.8x", GetLastError());
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x%lX", GetLastError());
return FALSE;
}
@ -873,7 +866,7 @@ static BOOL _set_lines(WINPR_COMM *pComm, UINT32 lines)
{
if (ioctl(pComm->fd, TIOCMBIS, &lines) < 0)
{
DEBUG_WARN("TIOCMBIS ioctl failed, lines=0x%0.4X, errno=[%d] %s", lines, errno, strerror(errno));
DEBUG_WARN("TIOCMBIS ioctl failed, lines=0x%X, errno=[%d] %s", lines, errno, strerror(errno));
SetLastError(ERROR_IO_DEVICE);
return FALSE;
}
@ -886,7 +879,7 @@ static BOOL _clear_lines(WINPR_COMM *pComm, UINT32 lines)
{
if (ioctl(pComm->fd, TIOCMBIC, &lines) < 0)
{
DEBUG_WARN("TIOCMBIC ioctl failed, lines=0x%0.4X, errno=[%d] %s", lines, errno, strerror(errno));
DEBUG_WARN("TIOCMBIC ioctl failed, lines=0x%X, errno=[%d] %s", lines, errno, strerror(errno));
SetLastError(ERROR_IO_DEVICE);
return FALSE;
}
@ -933,32 +926,30 @@ static BOOL _clear_dtr(WINPR_COMM *pComm)
static BOOL _set_rts(WINPR_COMM *pComm)
{
// TMP: really required?
/* SERIAL_HANDFLOW handflow; */
/* if (!_get_handflow(pComm, &handflow)) */
/* return FALSE; */
SERIAL_HANDFLOW handflow;
if (!_get_handflow(pComm, &handflow))
return FALSE;
/* if (handflow.FlowReplace & SERIAL_RTS_HANDSHAKE) */
/* { */
/* SetLastError(ERROR_INVALID_PARAMETER); */
/* return FALSE; */
/* } */
if (handflow.FlowReplace & SERIAL_RTS_HANDSHAKE)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return _set_lines(pComm, TIOCM_RTS);
}
static BOOL _clear_rts(WINPR_COMM *pComm)
{
// TMP: really required?
/* SERIAL_HANDFLOW handflow; */
/* if (!_get_handflow(pComm, &handflow)) */
/* return FALSE; */
SERIAL_HANDFLOW handflow;
if (!_get_handflow(pComm, &handflow))
return FALSE;
/* if (handflow.FlowReplace & SERIAL_RTS_HANDSHAKE) */
/* { */
/* SetLastError(ERROR_INVALID_PARAMETER); */
/* return FALSE; */
/* } */
if (handflow.FlowReplace & SERIAL_RTS_HANDSHAKE)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return _clear_lines(pComm, TIOCM_RTS);
}
@ -977,8 +968,9 @@ static BOOL _get_modemstatus(WINPR_COMM *pComm, ULONG *pRegister)
ZeroMemory(pRegister, sizeof(ULONG));
/* TODO: FIXME: how to get a direct access from the user space
* to the MSR register in order to complete the 4 first bits?
/* FIXME: Is the last read of the MSR register available or
* cached somewhere? Not quite sure we need to return the 4
* LSBits anyway.
*/
/* #define SERIAL_MSR_DCTS 0x01 */
@ -1038,13 +1030,13 @@ static BOOL _set_wait_mask(WINPR_COMM *pComm, const ULONG *pWaitMask)
// TMP: TODO:
// pending wait_on_mask must be stopped with STATUS_SUCCESS
// http://msdn.microsoft.com/en-us/library/ff546805%28v=vs.85%29.aspx
// and pOutputMask = 0;
possibleMask = *pWaitMask & _SERIAL_SYS_SUPPORTED_EV_MASK;
if (possibleMask != *pWaitMask)
{
DEBUG_WARN("Not all wait events supported (Serial.sys), requested events= 0X%0.4X, possible events= 0X%0.4X", *pWaitMask, possibleMask);
DEBUG_WARN("Not all wait events supported (Serial.sys), requested events= 0X%lX, possible events= 0X%lX", *pWaitMask, possibleMask);
/* FIXME: shall we really set the possibleMask and return FALSE? */
pComm->waitMask = possibleMask;
@ -1067,7 +1059,7 @@ static BOOL _wait_on_mask(WINPR_COMM *pComm, ULONG *pOutputMask)
{
assert(*pOutputMask == 0);
// TMP: TODO:
// TMP: TODO: be sure to get a dedicated thread
/* while (TRUE) */
{
int nbBytesToBeRead = 0;
@ -1097,7 +1089,7 @@ static BOOL _wait_on_mask(WINPR_COMM *pComm, ULONG *pOutputMask)
return FALSE;
}
/* NB: preferred below "currentCounters.* != pComm->counters.*" over "currentCounters.* > pComm->counters.*" thinking the counters can loop */
/* NB: preferred below (currentCounters.* != pComm->counters.*) over (currentCounters.* > pComm->counters.*) thinking the counters can loop */
/* events */
@ -1224,8 +1216,9 @@ static BOOL _wait_on_mask(WINPR_COMM *pComm, ULONG *pOutputMask)
}
/* FIXME: TIOCMIWAIT could be possible if _wait_on_mask gets its own thread */
/* if (*pOutputMask == 0) */
// TMP: TIOCMIWAIT could be possible if _wait_on_mask gets its own thread
/* if ((*pOutputMask == 0) && /\* don't bother at least one of the events event already occured *\/ */
/* ((pComm->waitMask & ~(SERIAL_EV_CTS | SERIAL_EV_DSR | SERIAL_EV_RLSD | SERIAL_EV_RING)) == 0)) /\* only events handled by TIOCMIWAIT, otherwise go through the regular loop *\/ */
/* { */
/* if (ioctl(pComm->fd, TIOCMIWAIT, &tiocmiwaitMask) < 0) */
/* { */
@ -1233,7 +1226,9 @@ static BOOL _wait_on_mask(WINPR_COMM *pComm, ULONG *pOutputMask)
/* SetLastError(ERROR_IO_DEVICE); */
/* return FALSE; */
/* } */
/* /\* TODO: check counters again after TIOCMIWAIT *\/ */
/* /\* check counters again after TIOCMIWAIT *\/ */
/* continue; */
/* } */
}
@ -1243,13 +1238,14 @@ static BOOL _wait_on_mask(WINPR_COMM *pComm, ULONG *pOutputMask)
return TRUE;
}
/* // TMP: */
/* DEBUG_WARN("waiting on events:0X%0.4X", pComm->waitMask); */
/* /\* // TMP: *\/ */
/* DEBUG_WARN("waiting on events:0X%lX", pComm->waitMask); */
/* sleep(1); */
}
DEBUG_WARN("_wait_on_mask pending on events:0X%0.4X", pComm->waitMask);
DEBUG_WARN("_wait_on_mask pending on events:0X%lX", pComm->waitMask);
SetLastError(ERROR_IO_PENDING); /* see: WaitCommEvent's help */
return FALSE;
}
@ -1275,10 +1271,10 @@ static BOOL _set_queue_size(WINPR_COMM *pComm, const SERIAL_QUEUE_SIZE *pQueueSi
/* FIXME: could be implemented on top of N_TTY */
if (pQueueSize->InSize > N_TTY_BUF_SIZE)
DEBUG_WARN("Requested an incompatible input buffer size: %d", pQueueSize->InSize);
DEBUG_WARN("Requested an incompatible input buffer size: %lu", pQueueSize->InSize);
if (pQueueSize->OutSize > N_TTY_BUF_SIZE)
DEBUG_WARN("Requested an incompatible output buffer size: %d", pQueueSize->OutSize);
DEBUG_WARN("Requested an incompatible output buffer size: %lu", pQueueSize->OutSize);
SetLastError(ERROR_CANCELLED);
return FALSE;
@ -1289,7 +1285,7 @@ static BOOL _purge(WINPR_COMM *pComm, const ULONG *pPurgeMask)
{
if ((*pPurgeMask & ~(SERIAL_PURGE_TXABORT | SERIAL_PURGE_RXABORT | SERIAL_PURGE_TXCLEAR | SERIAL_PURGE_RXCLEAR)) > 0)
{
DEBUG_WARN("Invalid purge mask: 0x%X\n", *pPurgeMask);
DEBUG_WARN("Invalid purge mask: 0x%lX\n", *pPurgeMask);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
@ -1313,9 +1309,10 @@ static BOOL _purge(WINPR_COMM *pComm, const ULONG *pPurgeMask)
}
/* TMP: TODO: double check if this gives well a change to abort a pending CommReadFile */
fcntl(pComm->fd, F_SETFL, fcntl(pComm->fd, F_GETFL) | O_NONBLOCK);
sleep(1);
fcntl(pComm->fd, F_SETFL, fcntl(pComm->fd, F_GETFL) & ~O_NONBLOCK);
//assert(0);
/* fcntl(pComm->fd, F_SETFL, fcntl(pComm->fd, F_GETFL) | O_NONBLOCK); */
/* sleep(1); */
/* fcntl(pComm->fd, F_SETFL, fcntl(pComm->fd, F_GETFL) & ~O_NONBLOCK); */
/* TMP: FIXME: synchronization of the incoming
* IRP_MJ_READ-s. Could be possible to make them to