diff --git a/libuavcan/include/uavcan/driver/can.hpp b/libuavcan/include/uavcan/driver/can.hpp index d29d10d436..1ba93d5be2 100644 --- a/libuavcan/include/uavcan/driver/can.hpp +++ b/libuavcan/include/uavcan/driver/can.hpp @@ -24,6 +24,7 @@ struct CanFrame static const uint32_t MaskExtID = 0x1FFFFFFF; static const uint32_t FlagEFF = 1 << 31; ///< Extended frame format static const uint32_t FlagRTR = 1 << 30; ///< Remote transmission request + static const uint32_t FlagERR = 1 << 29; ///< Error frame uint32_t id; ///< CAN ID with flags (above) uint8_t data[8]; @@ -50,8 +51,9 @@ struct CanFrame return (id == rhs.id) && (dlc == rhs.dlc) && std::equal(data, data + dlc, rhs.data); } - bool isExtended() const { return id & FlagEFF; } + bool isExtended() const { return id & FlagEFF; } bool isRemoteTransmissionRequest() const { return id & FlagRTR; } + bool isErrorFrame() const { return id & FlagERR; } enum StringRepresentation { StrTight, StrAligned }; std::string toString(StringRepresentation mode = StrTight) const; diff --git a/libuavcan/src/driver/can.cpp b/libuavcan/src/driver/can.cpp index caab7a2090..0113a6dfd5 100644 --- a/libuavcan/src/driver/can.cpp +++ b/libuavcan/src/driver/can.cpp @@ -14,6 +14,7 @@ const uint32_t CanFrame::MaskStdID; const uint32_t CanFrame::MaskExtID; const uint32_t CanFrame::FlagEFF; const uint32_t CanFrame::FlagRTR; +const uint32_t CanFrame::FlagERR; std::string CanFrame::toString(StringRepresentation mode) const @@ -42,6 +43,11 @@ std::string CanFrame::toString(StringRepresentation mode) const { wpos += snprintf(wpos, epos - wpos, " RTR"); } + else if (id & FlagERR) + { + // TODO: print error flags + wpos += snprintf(wpos, epos - wpos, " ERR"); + } else { for (int dlen = 0; dlen < dlc; dlen++) // hex bytes diff --git a/libuavcan/src/transport/frame.cpp b/libuavcan/src/transport/frame.cpp index db97f4ce0c..3c3483ee67 100644 --- a/libuavcan/src/transport/frame.cpp +++ b/libuavcan/src/transport/frame.cpp @@ -52,7 +52,7 @@ inline static uint32_t bitunpack(uint32_t val) bool Frame::parse(const CanFrame& can_frame) { - if ((can_frame.id & CanFrame::FlagRTR) || !(can_frame.id & CanFrame::FlagEFF)) + if (can_frame.isErrorFrame() || can_frame.isRemoteTransmissionRequest() || !can_frame.isExtended()) return false; if (can_frame.dlc > sizeof(CanFrame::data)) diff --git a/libuavcan/test/transport/can/can_driver.cpp b/libuavcan/test/transport/can/can_driver.cpp index 1970a997cb..9e730adec0 100644 --- a/libuavcan/test/transport/can/can_driver.cpp +++ b/libuavcan/test/transport/can/can_driver.cpp @@ -16,6 +16,9 @@ TEST(CanFrame, FrameProperties) uavcan::CanFrame frame = makeCanFrame(123, "", STD); frame.id |= uavcan::CanFrame::FlagRTR; EXPECT_TRUE(frame.isRemoteTransmissionRequest()); + EXPECT_FALSE(frame.isErrorFrame()); + frame.id |= uavcan::CanFrame::FlagERR; + EXPECT_TRUE(frame.isErrorFrame()); } TEST(CanFrame, ToString)