Dev: extend YCM config to search for compile database
[marnav.git] / examples / serial_to_tcp.cpp
blob985c2f5ea9efe9cc0551ad52c1357b6e633566b6
1 // This example shows how to receive NMEA sentences on a port, check them
2 // and forward it to a TCP server, which listens for sentences.
3 //
4 // Boost.ASIO is used for both, serial and TCP connections.
6 #include <marnav/nmea/nmea.hpp>
7 #include <marnav-io/default_nmea_reader.hpp>
8 #include <boost/asio.hpp>
10 namespace marnav_example
12 /// Synchronous reading of the serial port using Boost.ASIO
13 ///
14 /// @note Inline implemented for easier reading within this example.
15 class boost_asio_serial : public marnav::io::device
17 public:
18 boost_asio_serial(const std::string & port, int baud_rate = 4800)
19 : io()
20 , serial(io, port)
22 serial.set_option(boost::asio::serial_port_base::baud_rate(baud_rate));
25 virtual void open() override{};
27 virtual void close() override { serial.close(); }
29 virtual int read(char * buffer, uint32_t size) override
31 if ((buffer == nullptr) || (size == 0))
32 throw std::invalid_argument{"invalid buffer or size"};
33 if (!serial.is_open())
34 throw std::runtime_error{"device not open"};
35 return boost::asio::read(serial, boost::asio::buffer(buffer, size));
38 virtual int write(const char * buffer, uint32_t size) override
40 if (buffer == nullptr)
41 throw std::invalid_argument{"invalid buffer"};
42 if (!serial.is_open())
43 throw std::runtime_error{"device not open"};
44 return boost::asio::write(serial, boost::asio::buffer(buffer, size));
47 private:
48 boost::asio::io_service io;
49 boost::asio::serial_port serial;
52 /// Blocking TCP client
53 ///
54 /// @note Inline implemented for easier reading within this example.
55 class boost_asio_tcp_client
57 public:
58 boost_asio_tcp_client(const std::string & host, const std::string & port)
59 : io()
60 , socket(io)
62 boost::asio::ip::tcp::resolver resolver{io};
63 boost::asio::connect(socket, resolver.resolve({host, port}));
66 ~boost_asio_tcp_client() {}
68 int write(const char * buffer, uint32_t size)
70 if (buffer == nullptr)
71 throw std::invalid_argument{"invalid buffer or size"};
72 if (!socket.is_open())
73 throw std::runtime_error{"device not open"};
74 return boost::asio::write(socket, boost::asio::buffer(buffer, size));
77 private:
78 boost::asio::io_service io;
79 boost::asio::ip::tcp::socket socket;
83 int main(int, char **)
85 using namespace marnav;
86 using namespace marnav_example;
88 // open input port and reader
89 io::default_nmea_reader input{std::make_unique<boost_asio_serial>("/dev/ttyUSB0", 38400)};
91 // open output port (TCP client), default port of certain navigational software
92 boost_asio_tcp_client output{"127.0.0.1", "2947"};
94 std::string data;
96 // read and process NMEA sentences, bus synchronization is done automatically.
97 while (input.read_sentence(data)) {
98 try {
99 // data was successfully read from the NMEA bus, inclusive synchronization
100 // of NMEA sentences. This means it is possible to begin to listen on the
101 // bus at any time.
102 auto sentence = nmea::make_sentence(data);
104 // valid sentence was received, forward it
105 output.write(data.c_str(), data.size());
106 } catch (std::exception & e) {
107 // ignore unknown sentences and other stuff
111 return 0;