#include "GComPort.h"
// コンストラクタ
GComPort::GComPort(void) :
mComHandle(INVALID_HANDLE_VALUE)
{
}
// デストラクタ(終了処理)
GComPort::~GComPort(void)
{
this->Close();
}
// ポートを探して開く
int GComPort::Open(TCHAR* config)
{
for (int findPort = 1; findPort < COM_SEARCH_MAX; findPort++) {
if (this->Open(findPort, config)) {
this->Send((BYTE*)"s", 1);
Sleep(100);
BYTE buf[256];
this->Receive(buf, 256);
// TRACE("port %d recv %s\n", findPort, (char*)buf);
if (!strncmp((char*)buf, "OK", 2)) return findPort;
}
}
return 0;
}
// ポートを開く
bool GComPort::Open(int port, const TCHAR* config)
{
if (mComHandle != INVALID_HANDLE_VALUE) this->Close();
// ポート番号文字列生成
if (port < 1) return false;
TCHAR portStr[256];
wsprintf(portStr, _T("\\\\.\\COM%d"), port);
// Comポートを開く
mComHandle = CreateFile(portStr,
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (mComHandle == INVALID_HANDLE_VALUE) return false;
// ポート設定
DCB dcb;
GetCommState(mComHandle, &dcb);
BuildCommDCB(config, &dcb);
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDsrSensitivity = FALSE;
dcb.fAbortOnError = FALSE;
SetCommState(mComHandle, &dcb);
COMMTIMEOUTS timeout;
GetCommTimeouts(mComHandle, &timeout);
timeout.ReadIntervalTimeout = MAXDWORD;
timeout.ReadTotalTimeoutMultiplier = 1;
timeout.ReadTotalTimeoutConstant = 500;
timeout.WriteTotalTimeoutMultiplier = 1;
timeout.WriteTotalTimeoutConstant = 500;
SetCommTimeouts(mComHandle, &timeout);
return true;
}
// ポートを閉じる
void GComPort::Close()
{
if (mComHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(mComHandle);
mComHandle = INVALID_HANDLE_VALUE;
}
}
// データ送信
DWORD GComPort::Send(const BYTE* data, DWORD dataLen)
{
if (mComHandle == INVALID_HANDLE_VALUE) return 0;
DWORD sendSize; // 送信したバイト数
WriteFile(mComHandle, data, dataLen, &sendSize, NULL);
// TRACE("COM SEND: %s", (char*)data);
return sendSize;
}
// データ受信
DWORD GComPort::Receive(BYTE* buffer, DWORD bufferLen)
{
if (mComHandle == INVALID_HANDLE_VALUE) return 0;
DWORD errors;
COMSTAT stat;
ClearCommError(mComHandle, &errors, &stat);
DWORD queSize = stat.cbInQue;
if (queSize < 1) return 0;
if (bufferLen < queSize) queSize = bufferLen;
DWORD receiveSize; // 受信したバイト数
ReadFile(mComHandle, buffer, queSize, &receiveSize, NULL);
if (receiveSize < bufferLen) buffer[receiveSize] = '\0'; // 受信データに終端文字を追加
// TRACE("COM RECV: %s", (char*)buffer);
return receiveSize;
}
// タイムアウト付きデータ受信
DWORD GComPort::WaitReceive(BYTE* buffer, DWORD bufferLen, const int timeout)
{
if (mComHandle == INVALID_HANDLE_VALUE) return 0;
int receiveSize;
for (int i = 0; i < timeout &&
(receiveSize = this->Receive(buffer, bufferLen)) < 1; i++) Sleep(1);
return receiveSize;
}