Newer
Older
PrismSoftware / ECTrainer2 / GComPort.cpp
#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 < 20; 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 (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;
}