30 : port_(
std::move(port)),
38 flowcontrol_(flowcontrol) {
56 std::string escaped_port = escape(port_);
57 fd_ = ::CreateFileW(std::wstring(escaped_port.begin(), escaped_port.end()).c_str(), GENERIC_READ | GENERIC_WRITE, 0,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
nullptr);
71 DCB dcbSerialParams = {0};
72 dcbSerialParams.DCBlength =
sizeof(dcbSerialParams);
73 if (!::GetCommState(fd_, &dcbSerialParams)) {
77 dcbSerialParams.BaudRate = baudrate_;
80 case eightbits: dcbSerialParams.ByteSize = 8;
break;
81 case sevenbits: dcbSerialParams.ByteSize = 7;
break;
82 case sixbits: dcbSerialParams.ByteSize = 6;
break;
83 case fivebits: dcbSerialParams.ByteSize = 5;
break;
89 case stopbits_one: dcbSerialParams.StopBits = ONESTOPBIT;
break;
91 case stopbits_two: dcbSerialParams.StopBits = TWOSTOPBITS;
break;
97 case parity_none: dcbSerialParams.Parity = NOPARITY;
break;
98 case parity_even: dcbSerialParams.Parity = EVENPARITY;
break;
99 case parity_odd: dcbSerialParams.Parity = ODDPARITY;
break;
100 case parity_mark: dcbSerialParams.Parity = MARKPARITY;
break;
101 case parity_space: dcbSerialParams.Parity = SPACEPARITY;
break;
107 switch (flowcontrol_) {
109 dcbSerialParams.fOutxCtsFlow =
false;
110 dcbSerialParams.fRtsControl = RTS_CONTROL_DISABLE;
111 dcbSerialParams.fOutX =
false;
112 dcbSerialParams.fInX =
false;
115 dcbSerialParams.fOutxCtsFlow =
false;
116 dcbSerialParams.fRtsControl = RTS_CONTROL_DISABLE;
117 dcbSerialParams.fOutX =
true;
118 dcbSerialParams.fInX =
true;
121 dcbSerialParams.fOutxCtsFlow =
true;
122 dcbSerialParams.fRtsControl = RTS_CONTROL_HANDSHAKE;
123 dcbSerialParams.fOutX =
false;
124 dcbSerialParams.fInX =
false;
130 if (!::SetCommState(fd_, &dcbSerialParams)) {
134 COMMTIMEOUTS timeouts = {0};
135 timeouts.ReadIntervalTimeout = timeout_.getInterByteMilliseconds();
136 timeouts.ReadTotalTimeoutConstant = timeout_.getReadConstantMilliseconds();
137 timeouts.ReadTotalTimeoutMultiplier = timeout_.getReadMultiplierMilliseconds();
138 timeouts.WriteTotalTimeoutConstant = timeout_.getWriteConstantMilliseconds();
139 timeouts.WriteTotalTimeoutMultiplier = timeout_.getWriteMultiplierMilliseconds();
140 if (!::SetCommTimeouts(fd_, &timeouts)) {
162 if (!::ClearCommError(fd_,
nullptr, &stat)) {
165 return static_cast<size_t>(stat.cbInQue);
179 auto start = std::chrono::steady_clock::now();
180 uint32_t bit_time_ns = 1e9 / baudrate_;
181 uint32_t byte_time_ns = bit_time_ns * (1 + bytesize_ + parity_ + stopbits_);
183 std::this_thread::sleep_until(start + std::chrono::nanoseconds(byte_time_ns * count));
190 DWORD bytes_read = 0;
191 if (!::ReadFile(fd_, buf,
static_cast<DWORD
>(size), &bytes_read,
nullptr)) {
194 return static_cast<size_t>(bytes_read);
201 DWORD bytes_written = 0;
202 if (!::WriteFile(fd_, data,
static_cast<DWORD
>(size), &bytes_written,
nullptr)) {
205 return static_cast<size_t>(bytes_written);
228 baudrate_ = baudrate;
239 bytesize_ = bytesize;
261 stopbits_ = stopbits;
272 flowcontrol_ = flowcontrol;
286 if (!::PurgeComm(fd_, PURGE_RXCLEAR | PURGE_TXCLEAR)) {
295 if (!::PurgeComm(fd_, PURGE_RXCLEAR)) {
304 if (!::PurgeComm(fd_, PURGE_TXCLEAR)) {
314 setModemStatus(level ? SETBREAK : CLRBREAK);
321 if (!::EscapeCommFunction(fd_, request)) {
327 setModemStatus(level ? SETRTS : CLRRTS);
331 setModemStatus(level ? SETDTR : CLRDTR);
338 if (!::SetCommMask(fd_, EV_CTS | EV_DSR | EV_RING | EV_RLSD)) {
342 if (!::WaitCommEvent(fd_, &event,
nullptr)) {
352 if (!::GetCommModemStatus(fd_, &modem_status)) {
359 return getModemStatus() & MS_CTS_ON;
363 return getModemStatus() & MS_DSR_ON;
367 return getModemStatus() & MS_RING_ON;
371 return getModemStatus() & MS_RLSD_ON;
374 #endif // defined(_WIN32)