#ifdef _WINDOWS #include "StdAfx.h" #else //linux #include #endif #include "Serial.h" #include #include #include #include std::string writeLastError() { #ifdef _WINDOWS LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (LPSTR) &lpMsgBuf, 0, NULL); std::ostringstream out; out << "Error" << lpMsgBuf; return out.str(); #else //linux char message[256]; strerror_r(errno, message, 255); return std::string(message); #endif } CSerial::CSerial() { mIsopen = false; } CSerial::CSerial(char* port, int bitrate) { mPortstr = port; mBitrate = bitrate; mIsopen = false; #ifdef _WINDOWS openWindows(); #else openLinux(); #endif } CSerial::~CSerial(void) { close(); } void CSerial::open(char* port, int bitrate) { if (mIsopen) throw std::runtime_error("Port already opened"); mPortstr = port; mBitrate = bitrate; #ifdef _WINDOWS openWindows(); #else openLinux(); #endif } #ifdef _WINDOWS void CSerial::openWindows() { mComport = CreateFile( mPortstr, GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if (mComport == INVALID_HANDLE_VALUE) { throw std::runtime_error(writeLastError().c_str()); } DCB dcb; dcb.DCBlength = sizeof(DCB); mDcbRestore.DCBlength = sizeof(DCB); if (!GetCommState(mComport,&dcb) || !GetCommState(mComport,&mDcbRestore)) { std::string error = writeLastError(); CloseHandle(mComport); throw std::exception(error.c_str()); } dcb.BaudRate = mBitrate; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fParity = false; dcb.fDsrSensitivity = false; if (!SetCommState(mComport,&dcb)) { std::string error = writeLastError(); CloseHandle(mComport); throw std::exception(error.c_str()); } mIsopen = true; } #endif #ifndef _WINDOWS void CSerial::openLinux() { } #endif void CSerial::close() { if (mIsopen) { #ifdef _WINDOWS while (getComstat().cbOutQue >0) Sleep(5); SetCommState(mComport,&mDcbRestore); CloseHandle(mComport); #else // linux close() #endif mIsopen = false; } } unsigned char CSerial::readByte() { unsigned char out; unsigned long size; if (!mIsopen) throw std::runtime_error("Port not opened"); #ifdef _WINDOWS ReadFile(mComport,&out,1,&size,0); if (size != 1) { std::string error = writeLastError(); CloseHandle(mComport); throw std::exception(error.c_str()); } #else //linux readByte() #endif //printByte("Read", out); return out; } void CSerial::writeByte(unsigned char out) { unsigned long size; //printByte("Write", out); if (!mIsopen) throw std::runtime_error("Port not opened"); #ifdef _WINDOWS while (getComstat().cbOutQue >0) Sleep(2); WriteFile(mComport,&out,1,&size, NULL); if (size ==0) { std::string error = writeLastError(); CloseHandle(mComport); throw std::exception(error.c_str()); } #else //linux writeByte() #endif } #ifdef _WINDOWS COMSTAT CSerial::getComstat() const { if (!mIsopen) throw std::exception("Port not opened"); COMSTAT stat; DWORD x; ClearCommError(mComport,&x,&stat); return stat; } #endif int CSerial::bytesReady() const { #ifdef _WINDOWS return getComstat().cbInQue; #else return 0; #endif } int CSerial::outQueueSize() const { #ifdef _WINDOWS return getComstat().cbOutQue; #else return 0; #endif } /* Debug function void CSerial::printByte(char* description, unsigned char byte) { std::cout << description << " : " << (int) byte << "/" << std::setw(2) << std::setfill('0') << std::hex << (int) byte << std::endl; std::cout << std::dec; } */ /* void CSerial::writeBytes(UCVector out) { unsigned long bytesWritten; unsigned int size = out.size(); unsigned char *buf = new unsigned char[size]; for (int i=0; i