OSSIA
Open Scenario System for Interactive Application
serial_socket.hpp
1 #pragma once
2 #include <ossia/network/sockets/configuration.hpp>
3 #include <ossia/network/sockets/writers.hpp>
4 
5 #include <boost/asio/io_context.hpp>
6 #include <boost/asio/placeholders.hpp>
7 #include <boost/asio/serial_port.hpp>
8 #include <boost/asio/write.hpp>
9 
10 #include <nano_signal_slot.hpp>
11 
12 namespace ossia::net
13 {
14 
15 template <typename Framing>
16 class serial_socket
17 {
18 public:
19  using proto = boost::asio::serial_port;
20  using socket = boost::asio::serial_port;
21  using encoder = typename Framing::template encoder<boost::asio::serial_port>;
22  using decoder = typename Framing::template decoder<boost::asio::serial_port>;
23 
24  serial_socket(const serial_configuration& conf, boost::asio::io_context& ctx)
25  : m_context{ctx}
26  , m_conf{std::move(conf)}
27  , m_port{ctx}
28  , m_encoder{this->m_port}
29  , m_decoder{this->m_port}
30  {
31  }
32 
33  void connect()
34  {
35  m_port.open(m_conf.port);
36 
37  m_port.set_option(proto::baud_rate(m_conf.baud_rate));
38  m_port.set_option(proto::character_size(m_conf.character_size));
39  m_port.set_option(proto::flow_control(
40  static_cast<proto::flow_control::type>(m_conf.flow_control)));
41  m_port.set_option(proto::parity(static_cast<proto::parity::type>(m_conf.parity)));
42  m_port.set_option(
43  proto::stop_bits(static_cast<proto::stop_bits::type>(m_conf.stop_bits)));
44 
45  m_context.post([this] { on_open(); });
46  }
47 
48  template <typename F>
49  void receive(F f)
50  {
51  struct proc : stream_processor<serial_socket, F>
52  {
53  };
54  m_decoder.receive(proc{*this, std::move(f)});
55  }
56 
57  void close()
58  {
59  if(m_port.is_open())
60  {
61  m_port.cancel();
62  m_context.post([this] {
63  m_port.close();
64  on_close();
65  });
66  }
67  }
68 
69  void write(const char* data, std::size_t sz) { m_encoder.write(data, sz); }
70 
71  bool connected() const noexcept { return true; }
72 
73  Nano::Signal<void()> on_open;
74  Nano::Signal<void()> on_close;
75  Nano::Signal<void()> on_fail;
76 
77  boost::asio::io_context& m_context;
78  serial_configuration m_conf;
79  boost::asio::serial_port m_port;
80  encoder m_encoder;
81  decoder m_decoder;
82 };
83 }