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;
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 }