19#ifndef BUFFER_SIZE_RFLY
20#define BUFFER_SIZE_RFLY 65500
31 std::function<void(
const char*,
size_t)> onRawMessageReceived;
43 bool open(
const std::string &port,
size_t baud = 115200);
52 bool writeBytes(
const std::vector<uint8_t> &data);
57 bool writeLine(
const std::string &data);
62 std::vector<uint8_t> readBytes(
size_t n);
66 std::string readLine();
68 void StartRecvThread();
72 bool isDeviceConnected();
74 int RecvNoblock(
char * buf,
int maxrecvlen=BUFFER_SIZE_RFLY){
79 if (ReadFile(hSerial, buf, maxrecvlen, &bytesRead, NULL) && bytesRead > 0)
88 ssize_t messageLength = ::read(fd, buf, maxrecvlen);
89 if (messageLength > 0)
91 buf[messageLength]=
'\0';
92 readFlag=messageLength;
103 int SendTo(
const char* bytes,
size_t byteslength){
105 std::lock_guard<std::mutex> lock(mutex);
109 if (!WriteFile(hSerial, bytes, (DWORD)byteslength, &bytesWritten, NULL))
113 return (
int)byteslength;
116 ssize_t result = ::write(fd, bytes, byteslength);
130 return isDeviceConnected();
137 static void ReceiveThread(
SerialCPP *serial){
138 char tempBuffer[BUFFER_SIZE_RFLY+1];
142 if (ReadFile(serial->hSerial, &tempBuffer, BUFFER_SIZE_RFLY, &bytesRead, NULL) && bytesRead > 0)
144 tempBuffer[bytesRead] =
'\0';
145 if(serial->onRawMessageReceived)
147 serial->onRawMessageReceived(tempBuffer,bytesRead);
154 ssize_t messageLength = ::read(serial->fd, &tempBuffer, BUFFER_SIZE_RFLY);
155 if (messageLength > 0)
157 tempBuffer[messageLength] =
'\0';
158 if(serial->onRawMessageReceived){
159 serial->onRawMessageReceived(tempBuffer,bytesRead);
171 bool read(uint8_t &
byte);
176 bool write(
const uint8_t
byte);
178 std::string portName;
190SerialCPP::SerialCPP()
193 hSerial = INVALID_HANDLE_VALUE;
201SerialCPP::~SerialCPP()
206bool SerialCPP::open(
const std::string &port,
size_t baud)
212 std::lock_guard<std::mutex> lock(mutex);
215 hSerial = CreateFile(portName.c_str(), GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
216 if (hSerial == INVALID_HANDLE_VALUE)
222 DCB dcbSerialParameters = {0};
224 if (!GetCommState(hSerial, &dcbSerialParameters))
230 dcbSerialParameters.BaudRate = (DWORD)baudRate;
231 dcbSerialParameters.ByteSize = 8;
232 dcbSerialParameters.StopBits = ONESTOPBIT;
233 dcbSerialParameters.Parity = NOPARITY;
234 dcbSerialParameters.fDtrControl = DTR_CONTROL_ENABLE;
236 if (!SetCommState(hSerial, &dcbSerialParameters))
243 COMMTIMEOUTS timeouts = {0};
244 timeouts.ReadIntervalTimeout = MAXDWORD;
245 timeouts.ReadTotalTimeoutConstant = 0;
246 timeouts.ReadTotalTimeoutMultiplier = 0;
247 if (!SetCommTimeouts(hSerial, &timeouts))
255 fd = ::open(portName.c_str(), O_RDWR | O_NOCTTY );
262 memset(&tty, 0,
sizeof(tty));
264 if (tcgetattr(fd, &tty) != 0)
303 tty.c_cflag &= ~PARENB;
304 tty.c_cflag &= ~CSTOPB;
306 tty.c_cflag &= ~CRTSCTS;
307 tty.c_cflag |= CREAD | CLOCAL;
309 tty.c_lflag &= ~ICANON;
310 tty.c_lflag &= ~ECHO;
311 tty.c_lflag &= ~ECHOE;
312 tty.c_lflag &= ~ECHONL;
313 tty.c_lflag &= ~ISIG;
315 tty.c_iflag &= ~(IXON | IXOFF | IXANY);
316 tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
318 tty.c_oflag &= ~OPOST;
319 tty.c_oflag &= ~ONLCR;
322 cfsetispeed(&tty, speed);
323 cfsetospeed(&tty, speed);
326 if (tcsetattr(fd, TCSANOW, &tty) != 0)
335void SerialCPP::StartRecvThread(){
336 std::thread t(ReceiveThread,
this);
340bool SerialCPP::close()
343 std::lock_guard<std::mutex> lock(mutex);
346 if (hSerial != INVALID_HANDLE_VALUE)
348 if (!CloseHandle(hSerial))
352 hSerial = INVALID_HANDLE_VALUE;
357 if (::close(fd) == -1)
368bool SerialCPP::write(uint8_t
byte)
372 if (!WriteFile(hSerial, &
byte, 1, &bytesWritten, NULL))
377 ssize_t result = ::write(fd, &
byte, 1);
386bool SerialCPP::writeBytes(
const std::vector<uint8_t> &data)
389 std::lock_guard<std::mutex> lock(mutex);
391 for (
const uint8_t &
byte : data)
401bool SerialCPP::writeLine(
const std::string &data)
404 std::lock_guard<std::mutex> lock(mutex);
407 std::vector<uint8_t> byteData(data.begin(), data.end());
410 byteData.push_back(
'\n');
413 for (
size_t i = 0; i < byteData.size(); ++i)
415 if (!write(byteData.data()[i]))
423bool SerialCPP::read(uint8_t &byteR)
428 if (!ReadFile(hSerial, &
byte, 1, &bytesRead, NULL) || bytesRead == 0)
433 ssize_t result = ::read(fd, &
byte, 1);
443std::vector<uint8_t> SerialCPP::readBytes(
size_t n)
446 std::lock_guard<std::mutex> lock(mutex);
448 std::vector<uint8_t> buffer;
450 for (
size_t i = 0; i < n && read(
byte); ++i)
452 buffer.push_back(
byte);
457std::string SerialCPP::readLine()
459 std::lock_guard<std::mutex> lock(mutex);
463 while (read(
byte) &&
byte !=
'\n')
465 line +=
static_cast<char>(byte);
469 line.erase(std::remove(line.begin(), line.end(),
'\n'), line.end());
470 line.erase(std::remove(line.begin(), line.end(),
'\r'), line.end());
475bool SerialCPP::isDeviceConnected()
478 if (hSerial == INVALID_HANDLE_VALUE)
487 ClearCommError(hSerial, &errors, &status);
499 if (ioctl(fd, TIOCMGET, &mcs) < 0)