#include "pican.h" #include "piincludes_p.h" #if !defined(WINDOWS) && !defined(MAC_OS) # define PIP_CAN #endif #ifdef PIP_CAN # include # include # include # include # ifndef AF_CAN # define AF_CAN 29 # endif # ifndef PF_CAN # define PF_CAN AF_CAN # endif #endif //PRIVATE_DEFINITION_START(PICAN) //#ifdef PIP_CAN //int fd; //spi_ioc_transfer spi_ioc_tr; //#endif //PRIVATE_DEFINITION_END(PICAN) REGISTER_DEVICE(PICAN) PICAN::PICAN(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode) { setThreadedReadBufferSize(256); setPath(path); can_id = 0; } bool PICAN::openDevice() { #ifdef PIP_CAN sock = socket(PF_CAN, SOCK_RAW, CAN_RAW); if(sock < 0){ piCoutObj << "Error! while opening socket"; return false; } struct ifreq ifr; strcpy(ifr.ifr_name, path().dataAscii()); if(ioctl(sock, SIOCGIFINDEX, &ifr) < 0){ piCoutObj << "Error! while determin the interface ioctl"; return false; } // bind socket to all CAN interface struct sockaddr_can addr; addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0){ piCoutObj << "Error! while binding socket"; return false; } return true; #else piCoutObj << "PICAN not implemented on windows"; return false; #endif } bool PICAN::closeDevice() { #ifdef PIP_CAN if (sock > 0) ::close(sock); #endif return true; } int PICAN::readDevice(void * read_to, int max_size) { #ifdef PIP_CAN can_frame frame; int ret = 0; ret = ::read(sock, &frame, sizeof(can_frame)); if(ret < 0) {piCoutObj << "Error while read CAN frame " << ret; return -1;} piCoutObj << "receive CAN frame Id =" << frame.can_id; memcpy(read_to, frame.data, piMini(frame.can_dlc, max_size)); return max_size; #endif return 0; } int PICAN::writeDevice(const void * data, int max_size) { #ifdef PIP_CAN if (max_size > 8) {piCoutObj << "Can't send CAN frame bigger than 8 bytes (requested " << max_size << ")!"; return -1;} can_frame frame; frame.can_id = can_id; frame.can_dlc = max_size; memcpy(frame.data, data, max_size); int ret = 0; ret = ::write(sock, &frame, sizeof(can_frame)); if(ret < 0) {piCoutObj << "Error while send CAN frame " << ret; return -1;} return max_size; #endif return 0; } void PICAN::setCANID(int id) { can_id = id; } int PICAN::CANID() const { return can_id; } PIString PICAN::constructFullPathDevice() const { PIString ret; ret << path() << ":" << CANID(); return ret; } void PICAN::configureFromFullPathDevice(const PIString & full_path) { PIStringList pl = full_path.split(":"); for (int i = 0; i < pl.size_s(); ++i) { PIString p(pl[i]); switch (i) { case 0: setPath(p); break; case 1: setCANID(p.toInt(16)); break; default: break; } } }