can_layer.h
Go to the documentation of this file.
1 #ifndef H_CAN_LAYER
2 #define H_CAN_LAYER
3 
5 #include "layer.h"
7 
8 namespace canopen{
9 
10 class CANLayer: public Layer{
11  boost::mutex mutex_;
13  const std::string device_;
14  const bool loopback_;
18  void handleFrame(const can::Frame & msg){
19  boost::mutex::scoped_lock lock(mutex_);
20  last_error_ = msg;
21  ROSCANOPEN_ERROR("canopen_master", "Received error frame: " << msg);
22  }
23  std::shared_ptr<boost::thread> thread_;
24 
25 public:
26  CANLayer(const can::DriverInterfaceSharedPtr &driver, const std::string &device, bool loopback, can::SettingsConstSharedPtr settings)
27  : Layer(device + " Layer"), driver_(driver), device_(device), loopback_(loopback), settings_(settings) { assert(driver_); }
28 
29  [[deprecated("provide settings explicitly")]] CANLayer(const can::DriverInterfaceSharedPtr &driver, const std::string &device, bool loopback)
30  : Layer(device + " Layer"), driver_(driver), device_(device), loopback_(loopback), settings_(can::NoSettings::create()) { assert(driver_); }
31 
32  virtual void handleRead(LayerStatus &status, const LayerState &current_state) {
33  if(current_state > Init){
34  if(!driver_->getState().isReady()) status.error("CAN not ready");
35  }
36  }
37  virtual void handleWrite(LayerStatus &status, const LayerState &current_state) {
38  if(current_state > Init){
39  if(!driver_->getState().isReady()) status.error("CAN not ready");
40  }
41  }
42 
43  virtual void handleDiag(LayerReport &report){
44  can::State s = driver_->getState();
45  if(!s.isReady()){
46  report.error("CAN layer not ready");
47  report.add("driver_state", int(s.driver_state));
48  }
49  if(s.error_code){
50  report.add("socket_error", s.error_code);
51  }
52  if(s.internal_error != 0){
53  report.add("internal_error", int(s.internal_error));
54  std::string desc;
55  if(driver_->translateError(s.internal_error, desc)) report.add("internal_error_desc", desc);
56  std::stringstream sstr;
57  sstr << std::hex;
58  {
59  boost::mutex::scoped_lock lock(mutex_);
60  for(size_t i=0; i < last_error_.dlc; ++i){
61  sstr << (unsigned int) last_error_.data[i] << " ";
62  }
63  }
64  report.add("can_error_frame", sstr.str());
65 
66  }
67 
68  }
69 
70  virtual void handleInit(LayerStatus &status){
71  if(thread_){
72  status.warn("CAN thread already running");
73  } else if(!driver_->init(device_, loopback_, settings_)) {
74  status.error("CAN init failed");
75  } else {
76  can::StateWaiter waiter(driver_.get());
77 
78  thread_.reset(new boost::thread(&can::DriverInterface::run, driver_));
79  error_listener_ = driver_->createMsgListenerM(can::ErrorHeader(),this, &CANLayer::handleFrame);
80 
81  if(!waiter.wait(can::State::ready, boost::posix_time::seconds(1))){
82  status.error("CAN init timed out");
83  }
84  }
85  if(!driver_->getState().isReady()){
86  status.error("CAN is not ready");
87  }
88  }
89  virtual void handleShutdown(LayerStatus &status){
90  can::StateWaiter waiter(driver_.get());
91  error_listener_.reset();
92  driver_->shutdown();
93  if(!waiter.wait(can::State::closed, boost::posix_time::seconds(1))){
94  status.warn("CAN shutdown timed out");
95  }
96  if(thread_){
97  thread_->interrupt();
98  thread_->join();
99  thread_.reset();
100  }
101  }
102 
103  virtual void handleHalt(LayerStatus &status) { /* nothing to do */ }
104 
105  virtual void handleRecover(LayerStatus &status){
106  if(!driver_->getState().isReady()){
107  handleShutdown(status);
108  handleInit(status);
109  }
110  }
111 
112 };
113 } // namespace canopen
114 
115 #endif
const bool loopback_
Definition: can_layer.h:14
boost::mutex mutex_
Definition: can_layer.h:11
std::array< value_type, 8 > data
CANLayer(const can::DriverInterfaceSharedPtr &driver, const std::string &device, bool loopback)
Definition: can_layer.h:29
std::shared_ptr< DriverInterface > DriverInterfaceSharedPtr
#define ROSCANOPEN_ERROR(name, args)
const void warn(const std::string &r)
Definition: layer.h:44
virtual void run()=0
virtual void handleRecover(LayerStatus &status)
Definition: can_layer.h:105
const std::string device_
Definition: can_layer.h:13
can::DriverInterfaceSharedPtr driver_
Definition: can_layer.h:12
virtual void handleInit(LayerStatus &status)
Definition: can_layer.h:70
can::FrameListenerConstSharedPtr error_listener_
Definition: can_layer.h:17
can::Frame last_error_
Definition: can_layer.h:16
virtual bool isReady() const
CommInterface::FrameListenerConstSharedPtr FrameListenerConstSharedPtr
enum can::State::DriverState driver_state
std::shared_ptr< const Settings > SettingsConstSharedPtr
virtual void handleWrite(LayerStatus &status, const LayerState &current_state)
Definition: can_layer.h:37
void handleFrame(const can::Frame &msg)
Definition: can_layer.h:18
virtual void handleHalt(LayerStatus &status)
Definition: can_layer.h:103
std::shared_ptr< boost::thread > thread_
Definition: can_layer.h:23
virtual void handleShutdown(LayerStatus &status)
Definition: can_layer.h:89
virtual void handleRead(LayerStatus &status, const LayerState &current_state)
Definition: can_layer.h:32
void add(const std::string &key, const T &value)
Definition: layer.h:52
can::SettingsConstSharedPtr settings_
Definition: can_layer.h:15
const void error(const std::string &r)
Definition: layer.h:45
CANLayer(const can::DriverInterfaceSharedPtr &driver, const std::string &device, bool loopback, can::SettingsConstSharedPtr settings)
Definition: can_layer.h:26
virtual void handleDiag(LayerReport &report)
Definition: can_layer.h:43
unsigned int internal_error
unsigned char dlc
boost::system::error_code error_code


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