socketcan_gateway.cpp
Go to the documentation of this file.
00001 
00025 #include <string>
00026 #include <stdio.h>
00027 #include <unistd.h>
00028 #include <fcntl.h>
00029 #include <poll.h>
00030 #include <sys/types.h>
00031 #include <sys/socket.h>
00032 #include <sys/ioctl.h>
00033 #include <net/if.h>
00034 
00035 #include <linux/can.h>
00036 #include <linux/can/raw.h>
00037 
00038 #include "puma_motor_driver/socketcan_gateway.h"
00039 #include "ros/ros.h"
00040 
00041 namespace puma_motor_driver
00042 {
00043 
00044 SocketCANGateway::SocketCANGateway(std::string canbus_dev):
00045   canbus_dev_(canbus_dev),
00046   is_connected_(false),
00047   write_frames_index_(0)
00048 {
00049 }
00050 
00051 bool SocketCANGateway::connect()
00052 {
00053   if ((socket_ = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
00054   {
00055     ROS_ERROR("Error while opening socket");
00056     return false;
00057   }
00058 
00059   struct ifreq ifr;
00060 
00061   snprintf (ifr.ifr_name, sizeof(canbus_dev_.c_str()), "%s", canbus_dev_.c_str());
00062 
00063   if (ioctl(socket_, SIOCGIFINDEX, &ifr) < 0)
00064   {
00065     close(socket_);
00066     ROS_ERROR("Error while trying to control device");
00067     return false;
00068   }
00069 
00070   struct sockaddr_can addr;
00071   addr.can_family  = AF_CAN;
00072   addr.can_ifindex = ifr.ifr_ifindex;
00073 
00074   ROS_DEBUG("%s at index %d", canbus_dev_.c_str(), ifr.ifr_ifindex);
00075 
00076   if (bind(socket_, (struct sockaddr *)&addr, sizeof(addr)) < 0)
00077   {
00078     ROS_ERROR("Error in socket bind");
00079     return false;
00080   }
00081 
00082   struct timeval tv;
00083   tv.tv_sec = 0;
00084   tv.tv_usec = 1;  // microseconds
00085 
00086   setsockopt(socket_, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
00087 
00088   ROS_INFO("Opened Socket CAN on %s", canbus_dev_.c_str());
00089   is_connected_ = true;
00090 
00091   return is_connected_;
00092 }
00093 
00094 
00095 bool SocketCANGateway::isConnected()
00096 {
00097   return is_connected_;
00098 }
00099 
00100 
00101 bool SocketCANGateway::recv(Message* msg)
00102 {
00103   can_frame read_frame;
00104 
00105   int bytes = read(socket_, &read_frame, sizeof(struct can_frame));
00106   if (bytes == sizeof(struct can_frame))
00107   {
00108     ROS_DEBUG("Recieved ID 0x%08x, data (%d)", (read_frame.can_id& CAN_EFF_MASK), read_frame.can_dlc);
00109     msgToFrame(msg, &read_frame);
00110     return true;
00111   }
00112   else
00113   {
00114     if (bytes < 0)
00115     {
00116       if (errno == EAGAIN)
00117       {
00118         ROS_DEBUG("No more frames");
00119       }
00120       else
00121       {
00122         ROS_ERROR("Error reading from socketcan: %d", errno);
00123       }
00124     }
00125     else
00126     {
00127       ROS_ERROR("Socketcan read() returned unexpected size.");
00128     }
00129     return false;
00130   }
00131 }
00132 
00133 void SocketCANGateway::queue(const Message& msg)
00134 {
00135   ROS_DEBUG("Queuing ID 0x%08x, data (%d)", msg.id, msg.len);
00136   write_frames_[write_frames_index_].can_id = msg.id | CAN_EFF_FLAG;
00137   write_frames_[write_frames_index_].can_dlc = msg.len;
00138 
00139   for (int i = 0; i < msg.len; i++)
00140   {
00141     write_frames_[write_frames_index_].data[i] = msg.data[i];
00142   }
00143   write_frames_index_++;
00144 }
00145 
00146 bool SocketCANGateway::sendAllQueued()
00147 {
00148   for (int i = 0; i < write_frames_index_; i++)
00149   {
00150     ROS_DEBUG("Writing ID 0x%08x, data (%d)", write_frames_[i].can_id, write_frames_[i].can_dlc);
00151     int bytes = write(socket_, &write_frames_[i], sizeof(struct can_frame));
00152   }
00153   write_frames_index_ = 0;
00154   return true;
00155 }
00156 
00157 void SocketCANGateway::msgToFrame(Message* msg, can_frame* frame)
00158 {
00159   msg->id = frame->can_id & CAN_EFF_MASK;
00160   msg->len = frame->can_dlc;
00161   for (int i = 0; i < msg->len; i++)
00162   {
00163     msg->data[i] = frame->data[i];
00164   }
00165 }
00166 
00167 }  // namespace puma_motor_driver


puma_motor_driver
Author(s):
autogenerated on Sat Jun 8 2019 18:55:15