2012-05-06 17 views
9

पर एएसओ Socket CAN से डेटा पढ़ने के लिए मैं Boost Asio का उपयोग करने के बारे में सोच रहा था। linux/can.h में कुछ भी नहीं चल रहा है, और डिवाइस लूपबैक इंटरफ़ेस की तरह व्यवहार करना चाहिए, और कच्चे सॉकेट के साथ उपयोग किया जाना चाहिए।बूस्ट :: सॉकेटकैन

basic_raw_socket इंटरफेस को देखते हुए यह है लगता है कि मैं

socket(PF_CAN, SOCK_RAW, CAN_RAW); 

इस के साथ बनाया देशी सॉकेट आवंटित करने के लिए basic_raw_socket::assign का उपयोग कर सकते क्या मैं अब तक

namespace can { 
     class CanSocket { 
     public: 
       typedef boost::asio::ip::basic_endpoint<CanSocket> endpoint; 
       typedef boost::asio::ip::basic_resolver_query<CanSocket> resolver_query; 
       typedef boost::asio::ip::basic_resolver_iterator<CanSocket> resolver_iterator; 
       typedef boost::asio::basic_raw_socket<CanSocket> socket; 
       typedef boost::asio::ip::basic_resolver<CanSocket> resolver; 

       CanSocket() 
         : _protocol(CAN_RAW) 
         , _family(PF_CAN) 
       { 
       } 

       static CanSocket v4() 
       { 
         return CanSocket(); 
       } 
       static CanSocket v6(); 
       int type() const; 
       int protocol() const; 
       int family() const; 

       friend bool operator==(const CanSocket& p1, const CanSocket& p2) 
       { 
         return p1._protocol != p2._protocol || p1._family != p2._family; 
       } 
       friend bool operator!=(const CanSocket& p1, const CanSocket& p2) 
       { 
         return p1._protocol == p2._protocol || p1._family == p2._family; 
       } 

     private: 
       int _protocol; 
       int _family; 
}; 
} 

है और यह है मैं अपने आवेदन में इसका उपयोग कैसे करता हूं

boost::asio::io_service ioserv; 

    CanSocket::socket s(ioserv); 

    int sock = socket(PF_CAN, SOCK_RAW, CAN_RAW); 

    s.assign(CanSocket::v4(), sock); 

    struct ifreq ifr; 
    strcpy(ifr.ifr_name, "vcan0"); 
    ioctl(sock, SIOCGIFINDEX, &ifr); /* ifr.ifr_ifindex gets filled 
           * with that device's index */ 

    /* Select that CAN interface, and bind the socket to it. */ 

    /* this should be the endpoint */ 
    struct sockaddr_can addr; 
    addr.can_family = AF_CAN; 
    addr.can_ifindex = ifr.ifr_ifindex; 

    /* s.bind (....) */ 
    bind(sock, (struct sockaddr*)&addr, sizeof(addr)); 

मुझे काफी कुछ नहीं मिलता है कि मैं स्थानीय अंतराल पर binds कैसे कर सकता हूं? कोई आईपी या बंदरगाह शामिल नहीं हैं।

क्या कोई और चीज है जिसे इसे समाप्त करने के लिए एंडपॉइंट के अलावा लागू किया जाना चाहिए?

उत्तर

3

समाधान posix::stream_descriptor का उपयोग करना है।

बस मूल सॉकेट खोलें, बांधें और फिर posix::basic_stream_descriptor::assign का उपयोग करें।

+0

आप पढ़ने के लिए पूर्ण उदाहरण देते हैं कृपया सकते हैं/लेखन CAN फ्रेम की तरह ही मैं अजगर के लिए इसे बनाया है: http: //libbits.wordpress .com/2012/05/22/सॉकेटकैन-सपोर्ट-इन-पायथन/मैं इसे http://elinux.org/CAN_Bus#SocketCAN_Support_in_Programming_Languages.2FE वातावरण पर रखूंगा – yegorich

4

यहां उदाहरण के काम कर रहा है मैं इस सूत्र की मदद से इकट्ठा किया है

/// Encapsulates the flags needed for socket CAN. 
/** 
    * The can class contains flags necessary for CAN sockets. 
    */ 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 

#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) 
{ 
    //int nbytes; 
    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(); 

} 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^