/******************************************************************** // created: 2011/02/21 - 10:46 // filename: igepCanDriver.cpp // // author: Sergio Rodriguez // // version: $Id: igepCanDriver.cpp srodrigu $ // // purpose: Implementation of the igepCanDriver class // *********************************************************************/ #include #include "igepCanDriver.h" #include #include #include #include #include #include #include #include #include #include #include #include #define DEFAULT_NODE "/dev/pcanusb0" #define WAIT_RECEIVING_FRAME_TIMEOUT 1000 /** * Constructor which enables to initialize the different attributes of the class with default values. */ igepCanDriver::igepCanDriver (void) { printf("Notice : IGEP CAN Driver used\n"); //szDevNode_ = DEFAULT_NODE; mode_ = ReadOnly; } /** * Constructor which enables to initialize the different attributes of the class with default values. */ igepCanDriver::igepCanDriver (int channel) { printf("Notice : IGEP CAN Driver used\n"); //szDevNode_ = DEFAULT_NODE; mode_ = ReadOnly; } /** * Constructor which enables to initialize the different attributes of the class with default values. */ igepCanDriver::igepCanDriver (int channel, unsigned int bitRate) { printf("Notice : IGEP CAN Driver used\n"); //szDevNode_ = DEFAULT_NODE; mode_ = ReadOnly; } /** * Constructor which enables to initialize the different attributes of the class with default values. */ igepCanDriver::igepCanDriver(const char* port, const char* mode) { szDevNode_ =(char*) malloc(14*sizeof(char)); strcpy(szDevNode_,DEFAULT_NODE); printf("Notice : IGEP CAN Driver used\n"); //strcpy(szDevNode_, port); // printf("Driver to be connected at port: %s",szDevNode_); } /** * Destructor which clean up the different attributs of the class. */ igepCanDriver::~igepCanDriver (void) { } /** * Member used to initialise the configuration of the CAN Card. * @see cleanUpPort (void) * @return a Pstatus variable which contain the error code of the function. On success, it return PSUCCESS. On failure, it return Pstatus error code. */ short igepCanDriver::initPort (void) { int nbytes; struct sockaddr_can addr; struct ifreq ifr; char ifname[] = "can0"; if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { perror("Error while opening socket"); return 1; } strcpy(ifr.ifr_name, ifname); ioctl(s, SIOCGIFINDEX, &ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Error in socket bind"); return 1; } return PSUCCESS; } /** * Member used to clean up the configuration of the CAN Card. * @see initPort (void) * @return a Pstatus variable which contain the error code of the function. On success, it return PSUCCESS. On failure, it return Pstatus error code. */ short igepCanDriver::cleanUpPort (void) { if(canDeviceHandle_) { printf("Closing CAN Driver.."); close(s); // CAN_Close(canDeviceHandle_); return PSUCCESS; } printf("CAN Driver finished.\n"); return 1; } /** * Member which permit to send a frame on the CAN bus and test if the frame is well acknowledged. * @param flags a character which contain the flags of the sent frame. * @param dlc a character which defined the number of characters of the sent frame. * @param data a table of characters with the data of the sent frame. * @see receiveFrame (unsigned char * flags, unsigned char * dlc, unsigned char ** data) * @return a Pstatus variable which contain the error code of the function. On success, it return PSUCCESS. On failure, it return Pstatus error code. */ short igepCanDriver::sendFrame (struct CanFrame frame) { can_frame message; message.can_dlc = frame.dlc; message.can_id = frame.id; memcpy(message.data,frame.data, frame.dlc); write(s, &message, sizeof(struct can_frame)); return PSUCCESS; } /** * Member which permit to receive of a frame on the CAN bus. * @param flags a character pointer which contain the flags of the received frame. * @param dlc a character pointer which defined the number of characters of the received frame. * @param data a pointer of table of characters with the data of the received frame. * @see sendFrame (unsigned char flags, unsigned char dlc, unsigned char * data) * @return a Pstatus variable which contain the error code of the function. On success, it return PSUCCESS. On failure, it return Pstatus error code. */ short igepCanDriver::receiveFrame (struct CanFrame &frame) { can_frame message; if ((read(s, &message, sizeof(struct can_frame))) < 0) { perror("application: CAN_Read()"); std::cout << "ERREUR" << std::endl; std::flush(std::cout); return 1; } else { // std::cout << "id : " << message.can_id << " dlc : " << message.can_dlc << " message : " << message.data << std::endl; std::flush(std::cout); frame.dlc = message.can_dlc; //ok frame.id = message.can_id; if( ( frame.dlc > 8 ) || ( frame.dlc < 0 )) frame.dlc = 8; memcpy(frame.data,message.data, frame.dlc); return PSUCCESS; } } /** * Member which wait the reception of a frame on the CAN bus. * @see sendFrame (unsigned char flags, unsigned char dlc, unsigned char * data) * @see receiveFrame (unsigned char * flags, unsigned char * dlc, unsigned char ** data) */ void igepCanDriver::waitReceivingFrame(void) { } // print out the contents of a CAN message void igepCanDriver::print_message(TPCANMsg *m) { int i; // print RTR, 11 or 29, CAN-Id and datalength printf("message: %c %c 0x%08x %1d ", (m->MSGTYPE & MSGTYPE_RTR) ? 'r' : 'm', (m->MSGTYPE & MSGTYPE_EXTENDED) ? 'e' : 's', m->ID, m->LEN); // don't print any telegram contents for remote frames if (!(m->MSGTYPE & MSGTYPE_RTR)) for (i = 0; i < m->LEN; i++) printf("0x%02x ", m->DATA[i]); printf("\n"); }