asio_base.h
Go to the documentation of this file.
1 #ifndef H_ASIO_BASE
2 #define H_ASIO_BASE
3 
6 #include <boost/asio.hpp>
7 #include <boost/thread/mutex.hpp>
8 #include <boost/thread/thread.hpp>
9 #include <functional>
10 
11 namespace can{
12 
13 
14 template<typename Socket> class AsioDriver : public DriverInterface{
19 
21  boost::mutex state_mutex_;
22  boost::mutex socket_mutex_;
23 
24 protected:
25  boost::asio::io_service io_service_;
26 #if BOOST_ASIO_VERSION >= 101200 // Boost 1.66+
27  boost::asio::io_context::strand strand_;
28 #else
29  boost::asio::strand strand_;
30 #endif
31  Socket socket_;
33 
34  virtual void triggerReadSome() = 0;
35  virtual bool enqueue(const Frame & msg) = 0;
36 
37  void dispatchFrame(const Frame &msg){
38  strand_.post([this, msg]{ frame_dispatcher_.dispatch(msg.key(), msg);} ); // copies msg
39  }
40  void setErrorCode(const boost::system::error_code& error){
41  boost::mutex::scoped_lock lock(state_mutex_);
42  if(state_.error_code != error){
43  state_.error_code = error;
44  state_dispatcher_.dispatch(state_);
45  }
46  }
47  void setInternalError(unsigned int internal_error){
48  boost::mutex::scoped_lock lock(state_mutex_);
49  if(state_.internal_error != internal_error){
50  state_.internal_error = internal_error;
51  state_dispatcher_.dispatch(state_);
52  }
53  }
54 
56  boost::mutex::scoped_lock lock(state_mutex_);
57  if(state_.driver_state != state){
58  state_.driver_state = state;
59  state_dispatcher_.dispatch(state_);
60  }
61  }
62  void setNotReady(){
63  setDriverState(socket_.is_open()?State::open : State::closed);
64  }
65 
66  void frameReceived(const boost::system::error_code& error){
67  if(!error){
68  dispatchFrame(input_);
70  }else{
71  setErrorCode(error);
72  setNotReady();
73  }
74  }
75 
77  : strand_(io_service_), socket_(io_service_)
78  {}
79 
80 public:
81  virtual ~AsioDriver() { shutdown(); }
82 
84  boost::mutex::scoped_lock lock(state_mutex_);
85  return state_;
86  }
87  virtual void run(){
88  setNotReady();
89 
90  if(getState().driver_state == State::open){
91  io_service_.reset();
92  boost::asio::io_service::work work(io_service_);
94 
95  boost::thread post_thread([this]() { io_service_.run(); });
96 
98 
99  boost::system::error_code ec;
100  io_service_.run(ec);
101  setErrorCode(ec);
102 
103  setNotReady();
104  }
105  state_dispatcher_.dispatch(getState());
106  }
107  virtual bool send(const Frame & msg){
108  return getState().driver_state == State::ready && enqueue(msg);
109  }
110 
111  virtual void shutdown(){
112  if(socket_.is_open()){
113  socket_.cancel();
114  socket_.close();
115  }
116  io_service_.stop();
117  }
118 
120  return frame_dispatcher_.createListener(delegate);
121  }
123  return frame_dispatcher_.createListener(h.key(), delegate);
124  }
126  return state_dispatcher_.createListener(delegate);
127  }
128 
129 };
130 
131 } // namespace can
132 #endif
StateListener::ListenerConstSharedPtr StateListenerConstSharedPtr
Definition: interface.h:117
boost::mutex socket_mutex_
Definition: asio_base.h:22
virtual void shutdown()
Definition: asio_base.h:111
StateDispatcher state_dispatcher_
Definition: asio_base.h:18
virtual StateListenerConstSharedPtr createStateListener(const StateFunc &delegate)
Definition: asio_base.h:125
Definition: asio_base.h:11
void setInternalError(unsigned int internal_error)
Definition: asio_base.h:47
std::function< void(const Frame &)> FrameFunc
Definition: interface.h:137
void setNotReady()
Definition: asio_base.h:62
boost::asio::strand strand_
Definition: asio_base.h:29
void dispatch(const K &key, const typename BaseClass::Type &obj)
Definition: dispatcher.h:98
virtual FrameListenerConstSharedPtr createMsgListener(const FrameFunc &delegate)
Definition: asio_base.h:119
State getState()
Definition: asio_base.h:83
virtual bool send(const Frame &msg)
Definition: asio_base.h:107
FrameListener::ListenerConstSharedPtr FrameListenerConstSharedPtr
Definition: interface.h:140
virtual void triggerReadSome()=0
boost::mutex state_mutex_
Definition: asio_base.h:21
virtual bool enqueue(const Frame &msg)=0
FrameDispatcher frame_dispatcher_
Definition: asio_base.h:17
std::function< void(const State &)> StateFunc
Definition: interface.h:114
virtual ~AsioDriver()
Definition: asio_base.h:81
void setErrorCode(const boost::system::error_code &error)
Definition: asio_base.h:40
void dispatch(const Type &obj)
Definition: dispatcher.h:70
boost::asio::io_service io_service_
Definition: asio_base.h:25
unsigned int key() const
Definition: interface.h:32
enum can::State::DriverState driver_state
void setDriverState(State::DriverState state)
Definition: asio_base.h:55
void dispatchFrame(const Frame &msg)
Definition: asio_base.h:37
virtual void run()
Definition: asio_base.h:87
void frameReceived(const boost::system::error_code &error)
Definition: asio_base.h:66
BaseClass::ListenerConstSharedPtr createListener(const K &key, const typename BaseClass::Callable &callable)
Definition: dispatcher.h:85
ListenerConstSharedPtr createListener(const Callable &callable)
Definition: dispatcher.h:66
unsigned int internal_error
driver specific error
Definition: interface.h:92
virtual FrameListenerConstSharedPtr createMsgListener(const Frame::Header &h, const FrameFunc &delegate)
Definition: asio_base.h:122
Socket socket_
Definition: asio_base.h:31
boost::system::error_code error_code
device access error
Definition: interface.h:91


socketcan_interface
Author(s): Mathias Lüdtke
autogenerated on Mon Feb 28 2022 23:28:00