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.
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
14 /// @note Inline implemented for easier reading within this example.
15 class boost_asio_serial
: public marnav::io::device
18 boost_asio_serial(const std::string
& port
, int baud_rate
= 4800)
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
));
48 boost::asio::io_service io
;
49 boost::asio::serial_port serial
;
52 /// Blocking TCP client
54 /// @note Inline implemented for easier reading within this example.
55 class boost_asio_tcp_client
58 boost_asio_tcp_client(const std::string
& host
, const std::string
& port
)
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
));
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"};
96 // read and process NMEA sentences, bus synchronization is done automatically.
97 while (input
.read_sentence(data
)) {
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
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