mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-21 15:09:23 +08:00
Modify the Windows serial handling.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2004,2007-2011,2013,2014-2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2002-2004,2007-2011,2013,2014-2017 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 1999-2001 by Thomas Sailor HB9JNX
|
* Copyright (C) 1999-2001 by Thomas Sailor HB9JNX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -40,27 +40,19 @@
|
|||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
|
||||||
const unsigned int BUFFER_LENGTH = 1000U;
|
|
||||||
|
|
||||||
CSerialController::CSerialController(const std::string& device, SERIAL_SPEED speed, bool assertRTS) :
|
CSerialController::CSerialController(const std::string& device, SERIAL_SPEED speed, bool assertRTS) :
|
||||||
m_device(device),
|
m_device(device),
|
||||||
m_speed(speed),
|
m_speed(speed),
|
||||||
m_assertRTS(assertRTS),
|
m_assertRTS(assertRTS),
|
||||||
m_handle(INVALID_HANDLE_VALUE),
|
m_handle(INVALID_HANDLE_VALUE),
|
||||||
m_readOverlapped(),
|
m_readOverlapped(),
|
||||||
m_writeOverlapped(),
|
m_writeOverlapped()
|
||||||
m_readBuffer(NULL),
|
|
||||||
m_readLength(0U),
|
|
||||||
m_readPending(false)
|
|
||||||
{
|
{
|
||||||
assert(!device.empty());
|
assert(!device.empty());
|
||||||
|
|
||||||
m_readBuffer = new unsigned char[BUFFER_LENGTH];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSerialController::~CSerialController()
|
CSerialController::~CSerialController()
|
||||||
{
|
{
|
||||||
delete[] m_readBuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSerialController::open()
|
bool CSerialController::open()
|
||||||
@@ -145,10 +137,6 @@ bool CSerialController::open()
|
|||||||
m_readOverlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
m_readOverlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
m_writeOverlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
m_writeOverlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
|
||||||
m_readLength = 0U;
|
|
||||||
m_readPending = false;
|
|
||||||
::memset(m_readBuffer, 0x00U, BUFFER_LENGTH);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,51 +167,41 @@ int CSerialController::readNonblock(unsigned char* buffer, unsigned int length)
|
|||||||
assert(m_handle != INVALID_HANDLE_VALUE);
|
assert(m_handle != INVALID_HANDLE_VALUE);
|
||||||
assert(buffer != NULL);
|
assert(buffer != NULL);
|
||||||
|
|
||||||
if (length > BUFFER_LENGTH)
|
|
||||||
length = BUFFER_LENGTH;
|
|
||||||
|
|
||||||
if (m_readPending && length != m_readLength) {
|
|
||||||
::CancelIo(m_handle);
|
|
||||||
m_readPending = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_readLength = length;
|
|
||||||
|
|
||||||
if (length == 0U)
|
if (length == 0U)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!m_readPending) {
|
DWORD errors;
|
||||||
DWORD bytes = 0UL;
|
COMSTAT status;
|
||||||
BOOL res = ::ReadFile(m_handle, m_readBuffer, m_readLength, &bytes, &m_readOverlapped);
|
if (::ClearCommError(m_handle, &errors, &status) == 0) {
|
||||||
if (res) {
|
LogError("Error from ClearCommError for %s, err=%04lx", m_device.c_str(), ::GetLastError());
|
||||||
::memcpy(buffer, m_readBuffer, bytes);
|
return -1;
|
||||||
return int(bytes);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DWORD error = ::GetLastError();
|
if (status.cbInQue == 0UL)
|
||||||
if (error != ERROR_IO_PENDING) {
|
return 0;
|
||||||
LogError("Error from ReadFile: %04lx", error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_readPending = true;
|
DWORD readLength = status.cbInQue;
|
||||||
}
|
if (length < status.cbInQue)
|
||||||
|
readLength = length;
|
||||||
BOOL res = HasOverlappedIoCompleted(&m_readOverlapped);
|
|
||||||
if (!res)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
DWORD bytes = 0UL;
|
DWORD bytes = 0UL;
|
||||||
res = ::GetOverlappedResult(m_handle, &m_readOverlapped, &bytes, TRUE);
|
BOOL res = ::ReadFile(m_handle, buffer, readLength, &bytes, &m_readOverlapped);
|
||||||
if (!res) {
|
if (res)
|
||||||
LogError("Error from GetOverlappedResult (ReadFile): %04lx", ::GetLastError());
|
return int(bytes);
|
||||||
|
|
||||||
|
DWORD error = ::GetLastError();
|
||||||
|
if (error != ERROR_IO_PENDING) {
|
||||||
|
LogError("Error from ReadFile for %s: %04lx", m_device.c_str(), error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
::memcpy(buffer, m_readBuffer, bytes);
|
DWORD ret = ::WaitForSingleObject(m_readOverlapped.hEvent, 100UL);
|
||||||
m_readPending = false;
|
if (ret != WAIT_OBJECT_0) {
|
||||||
|
LogError("Error from WaitForSIngleObject for %s: %04lx", m_device.c_str(), ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return int(bytes);
|
return int(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSerialController::write(const unsigned char* buffer, unsigned int length)
|
int CSerialController::write(const unsigned char* buffer, unsigned int length)
|
||||||
@@ -242,13 +220,13 @@ int CSerialController::write(const unsigned char* buffer, unsigned int length)
|
|||||||
if (!res) {
|
if (!res) {
|
||||||
DWORD error = ::GetLastError();
|
DWORD error = ::GetLastError();
|
||||||
if (error != ERROR_IO_PENDING) {
|
if (error != ERROR_IO_PENDING) {
|
||||||
LogError("Error from WriteFile: %04lx", error);
|
LogError("Error from WriteFile for %s: %04lx", m_device.c_str(), error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = ::GetOverlappedResult(m_handle, &m_writeOverlapped, &bytes, TRUE);
|
res = ::GetOverlappedResult(m_handle, &m_writeOverlapped, &bytes, TRUE);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
LogError("Error from GetOverlappedResult (WriteFile): %04lx", ::GetLastError());
|
LogError("Error from GetOverlappedResult for %s: %04lx", m_device.c_str(), ::GetLastError());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2004,2007-2009,2011-2013,2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2002-2004,2007-2009,2011-2013,2015-2017 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 1999-2001 by Thomas Sailor HB9JNX
|
* Copyright (C) 1999-2001 by Thomas Sailor HB9JNX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -61,9 +61,6 @@ private:
|
|||||||
HANDLE m_handle;
|
HANDLE m_handle;
|
||||||
OVERLAPPED m_readOverlapped;
|
OVERLAPPED m_readOverlapped;
|
||||||
OVERLAPPED m_writeOverlapped;
|
OVERLAPPED m_writeOverlapped;
|
||||||
unsigned char* m_readBuffer;
|
|
||||||
unsigned int m_readLength;
|
|
||||||
bool m_readPending;
|
|
||||||
#else
|
#else
|
||||||
int m_fd;
|
int m_fd;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user