Communication: Add missing CAN error types

icsneo_api
Jonathan Schwartz 2025-02-04 15:15:44 +00:00 committed by Kyle Schwarz
parent a22791c9e0
commit c5ba2d8d32
17 changed files with 126 additions and 69 deletions

View File

@ -12,7 +12,7 @@ pybind11_add_module(icsneopy
icsneopy/communication/network.cpp
icsneopy/communication/message/message.cpp
icsneopy/communication/message/canmessage.cpp
icsneopy/communication/message/canerrorcountmessage.cpp
icsneopy/communication/message/canerrormessage.cpp
icsneopy/communication/message/ethernetmessage.cpp
icsneopy/communication/message/linmessage.cpp
icsneopy/communication/message/tc10statusmessage.cpp

View File

@ -1,18 +0,0 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/message/canerrorcountmessage.h"
namespace icsneo {
void init_canerrorcountmessage(pybind11::module_& m) {
pybind11::class_<CANErrorCountMessage, std::shared_ptr<CANErrorCountMessage>, Message>(m, "CANErrorCountMessage")
.def_readonly("network", &CANErrorCountMessage::network)
.def_readonly("transmitErrorCount", &CANErrorCountMessage::transmitErrorCount)
.def_readonly("receiveErrorCount", &CANErrorCountMessage::receiveErrorCount)
.def_readonly("busOff", &CANErrorCountMessage::busOff);
}
} // namespace icsneo

View File

@ -0,0 +1,38 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/message/canerrormessage.h"
namespace icsneo {
void init_errorcodes(pybind11::module_& m) {
pybind11::enum_<CANErrorCode>(m, "CANErrorCode")
.value("NoError", CANErrorCode::NoError)
.value("StuffError", CANErrorCode::StuffError)
.value("FormError", CANErrorCode::FormError)
.value("AckError", CANErrorCode::AckError)
.value("Bit1Error", CANErrorCode::Bit1Error)
.value("Bit0Error", CANErrorCode::Bit0Error)
.value("CRCError", CANErrorCode::CRCError)
.value("NoChange", CANErrorCode::NoChange);
}
void init_canerrormessage(pybind11::module_& m) {
init_errorcodes(m);
pybind11::class_<CANErrorMessage, std::shared_ptr<CANErrorMessage>, Message>(m, "CANErrorMessage")
.def_readonly("network", &CANErrorMessage::network)
.def_readonly("transmitErrorCount", &CANErrorMessage::transmitErrorCount)
.def_readonly("receiveErrorCount", &CANErrorMessage::receiveErrorCount)
.def_readonly("busOff", &CANErrorMessage::busOff)
.def_readonly("errorPassive", &CANErrorMessage::errorPassive)
.def_readonly("errorWarn", &CANErrorMessage::errorWarn)
.def_readonly("dataErrorCode", &CANErrorMessage::dataErrorCode)
.def_readonly("errorCode", &CANErrorMessage::errorCode);
m.attr("CANErrorCountMessage") = m.attr("CANErrorMessage");
}
} // namespace icsneo

View File

@ -11,6 +11,7 @@ void init_message(pybind11::module_& m) {
pybind11::enum_<Message::Type>(message, "Type")
.value("Frame", Message::Type::Frame)
.value("CANErrorCount", Message::Type::CANErrorCount)
.value("CANError", Message::Type::CANError)
.value("LINHeaderOnly", Message::Type::LINHeaderOnly)
.value("LINBreak", Message::Type::LINBreak)
.value("Invalid", Message::Type::Invalid)

View File

@ -13,7 +13,7 @@ void init_network(pybind11::module_&);
void init_devicetype(pybind11::module_&);
void init_message(pybind11::module_&);
void init_canmessage(pybind11::module_&);
void init_canerrorcountmessage(pybind11::module_&);
void init_canerrormessage(pybind11::module_&);
void init_ethernetmessage(pybind11::module_&);
void init_linmessage(pybind11::module_&);
void init_tc10statusmessage(pybind11::module_&);
@ -38,7 +38,7 @@ PYBIND11_MODULE(icsneopy, m) {
init_network(m);
init_message(m);
init_canmessage(m);
init_canerrorcountmessage(m);
init_canerrormessage(m);
init_ethernetmessage(m);
init_linmessage(m);
init_tc10statusmessage(m);

View File

@ -3,7 +3,7 @@
#include "icsneo/communication/message/serialnumbermessage.h"
#include "icsneo/communication/message/resetstatusmessage.h"
#include "icsneo/communication/message/readsettingsmessage.h"
#include "icsneo/communication/message/canerrorcountmessage.h"
#include "icsneo/communication/message/canerrormessage.h"
#include "icsneo/communication/message/neoreadmemorysdmessage.h"
#include "icsneo/communication/message/flashmemorymessage.h"
#include "icsneo/communication/message/extendedresponsemessage.h"
@ -95,7 +95,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
break;
}
case Message::Type::CANErrorCount: {
CANErrorCountMessage& can = *static_cast<CANErrorCountMessage*>(result.get());
CANErrorMessage& can = *static_cast<CANErrorMessage*>(result.get());
can.network = packet->network;
break;
}

View File

@ -1,7 +1,7 @@
#include "icsneo/communication/message/neomessage.h"
#include "icsneo/communication/message/canmessage.h"
#include "icsneo/communication/message/ethernetmessage.h"
#include "icsneo/communication/message/canerrorcountmessage.h"
#include "icsneo/communication/message/canerrormessage.h"
#include "icsneo/communication/message/linmessage.h"
using namespace icsneo;
@ -104,7 +104,7 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
}
case Message::Type::CANErrorCount: {
neomessage_can_error_t& canerror = *(neomessage_can_error_t*)&neomsg;
auto canerrormsg = std::static_pointer_cast<CANErrorCountMessage>(message);
auto canerrormsg = std::static_pointer_cast<CANErrorMessage>(message);
canerror.transmitErrorCount = canerrormsg->transmitErrorCount;
canerror.receiveErrorCount = canerrormsg->receiveErrorCount;
canerror.status.canBusOff = canerrormsg->busOff;

View File

@ -1,5 +1,5 @@
#include "icsneo/communication/packet/canpacket.h"
#include "icsneo/communication/message/canerrorcountmessage.h"
#include "icsneo/communication/message/canerrormessage.h"
using namespace icsneo;
@ -53,16 +53,18 @@ static std::optional<uint8_t> CAN_LengthToDLC(size_t dataLength, bool fd)
return std::nullopt;
}
std::shared_ptr<Message> HardwareCANPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
const HardwareCANPacket* data = (const HardwareCANPacket*)bytestream.data();
if(data->dlc.RB1) { // Change counts reporting
const bool busOff = data->data[0] & 0b00100000;
auto msg = std::make_shared<CANErrorCountMessage>(data->data[2], data->data[1], busOff);
const HardwareCANErrorPacket* errPacket = (const HardwareCANErrorPacket*)bytestream.data();
if(errPacket->ERROR_INDICATOR) {
auto msg = std::make_shared<CANErrorMessage>();
msg->receiveErrorCount = errPacket->REC;
msg->transmitErrorCount = errPacket->TEC;
msg->errorWarn = HardwareCANErrorPacket::GetErrorWarn(errPacket->flags);
msg->errorPassive = HardwareCANErrorPacket::GetErrorPassive(errPacket->flags);
msg->busOff = HardwareCANErrorPacket::GetBusOff(errPacket->flags);
msg->errorCode = (CANErrorCode)errPacket->error_code;
msg->dataErrorCode = (CANErrorCode)errPacket->brs_data_error_code;
// This timestamp is raw off the device (in timestampResolution increments)
// Decoder will fix as it has information about the timestampResolution increments
msg->timestamp = data->timestamp.TS;

View File

@ -815,11 +815,6 @@ std::shared_ptr<HardwareInfo> Device::getHardwareInfo(std::chrono::milliseconds
return nullptr;
}
if(!isOnline()) {
report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error);
return nullptr;
}
auto filter = std::make_shared<MessageFilter>(Message::Type::HardwareInfo);
auto response = com->waitForMessageSync([this]() {

View File

@ -267,7 +267,7 @@ void printMessage(const std::shared_ptr<icsneo::Message>& message) {
} // end of icsneo::Message::Type::Frame
case icsneo::Message::Type::CANErrorCount: {
// A message of type CANErrorCount is guaranteed to be a CANErrorCount, so we can static cast safely
auto cec = std::static_pointer_cast<icsneo::CANErrorCountMessage>(message);
auto cec = std::static_pointer_cast<icsneo::CANErrorMessage>(message);
std::cout << "\t\t" << cec->network << " error counts changed, REC=" << cec->receiveErrorCount
<< " TEC=" << cec->transmitErrorCount << " (" << (cec->busOff ? "" : "Not ") << "Bus Off)" << std::endl;
break;

View File

@ -252,7 +252,7 @@ int main() {
} // end of icsneo::Message::Type::Frame
case icsneo::Message::Type::CANErrorCount: {
// A message of type CANErrorCount is guaranteed to be a CANErrorCount, so we can static cast safely
auto cec = std::static_pointer_cast<icsneo::CANErrorCountMessage>(message);
auto cec = std::static_pointer_cast<icsneo::CANErrorMessage>(message);
// Print the error counts
std::cout << "\t\t" << cec->network << " error counts changed, REC=" << std::to_string(cec->receiveErrorCount)

View File

@ -1,25 +0,0 @@
#ifndef __CANERRORCOUNTMESSAGE_H_
#define __CANERRORCOUNTMESSAGE_H_
#ifdef __cplusplus
#include "icsneo/communication/message/message.h"
namespace icsneo {
class CANErrorCountMessage : public Message {
public:
CANErrorCountMessage(uint8_t tec, uint8_t rec, bool busOffFlag)
: Message(Message::Type::CANErrorCount), transmitErrorCount(tec), receiveErrorCount(rec), busOff(busOffFlag){}
Network network;
uint8_t transmitErrorCount;
uint8_t receiveErrorCount;
bool busOff;
};
}
#endif // __cplusplus
#endif

View File

@ -0,0 +1,40 @@
#ifndef __CANERRORMESSAGE_H_
#define __CANERRORMESSAGE_H_
#ifdef __cplusplus
#include "icsneo/communication/message/message.h"
namespace icsneo {
enum class CANErrorCode : uint8_t
{
NoError = 0,
StuffError = 1,
FormError = 2,
AckError = 3,
Bit1Error = 4,
Bit0Error = 5,
CRCError = 6,
NoChange = 7
};
class CANErrorMessage : public Message {
public:
CANErrorMessage() : Message(Type::CANError) {}
Network network;
uint8_t transmitErrorCount;
uint8_t receiveErrorCount;
bool busOff;
bool errorPassive;
bool errorWarn;
CANErrorCode dataErrorCode;
CANErrorCode errorCode;
};
using CANErrorCountMessage = CANErrorMessage;
}
#endif // __cplusplus
#endif

View File

@ -17,6 +17,7 @@ public:
Frame = 0,
CANErrorCount = 0x100,
CANError = 0x100,
LINHeaderOnly = 0x200,
LINBreak = 0x201,

View File

@ -13,6 +13,7 @@ namespace icsneo {
typedef uint16_t icscm_bitfield;
#pragma pack(push,2)
struct HardwareCANPacket {
static std::shared_ptr<Message> DecodeToMessage(const std::vector<uint8_t>& bytestream);
static bool EncodeFromMessage(const CANMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report);
@ -50,6 +51,28 @@ struct HardwareCANPacket {
uint64_t IsExtended : 1;
} timestamp;
};
struct HardwareCANErrorPacket {
uint8_t error_code;
uint8_t brs_data_error_code;
uint16_t reserved;
uint16_t DLC : 4;
uint16_t : 4;
uint16_t ERROR_INDICATOR : 1;
uint16_t : 7;
uint8_t flags;
uint8_t REC;
uint8_t TEC;
static bool GetErrorWarn(uint8_t flags) { return flags & 0b0000'0001; }
static bool GetErrorPassive(uint8_t flags) { return flags & 0b0000'1000; }
static bool GetBusOff(uint8_t flags) { return flags & 0b0010'0000; }
};
#pragma pack(pop)
}

View File

@ -14,7 +14,7 @@
#include "icsneo/communication/message/ethernetmessage.h"
#include "icsneo/communication/message/flexray/flexraymessage.h"
#include "icsneo/communication/message/iso9141message.h"
#include "icsneo/communication/message/canerrorcountmessage.h"
#include "icsneo/communication/message/canerrormessage.h"
#include "icsneo/communication/message/ethphymessage.h"
#include "icsneo/communication/message/i2cmessage.h"
#include "icsneo/communication/message/a2bmessage.h"

View File

@ -55,7 +55,7 @@
#include <io.h>
#ifndef __MINGW32__
#include "IP6_misc.h"
#include "ip6_misc.h"
#endif
#define caddr_t char*