mirror of https://github.com/FreeRDP/FreeRDP
wimpr-comm: got IOCTL_SERIAL_SET_LINE_CONTROL and IOCTL_SERIAL_GET_LINE_CONTROL
This commit is contained in:
parent
ee2339addc
commit
feb4405941
|
@ -223,7 +223,19 @@ BOOL GetCommState(HANDLE hFile, LPDCB lpDCB)
|
|||
/* TMP: TODO: */
|
||||
/* (...) */
|
||||
|
||||
|
||||
SERIAL_LINE_CONTROL lineControl;
|
||||
if (!CommDeviceIoControl(pComm, IOCTL_SERIAL_GET_LINE_CONTROL, NULL, 0, &lineControl, sizeof(SERIAL_LINE_CONTROL), &bytesReturned, NULL))
|
||||
{
|
||||
DEBUG_WARN("GetCommState failure: could not get the control settings.");
|
||||
goto error_handle;
|
||||
}
|
||||
|
||||
lpLocalDcb->ByteSize = lineControl.WordLength;
|
||||
|
||||
lpLocalDcb->Parity = lineControl.Parity;
|
||||
|
||||
lpLocalDcb->StopBits = lineControl.StopBits;
|
||||
|
||||
|
||||
SERIAL_CHARS serialChars;
|
||||
if (!CommDeviceIoControl(pComm, IOCTL_SERIAL_GET_CHARS, NULL, 0, &serialChars, sizeof(SERIAL_CHARS), &bytesReturned, NULL))
|
||||
|
@ -316,6 +328,16 @@ BOOL SetCommState(HANDLE hFile, LPDCB lpDCB)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
SERIAL_LINE_CONTROL lineControl;
|
||||
lineControl.StopBits = lpDCB->StopBits;
|
||||
lineControl.Parity = lpDCB->Parity;
|
||||
lineControl.WordLength = lpDCB->ByteSize;
|
||||
if (!CommDeviceIoControl(pComm, IOCTL_SERIAL_SET_LINE_CONTROL, &lineControl, sizeof(SERIAL_LINE_CONTROL), NULL, 0, &bytesReturned, NULL))
|
||||
{
|
||||
DEBUG_WARN("SetCommState failure: could not set the control settings.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/** upcomingTermios stage **/
|
||||
|
||||
|
|
|
@ -212,6 +212,43 @@ BOOL CommDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffe
|
|||
return TRUE;
|
||||
}
|
||||
}
|
||||
case IOCTL_SERIAL_SET_LINE_CONTROL:
|
||||
{
|
||||
if (pRemoteSerialDriver->set_line_control)
|
||||
{
|
||||
SERIAL_LINE_CONTROL *pLineControl = (SERIAL_LINE_CONTROL*)lpInBuffer;
|
||||
|
||||
assert(nInBufferSize >= sizeof(SERIAL_LINE_CONTROL));
|
||||
if (nInBufferSize < sizeof(SERIAL_LINE_CONTROL))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return pRemoteSerialDriver->set_line_control(pComm, pLineControl);
|
||||
}
|
||||
}
|
||||
case IOCTL_SERIAL_GET_LINE_CONTROL:
|
||||
{
|
||||
if (pRemoteSerialDriver->get_line_control)
|
||||
{
|
||||
SERIAL_LINE_CONTROL *pLineControl = (SERIAL_LINE_CONTROL*)lpOutBuffer;
|
||||
|
||||
assert(nOutBufferSize >= sizeof(SERIAL_LINE_CONTROL));
|
||||
if (nOutBufferSize < sizeof(SERIAL_LINE_CONTROL))
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!pRemoteSerialDriver->get_line_control(pComm, pLineControl))
|
||||
return FALSE;
|
||||
|
||||
*lpBytesReturned = sizeof(SERIAL_LINE_CONTROL);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DEBUG_WARN(_T("unsupported IoControlCode: Ox%x (remote serial driver: %s)"), dwIoControlCode, pRemoteSerialDriver->name);
|
||||
|
|
|
@ -43,9 +43,8 @@ extern "C" {
|
|||
|
||||
#define IOCTL_SERIAL_SET_BAUD_RATE 0x001B0004
|
||||
#define IOCTL_SERIAL_GET_BAUD_RATE 0x001B0050
|
||||
|
||||
/* #define IOCTL_SERIAL_SET_LINE_CONTROL 0x001B000C */
|
||||
/* IOCTL_SERIAL_GET_LINE_CONTROL 0x001B0054 */
|
||||
#define IOCTL_SERIAL_SET_LINE_CONTROL 0x001B000C
|
||||
#define IOCTL_SERIAL_GET_LINE_CONTROL 0x001B0054
|
||||
/* IOCTL_SERIAL_SET_TIMEOUTS 0x001B001C */
|
||||
/* IOCTL_SERIAL_GET_TIMEOUTS 0x001B0020 */
|
||||
|
||||
|
@ -97,6 +96,16 @@ extern "C" {
|
|||
/* IOCTL_PAR_IS_PORT_FREE 0x00160054 */
|
||||
|
||||
|
||||
#define STOP_BIT_1 0
|
||||
#define STOP_BITS_1_5 1
|
||||
#define STOP_BITS_2 2
|
||||
|
||||
#define NO_PARITY 0
|
||||
#define ODD_PARITY 1
|
||||
#define EVEN_PARITY 2
|
||||
#define MARK_PARITY 3
|
||||
#define SPACE_PARITY 4
|
||||
|
||||
|
||||
typedef struct _SERIAL_BAUD_RATE
|
||||
{
|
||||
|
@ -115,6 +124,14 @@ typedef struct _SERIAL_CHARS
|
|||
} SERIAL_CHARS, *PSERIAL_CHARS;
|
||||
|
||||
|
||||
typedef struct _SERIAL_LINE_CONTROL
|
||||
{
|
||||
UCHAR StopBits;
|
||||
UCHAR Parity;
|
||||
UCHAR WordLength;
|
||||
} SERIAL_LINE_CONTROL, *PSERIAL_LINE_CONTROL;
|
||||
|
||||
|
||||
/**
|
||||
* A function might be NULL if not supported by the underlying remote driver.
|
||||
*
|
||||
|
@ -129,6 +146,8 @@ typedef struct _REMOTE_SERIAL_DRIVER
|
|||
BOOL (*get_properties)(WINPR_COMM *pComm, COMMPROP *pProperties);
|
||||
BOOL (*set_serial_chars)(WINPR_COMM *pComm, const SERIAL_CHARS *pSerialChars);
|
||||
BOOL (*get_serial_chars)(WINPR_COMM *pComm, SERIAL_CHARS *pSerialChars);
|
||||
BOOL (*set_line_control)(WINPR_COMM *pComm, const SERIAL_LINE_CONTROL *pLineControl);
|
||||
BOOL (*get_line_control)(WINPR_COMM *pComm, SERIAL_LINE_CONTROL *pLineControl);
|
||||
|
||||
} REMOTE_SERIAL_DRIVER;
|
||||
|
||||
|
|
|
@ -61,12 +61,14 @@ static REMOTE_SERIAL_DRIVER _SerCx2Sys =
|
|||
.get_properties = NULL,
|
||||
.set_serial_chars = _set_serial_chars,
|
||||
.get_serial_chars = _get_serial_chars,
|
||||
.set_line_control = NULL,
|
||||
.get_line_control = NULL,
|
||||
};
|
||||
|
||||
|
||||
REMOTE_SERIAL_DRIVER* SerCx2Sys_s()
|
||||
{
|
||||
/* _SerCx2Sys completed with SerialSys or SerCxSys default functions */
|
||||
/* _SerCx2Sys completed with inherited functions from SerialSys or SerCxSys */
|
||||
//REMOTE_SERIAL_DRIVER* pSerialSys = SerialSys_s();
|
||||
REMOTE_SERIAL_DRIVER* pSerCxSys = SerCxSys_s();
|
||||
|
||||
|
@ -74,6 +76,9 @@ REMOTE_SERIAL_DRIVER* SerCx2Sys_s()
|
|||
_SerCx2Sys.get_baud_rate = pSerCxSys->get_baud_rate;
|
||||
_SerCx2Sys.get_properties = pSerCxSys->get_properties;
|
||||
|
||||
_SerCx2Sys.set_line_control = pSerCxSys->set_line_control;
|
||||
_SerCx2Sys.get_line_control = pSerCxSys->get_line_control;
|
||||
|
||||
return &_SerCx2Sys;
|
||||
}
|
||||
|
||||
|
|
|
@ -139,22 +139,16 @@ static const speed_t _SERCX_SYS_BAUD_TABLE[][3] = {
|
|||
static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties)
|
||||
{
|
||||
int i;
|
||||
REMOTE_SERIAL_DRIVER* pSerialSys = SerialSys_s();
|
||||
|
||||
// TMP: TODO:
|
||||
if (!pSerialSys->get_properties(pComm, pProperties))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// TMP: required?
|
||||
// ZeroMemory(pProperties, sizeof(COMMPROP);
|
||||
/* override some of the inherited properties from SerialSys ... */
|
||||
|
||||
/* pProperties->PacketLength; */
|
||||
/* pProperties->PacketVersion; */
|
||||
/* pProperties->ServiceMask; */
|
||||
/* pProperties->Reserved1; */
|
||||
/* pProperties->MaxTxQueue; */
|
||||
/* pProperties->MaxRxQueue; */
|
||||
pProperties->dwMaxBaud = BAUD_USER;
|
||||
/* pProperties->ProvSubType; */
|
||||
/* pProperties->ProvCapabilities; */
|
||||
/* pProperties->SettableParams; */
|
||||
|
||||
pProperties->dwSettableBaud = 0;
|
||||
for (i=0; _SERCX_SYS_BAUD_TABLE[i][0]<=__MAX_BAUD; i++)
|
||||
|
@ -162,14 +156,6 @@ static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties)
|
|||
pProperties->dwSettableBaud |= _SERCX_SYS_BAUD_TABLE[i][2];
|
||||
}
|
||||
|
||||
/* pProperties->SettableData; */
|
||||
/* pProperties->SettableStopParity; */
|
||||
/* pProperties->CurrentTxQueue; */
|
||||
/* pProperties->CurrentRxQueue; */
|
||||
/* pProperties->ProvSpec1; */
|
||||
/* pProperties->ProvSpec2; */
|
||||
/* pProperties->ProvChar[1]; */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -256,17 +242,21 @@ static REMOTE_SERIAL_DRIVER _SerCxSys =
|
|||
.get_properties = _get_properties,
|
||||
.set_serial_chars = NULL,
|
||||
.get_serial_chars = NULL,
|
||||
.set_line_control = NULL,
|
||||
.get_line_control = NULL,
|
||||
};
|
||||
|
||||
|
||||
|
||||
REMOTE_SERIAL_DRIVER* SerCxSys_s()
|
||||
{
|
||||
/* _SerCxSys completed with default SerialSys_s functions */
|
||||
/* _SerCxSys completed with inherited functions from SerialSys */
|
||||
REMOTE_SERIAL_DRIVER* pSerialSys = SerialSys_s();
|
||||
|
||||
_SerCxSys.set_serial_chars = pSerialSys->set_serial_chars;
|
||||
_SerCxSys.get_serial_chars = pSerialSys->get_serial_chars;
|
||||
_SerCxSys.set_line_control = pSerialSys->set_line_control;
|
||||
_SerCxSys.get_line_control = pSerialSys->get_line_control;
|
||||
|
||||
return &_SerCxSys;
|
||||
}
|
||||
|
|
|
@ -142,6 +142,10 @@ static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties)
|
|||
{
|
||||
int i;
|
||||
|
||||
/* FIXME: properties should be better probe. The current
|
||||
* implementation just relies on the Linux' implementation.
|
||||
*/
|
||||
|
||||
// TMP: TODO:
|
||||
|
||||
// TMP: required?
|
||||
|
@ -164,8 +168,10 @@ static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties)
|
|||
pProperties->dwSettableBaud |= _SERIAL_SYS_BAUD_TABLE[i][1];
|
||||
}
|
||||
|
||||
/* pProperties->SettableData; */
|
||||
/* pProperties->SettableStopParity; */
|
||||
pProperties->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 /*| DATABITS_16 | DATABITS_16X*/;
|
||||
|
||||
pProperties->wSettableStopParity = STOPBITS_10 | /*STOPBITS_15 |*/ STOPBITS_20 | PARITY_NONE | PARITY_ODD | PARITY_EVEN | PARITY_MARK | PARITY_SPACE;
|
||||
|
||||
/* pProperties->CurrentTxQueue; */
|
||||
/* pProperties->CurrentRxQueue; */
|
||||
/* pProperties->ProvSpec1; */
|
||||
|
@ -380,6 +386,168 @@ static BOOL _get_serial_chars(WINPR_COMM *pComm, SERIAL_CHARS *pSerialChars)
|
|||
}
|
||||
|
||||
|
||||
static BOOL _set_line_control(WINPR_COMM *pComm, const SERIAL_LINE_CONTROL *pLineControl)
|
||||
{
|
||||
BOOL result = TRUE;
|
||||
struct termios upcomingTermios;
|
||||
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa363214%28v=vs.85%29.aspx
|
||||
*
|
||||
* The use of 5 data bits with 2 stop bits is an invalid
|
||||
* combination, as is 6, 7, or 8 data bits with 1.5 stop bits.
|
||||
*
|
||||
* FIXME: prefered to let the underlying driver to deal with
|
||||
* this issue. At least produce a warning message?
|
||||
*/
|
||||
|
||||
|
||||
ZeroMemory(&upcomingTermios, sizeof(struct termios));
|
||||
if (tcgetattr(pComm->fd, &upcomingTermios) < 0)
|
||||
{
|
||||
SetLastError(ERROR_IO_DEVICE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIXME: use of a COMMPROP to validate new settings? */
|
||||
|
||||
switch (pLineControl->StopBits)
|
||||
{
|
||||
case STOP_BIT_1:
|
||||
upcomingTermios.c_cflag &= ~CSTOPB;
|
||||
break;
|
||||
|
||||
case STOP_BITS_1_5:
|
||||
DEBUG_WARN("Unsupported one and a half stop bits.");
|
||||
break;
|
||||
|
||||
case STOP_BITS_2:
|
||||
upcomingTermios.c_cflag |= CSTOPB;
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_WARN("unexpected number of stop bits: %d\n", pLineControl->StopBits);
|
||||
result = FALSE; /* but keep on */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch (pLineControl->Parity)
|
||||
{
|
||||
case NO_PARITY:
|
||||
upcomingTermios.c_cflag &= ~(PARENB | PARODD | CMSPAR);
|
||||
break;
|
||||
|
||||
case ODD_PARITY:
|
||||
upcomingTermios.c_cflag &= ~CMSPAR;
|
||||
upcomingTermios.c_cflag |= PARENB | PARODD;
|
||||
break;
|
||||
|
||||
case EVEN_PARITY:
|
||||
upcomingTermios.c_cflag &= ~(PARODD | CMSPAR);
|
||||
upcomingTermios.c_cflag |= PARENB;
|
||||
break;
|
||||
|
||||
case MARK_PARITY:
|
||||
upcomingTermios.c_cflag |= PARENB | PARODD | CMSPAR;
|
||||
break;
|
||||
|
||||
case SPACE_PARITY:
|
||||
upcomingTermios.c_cflag &= ~PARODD;
|
||||
upcomingTermios.c_cflag |= PARENB | CMSPAR;
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_WARN("unexpected type of parity: %d\n", pLineControl->Parity);
|
||||
result = FALSE; /* but keep on */
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pLineControl->WordLength)
|
||||
{
|
||||
case 5:
|
||||
upcomingTermios.c_cflag &= ~CSIZE;
|
||||
upcomingTermios.c_cflag |= CS5;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
upcomingTermios.c_cflag &= ~CSIZE;
|
||||
upcomingTermios.c_cflag |= CS6;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
upcomingTermios.c_cflag &= ~CSIZE;
|
||||
upcomingTermios.c_cflag |= CS7;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
upcomingTermios.c_cflag &= ~CSIZE;
|
||||
upcomingTermios.c_cflag |= CS8;
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_WARN("unexpected number od data bits per character: %d\n", pLineControl->WordLength);
|
||||
result = FALSE; /* but keep on */
|
||||
break;
|
||||
}
|
||||
|
||||
if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &upcomingTermios) < 0)
|
||||
{
|
||||
DEBUG_WARN("_comm_ioctl_tcsetattr failure: last-error: 0x0.8x", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static BOOL _get_line_control(WINPR_COMM *pComm, SERIAL_LINE_CONTROL *pLineControl)
|
||||
{
|
||||
struct termios currentTermios;
|
||||
|
||||
ZeroMemory(¤tTermios, sizeof(struct termios));
|
||||
if (tcgetattr(pComm->fd, ¤tTermios) < 0)
|
||||
{
|
||||
SetLastError(ERROR_IO_DEVICE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pLineControl->StopBits = (currentTermios.c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BIT_1;
|
||||
|
||||
if (!(currentTermios.c_cflag & PARENB))
|
||||
{
|
||||
pLineControl->Parity = NO_PARITY;
|
||||
}
|
||||
else if (currentTermios.c_cflag & CMSPAR)
|
||||
{
|
||||
pLineControl->Parity = (currentTermios.c_cflag & PARODD) ? MARK_PARITY : SPACE_PARITY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* PARENB is set */
|
||||
pLineControl->Parity = (currentTermios.c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY;
|
||||
}
|
||||
|
||||
switch (currentTermios.c_cflag & CSIZE)
|
||||
{
|
||||
case CS5:
|
||||
pLineControl->WordLength = 5;
|
||||
break;
|
||||
case CS6:
|
||||
pLineControl->WordLength = 6;
|
||||
break;
|
||||
case CS7:
|
||||
pLineControl->WordLength = 7;
|
||||
break;
|
||||
default:
|
||||
pLineControl->WordLength = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static REMOTE_SERIAL_DRIVER _SerialSys =
|
||||
{
|
||||
|
@ -390,6 +558,8 @@ static REMOTE_SERIAL_DRIVER _SerialSys =
|
|||
.get_properties = _get_properties,
|
||||
.set_serial_chars = _set_serial_chars,
|
||||
.get_serial_chars = _get_serial_chars,
|
||||
.set_line_control = _set_line_control,
|
||||
.get_line_control = _get_line_control
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ set(${MODULE_PREFIX}_TESTS
|
|||
TestGetCommState.c
|
||||
TestSetCommState.c
|
||||
TestSerialChars.c
|
||||
TestControlSettings.c
|
||||
TestCommMonitor.c)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Serial Communication API
|
||||
*
|
||||
* Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <winpr/comm.h>
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include "../comm.h"
|
||||
|
||||
int TestControlSettings(int argc, char* argv[])
|
||||
{
|
||||
BOOL result;
|
||||
HANDLE hComm;
|
||||
DCB dcb;
|
||||
|
||||
// TMP: FIXME: check if we can proceed with tests on the actual device, skip and warn otherwise but don't fail
|
||||
result = DefineCommDevice("COM1", "/dev/ttyS0");
|
||||
if (!result)
|
||||
{
|
||||
fprintf(stderr, "DefineCommDevice failure: 0x%x\n", GetLastError());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
hComm = CreateFile("COM1",
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hComm == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
fprintf(stderr, "CreateFileA failure: 0x%x\n", GetLastError());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZeroMemory(&dcb, sizeof(DCB));
|
||||
dcb.DCBlength = sizeof(DCB);
|
||||
if (!GetCommState(hComm, &dcb))
|
||||
{
|
||||
fprintf(stderr, "GetCommState failure; GetLastError(): %0.8x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Test 1 */
|
||||
|
||||
dcb.ByteSize = 5;
|
||||
dcb.StopBits = ONESTOPBIT;
|
||||
dcb.Parity = MARKPARITY;
|
||||
|
||||
if (!SetCommState(hComm, &dcb))
|
||||
{
|
||||
fprintf(stderr, "SetCommState failure; GetLastError(): %0.8x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ZeroMemory(&dcb, sizeof(DCB));
|
||||
dcb.DCBlength = sizeof(DCB);
|
||||
if (!GetCommState(hComm, &dcb))
|
||||
{
|
||||
fprintf(stderr, "GetCommState failure; GetLastError(): %0.8x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((dcb.ByteSize != 5) || (dcb.StopBits != ONESTOPBIT) || (dcb.Parity != MARKPARITY))
|
||||
{
|
||||
fprintf(stderr, "test1 failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Test 2 */
|
||||
|
||||
dcb.ByteSize = 8;
|
||||
dcb.StopBits = ONESTOPBIT;
|
||||
dcb.Parity = NOPARITY;
|
||||
|
||||
if (!SetCommState(hComm, &dcb))
|
||||
{
|
||||
fprintf(stderr, "SetCommState failure; GetLastError(): %0.8x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ZeroMemory(&dcb, sizeof(DCB));
|
||||
dcb.DCBlength = sizeof(DCB);
|
||||
if (!GetCommState(hComm, &dcb))
|
||||
{
|
||||
fprintf(stderr, "GetCommState failure; GetLastError(): %0.8x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((dcb.ByteSize != 8) || (dcb.StopBits != ONESTOPBIT) || (dcb.Parity != NOPARITY))
|
||||
{
|
||||
fprintf(stderr, "test2 failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (!CloseHandle(hComm))
|
||||
{
|
||||
fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue