can_layer.h
Go to the documentation of this file.
00001 #ifndef H_CAN_LAYER
00002 #define H_CAN_LAYER
00003 
00004 #include <socketcan_interface/threading.h>
00005 #include "layer.h"
00006 
00007 namespace canopen{
00008 
00009 class CANLayer: public Layer{
00010     boost::mutex mutex_;
00011     boost::shared_ptr<can::DriverInterface> driver_;
00012     const std::string device_;
00013     const bool loopback_;
00014     can::Frame last_error_;
00015     can::CommInterface::FrameListener::Ptr error_listener_;
00016     void handleFrame(const can::Frame & msg){
00017         boost::mutex::scoped_lock lock(mutex_);
00018         last_error_ = msg;
00019         LOG("ID: " << msg.id);
00020     }
00021     boost::shared_ptr<boost::thread> thread_;
00022 
00023 public:
00024     CANLayer(const boost::shared_ptr<can::DriverInterface> &driver, const std::string &device, bool loopback)
00025     : Layer(device + " Layer"), driver_(driver), device_(device), loopback_(loopback) { assert(driver_); }
00026 
00027     virtual void handleRead(LayerStatus &status, const LayerState &current_state) {
00028         if(current_state > Init){
00029             if(!driver_->getState().isReady()) status.error("CAN not ready");
00030         }
00031     }
00032     virtual void handleWrite(LayerStatus &status, const LayerState &current_state) {
00033         if(current_state > Init){
00034             if(!driver_->getState().isReady()) status.error("CAN not ready");
00035         }
00036     }
00037 
00038     virtual void handleDiag(LayerReport &report){
00039         can::State s = driver_->getState();
00040         if(!s.isReady()){
00041             report.error("CAN layer not ready");
00042             report.add("driver_state", int(s.driver_state));
00043         }
00044         if(s.error_code){
00045             report.add("socket_error", s.error_code);
00046         }
00047         if(s.internal_error != 0){
00048             report.add("internal_error", int(s.internal_error));
00049             std::string desc;
00050             if(driver_->translateError(s.internal_error, desc)) report.add("internal_error_desc", desc);
00051             std::stringstream sstr;
00052             sstr << std::hex;
00053             {
00054                 boost::mutex::scoped_lock lock(mutex_);
00055                 for(size_t i=0; i < last_error_.dlc; ++i){
00056                     sstr << (unsigned int) last_error_.data[i] << " ";
00057                 }
00058             }
00059             report.add("can_error_frame", sstr.str());
00060 
00061         }
00062 
00063     }
00064     
00065     virtual void handleInit(LayerStatus &status){
00066         if(thread_){
00067             status.warn("CAN thread already running");
00068         } else if(!driver_->init(device_, loopback_)) {
00069             status.error("CAN init failed");
00070         } else {
00071             can::StateWaiter waiter(driver_.get());
00072 
00073             thread_.reset(new boost::thread(&can::DriverInterface::run, driver_));
00074             error_listener_ = driver_->createMsgListener(can::ErrorHeader(), can::CommInterface::FrameDelegate(this, &CANLayer::handleFrame));
00075             
00076             if(!waiter.wait(can::State::ready, boost::posix_time::seconds(1))){
00077                 status.error("CAN init timed out");
00078             }
00079         }
00080         if(!driver_->getState().isReady()){
00081           status.error("CAN is not ready");
00082         }
00083     }
00084     virtual void handleShutdown(LayerStatus &status){
00085         can::StateWaiter waiter(driver_.get());
00086         error_listener_.reset();
00087         driver_->shutdown();
00088         if(!waiter.wait(can::State::closed, boost::posix_time::seconds(1))){
00089              status.warn("CAN shutdown timed out");
00090         }
00091         if(thread_){
00092             thread_->interrupt();
00093             thread_->join();
00094             thread_.reset();
00095         }
00096     }
00097 
00098     virtual void handleHalt(LayerStatus &status) { /* nothing to do */ }
00099     
00100     virtual void handleRecover(LayerStatus &status){
00101         if(!driver_->getState().isReady()){
00102             handleShutdown(status);
00103             handleInit(status);
00104         }
00105     }
00106 
00107 };
00108 } // namespace canopen
00109 
00110 #endif


canopen_master
Author(s): Mathias Lüdtke
autogenerated on Sun Sep 3 2017 03:10:42