layer.h
Go to the documentation of this file.
1 #ifndef H_CANOPEN_LAYER
2 #define H_CANOPEN_LAYER
3 
4 #include <vector>
5 #include <memory>
6 #include <boost/thread/shared_mutex.hpp>
7 #include <atomic>
8 #include <boost/exception/diagnostic_information.hpp>
9 
10 namespace canopen{
11 
13  mutable boost::mutex write_mutex_;
14  enum State{
15  OK = 0, WARN = 1, ERROR= 2, STALE = 3, UNBOUNDED = 3
16  };
17  std::atomic<State> state;
18  std::string reason_;
19 
20  virtual void set(const State &s, const std::string &r){
21  boost::mutex::scoped_lock lock(write_mutex_);
22  if(s > state) state = s;
23  if(!r.empty()){
24  if(reason_.empty()) reason_ = r;
25  else reason_ += "; " + r;
26  }
27  }
28 public:
29  struct Ok { static const State state = OK; private: Ok();};
30  struct Warn { static const State state = WARN; private: Warn(); };
31  struct Error { static const State state = ERROR; private: Error(); };
32  struct Stale { static const State state = STALE; private: Stale(); };
33  struct Unbounded { static const State state = UNBOUNDED; private: Unbounded(); };
34 
35  template<typename T> bool bounded() const{ return state <= T::state; }
36  template<typename T> bool equals() const{ return state == T::state; }
37 
39 
40  int get() const { return state; }
41 
42  const std::string reason() const { boost::mutex::scoped_lock lock(write_mutex_); return reason_; }
43 
44  const void warn(const std::string & r) { set(WARN, r); }
45  const void error(const std::string & r) { set(ERROR, r); }
46  const void stale(const std::string & r) { set(STALE, r); }
47 };
48 class LayerReport : public LayerStatus {
49  std::vector<std::pair<std::string, std::string> > values_;
50 public:
51  const std::vector<std::pair<std::string, std::string> > &values() const { return values_; }
52  template<typename T> void add(const std::string &key, const T &value) {
53  std::stringstream str;
54  str << value;
55  values_.push_back(std::make_pair(key,str.str()));
56  }
57 };
58 
59 #define CATCH_LAYER_HANDLER_EXCEPTIONS(command, status) \
60  try{ command; } \
61  catch(std::exception &e) {status.error(boost::diagnostic_information(e)); }
62 
63 class Layer{
64 public:
65  enum LayerState{
66  Off,
73  };
74 
75  const std::string name;
76 
77  void read(LayerStatus &status) {
79  }
80  void write(LayerStatus &status) {
82  }
83  void diag(LayerReport &report) {
85  }
86  void init(LayerStatus &status) {
87  if(state == Off){
88  if(status.bounded<LayerStatus::Warn>()){
89  state = Init;
91  }
92  if(!status.bounded<LayerStatus::Warn>()) shutdown(status);
93  else state = Ready;
94  }
95  }
96  void shutdown(LayerStatus &status) {
97  if(state != Off){
98  state = Shutdown;
100  state = Off;
101  }
102  }
103  void halt(LayerStatus &status) {
104  if(state > Halt){
105  state = Halt;
107  state = Error;
108  }
109  }
110  void recover(LayerStatus &status) {
111  if(state == Error){
112  if(status.bounded<LayerStatus::Warn>()){
113  state = Recover;
115  }
116  if(!status.bounded<LayerStatus::Warn>()){
117  halt(status);
118  }else{
119  state = Ready;
120  }
121  }
122 
123  }
124 
126 
127  Layer(const std::string &n) : name(n), state(Off) {}
128 
129  virtual ~Layer() {}
130 
131 protected:
132  virtual void handleRead(LayerStatus &status, const LayerState &current_state) = 0;
133  virtual void handleWrite(LayerStatus &status, const LayerState &current_state) = 0;
134 
135  virtual void handleDiag(LayerReport &report) = 0;
136 
137  virtual void handleInit(LayerStatus &status) = 0;
138  virtual void handleShutdown(LayerStatus &status) = 0;
139 
140  virtual void handleHalt(LayerStatus &status) = 0;
141  virtual void handleRecover(LayerStatus &status) = 0;
142 
143 private:
144  std::atomic<LayerState> state;
145 
146 };
147 
148 template<typename T> class VectorHelper{
149 public:
150  typedef std::shared_ptr<T> VectorMemberSharedPtr;
151 protected:
152  typedef std::vector<VectorMemberSharedPtr> vector_type ;
153  template<typename Bound, typename Data, typename FuncType> typename vector_type::iterator call(FuncType func, Data &status){
154  boost::shared_lock<boost::shared_mutex> lock(mutex);
155  return call<Bound>(func, status, layers.begin(), layers.end());
156  }
157  template<typename Data, typename FuncType> typename vector_type::iterator call(FuncType func, Data &status){
158  boost::shared_lock<boost::shared_mutex> lock(mutex);
159  return call<LayerStatus::Unbounded>(func, status, layers.begin(), layers.end());
160  }
161  template<typename Bound, typename Data, typename FuncType> typename vector_type::reverse_iterator call_rev(FuncType func, Data &status){
162  boost::shared_lock<boost::shared_mutex> lock(mutex);
163  return call<Bound>(func, status, layers.rbegin(), layers.rend());
164  }
165  template<typename Data, typename FuncType> typename vector_type::reverse_iterator call_rev(FuncType func, Data &status){
166  boost::shared_lock<boost::shared_mutex> lock(mutex);
167  return call<LayerStatus::Unbounded>(func, status, layers.rbegin(), layers.rend());
168  }
169  void destroy() { boost::unique_lock<boost::shared_mutex> lock(mutex); layers.clear(); }
170 
171 public:
172  virtual void add(const VectorMemberSharedPtr &l) { boost::unique_lock<boost::shared_mutex> lock(mutex); layers.push_back(l); }
173 
174  template<typename Bound, typename Data, typename FuncType> bool callFunc(FuncType func, Data &status){
175  boost::shared_lock<boost::shared_mutex> lock(mutex);
176  return call<Bound>(func, status, layers.begin(), layers.end()) == layers.end();
177  }
178 private:
180  boost::shared_mutex mutex;
181 
182  template<typename Bound, typename Iterator, typename Data, typename FuncType> Iterator call(FuncType func, Data &status, const Iterator &begin, const Iterator &end){
183  bool okay_on_start = status.template bounded<Bound>();
184 
185  for(Iterator it = begin; it != end; ++it){
186  ((**it).*func)(status);
187  if(okay_on_start && !status.template bounded<Bound>()){
188  return it;
189  }
190  }
191  return end;
192  }
193  template<typename Iterator, typename Data, typename FuncType> Iterator call(FuncType func, Data &status, const Iterator &begin, const Iterator &end){
194  return call<LayerStatus::Unbounded, Iterator, Data>(func, status, begin, end);
195  }
196 };
197 
198 template<typename T=Layer> class LayerGroup : public Layer, public VectorHelper<T> {
199 protected:
200  template<typename Data, typename FuncType, typename FailType> void call_or_fail(FuncType func, FailType fail, Data &status){
201  this->template call(func, status);
202  if(!status.template bounded<LayerStatus::Warn>()){
203  this->template call(fail, status);
204  (this->*fail)(status);
205  }
206  }
207  template<typename Data, typename FuncType, typename FailType> void call_or_fail_rev(FuncType func, FailType fail, Data &status){
208  this->template call_rev(func, status);
209  if(!status.template bounded<LayerStatus::Warn>()){
210  this->template call_rev(fail, status);
211  (this->*fail)(status);
212  }
213  }
214 
215  virtual void handleRead(LayerStatus &status, const LayerState &current_state) {
216  this->template call_or_fail(&Layer::read, &Layer::halt, status);
217  }
218  virtual void handleWrite(LayerStatus &status, const LayerState &current_state) {
219  this->template call_or_fail(&Layer::write, &Layer::halt, status);
220  }
221 
222  virtual void handleDiag(LayerReport &report) { this->template call(&Layer::diag, report); }
223 
224  virtual void handleInit(LayerStatus &status) { this->template call<LayerStatus::Warn>(&Layer::init, status); }
225  virtual void handleShutdown(LayerStatus &status) { this->template call(&Layer::shutdown, status); }
226 
227  virtual void handleHalt(LayerStatus &status) { this->template call(&Layer::halt, status); }
228  virtual void handleRecover(LayerStatus &status) { this->template call<LayerStatus::Warn>(&Layer::recover, status); }
229 public:
230  LayerGroup(const std::string &n) : Layer(n) {}
231 };
232 
233 class LayerStack : public LayerGroup<>{
234 
235 protected:
236  virtual void handleWrite(LayerStatus &status, const LayerState &current_state) { call_or_fail_rev(&Layer::write, &Layer::halt, status);}
237  virtual void handleShutdown(LayerStatus &status) { call_rev(&Layer::shutdown, status); }
238 public:
239  LayerStack(const std::string &n) : LayerGroup(n) {}
240 };
241 
242 template<typename T> class LayerGroupNoDiag : public LayerGroup<T>{
243 public:
244  LayerGroupNoDiag(const std::string &n) : LayerGroup<T>(n) {}
245  virtual void handleDiag(LayerReport &report) {}
246 };
247 
248 template<typename T> class DiagGroup : public VectorHelper<T>{
250 public:
251  virtual void diag(LayerReport &report){
252  this->template call(&Layer::diag, report);
253  }
254 };
255 
256 
257 
258 } // namespace canopen
259 
260 #endif
canopen::LayerGroupNoDiag::LayerGroupNoDiag
LayerGroupNoDiag(const std::string &n)
Definition: layer.h:244
canopen::LayerGroupNoDiag::handleDiag
virtual void handleDiag(LayerReport &report)
Definition: layer.h:245
canopen::Layer::shutdown
void shutdown(LayerStatus &status)
Definition: layer.h:96
canopen::Layer::write
void write(LayerStatus &status)
Definition: layer.h:80
canopen::LayerGroup::call_or_fail_rev
void call_or_fail_rev(FuncType func, FailType fail, Data &status)
Definition: layer.h:207
canopen::Layer::handleWrite
virtual void handleWrite(LayerStatus &status, const LayerState &current_state)=0
canopen::Layer::handleShutdown
virtual void handleShutdown(LayerStatus &status)=0
canopen::DiagGroup
Definition: layer.h:248
canopen::VectorHelper::call
Iterator call(FuncType func, Data &status, const Iterator &begin, const Iterator &end)
Definition: layer.h:182
canopen::LayerGroup::call_or_fail
void call_or_fail(FuncType func, FailType fail, Data &status)
Definition: layer.h:200
canopen::Layer::diag
void diag(LayerReport &report)
Definition: layer.h:83
canopen::VectorHelper::call
vector_type::iterator call(FuncType func, Data &status)
Definition: layer.h:157
canopen::VectorHelper::add
virtual void add(const VectorMemberSharedPtr &l)
Definition: layer.h:172
canopen::LayerStatus::Stale::Stale
Stale()
canopen::LayerStatus::Unbounded::Unbounded
Unbounded()
canopen::LayerStack::handleWrite
virtual void handleWrite(LayerStatus &status, const LayerState &current_state)
Definition: layer.h:236
canopen::LayerStatus::Warn::state
static const State state
Definition: layer.h:30
canopen::LayerStatus::Unbounded
Definition: layer.h:33
canopen::LayerStatus::error
const void error(const std::string &r)
Definition: layer.h:45
canopen::Layer::Layer
Layer(const std::string &n)
Definition: layer.h:127
canopen::LayerStatus::Ok::state
static const State state
Definition: layer.h:29
canopen::LayerReport::add
void add(const std::string &key, const T &value)
Definition: layer.h:52
canopen::LayerStatus::Unbounded::state
static const State state
Definition: layer.h:33
canopen::LayerStatus::warn
const void warn(const std::string &r)
Definition: layer.h:44
canopen::LayerStatus::Error::state
static const State state
Definition: layer.h:31
canopen::Layer::getLayerState
LayerState getLayerState()
Definition: layer.h:125
canopen::LayerStatus::UNBOUNDED
@ UNBOUNDED
Definition: layer.h:15
canopen::VectorHelper
Definition: layer.h:148
canopen::Layer::Shutdown
@ Shutdown
Definition: layer.h:68
canopen::Layer::Ready
@ Ready
Definition: layer.h:72
canopen::LayerGroup
Definition: layer.h:198
canopen::DiagGroup::V
VectorHelper< T > V
Definition: layer.h:249
canopen::Layer::Init
@ Init
Definition: layer.h:67
canopen::Layer::LayerState
LayerState
Definition: layer.h:65
canopen::LayerStatus::ERROR
@ ERROR
Definition: layer.h:15
canopen::LayerStatus::bounded
bool bounded() const
Definition: layer.h:35
canopen::LayerStatus::equals
bool equals() const
Definition: layer.h:36
canopen::LayerStatus::reason
const std::string reason() const
Definition: layer.h:42
canopen::Layer::halt
void halt(LayerStatus &status)
Definition: layer.h:103
canopen::LayerStatus::WARN
@ WARN
Definition: layer.h:15
canopen::LayerStatus::State
State
Definition: layer.h:14
canopen::VectorHelper::callFunc
bool callFunc(FuncType func, Data &status)
Definition: layer.h:174
canopen::Layer::Halt
@ Halt
Definition: layer.h:70
canopen::Layer::handleHalt
virtual void handleHalt(LayerStatus &status)=0
canopen::Layer::recover
void recover(LayerStatus &status)
Definition: layer.h:110
canopen::VectorHelper::destroy
void destroy()
Definition: layer.h:169
CATCH_LAYER_HANDLER_EXCEPTIONS
#define CATCH_LAYER_HANDLER_EXCEPTIONS(command, status)
Definition: layer.h:59
canopen::LayerStatus::get
int get() const
Definition: layer.h:40
canopen::LayerStatus::OK
@ OK
Definition: layer.h:15
canopen::LayerGroup::handleRecover
virtual void handleRecover(LayerStatus &status)
Definition: layer.h:228
canopen::LayerStatus::Warn
Definition: layer.h:30
canopen::VectorHelper::layers
vector_type layers
Definition: layer.h:179
canopen::LayerStatus::Ok
Definition: layer.h:29
canopen::Layer::read
void read(LayerStatus &status)
Definition: layer.h:77
canopen::LayerStack::LayerStack
LayerStack(const std::string &n)
Definition: layer.h:239
canopen::LayerGroup::handleShutdown
virtual void handleShutdown(LayerStatus &status)
Definition: layer.h:225
canopen::Layer::handleRecover
virtual void handleRecover(LayerStatus &status)=0
canopen::LayerStatus::Stale::state
static const State state
Definition: layer.h:32
canopen::LayerGroup::LayerGroup
LayerGroup(const std::string &n)
Definition: layer.h:230
canopen::LayerGroup::handleDiag
virtual void handleDiag(LayerReport &report)
Definition: layer.h:222
canopen::LayerStatus::Warn::Warn
Warn()
canopen::LayerStatus::set
virtual void set(const State &s, const std::string &r)
Definition: layer.h:20
canopen::LayerReport::values_
std::vector< std::pair< std::string, std::string > > values_
Definition: layer.h:49
canopen::Layer::handleInit
virtual void handleInit(LayerStatus &status)=0
canopen::VectorHelper::VectorMemberSharedPtr
std::shared_ptr< T > VectorMemberSharedPtr
Definition: layer.h:150
canopen::LayerStatus::reason_
std::string reason_
Definition: layer.h:18
canopen
Definition: bcm_sync.h:8
canopen::LayerGroup::handleRead
virtual void handleRead(LayerStatus &status, const LayerState &current_state)
Definition: layer.h:215
canopen::Layer::init
void init(LayerStatus &status)
Definition: layer.h:86
canopen::Layer::state
std::atomic< LayerState > state
Definition: layer.h:144
canopen::Layer::handleDiag
virtual void handleDiag(LayerReport &report)=0
canopen::LayerGroup::handleInit
virtual void handleInit(LayerStatus &status)
Definition: layer.h:224
canopen::LayerStatus::write_mutex_
boost::mutex write_mutex_
Definition: layer.h:13
canopen::VectorHelper::call
vector_type::iterator call(FuncType func, Data &status)
Definition: layer.h:153
canopen::DiagGroup::diag
virtual void diag(LayerReport &report)
Definition: layer.h:251
canopen::LayerStatus::STALE
@ STALE
Definition: layer.h:15
canopen::Layer::~Layer
virtual ~Layer()
Definition: layer.h:129
canopen::LayerGroup::handleHalt
virtual void handleHalt(LayerStatus &status)
Definition: layer.h:227
canopen::LayerStack
Definition: layer.h:233
canopen::LayerStatus::stale
const void stale(const std::string &r)
Definition: layer.h:46
canopen::LayerStatus::LayerStatus
LayerStatus()
Definition: layer.h:38
canopen::LayerReport::values
const std::vector< std::pair< std::string, std::string > > & values() const
Definition: layer.h:51
canopen::LayerStatus::Stale
Definition: layer.h:32
canopen::VectorHelper::vector_type
std::vector< VectorMemberSharedPtr > vector_type
Definition: layer.h:152
canopen::Layer::Recover
@ Recover
Definition: layer.h:71
canopen::Layer::Off
@ Off
Definition: layer.h:66
canopen::Layer::name
const std::string name
Definition: layer.h:75
canopen::VectorHelper::call_rev
vector_type::reverse_iterator call_rev(FuncType func, Data &status)
Definition: layer.h:165
canopen::LayerGroup::handleWrite
virtual void handleWrite(LayerStatus &status, const LayerState &current_state)
Definition: layer.h:218
canopen::VectorHelper::call
Iterator call(FuncType func, Data &status, const Iterator &begin, const Iterator &end)
Definition: layer.h:193
canopen::LayerGroupNoDiag
Definition: layer.h:242
canopen::LayerStatus::Error::Error
Error()
canopen::VectorHelper::call_rev
vector_type::reverse_iterator call_rev(FuncType func, Data &status)
Definition: layer.h:161
canopen::LayerStack::handleShutdown
virtual void handleShutdown(LayerStatus &status)
Definition: layer.h:237
canopen::VectorHelper::mutex
boost::shared_mutex mutex
Definition: layer.h:180
canopen::LayerStatus::state
std::atomic< State > state
Definition: layer.h:17
canopen::Layer
Definition: layer.h:63
canopen::LayerStatus
Definition: layer.h:12
canopen::Layer::Error
@ Error
Definition: layer.h:69
canopen::LayerStatus::Error
Definition: layer.h:31
canopen::LayerReport
Definition: layer.h:48
canopen::LayerStatus::Ok::Ok
Ok()
canopen::Layer::handleRead
virtual void handleRead(LayerStatus &status, const LayerState &current_state)=0


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