boost::asio over SocketCAN

前端 未结 2 1196
青春惊慌失措
青春惊慌失措 2021-02-20 18:35

I was thinking of making use of Boost Asio to read data from a Socket CAN. There\'s nothing fancy going on in linux/can.h , and the device should behave like the loopback inter

相关标签:
2条回答
  • 2021-02-20 19:03

    Here is working example, assembled with help of this thread

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <iostream>
    
    #include <net/if.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/ioctl.h>
    
    #include <linux/can.h>
    #include <linux/can/raw.h>
    
    #include <boost/asio.hpp>
    #include <boost/bind.hpp>
    
    void data_send(void) {
      std::cout << "omg sent" << std::endl;
    }
    
    void data_rec(struct can_frame &rec_frame,
                  boost::asio::posix::basic_stream_descriptor<> &stream) {
      std::cout << std::hex << rec_frame.can_id << "  ";
      for (int i = 0; i < rec_frame.can_dlc; i++) {
        std::cout << std::hex << int(rec_frame.data[i]) << " ";
      }
      std::cout << std::dec << std::endl;
      stream.async_read_some(
          boost::asio::buffer(&rec_frame, sizeof(rec_frame)),
          boost::bind(data_rec, boost::ref(rec_frame), boost::ref(stream)));
    }
    
    int main(void) {
      struct sockaddr_can addr;
      struct can_frame frame;
      struct can_frame rec_frame;
      struct ifreq ifr;
    
      int natsock = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    
      strcpy(ifr.ifr_name, "vcan0");
      ioctl(natsock, SIOCGIFINDEX, &ifr);
    
      addr.can_family = AF_CAN;
      addr.can_ifindex = ifr.ifr_ifindex;
      if (bind(natsock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("Error in socket bind");
        return -2;
      }
    
      frame.can_id = 0x123;
      frame.can_dlc = 2;
      frame.data[0] = 0x11;
      frame.data[1] = 0x23;
    
      boost::asio::io_service ios;
      boost::asio::posix::basic_stream_descriptor<> stream(ios);
      stream.assign(natsock);
    
      stream.async_write_some(boost::asio::buffer(&frame, sizeof(frame)),
                              boost::bind(data_send));
      stream.async_read_some(
          boost::asio::buffer(&rec_frame, sizeof(rec_frame)),
          boost::bind(data_rec, boost::ref(rec_frame), boost::ref(stream)));
      ios.run();
    }
    
    0 讨论(0)
  • 2021-02-20 19:10

    The solution is to use posix::stream_descriptor.

    Just open the native socket, bind and then use posix::basic_stream_descriptor::assign.

    0 讨论(0)
提交回复
热议问题