bcm.h
Go to the documentation of this file.
00001 #ifndef H_CAN_BCM
00002 #define H_CAN_BCM
00003 
00004 #include <socketcan_interface/interface.h>
00005 
00006 #include <sys/types.h>
00007 #include <sys/socket.h>
00008 #include <sys/ioctl.h>
00009 #include <net/if.h>
00010  
00011 #include <linux/can.h>
00012 #include <linux/can/bcm.h>
00013 #include <linux/can/error.h>
00014 
00015 namespace can {
00016 
00017 class BCMsocket{
00018     int s_;
00019     struct Message {
00020         size_t size;
00021         uint8_t *data;
00022         Message(size_t n)
00023         : size(sizeof(bcm_msg_head) + sizeof(can_frame)*n), data(new uint8_t[size])
00024         {
00025             assert(n<=256);
00026             memset(data, 0, size);
00027             head().nframes = n;
00028         }
00029         bcm_msg_head& head() {
00030             return *(bcm_msg_head*)data;
00031         }
00032         template<typename T> void setIVal2(T period){
00033             long long usec = boost::chrono::duration_cast<boost::chrono::microseconds>(period).count();
00034             head().ival2.tv_sec = usec / 1000000;
00035             head().ival2.tv_usec = usec % 1000000;
00036         }
00037         void setHeader(Header header){
00038             head().can_id = header.id | (header.is_extended?CAN_EFF_FLAG:0);
00039         }
00040         bool write(int s){
00041             return ::write(s, data, size) > 0;
00042         }
00043         ~Message(){
00044             delete[] data;
00045             data = 0;
00046             size = 0;
00047         }
00048     };
00049 public:
00050     BCMsocket():s_(-1){
00051     }
00052     bool init(const std::string &device){
00053         s_ = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
00054 
00055         if(s_ < 0 ) return false;
00056         struct ifreq ifr;
00057         strcpy(ifr.ifr_name, device.c_str());
00058         int ret = ioctl(s_, SIOCGIFINDEX, &ifr);
00059 
00060         if(ret != 0){
00061             shutdown();
00062             return false;
00063         }
00064 
00065         struct sockaddr_can addr = {0};
00066         addr.can_family = AF_CAN;
00067         addr.can_ifindex = ifr.ifr_ifindex;
00068 
00069         ret = connect(s_, (struct sockaddr *)&addr, sizeof(addr));
00070 
00071         if(ret < 0){
00072             shutdown();
00073             return false;
00074         }
00075         return true;
00076     }
00077     template<typename DurationType> bool startTX(DurationType period, Header header, size_t num, Frame *frames) {
00078         Message msg(num);
00079         msg.setHeader(header);
00080         msg.setIVal2(period);
00081 
00082         bcm_msg_head &head = msg.head();
00083 
00084         head.opcode = TX_SETUP;
00085         head.flags |= SETTIMER | STARTTIMER;
00086 
00087         for(size_t i=0; i < num; ++i){ // msg nr
00088             head.frames[i].can_dlc = frames[i].dlc;
00089             head.frames[i].can_id = head.can_id;
00090             for(size_t j = 0; j < head.frames[i].can_dlc; ++j){ // byte nr
00091                 head.frames[i].data[j] = frames[i].data[j];
00092             }
00093         }
00094         return msg.write(s_);
00095     }
00096     bool stopTX(Header header){
00097         Message msg(0);
00098         msg.head().opcode = TX_DELETE;
00099         msg.setHeader(header);
00100         return msg.write(s_);
00101     }
00102     void shutdown(){
00103         if(s_ > 0){
00104             close(s_);
00105             s_ = -1;
00106         }
00107     }
00108 
00109     virtual ~BCMsocket(){
00110         shutdown();
00111     }
00112 };
00113 
00114 }
00115 
00116 #endif


socketcan_interface
Author(s): Mathias Lüdtke
autogenerated on Thu Jun 6 2019 20:43:53