37 #include <linux/input.h>
38 #include <linux/serial.h>
41 #include <boost/asio.hpp>
42 #include <boost/asio/deadline_timer.hpp>
43 #include <boost/lambda/bind.hpp>
44 #include <boost/lambda/lambda.hpp>
60 1200, 2400, 4800, 9600, 19200, 38400, 57600,
61 115200, 230400, 460800, 500000, 576000, 921600, 1000000,
62 1152000, 1500000, 2000000, 2500000, 3000000, 3500000, 4000000};
91 socket_ = std::make_unique<boost::asio::ip::udp::socket>(
93 boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(),
port_));
100 "Listening on UDP port " + std::to_string(
port_));
109 boost::asio::placeholders::error,
110 boost::asio::placeholders::bytes_transferred));
119 if (!error && (bytes_recvd > 0))
121 while ((bytes_recvd - idx) > 2)
123 auto telegram = std::make_shared<Telegram>();
124 telegram->stamp = stamp;
136 telegram->message.assign(&
buffer_[idx],
145 "AsyncManager crc failed for SBF " +
147 telegram->message)) +
157 telegram->message.assign(&
buffer_[idx],
167 telegram->message.assign(&
buffer_[idx],
176 std::string(std::string(
177 telegram->message.begin(),
178 telegram->message.begin() + 2)));
189 "UDP client receive error: " + error.message());
205 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
210 "UDP client connection lost. Trying to reconnect.");
221 size_t idx_end = idx + 2;
223 while (idx_end < bytes_recvd)
239 boost::asio::ip::udp::endpoint
eP_;
240 std::unique_ptr<boost::asio::ip::udp::socket>
socket_;
241 std::array<uint8_t, MAX_UDP_PACKET_SIZE>
buffer_;
249 std::shared_ptr<boost::asio::io_context> ioContext) :
254 deadline_.expires_at(boost::posix_time::pos_infin);
270 boost::asio::ip::tcp::resolver::results_type endpoints;
274 boost::asio::ip::tcp::resolver resolver(*
ioContext_);
277 }
catch (
const std::runtime_error& e)
281 " on port " +
port_ +
": " + e.what());
297 "TCP connection to " +
304 endpoints.begin()->endpoint().port()) +
305 " failed: " + ec.message() +
". Retrying ...");
306 using namespace std::chrono_literals;
307 std::this_thread::sleep_for(1
s);
313 }
catch (
const std::runtime_error& e)
316 "Could not connect to " + endpoints.begin()->host_name() +
317 ": " + endpoints.begin()->service_name() +
": " +
322 deadline_.expires_at(boost::posix_time::pos_infin);
323 stream_->set_option(boost::asio::ip::tcp::no_delay(
true));
325 endpoints.begin()->host_name() +
":" +
326 endpoints.begin()->service_name() +
".");
332 const boost::asio::ip::tcp::resolver::results_type& endpoints)
334 boost::system::error_code ec;
335 deadline_.expires_from_now(boost::posix_time::seconds(10));
336 ec = boost::asio::error::would_block;
337 boost::asio::async_connect(*
stream_, endpoints,
338 boost::lambda::var(ec) = boost::lambda::_1);
341 while (
node_->
ok() && (ec == boost::asio::error::would_block));
348 boost::asio::deadline_timer::traits_type::now())
350 boost::system::error_code ignored_ec;
353 deadline_.expires_at(boost::posix_time::pos_infin);
365 std::unique_ptr<boost::asio::ip::tcp::socket>
stream_;
372 std::shared_ptr<boost::asio::io_context> ioContext) :
374 flowcontrol_(node->
settings()->hw_flow_control),
375 baudrate_(node->
settings()->baudrate)
398 "Connecting serially to device " +
400 ", targeted baudrate: " +
404 }
catch (
const boost::system::system_error& err)
408 ". Error: " + err.what() +
409 ". Will retry every second.");
411 using namespace std::chrono_literals;
412 std::this_thread::sleep_for(1
s);
419 stream_->set_option(boost::asio::serial_port_base::baud_rate(baudrate_));
420 stream_->set_option(boost::asio::serial_port_base::parity(
421 boost::asio::serial_port_base::parity::none));
422 stream_->set_option(boost::asio::serial_port_base::character_size(8));
423 stream_->set_option(boost::asio::serial_port_base::stop_bits(
424 boost::asio::serial_port_base::stop_bits::one));
427 if (flowcontrol_ ==
"RTS|CTS")
429 stream_->set_option(boost::asio::serial_port_base::flow_control(
430 boost::asio::serial_port_base::flow_control::hardware));
433 stream_->set_option(boost::asio::serial_port_base::flow_control(
434 boost::asio::serial_port_base::flow_control::none));
438 int fd =
stream_->native_handle();
439 struct serial_struct serialInfo;
440 ioctl(fd, TIOCGSERIAL, &serialInfo);
441 serialInfo.flags |= ASYNC_LOW_LATENCY;
442 ioctl(fd, TIOCSSERIAL, &serialInfo);
444 return setBaudrate();
451 "Gradually increasing the baudrate to the desired value...");
452 boost::asio::serial_port_base::baud_rate current_baudrate;
456 stream_->get_option(current_baudrate);
462 }
catch (boost::system::system_error& e)
466 static_cast<std::string
>(e.what()));
468 static_cast<std::string
>(e.what()));
482 "Current baudrate is " +
483 std::to_string(current_baudrate.value()));
484 for (uint8_t i = 0; i <
baudrates.size(); i++)
486 if (current_baudrate.value() == baudrate_)
490 if (current_baudrate.value() >=
baudrates[i] &&
499 boost::asio::serial_port_base::baud_rate(
baudrates[i]));
500 }
catch (boost::system::system_error& e)
504 "set_option failed due to " +
505 static_cast<std::string
>(e.what()));
507 "Additional info about error is " +
508 static_cast<std::string
>(e.what()));
511 using namespace std::chrono_literals;
512 std::this_thread::sleep_for(500ms);
516 stream_->get_option(current_baudrate);
517 }
catch (boost::system::system_error& e)
521 "get_option failed due to " +
522 static_cast<std::string
>(e.what()));
524 "Additional info about error is " +
525 static_cast<std::string
>(e.what()));
536 "Set ASIO baudrate to " +
537 std::to_string(current_baudrate.value()));
540 "Set ASIO baudrate to " +
541 std::to_string(current_baudrate.value()) +
542 ", leaving InitializeSerial() method");
545 ::tcflush(
stream_->native_handle(), TCIOFLUSH);
557 std::unique_ptr<boost::asio::serial_port>
stream_;
564 std::shared_ptr<boost::asio::io_context> ioContext) :
587 stream_ = std::make_unique<boost::asio::posix::stream_descriptor>(
591 }
catch (std::runtime_error& e)
594 static_cast<std::string
>(e.what()));
605 std::unique_ptr<boost::asio::posix::stream_descriptor>
stream_;
612 std::shared_ptr<boost::asio::io_context> ioContext) :
636 stream_ = std::make_unique<boost::asio::posix::stream_descriptor>(
641 stream_->assign(pcap_get_selectable_fd(pcap_));
643 }
catch (std::runtime_error& e)
646 static_cast<std::string
>(e.what()));
659 std::unique_ptr<boost::asio::posix::stream_descriptor>
stream_;