Добавил:
Mymnan
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Сборка Часть1 / avmis_labs / неразобрано / 503 / Лаб_СОМ / Тимоховцев / Source / COM
.cpp#include "StdAfx.h"
#include "COM.h"
#include "Exception.h"
using namespace Kingas;
using namespace Kingas::Communication;
COM::COM(void)
: _hCommunication(INVALID_HANDLE_VALUE), _WriterThreadId(0), _ReaderThreadId(0),
_AbortReading(false) {
}
COM::~COM(void) {
Close();
}
unsigned long WINAPI COM::WriteThreadProc(void * lpParameter) {
COM * parameter = (COM *)lpParameter;
unsigned long writed, toWrite = wcslen(parameter->_WriteCache) * sizeof(TCHAR);
parameter->_WriterCompleteStatus = COM::CompleteStatus::Success;
if (!WriteFile(parameter->_hCommunication,
parameter->_WriteCache,
toWrite,
&writed,
NULL))
parameter->_WriterCompleteStatus = COM::CompleteStatus::Error;
if (!writed)
parameter->_WriterCompleteStatus = COM::CompleteStatus::TimeOut;
if (!CreateThread(NULL,
sizeof(parameter),
WriterAsyncCallback,
parameter,
0,
NULL))
parameter->_WriterThreadId = 0;
return parameter->_WriterCompleteStatus;
}
unsigned long WINAPI COM::WriterAsyncCallback(void * lpParameter) {
COM * parameter = (COM *)lpParameter;
void (*callback)(COM::CompleteStatus);
callback = parameter->_WriteCompleteCallback;
COM::CompleteStatus returnStatus = parameter->_WriterCompleteStatus;
parameter->_WriterThreadId = 0;
callback(returnStatus);
return returnStatus;
}
unsigned long WINAPI COM::ReadThreadProc(void * lpParameter) {
COM * parameter = (COM *)lpParameter;
unsigned long readed;
parameter->_ReaderCompleteStatus = COM::CompleteStatus::Success;
parameter->_ReadedCache = new TCHAR[parameter->_ReadLimit + 1];
memset(parameter->_ReadedCache, 0, parameter->_ReadLimit + 1);
if (!ReadFile(parameter->_hCommunication,
parameter->_ReadedCache,
parameter->_ReadLimit * sizeof(TCHAR),
&readed,
NULL))
{
parameter->_ReaderCompleteStatus = COM::CompleteStatus::Error;
}
if (!readed)
parameter->_ReaderCompleteStatus = COM::CompleteStatus::TimeOut;
if (!CreateThread(NULL,
sizeof(parameter),
ReaderAsyncCallback,
parameter,
0,
NULL))
delete[] parameter->_ReadedCache;
return parameter->_ReaderCompleteStatus;
}
unsigned long WINAPI COM::ReaderAsyncCallback(void * lpParameter) {
COM * parameter = (COM *)lpParameter;
void (*callback)(TCHAR *, COM::CompleteStatus);
callback = parameter->_ReadCompleteCallback;
COM::CompleteStatus returnStatus = parameter->_ReaderCompleteStatus;
TCHAR * buffer = new TCHAR[wcslen(parameter->_ReadedCache) + 1];
wcscpy(buffer, parameter->_ReadedCache);
buffer[wcslen(parameter->_ReadedCache)] = 0;
delete[] parameter->_ReadedCache;
if (!parameter->_AbortReading)
{
CreateThread(NULL,
sizeof(parameter),
ReadThreadProc,
parameter,
0,
¶meter->_ReaderThreadId);
}
else
{
parameter->_AbortReading = false;
parameter->_ReaderThreadId = 0;
}
callback(buffer, returnStatus);
return returnStatus;
}
void COM::Open(unsigned char port) {
if (_hCommunication != INVALID_HANDLE_VALUE)
throw Exception(_T("[Kingas::Communication::COM::Open] COM already is open."));
Stream stream;
stream << _T("COM") << port;
_hCommunication = CreateFile(stream.str().c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
NULL);
if (_hCommunication == INVALID_HANDLE_VALUE) {
Stream errorMessage;
errorMessage << _T("[Kingas::Communication::COM::Open] Cann't open communication port ")
<< stream.str() << _T(".");
throw Exception(errorMessage.str());
}
COMMTIMEOUTS timeouts = {0};
timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutMultiplier = 1;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.WriteTotalTimeoutMultiplier = 1;
timeouts.WriteTotalTimeoutConstant = 1;
if (!SetCommTimeouts(_hCommunication, &timeouts))
throw Exception(_T("[Kingas::Communication::COM::Open] Error setting time-outs."));
DCB dcb = {0};
if (!GetCommState(_hCommunication, &dcb))
throw Exception(_T("[Kingas::Communication::COM::Open] Error in GetCommState."));
dcb.BaudRate = CBR_57600;
SetCommState(_hCommunication, &dcb);
}
bool COM::Close() {
if (_hCommunication != INVALID_HANDLE_VALUE)
{
CloseHandle(_hCommunication);
_hCommunication = INVALID_HANDLE_VALUE;
return true;
}
return false;
}
void COM::AsyncWrite(const TCHAR * message, void (*callback)(COM::CompleteStatus)) {
if (_WriterThreadId)
throw Exception(_T("[Kingas::Communication::COM::AsyncWrite] Writer already exist."));
_WriteCompleteCallback = callback;
_WriteCache = new TCHAR[wcslen(message) + 1];
_WriteCache[wcslen(message)] = 0;
wcscpy(_WriteCache, message);
CreateThread(NULL,
sizeof(COM *),
COM::WriteThreadProc,
(void *)this,
0,
&_WriterThreadId);
}
void COM::AsyncRead(void (*callback)(TCHAR * message, COM::CompleteStatus), unsigned long limit) {
if (_ReaderThreadId)
throw Exception(_T("[Kingas::Communication::COM::AsyncRead] Reader already exist."));
_ReadCompleteCallback = callback;
_ReadLimit = limit;
CreateThread(NULL,
sizeof(COM *),
COM::ReadThreadProc,
(void *)this,
0,
&_ReaderThreadId);
}
void COM::AbortReading() {
_AbortReading = true;
}