00001 #include "SocketCANController.hpp"
00002
00003 #include <rtt/Logger.hpp>
00004
00005 #include <sys/socket.h>
00006 #include <sys/ioctl.h>
00007
00008 #include <net/if.h>
00009 #include <linux/can.h>
00010 #include <linux/can/raw.h>
00011
00012
00013 #define PF_CAN 29
00014
00015 #define AF_CAN PF_CAN
00016
00017 #define INVALID -1
00018
00019 struct SocketCANControllerPrivate
00020 {
00021
00022
00023 fd_set fdset;
00024
00025 int fd;
00026
00027 struct timeval tv;
00028
00029 struct ifreq ifr;
00030
00031 struct sockaddr_can addr;
00032 bool exit;
00033
00034 RTT::CAN::CANBusInterface * bus;
00035
00036
00037 unsigned int total_TX;
00038
00039 unsigned int total_RX;
00040
00041 unsigned int failed_TX;
00042
00043 unsigned int failed_RX;
00044 };
00045
00046 namespace RTT
00047 {
00048 namespace CAN
00049 {
00050
00051 SocketCANController::SocketCANController(int priority,
00052 std::string dev_name, int timeout) :
00053 NonPeriodicActivity(ORO_SCHED_OTHER, priority),
00054 d(new SocketCANControllerPrivate)
00055 {
00056 int ifindex;
00057
00058 Logger::In in("SocketCANController");
00059
00060
00061 FD_ZERO(&d->fdset);
00062 log(Info) << "Trying to open " << dev_name << endlog();
00063 d->fd = socket(PF_CAN,SOCK_RAW, CAN_RAW);
00064 if (d->fd < 0)
00065 {
00066 log(Error) << d->fd << " error" << endlog();
00067 log(Error) << dev_name << ": failed. Could not open device."
00068 << endlog();
00069 }
00070 else
00071 {
00072
00073 FD_SET(d->fd, &d->fdset);
00074
00075 d->tv.tv_sec = 0;
00076 d->tv.tv_usec = timeout * 1000;
00077 strcpy(d->ifr.ifr_name, dev_name.c_str());
00078
00079 ioctl(d->fd, SIOCGIFINDEX, &d->ifr);
00080 ifindex = d->ifr.ifr_ifindex;
00081
00082 d->addr.can_family = AF_CAN;
00083 d->addr.can_ifindex = ifindex;
00084
00085 if (bind(d->fd, (struct sockaddr *) &d->addr, sizeof(d->addr)) < 0)
00086 log(Error) << dev_name << ": failed. Could not bind to device." << endlog();
00087 }
00088 }
00089
00090 SocketCANController::~SocketCANController()
00091 {
00092 Logger::In in("SocketCANController");
00093
00094
00095 this->stop();
00096
00097
00098 if (d->fd >= 0)
00099 {
00100 close(d->fd);
00101 d->fd = INVALID;
00102 }
00103
00104
00105 delete (d);
00106
00107 }
00108
00109 bool SocketCANController::initialize()
00110 {
00111 Logger::In in("SocketCANController");
00112
00113 if (d->fd == INVALID)
00114 return false;
00115
00116 d->exit = false;
00117
00118 d->total_RX = d->total_TX = 0;
00119 d->failed_RX = d->failed_TX = 0;
00120
00121 return true;
00122 }
00123
00124 void SocketCANController::loop()
00125 {
00126 while (!d->exit)
00127 {
00128 this->readFromBuffer();
00129 }
00130 }
00131
00132 bool SocketCANController::breakLoop()
00133 {
00134 d->exit = true;
00135 return true;
00136 }
00137
00138 void SocketCANController::finalize()
00139 {
00140 Logger::In in("SocketCANController");
00141 log(Info) << "Socket CAN Controller stopped. Last run statistics :"
00142 << endlog();
00143 log(Info) << " Total Received : " << d->total_RX
00144 << ". Failed to Receive : " << d->failed_RX
00145 << endlog();
00146 log(Info) << " Total Transmitted : " << d->total_TX
00147 << ". Failed to Transmit : " << d->failed_TX
00148 << endlog();
00149 d->total_RX = d->failed_RX
00150 = d->total_TX = d->failed_TX = 0;
00151 }
00152
00153 void SocketCANController::addBus(CANBusInterface* bus)
00154 {
00155 Logger::In in("SocketCANController");
00156
00157 if(bus == NULL)
00158 log(Error) << "Can not add CANBus, CANBusInterface is not valid!" << endlog();
00159 else {
00160 d->bus = bus;
00161 bus->setController(this);
00162 }
00163 }
00164
00165 void SocketCANController::process(const CANMessage* msg)
00166 {
00167 Logger::In in("SocketCANController");
00168
00169 int ret = 0;
00170
00171
00172 struct can_frame frame;
00173 for (unsigned int i = 0; i < msg->getDLC(); i++)
00174 frame.data[i] = msg->getData(i);
00175
00176
00177 frame.can_dlc = msg->getDLC();
00178
00179
00180 if (msg->isExtended())
00181 frame.can_id = msg->getExtId() | CAN_EFF_FLAG;
00182 else
00183
00184 frame.can_id = msg->getStdId();
00185
00186 if (msg->isRemote())
00187 frame.can_id = CAN_RTR_FLAG;
00188
00189
00190 ret = write(d->fd, &frame, sizeof(can_frame));
00191 if (ret > 0)
00192 d->total_TX++;
00193 else if (ret < 0)
00194 d->failed_TX++;
00195
00196 }
00197
00198 bool SocketCANController::readFromBuffer()
00199 {
00200 Logger::In in("SocketCANController");
00201
00202 struct can_frame frame;
00203 CANMessage msg;
00204 int ret;
00205 struct timeval tv;
00206 tv.tv_sec = d->tv.tv_sec;
00207 tv.tv_usec = d->tv.tv_usec;
00208
00209 FD_ZERO(&d->fdset);
00210 FD_SET(d->fd, &d->fdset);
00211
00212 if(d->bus == NULL) {
00213 log(Error) << "No CANBus added! Use SocketCANController::addBus " << endlog();
00214 return false;
00215 }
00216
00217
00218 ret = select(d->fd+1, &d->fdset,
00219 NULL, NULL, &tv);
00220 if (ret > 0)
00221 {
00222 ret = recv(d->fd, &frame, sizeof(can_frame),
00223 MSG_DONTWAIT);
00224 if (ret > 0)
00225 {
00226 msg.clear();
00227
00228 msg.setDLC(frame.can_dlc);
00229
00230 if (frame.can_id == CAN_RTR_FLAG)
00231 msg.setRemote();
00232
00233 if ((frame.can_id & CAN_EFF_MASK) > CAN_SFF_MASK)
00234 msg.setExtId(frame.can_id);
00235 else
00236
00237 msg.setStdId(frame.can_id);
00238
00239 for (unsigned int i = 0; i < msg.getDLC(); i++)
00240 msg.setData(i, frame.data[i]);
00241
00242 #if 0
00243 log(Debug) << "Receiving CAN Message: Id=";
00244 if (msg.isStandard())
00245 log(Debug) << msg.getStdId();
00246 else
00247 log(Debug) << msg.getExtId();
00248 log(Debug) << ", DLC=" << msg.getDLC() << ", DATA = ";
00249 for (unsigned int i=0; i < msg.getDLC(); i++)
00250 log(Debug) << (unsigned int) msg.getData(i) << " ";
00251 log(Debug) << endlog();
00252 #endif
00253
00254 msg.origin = this;
00255 d->bus->write(&msg);
00256 d->total_RX++;
00257 }
00258 else
00259 d->failed_RX++;
00260 }
00264 else if (ret < 0)
00265 d->failed_RX++;
00266
00267
00268
00269 return true;
00270 }
00271
00272 }
00273 }