/* Copyright (c) 2015, 2016 Hubert Denkmair This file is part of cangaroo. cangaroo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. cangaroo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cangaroo. If not, see . */ #include "CanMessage.h" #include enum { id_flag_extended = 0x80000000, id_flag_rtr = 0x40000000, id_flag_error = 0x20000000, id_mask_extended = 0x1FFFFFFF, id_mask_standard = 0x7FF }; CanMessage::CanMessage() : _raw_id(0), _dlc(0), _isFD(false), _interface(0), _u8() { _timestamp.tv_sec = 0; _timestamp.tv_usec = 0; } CanMessage::CanMessage(uint32_t can_id) : _dlc(0), _interface(0), _u8() { _timestamp.tv_sec = 0; _timestamp.tv_usec = 0; setId(can_id); } CanMessage::CanMessage(const CanMessage &msg) { cloneFrom(msg); } void CanMessage::cloneFrom(const CanMessage &msg) { _raw_id = msg._raw_id; _dlc = msg._dlc; // Copy data for(int i=0; i<64; i++) { _u8[i] = msg._u8[i]; } _interface = msg._interface; _timestamp = msg._timestamp; //从文件发送数据pushback 某些变量值不对的问题 _isFD=msg._isFD; _isBRS=msg._isBRS; } uint32_t CanMessage::getRawId() const { return _raw_id; } void CanMessage::setRawId(const uint32_t raw_id) { _raw_id = raw_id; } uint32_t CanMessage::getId() const { if (isExtended()) { return _raw_id & id_mask_extended; } else { return _raw_id & id_mask_standard; } } void CanMessage::setId(const uint32_t id) { _raw_id &= ~ id_mask_extended; _raw_id = id; if (id>0x7FF) { setExtended(true); } } bool CanMessage::isExtended() const { return (_raw_id & id_flag_extended) != 0; } void CanMessage::setExtended(const bool isExtended) { if (isExtended) { _raw_id |= id_flag_extended; } else { _raw_id &= ~id_flag_extended; } } bool CanMessage::isRTR() const { return (_raw_id & id_flag_rtr) != 0; } void CanMessage::setRTR(const bool isRTR) { if (isRTR) { _raw_id |= id_flag_rtr; } else { _raw_id &= ~id_flag_rtr; } } bool CanMessage::isFD() const { return _isFD; } void CanMessage::setFD(const bool isFD) { _isFD = isFD; } bool CanMessage::isBRS() const { return _isBRS; } void CanMessage::setBRS(const bool isBRS) { _isBRS = isBRS; } bool CanMessage::isErrorFrame() const { return (_raw_id & id_flag_error) != 0; } void CanMessage::setErrorFrame(const bool isErrorFrame) { if (isErrorFrame) { _raw_id |= id_flag_error; } else { _raw_id &= ~id_flag_error; } } CanInterfaceId CanMessage::getInterfaceId() const { return _interface; } void CanMessage::setInterfaceId(CanInterfaceId interface) { _interface = interface; } uint8_t CanMessage::getLength() const { return _dlc; } void CanMessage::setLength(const uint8_t dlc) { // Limit to CANFD max length if (dlc<=64) { _dlc = dlc; } else { _dlc = 8; } } uint8_t CanMessage::getByte(const uint8_t index) const { if (index (getLength()*8)) { // return 0; // } // FIXME: This only gives access to data bytes 0-8. Need to rework for CANFD. uint64_t data = le64toh(_u64[0]); data >>= start_bit; uint64_t mask = 0xFFFFFFFFFFFFFFFF; mask <<= length; mask = ~mask; data &= mask; // If the length is greater than 8, we need to byteswap to preserve endianness if (isBigEndian && (length > 8)) { // Swap bytes data = __builtin_bswap64(data); // Shift out unused bits data >>= 64 - length; } return data; } void CanMessage::setDataAt(uint8_t position, uint8_t data) { if(position < 64) _u8[position] = data; else return; } void CanMessage::setData(const uint8_t d0) { _dlc = 1; _u8[0] = d0; } void CanMessage::setData(const uint8_t d0, const uint8_t d1) { _dlc = 2; _u8[0] = d0; _u8[1] = d1; } void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2) { _dlc = 3; _u8[0] = d0; _u8[1] = d1; _u8[2] = d2; } void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3) { _dlc = 4; _u8[0] = d0; _u8[1] = d1; _u8[2] = d2; _u8[3] = d3; } void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3, const uint8_t d4) { _dlc = 5; _u8[0] = d0; _u8[1] = d1; _u8[2] = d2; _u8[3] = d3; _u8[4] = d4; } void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3, const uint8_t d4, const uint8_t d5) { _dlc = 6; _u8[0] = d0; _u8[1] = d1; _u8[2] = d2; _u8[3] = d3; _u8[4] = d4; _u8[5] = d5; } void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3, const uint8_t d4, const uint8_t d5, const uint8_t d6) { _dlc = 7; _u8[0] = d0; _u8[1] = d1; _u8[2] = d2; _u8[3] = d3; _u8[4] = d4; _u8[5] = d5; _u8[6] = d6; } void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3, const uint8_t d4, const uint8_t d5, const uint8_t d6, const uint8_t d7) { _dlc = 8; _u8[0] = d0; _u8[1] = d1; _u8[2] = d2; _u8[3] = d3; _u8[4] = d4; _u8[5] = d5; _u8[6] = d6; _u8[7] = d7; } timeval CanMessage::getTimestamp() const { return _timestamp; } void CanMessage::setTimestamp(const timeval timestamp) { _timestamp = timestamp; } void CanMessage::setTimestamp(const uint64_t seconds, const uint32_t micro_seconds) { _timestamp.tv_sec = seconds; _timestamp.tv_usec = micro_seconds; } double CanMessage::getFloatTimestamp() const { return (double)_timestamp.tv_sec + ((double)_timestamp.tv_usec/1000000); } QDateTime CanMessage::getDateTime() const { return QDateTime::fromMSecsSinceEpoch((qint64)(1000*getFloatTimestamp())); } QString CanMessage::getIdString() const { if (isExtended()) { return QString().sprintf("0x%08X", getId()); } else { return QString().sprintf("0x%03X", getId()); } } QString CanMessage::getDataHexString() const { if(getLength() == 0) return ""; QString outstr = ""; for(int i=0; i