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);
153 ssize_t messageLength = ::read(serial->fd, &tempBuffer, BUFFER_SIZE_RFLY);
154 if (messageLength > 0)
156 tempBuffer[messageLength] =
'\0';
157 if(serial->onRawMessageReceived){
158 serial->onRawMessageReceived(tempBuffer,bytesRead);
170 bool read(uint8_t &
byte);
175 bool write(
const uint8_t
byte);
177 std::string portName;
189SerialCPP::SerialCPP()
192 hSerial = INVALID_HANDLE_VALUE;
200SerialCPP::~SerialCPP()
205bool SerialCPP::open(
const std::string &port,
size_t baud)
211 std::lock_guard<std::mutex> lock(mutex);
214 hSerial = CreateFile(portName.c_str(), GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
215 if (hSerial == INVALID_HANDLE_VALUE)
221 DCB dcbSerialParameters = {0};
223 if (!GetCommState(hSerial, &dcbSerialParameters))
229 dcbSerialParameters.BaudRate = (DWORD)baudRate;
230 dcbSerialParameters.ByteSize = 8;
231 dcbSerialParameters.StopBits = ONESTOPBIT;
232 dcbSerialParameters.Parity = NOPARITY;
233 dcbSerialParameters.fDtrControl = DTR_CONTROL_ENABLE;
235 if (!SetCommState(hSerial, &dcbSerialParameters))
242 COMMTIMEOUTS timeouts = {0};
243 timeouts.ReadIntervalTimeout = MAXDWORD;
244 timeouts.ReadTotalTimeoutConstant = 0;
245 timeouts.ReadTotalTimeoutMultiplier = 0;
246 if (!SetCommTimeouts(hSerial, &timeouts))
254 fd = ::open(portName.c_str(), O_RDWR | O_NOCTTY );
261 memset(&tty, 0,
sizeof(tty));
263 if (tcgetattr(fd, &tty) != 0)
302 tty.c_cflag &= ~PARENB;
303 tty.c_cflag &= ~CSTOPB;
305 tty.c_cflag &= ~CRTSCTS;
306 tty.c_cflag |= CREAD | CLOCAL;
308 tty.c_lflag &= ~ICANON;
309 tty.c_lflag &= ~ECHO;
310 tty.c_lflag &= ~ECHOE;
311 tty.c_lflag &= ~ECHONL;
312 tty.c_lflag &= ~ISIG;
314 tty.c_iflag &= ~(IXON | IXOFF | IXANY);
315 tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
317 tty.c_oflag &= ~OPOST;
318 tty.c_oflag &= ~ONLCR;
321 cfsetispeed(&tty, speed);
322 cfsetospeed(&tty, speed);
325 if (tcsetattr(fd, TCSANOW, &tty) != 0)
334void SerialCPP::StartRecvThread(){
335 std::thread t(ReceiveThread,
this);
339bool SerialCPP::close()
342 std::lock_guard<std::mutex> lock(mutex);
345 if (hSerial != INVALID_HANDLE_VALUE)
347 if (!CloseHandle(hSerial))
351 hSerial = INVALID_HANDLE_VALUE;
356 if (::close(fd) == -1)
367bool SerialCPP::write(uint8_t
byte)
371 if (!WriteFile(hSerial, &
byte, 1, &bytesWritten, NULL))
376 ssize_t result = ::write(fd, &
byte, 1);
385bool SerialCPP::writeBytes(
const std::vector<uint8_t> &data)
388 std::lock_guard<std::mutex> lock(mutex);
390 for (
const uint8_t &
byte : data)
400bool SerialCPP::writeLine(
const std::string &data)
403 std::lock_guard<std::mutex> lock(mutex);
406 std::vector<uint8_t> byteData(data.begin(), data.end());
409 byteData.push_back(
'\n');
412 for (
size_t i = 0; i < byteData.size(); ++i)
414 if (!write(byteData.data()[i]))
422bool SerialCPP::read(uint8_t &byteR)
427 if (!ReadFile(hSerial, &
byte, 1, &bytesRead, NULL) || bytesRead == 0)
432 ssize_t result = ::read(fd, &
byte, 1);
442std::vector<uint8_t> SerialCPP::readBytes(
size_t n)
445 std::lock_guard<std::mutex> lock(mutex);
447 std::vector<uint8_t> buffer;
449 for (
size_t i = 0; i < n && read(
byte); ++i)
451 buffer.push_back(
byte);
456std::string SerialCPP::readLine()
458 std::lock_guard<std::mutex> lock(mutex);
462 while (read(
byte) &&
byte !=
'\n')
464 line +=
static_cast<char>(byte);
468 line.erase(std::remove(line.begin(), line.end(),
'\n'), line.end());
469 line.erase(std::remove(line.begin(), line.end(),
'\r'), line.end());
474bool SerialCPP::isDeviceConnected()
477 if (hSerial == INVALID_HANDLE_VALUE)
486 ClearCommError(hSerial, &errors, &status);
498 if (ioctl(fd, TIOCMGET, &mcs) < 0)