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
canopen::CANLayer::handleWrite
virtual void handleWrite(LayerStatus &status, const LayerState &current_state)
Definition: can_layer.h:37
can::Frame
canopen::CANLayer
Definition: can_layer.h:10
threading.h
canopen::CANLayer::mutex_
boost::mutex mutex_
Definition: can_layer.h:11
canopen::CANLayer::loopback_
const bool loopback_
Definition: can_layer.h:14
canopen::CANLayer::CANLayer
CANLayer(const can::DriverInterfaceSharedPtr &driver, const std::string &device, bool loopback)
Definition: can_layer.h:29
canopen::LayerStatus::error
const void error(const std::string &r)
Definition: layer.h:45
canopen::CANLayer::handleHalt
virtual void handleHalt(LayerStatus &status)
Definition: can_layer.h:103
canopen::LayerReport::add
void add(const std::string &key, const T &value)
Definition: layer.h:52
canopen::LayerStatus::warn
const void warn(const std::string &r)
Definition: layer.h:44
canopen::CANLayer::handleShutdown
virtual void handleShutdown(LayerStatus &status)
Definition: can_layer.h:89
layer.h
can::Frame::dlc
unsigned char dlc
canopen::Layer::Init
@ Init
Definition: layer.h:67
canopen::CANLayer::settings_
can::SettingsConstSharedPtr settings_
Definition: can_layer.h:15
canopen::Layer::LayerState
LayerState
Definition: layer.h:65
can::State::closed
closed
can::DriverInterfaceSharedPtr
std::shared_ptr< DriverInterface > DriverInterfaceSharedPtr
can::StateWaiter
ROSCANOPEN_ERROR
#define ROSCANOPEN_ERROR(name, args)
canopen::CANLayer::handleRecover
virtual void handleRecover(LayerStatus &status)
Definition: can_layer.h:105
can::State::error_code
boost::system::error_code error_code
canopen::CANLayer::driver_
can::DriverInterfaceSharedPtr driver_
Definition: can_layer.h:12
can::Frame::data
std::array< value_type, 8 > data
canopen::CANLayer::device_
const std::string device_
Definition: can_layer.h:13
can::SettingsConstSharedPtr
std::shared_ptr< const Settings > SettingsConstSharedPtr
canopen::CANLayer::handleFrame
void handleFrame(const can::Frame &msg)
Definition: can_layer.h:18
canopen::CANLayer::error_listener_
can::FrameListenerConstSharedPtr error_listener_
Definition: can_layer.h:17
can::State::isReady
virtual bool isReady() const
can::DriverInterface::run
virtual void run()=0
can
canopen
Definition: bcm_sync.h:8
canopen::CANLayer::handleDiag
virtual void handleDiag(LayerReport &report)
Definition: can_layer.h:43
string.h
can::StateWaiter::wait
bool wait(const can::State::DriverState &s, const DurationType &duration)
can::ErrorHeader
can::FrameListenerConstSharedPtr
CommInterface::FrameListenerConstSharedPtr FrameListenerConstSharedPtr
canopen::CANLayer::handleRead
virtual void handleRead(LayerStatus &status, const LayerState &current_state)
Definition: can_layer.h:32
can::State::ready
ready
can::State
canopen::CANLayer::last_error_
can::Frame last_error_
Definition: can_layer.h:16
canopen::CANLayer::thread_
std::shared_ptr< boost::thread > thread_
Definition: can_layer.h:23
can::State::driver_state
enum can::State::DriverState driver_state
canopen::CANLayer::CANLayer
CANLayer(const can::DriverInterfaceSharedPtr &driver, const std::string &device, bool loopback, can::SettingsConstSharedPtr settings)
Definition: can_layer.h:26
canopen::Layer
Definition: layer.h:63
canopen::LayerStatus
Definition: layer.h:12
canopen::CANLayer::handleInit
virtual void handleInit(LayerStatus &status)
Definition: can_layer.h:70
can::State::internal_error
unsigned int internal_error
canopen::LayerReport
Definition: layer.h:48


canopen_master
Author(s): Mathias Lüdtke
autogenerated on Wed Mar 2 2022 00:52:26