// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- //
// C++ Source Code File Name: r_win32.cpp
// C++ Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC
// Produced By: glNET Software
// File Creation Date: 09/20/1999
// Date Last Modified: 06/25/2001
// Copyright (c) 2001 glNET Software
// ----------------------------------------------------------- //
// ------------- Program Description and Details ------------- //
// ----------------------------------------------------------- //
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
Code used by Win32 applications to read and write data to and
from a serial port using overlapped I/O.
*/
// ----------------------------------------------------------- //
void PrintError(LPCSTR str)
{
LPVOID lpMessageBuffer;
int error = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMessageBuffer,
0,
NULL);
cout << str << ": " << error << " " << lpMessageBuffer << endl;
LocalFree(lpMessageBuffer);
}
DWORD CALLBACK ConsoleThread(HANDLE h)
// Starts a user input thread using the console.
// Takes console characters and sends them to the com port.
{
OVERLAPPED ov;
HANDLE hconn = GetStdHandle(STD_INPUT_HANDLE);
BOOL quit = FALSE;
ZeroMemory(&ov, sizeof(ov));
ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if(ov.hEvent == INVALID_HANDLE_VALUE) {
PrintError("CreateEvent failed");
SetCommMask(h, 0);
return 0;
}
SetConsoleMode(hconn, 0);
cout << "Waiting to receive..." << endl;
cout << "Press Esc to terminate." << endl;
do {
char buf[10];
DWORD bytes_read = 0;
// Wait for user data
WaitForSingleObject(hconn, INFINITE);
// Read the console buffer
if(!ReadConsole(hconn, buf, sizeof(buf), &bytes_read, NULL)) {
PrintError("ReadConsole failed");
quit = TRUE;
}
if(bytes_read) {
DWORD write;
// Check for Esc key
for(write=0; write < bytes_read; write++) {
// Terminate when Esc key is pressed
if(buf[write] == 0x1b) {
quit = TRUE;
break;
}
}
// Send data to the serail device
if(write) {
if(!WriteFile(h, buf, write, &write, &ov)) {
if(GetLastError() == ERROR_IO_PENDING) {
if(!GetOverlappedResult(h, &ov, &write, TRUE)) {
PrintError("GetOverlappedResult failed");
quit = TRUE;
}
}
} else {
PrintError("WriteFile failed");
quit = TRUE;
}
}
}
} while(!quit);
// Signal the terminal thread to quit
SetCommMask(h, 0);
return 0;
}
void SerialRead(gxSerialComm *dev, char *dumpfile = 0)
{
fstream outfile;
if(dumpfile) {
cout << "Writing output to the " << dumpfile << " file" << endl;
outfile.open(dumpfile, ios::out|ios::binary|ios::trunc);
if(!outfile) {
cout << endl;
cout << "Cannot open the: " << dumpfile << " capture file"
<< endl;
cout << "Exiting..." << endl;
cout << endl;
return;
}
}
HANDLE hconn = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE h = dev->DeviceHandle();
DWORD mask;
DWORD id;
OVERLAPPED ov;
HANDLE hConsole = CreateThread(NULL, 0, ConsoleThread, h, 0, &id);
if(hConsole == INVALID_HANDLE_VALUE) {
PrintError("CreateThread failed");
return;
}
CloseHandle(hConsole);
ZeroMemory(&ov, sizeof(ov));
// Create event for overlapped I/O
ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if(ov.hEvent == INVALID_HANDLE_VALUE)
PrintError("CreateEvent failed");
// Wait for received characters
if(!SetCommMask(h, EV_RXCHAR))
PrintError("SetCommMask failed");
while(1) {
// Get the event mask
if(!WaitCommEvent(h, &mask, &ov)) {
DWORD e = GetLastError();
if(e == ERROR_IO_PENDING) {
DWORD r;
if(!GetOverlappedResult(h, &ov, &r, TRUE)) {
PrintError("GetOverlappedResult failed");
break;
}
} else {
PrintError("WaitCommEvent failed");
break;
}
}
// If no event, then UI thread terminated with SetCommMask(h, 0)
if(mask == 0) {
break;
}
if(mask & EV_RXCHAR) {
char buf[10];
DWORD bytes_read;
do {
bytes_read = 0;
if(!ReadFile(h, buf, sizeof(buf), &bytes_read, &ov)) {
if(GetLastError() == ERROR_IO_PENDING) {
if(!GetOverlappedResult(h, &ov, &bytes_read, TRUE)) {
PrintError("GetOverlappedResult failed");
break;
}
} else {
PrintError("ReadFile failed");
break;
}
}
if(bytes_read) {
if(dumpfile) { // Capture the data to a file
outfile.write((char *)buf, bytes_read);
outfile.flush();
}
else // Write the data to the console
WriteFile(hconn, buf, bytes_read, &bytes_read, NULL);
}
} while(bytes_read);
}
mask = 0;
}
outfile.close();
CloseHandle(ov.hEvent); // Close the event
}
// ----------------------------------------------------------- //
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //