// // Created by lgv on 2025/7/14. // #pragma once #include "abstract_device.h" #include "cmvr/msgs/error_code.pb.h" #include "canbus/common/byte.h" namespace cmvr::device { /** * @class CanFrame * @brief The class which defines the information to send and receive. */ struct CanFrame { /// Message id uint32_t id; /// Message length uint8_t len; /// Message content uint8_t data[8]; /// Time stamp struct timeval timestamp; /** * @brief Constructor */ CanFrame() : id(0), len(0), timestamp{0} { std::memset(data, 0, sizeof(data)); } /** * @brief CanFrame string including essential information about the message. * @return The info string. */ std::string CanFrameString() const { std::stringstream output_stream(""); output_stream << "id:0x" << Byte::byte_to_hex(id) << ",len:" << static_cast(len) << ",data:"; for (uint8_t i = 0; i < len; ++i) { output_stream << Byte::byte_to_hex(data[i]); } output_stream << ","; return output_stream.str(); } }; const int CAN_RESULT_SUCC = 0; const int CAN_ERROR_BASE = 2000; const int CAN_ERROR_OPEN_DEVICE_FAILED = CAN_ERROR_BASE + 1; const int CAN_ERROR_FRAME_NUM = CAN_ERROR_BASE + 2; const int CAN_ERROR_SEND_FAILED = CAN_ERROR_BASE + 3; const int CAN_ERROR_RECV_FAILED = CAN_ERROR_BASE + 4; class AbstractCanbus : public AbstractDevice { public: AbstractCanbus(const XmlNode &cfg) : AbstractDevice(cfg) {} ~AbstractCanbus() {} /** * @brief Send messages * @param frames The messages to send. * @param frame_num The amount of messages to send. * @return The status of the sending action */ virtual cmvr::msgs::ErrorCode send(const std::vector &frames, int32_t *const frame_num) = 0; /** * @brief Send a single message. * @param frames A single-element vector containing only one message. * @return The status of the sending single message action */ virtual cmvr::msgs::ErrorCode sendSingleFrame( const std::vector &frames) { CHECK_EQ(frames.size(), 1U) << "frames size not equal to 1, actual frame size :" << frames.size(); int32_t n = 1; return send(frames, &n); } /** * @brief Receive messages * @param frames The messages to receive. * @param frame_num The amount of messages to receive. * @return The status of the receiving action which is defined by * apollo::common::ErrorCode. */ virtual cmvr::msgs::ErrorCode receive(std::vector *const frames, int32_t *const frame_num) = 0; /** * @brief Get the error string. * @param status The status to get the error string. */ virtual std::string getErrorString(const int32_t status) = 0; protected: /// The CAN client is started. bool is_started_ = false; /// CAN clientstatus cmvr::msgs::ErrorCode status_; // bool enable_log_{false}; }; }