bcm.h
Go to the documentation of this file.
1 #ifndef H_CAN_BCM
2 #define H_CAN_BCM
3 
5 
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <sys/ioctl.h>
9 #include <net/if.h>
10 
11 #include <linux/can.h>
12 #include <linux/can/bcm.h>
13 #include <linux/can/error.h>
14 
15 namespace can {
16 
17 class BCMsocket{
18  int s_;
19  struct Message {
20  size_t size;
21  uint8_t *data;
22  Message(size_t n)
23  : size(sizeof(bcm_msg_head) + sizeof(can_frame)*n), data(new uint8_t[size])
24  {
25  assert(n<=256);
26  memset(data, 0, size);
27  head().nframes = n;
28  }
29  bcm_msg_head& head() {
30  return *(bcm_msg_head*)data;
31  }
32  template<typename T> void setIVal2(T period){
33  long long usec = boost::chrono::duration_cast<boost::chrono::microseconds>(period).count();
34  head().ival2.tv_sec = usec / 1000000;
35  head().ival2.tv_usec = usec % 1000000;
36  }
37  void setHeader(Header header){
38  head().can_id = header.id | (header.is_extended?CAN_EFF_FLAG:0);
39  }
40  bool write(int s){
41  return ::write(s, data, size) > 0;
42  }
44  delete[] data;
45  data = 0;
46  size = 0;
47  }
48  };
49 public:
50  BCMsocket():s_(-1){
51  }
52  bool init(const std::string &device){
53  s_ = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
54 
55  if(s_ < 0 ) return false;
56  struct ifreq ifr;
57  strcpy(ifr.ifr_name, device.c_str());
58  int ret = ioctl(s_, SIOCGIFINDEX, &ifr);
59 
60  if(ret != 0){
61  shutdown();
62  return false;
63  }
64 
65  struct sockaddr_can addr = {0};
66  addr.can_family = AF_CAN;
67  addr.can_ifindex = ifr.ifr_ifindex;
68 
69  ret = connect(s_, (struct sockaddr *)&addr, sizeof(addr));
70 
71  if(ret < 0){
72  shutdown();
73  return false;
74  }
75  return true;
76  }
77  template<typename DurationType> bool startTX(DurationType period, Header header, size_t num, Frame *frames) {
78  Message msg(num);
79  msg.setHeader(header);
80  msg.setIVal2(period);
81 
82  bcm_msg_head &head = msg.head();
83 
84  head.opcode = TX_SETUP;
85  head.flags |= SETTIMER | STARTTIMER;
86 
87  for(size_t i=0; i < num; ++i){ // msg nr
88  head.frames[i].can_dlc = frames[i].dlc;
89  head.frames[i].can_id = head.can_id;
90  for(size_t j = 0; j < head.frames[i].can_dlc; ++j){ // byte nr
91  head.frames[i].data[j] = frames[i].data[j];
92  }
93  }
94  return msg.write(s_);
95  }
96  bool stopTX(Header header){
97  Message msg(0);
98  msg.head().opcode = TX_DELETE;
99  msg.setHeader(header);
100  return msg.write(s_);
101  }
102  void shutdown(){
103  if(s_ > 0){
104  close(s_);
105  s_ = -1;
106  }
107  }
108 
109  virtual ~BCMsocket(){
110  shutdown();
111  }
112 };
113 
114 }
115 
116 #endif
bool stopTX(Header header)
Definition: bcm.h:96
Definition: asio_base.h:11
void setHeader(Header header)
Definition: bcm.h:37
boost::array< value_type, 8 > data
array for 8 data bytes with bounds checking
Definition: interface.h:58
unsigned int is_extended
frame uses 29 bit CAN identifier
Definition: interface.h:22
bool write(int s)
Definition: bcm.h:40
virtual ~BCMsocket()
Definition: bcm.h:109
int s_
Definition: bcm.h:18
bcm_msg_head & head()
Definition: bcm.h:29
bool init(const std::string &device)
Definition: bcm.h:52
uint8_t * data
Definition: bcm.h:21
void setIVal2(T period)
Definition: bcm.h:32
void shutdown()
Definition: bcm.h:102
BCMsocket()
Definition: bcm.h:50
bool startTX(DurationType period, Header header, size_t num, Frame *frames)
Definition: bcm.h:77
unsigned char dlc
len of data
Definition: interface.h:59
unsigned int id
CAN ID (11 or 29 bits valid, depending on is_extended member.
Definition: interface.h:19
Message(size_t n)
Definition: bcm.h:22


socketcan_interface
Author(s): Mathias Lüdtke
autogenerated on Fri May 14 2021 02:59:39