Go to the documentation of this file.00001 #ifndef H_CAN_INTERFACE
00002 #define H_CAN_INTERFACE
00003
00004 #include <boost/array.hpp>
00005 #include <boost/system/error_code.hpp>
00006 #include <boost/shared_ptr.hpp>
00007
00008 #include "FastDelegate.h"
00009
00010 namespace can{
00011
00013 struct Header{
00014 static const unsigned int ID_MASK = (1u << 29)-1;
00015 static const unsigned int ERROR_MASK = (1u << 29);
00016 static const unsigned int RTR_MASK = (1u << 30);
00017 static const unsigned int EXTENDED_MASK = (1u << 31);
00018
00019 unsigned int id:29;
00020 unsigned int is_error:1;
00021 unsigned int is_rtr:1;
00022 unsigned int is_extended:1;
00023
00024 bool isValid() const{
00025 return id < (is_extended?(1<<29):(1<<11));
00026 }
00033 operator const unsigned int() const { return is_error ? (ERROR_MASK) : *(unsigned int*) this; }
00034
00035 Header()
00036 : id(0),is_error(0),is_rtr(0), is_extended(0) {}
00037
00038 Header(unsigned int i, bool extended, bool rtr, bool error)
00039 : id(i),is_error(error?1:0),is_rtr(rtr?1:0), is_extended(extended?1:0) {}
00040 };
00041
00042
00043 struct MsgHeader : public Header{
00044 MsgHeader(unsigned int i=0, bool rtr = false) : Header(i, false, rtr, false) {}
00045 };
00046 struct ExtendedHeader : public Header{
00047 ExtendedHeader(unsigned int i=0, bool rtr = false) : Header(i, true, rtr, false) {}
00048 };
00049 struct ErrorHeader : public Header{
00050 ErrorHeader(unsigned int i=0) : Header(i, false, false, true) {}
00051 };
00052
00053
00054
00056 struct Frame: public Header{
00057 boost::array<unsigned char, 8> data;
00058 unsigned char dlc;
00059
00061 bool isValid() const{
00062 return (dlc <= 8) && Header::isValid();
00063 }
00071 Frame() : Header(), dlc(0) {}
00072 Frame(const Header &h, unsigned char l = 0) : Header(h), dlc(l) {}
00073 };
00074
00076 class State{
00077 public:
00078 enum DriverState{
00079 closed, open, ready
00080 } driver_state;
00081 boost::system::error_code error_code;
00082 unsigned int internal_error;
00083
00084 State() : driver_state(closed), internal_error(0) {}
00085 virtual bool isReady() const { return driver_state == ready; }
00086 virtual ~State() {}
00087 };
00088
00090 template <typename T,typename U> class Listener{
00091 const T callable_;
00092 public:
00093 typedef U Type;
00094 typedef T Callable;
00095 typedef boost::shared_ptr<const Listener> Ptr;
00096
00097 Listener(const T &callable):callable_(callable){ }
00098 void operator()(const U & u) const { if(callable_) callable_(u); }
00099 virtual ~Listener() {}
00100 };
00101
00102 class StateInterface{
00103 public:
00104 typedef fastdelegate::FastDelegate1<const State&> StateDelegate;
00105 typedef Listener<const StateDelegate, const State&> StateListener;
00106
00113 virtual StateListener::Ptr createStateListener(const StateDelegate &delegate) = 0;
00114
00115 virtual ~StateInterface() {}
00116 };
00117
00118 class CommInterface{
00119 public:
00120 typedef fastdelegate::FastDelegate1<const Frame&> FrameDelegate;
00121 typedef Listener<const FrameDelegate, const Frame&> FrameListener;
00122
00129 virtual bool send(const Frame & msg) = 0;
00130
00137 virtual FrameListener::Ptr createMsgListener(const FrameDelegate &delegate) = 0;
00138
00146 virtual FrameListener::Ptr createMsgListener(const Frame::Header&, const FrameDelegate &delegate) = 0;
00147
00148 virtual ~CommInterface() {}
00149 };
00150
00151 class DriverInterface : public CommInterface, public StateInterface {
00152 public:
00160 virtual bool init(const std::string &device, bool loopback) = 0;
00161
00167 virtual bool recover() = 0;
00168
00172 virtual State getState() = 0;
00173
00179 virtual void shutdown() = 0;
00180
00181 virtual bool translateError(unsigned int internal_error, std::string & str) = 0;
00182
00183 virtual bool doesLoopBack() const = 0;
00184
00185 virtual void run() = 0;
00186
00187 virtual ~DriverInterface() {}
00188 };
00189
00190
00191 }
00192
00193 #include <boost/thread/mutex.hpp>
00194
00195 struct _cout_wrapper{
00196 static boost::mutex& get_cout_mutex(){
00197 static boost::mutex mutex;
00198 return mutex;
00199 }
00200 };
00201
00202 #define LOG(log) { boost::mutex::scoped_lock _cout_lock(_cout_wrapper::get_cout_mutex()); std::cout << log << std::endl; }
00203
00204
00205 #endif