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 <boost/asio.hpp>
7 #include <marnav/nmea/nmea.hpp>
8 #include <marnav/io/default_nmea_reader.hpp>
9 #include <marnav/utils/unique.hpp>
11 namespace marnav_example
13 /// Synchronous reading of the serial port using Boost.ASIO
15 /// @note Inline implemented for easier reading within this example.
16 class boost_asio_serial
: public marnav::io::device
19 boost_asio_serial(const std::string
& port
, int baud_rate
= 4800)
23 serial
.set_option(boost::asio::serial_port_base::baud_rate(baud_rate
));
26 virtual void open() override
{};
28 virtual void close() override
{ serial
.close(); }
30 virtual int read(char * buffer
, uint32_t size
) override
32 if ((buffer
== nullptr) || (size
== 0))
33 throw std::invalid_argument
{"invalid buffer or size"};
34 if (!serial
.is_open())
35 throw std::runtime_error
{"device not open"};
36 return boost::asio::read(serial
, boost::asio::buffer(buffer
, size
));
39 virtual int write(const char * buffer
, uint32_t size
) override
41 if (buffer
== nullptr)
42 throw std::invalid_argument
{"invalid buffer"};
43 if (!serial
.is_open())
44 throw std::runtime_error
{"device not open"};
45 return boost::asio::write(serial
, boost::asio::buffer(buffer
, size
));
49 boost::asio::io_service io
;
50 boost::asio::serial_port serial
;
53 /// Blocking TCP client
55 /// @note Inline implemented for easier reading within this example.
56 class boost_asio_tcp_client
59 boost_asio_tcp_client(const std::string
& host
, const std::string
& port
)
63 boost::asio::ip::tcp::resolver resolver
{io
};
64 boost::asio::connect(socket
, resolver
.resolve({host
, port
}));
67 ~boost_asio_tcp_client() {}
69 int write(const char * buffer
, uint32_t size
)
71 if (buffer
== nullptr)
72 throw std::invalid_argument
{"invalid buffer or size"};
73 if (!socket
.is_open())
74 throw std::runtime_error
{"device not open"};
75 return boost::asio::write(socket
, boost::asio::buffer(buffer
, size
));
79 boost::asio::io_service io
;
80 boost::asio::ip::tcp::socket socket
;
84 int main(int, char **)
86 using namespace marnav
;
87 using namespace marnav_example
;
89 // open input port and reader
90 io::default_nmea_reader input
{utils::make_unique
<boost_asio_serial
>("/dev/ttyUSB0", 38400)};
92 // open output port (TCP client), default port of certain navigational software
93 boost_asio_tcp_client output
{"127.0.0.1", "2947"};
97 // read and process NMEA sentences, bus synchronization is done automatically.
98 while (input
.read_sentence(data
)) {
100 // data was successfully read from the NMEA bus, inclusive synchronization
101 // of NMEA sentences. This means it is possible to begin to listen on the
103 auto sentence
= nmea::make_sentence(data
);
105 // valid sentence was received, forward it
106 output
.write(data
.c_str(), data
.size());
107 } catch (std::exception
& e
) {
108 // ignore unknown sentences and other stuff