mavtables  0.2.1
MAVLink router and firewall.
SerialInterface.cpp
Go to the documentation of this file.
1 // MAVLink router and firewall.
2 // Copyright (C) 2018 Michael R. Shannon <mrshannon.aerospace@gmail.com>
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 
18 #include <chrono>
19 #include <memory>
20 #include <stdexcept>
21 
22 #include "Connection.hpp"
23 #include "ConnectionPool.hpp"
24 #include "SerialInterface.hpp"
25 #include "SerialPort.hpp"
26 
27 
28 /** Construct a serial port interface using a given device.
29  *
30  * \param port The serial port device to communicate over.
31  * \param connection_pool The connection pool to use for sending packets the
32  * interface has received and to register the \p connection with.
33  * \param connection The connection to get packets to send packets from. This
34  * will be registered with the given \ref ConnectionPool.
35  * \throws std::invalid_argument if the serial \p port device pointer is null.
36  * \throws std::invalid_argument if the \p connection_pool pointer is null.
37  * \throws std::invalid_argument if the \p connection pointer is null.
38  */
40  std::unique_ptr<SerialPort> port,
41  std::shared_ptr<ConnectionPool> connection_pool,
42  std::unique_ptr<Connection> connection)
43  : port_(std::move(port)),
44  connection_pool_(std::move(connection_pool)),
45  connection_(std::move(connection))
46 {
47  if (port_ == nullptr)
48  {
49  throw std::invalid_argument("Given serial port pointer is null.");
50  }
51 
52  if (connection_pool_ == nullptr)
53  {
54  throw std::invalid_argument("Given connection pool pointer is null.");
55  }
56 
57  if (connection_ == nullptr)
58  {
59  throw std::invalid_argument("Given connection pointer is null.");
60  }
61 
62  connection_pool_->add(connection_);
63 }
64 
65 
66 /** \copydoc Interface::send_packet(const std::chrono::nanoseconds &)
67  *
68  * Writes up to one packet from the contained connection to the serial port.
69  */
70 void SerialInterface::send_packet(const std::chrono::nanoseconds &timeout)
71 {
72  auto packet = connection_->next_packet(timeout);
73 
74  if (packet != nullptr)
75  {
76  port_->write(packet->data());
77  }
78 }
79 
80 
81 /** \copydoc Interface::receive_packet(const std::chrono::nanoseconds &)
82  *
83  * Reads the data in the serial port's receive buffer or waits for up to \p
84  * timeout until data arrives if no data is present in the serial port buffer.
85  */
86 void SerialInterface::receive_packet(const std::chrono::nanoseconds &timeout)
87 {
88  auto buffer = port_->read(timeout);
89 
90  if (!buffer.empty())
91  {
92  // Parse the bytes.
93  for (auto byte : buffer)
94  {
95  auto packet = parser_.parse_byte(byte);
96 
97  if (packet != nullptr)
98  {
99  packet->connection(connection_);
100  connection_->add_address(packet->source());
101  connection_pool_->send(std::move(packet));
102  }
103  }
104  }
105 }
106 
107 
108 /** \copydoc Interface::print_(std::ostream &os)const
109  *
110  * Example:
111  * ```
112  * serial {
113  * device /dev/ttyUSB0;
114  * baudrate 115200;
115  * flow_control yes;
116  * }
117  * ```
118  *
119  * \param os The output stream to print to.
120  */
121 std::ostream &SerialInterface::print_(std::ostream &os) const
122 {
123  os << *port_;
124  return os;
125 }
void receive_packet(const std::chrono::nanoseconds &timeout) final
void send_packet(const std::chrono::nanoseconds &timeout) final
std::ostream & print_(std::ostream &os) const final
STL namespace.
SerialInterface(std::unique_ptr< SerialPort > port, std::shared_ptr< ConnectionPool > connection_pool, std::unique_ptr< Connection > connection)
std::unique_ptr< Packet > parse_byte(uint8_t byte)