Add receive support for ISO 9141-2

pull/32/head
Paul Hollinsky 2021-02-18 23:19:33 -05:00
parent 4d655da69d
commit f63c187ed3
9 changed files with 222 additions and 16 deletions

View File

@ -122,6 +122,7 @@ set(SRC_FILES
communication/packet/flexraypacket.cpp
communication/packet/canpacket.cpp
communication/packet/ethernetpacket.cpp
communication/packet/iso9141packet.cpp
communication/decoder.cpp
communication/encoder.cpp
communication/ethernetpacketizer.cpp

View File

@ -9,6 +9,7 @@
#include "icsneo/communication/packet/canpacket.h"
#include "icsneo/communication/packet/ethernetpacket.h"
#include "icsneo/communication/packet/flexraypacket.h"
#include "icsneo/communication/packet/iso9141packet.h"
#include <iostream>
using namespace icsneo;
@ -70,6 +71,22 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
result->network = packet->network;
return true;
}
case Network::Type::ISO9141: {
if(packet->data.size() < sizeof(HardwareISO9141Packet)) {
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return false;
}
result = iso9141decoder.decodeToMessage(packet->data);
if(!result)
return false; // A nullptr was returned, more data is required to decode this packet
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
// The resolution depends on the device
result->timestamp *= timestampResolution;
result->network = packet->network;
return true;
}
case Network::Type::Internal: {
switch(packet->network.getNetID()) {
case Network::NetID::Reset_Status: {

View File

@ -0,0 +1,64 @@
#include "icsneo/communication/packet/iso9141packet.h"
#include <algorithm>
using namespace icsneo;
std::shared_ptr<ISO9141Message> HardwareISO9141Packet::Decoder::decodeToMessage(const std::vector<uint8_t>& bytestream) {
const HardwareISO9141Packet* data = (const HardwareISO9141Packet*)bytestream.data();
if(!mMsg) {
mMsg = std::make_shared<ISO9141Message>();
mGotPackets = 0;
}
mGotPackets++;
const bool morePacketsComing = data->c3.frm == 0;
const uint8_t bytesInCurrentMessage = data->c3.len;
if(mMsg->data.size() + bytesInCurrentMessage > 500) {
mMsg.reset();
return std::shared_ptr<ISO9141Message>();
}
// This timestamp is raw off the device (in timestampResolution increments)
// Decoder will fix as it has information about the timestampResolution increments
mMsg->timestamp = data->timestamp.TS;
auto* dataStart = data->data;
if(mGotPackets == 1) {
// Header
if(bytesInCurrentMessage < 3) {
mMsg.reset(); // We don't have the header for some reason
return std::shared_ptr<ISO9141Message>();
}
std::copy(data->data, data->data + 3, mMsg->header.begin());
dataStart += 3;
}
// Data
mMsg->data.insert(mMsg->data.end(), dataStart, data->data + (bytesInCurrentMessage > 8 ? 8 : bytesInCurrentMessage));
if(bytesInCurrentMessage > 8)
mMsg->data.push_back(data->c1.d8);
if(bytesInCurrentMessage > 9)
mMsg->data.push_back(data->c2.d9);
if(bytesInCurrentMessage > 10)
mMsg->data.push_back(data->c2.d10);
if(bytesInCurrentMessage > 11)
mMsg->data.push_back(data->c3.d11);
if(morePacketsComing)
return std::shared_ptr<ISO9141Message>();
mMsg->transmitted = data->c1.tx;
mMsg->isInit = data->c3.init;
mMsg->framingError = data->c1.options & 0x1;
mMsg->overflowError = data->c1.options & 0x2;
mMsg->parityError = data->c1.options & 0x4;
mMsg->rxTimeoutError = data->c1.options & 0x8;
mMsg->description = data->stats;
auto ret = mMsg;
mMsg.reset();
return ret;
}

View File

@ -176,6 +176,30 @@ int main() {
std::cout << std::dec << std::endl;
break;
}
case icsneo::Network::Type::ISO9141: {
// Note that the default settings on some devices have ISO9141 disabled by default in favor of LIN
// and that this example loads the device defaults at the very end.
// A message of type ISO9414 is guaranteed to be an ISO9141Message, so we can static cast safely
auto isoMessage = std::static_pointer_cast<icsneo::ISO9141Message>(message);
std::cout << "\t\tISO 9141-2 ";
// Print the header bytes
std::cout << '(' << std::hex << std::setfill('0') << std::setw(2) << (uint32_t)isoMessage->header[0] << ' ';
std::cout << std::setfill('0') << std::setw(2) << (uint32_t)isoMessage->header[1] << ' ';
std::cout << std::setfill('0') << std::setw(2) << (uint32_t)isoMessage->header[2] << ") ";
// Print the data length
std::cout << std::dec << " [" << isoMessage->data.size() << "] ";
// Print the data
for(auto& databyte : isoMessage->data)
std::cout << std::hex << std::setfill('0') << std::setw(2) << (uint32_t)databyte << ' ';
// Print the timestamp
std::cout << std::dec << '(' << isoMessage->timestamp << " ns since 1/1/2007)\n";
break;
}
default:
// Ignoring non-network messages
break;

View File

@ -7,6 +7,7 @@
#include "icsneo/communication/message/canmessage.h"
#include "icsneo/communication/packet.h"
#include "icsneo/communication/network.h"
#include "icsneo/communication/packet/iso9141packet.h"
#include "icsneo/api/eventmanager.h"
#include <queue>
#include <vector>
@ -25,6 +26,7 @@ public:
private:
device_eventhandler_t report;
HardwareISO9141Packet::Decoder iso9141decoder;
#pragma pack(push, 1)

View File

@ -0,0 +1,29 @@
#ifndef __ISO9141MESSAGE_H_
#define __ISO9141MESSAGE_H_
#ifdef __cplusplus
#include "icsneo/communication/message/message.h"
#include <array>
namespace icsneo {
class ISO9141Message : public Message {
public:
std::array<uint8_t, 3> header;
bool isInit = false;
bool framingError = false;
bool overflowError = false;
bool parityError = false;
bool rxTimeoutError = false;
// Checksum not yet implemted, it's just at the end of the data if enabled for now
// bool checksumError = false;
// bool hasChecksum = false;
// uint8_t checksum = 0;
};
}
#endif // __cplusplus
#endif

View File

@ -20,12 +20,12 @@ public:
J1708 = 6,
Aux = 7,
J1850VPW = 8,
ISO = 9,
ISO9141 = 9,
ISOPIC = 10,
Main51 = 11,
RED = 12,
SCI = 13,
ISO2 = 14,
ISO9141_2 = 14,
ISO14230 = 15,
LIN = 16,
OP_Ethernet1 = 17,
@ -57,12 +57,12 @@ public:
RED_GET_RTC = 40,
// END Device Command Returns
ISO3 = 41,
ISO9141_3 = 41,
HSCAN2 = 42,
HSCAN3 = 44,
OP_Ethernet4 = 45,
OP_Ethernet5 = 46,
ISO4 = 47,
ISO9141_4 = 47,
LIN2 = 48,
LIN3 = 49,
LIN4 = 50,
@ -132,6 +132,7 @@ public:
Ethernet = 6,
LSFTCAN = 7,
SWCAN = 8,
ISO9141 = 9,
Any = 0xFE, // Never actually set as type, but used as flag for filtering
Other = 0xFF
};
@ -149,6 +150,8 @@ public:
return "Other";
case Type::Internal:
return "Internal";
case Type::ISO9141:
return "ISO 9141-2";
case Type::Ethernet:
return "Ethernet";
case Type::LSFTCAN:
@ -219,6 +222,11 @@ public:
case NetID::SWCAN:
case NetID::SWCAN2:
return Type::SWCAN;
case NetID::ISO9141:
case NetID::ISO9141_2:
case NetID::ISO9141_3:
case NetID::ISO9141_4:
return Type::ISO9141;
default:
return Type::Other;
}
@ -243,8 +251,8 @@ public:
return "Aux";
case NetID::J1850VPW:
return "J1850 VPW";
case NetID::ISO:
return "ISO";
case NetID::ISO9141:
return "ISO 9141";
case NetID::ISOPIC:
return "ISOPIC";
case NetID::Main51:
@ -253,8 +261,8 @@ public:
return "RED";
case NetID::SCI:
return "SCI";
case NetID::ISO2:
return "ISO 2";
case NetID::ISO9141_2:
return "ISO 9141 2";
case NetID::ISO14230:
return "ISO 14230";
case NetID::LIN:
@ -307,8 +315,8 @@ public:
return "RED_HARDWARE_EXCEP";
case NetID::RED_GET_RTC:
return "RED_GET_RTC";
case NetID::ISO3:
return "ISO 3";
case NetID::ISO9141_3:
return "ISO 9141 3";
case NetID::HSCAN2:
return "HSCAN 2";
case NetID::HSCAN3:
@ -317,8 +325,8 @@ public:
return "OP (BR) Ethernet 4";
case NetID::OP_Ethernet5:
return "OP (BR) Ethernet 5";
case NetID::ISO4:
return "ISO 4";
case NetID::ISO9141_4:
return "ISO 9141 4";
case NetID::LIN2:
return "LIN 2";
case NetID::LIN3:
@ -471,12 +479,12 @@ private:
#define ICSNEO_NETID_J1708 6
#define ICSNEO_NETID_AUX 7
#define ICSNEO_NETID_J1850VPW 8
#define ICSNEO_NETID_ISO 9
#define ICSNEO_NETID_ISO9141 9
#define ICSNEO_NETID_ISOPIC 10
#define ICSNEO_NETID_MAIN51 11
#define ICSNEO_NETID_RED 12
#define ICSNEO_NETID_SCI 13
#define ICSNEO_NETID_ISO2 14
#define ICSNEO_NETID_ISO9141_2 14
#define ICSNEO_NETID_ISO14230 15
#define ICSNEO_NETID_LIN 16
#define ICSNEO_NETID_OP_ETHERNET1 17
@ -508,12 +516,12 @@ private:
#define ICSNEO_NETID_RED_GET_RTC 40
// END Device Command Returns
#define ICSNEO_NETID_ISO3 41
#define ICSNEO_NETID_ISO9141_3 41
#define ICSNEO_NETID_HSCAN2 42
#define ICSNEO_NETID_HSCAN3 44
#define ICSNEO_NETID_OP_ETHERNET4 45
#define ICSNEO_NETID_OP_ETHERNET5 46
#define ICSNEO_NETID_ISO4 47
#define ICSNEO_NETID_ISO9141_4 47
#define ICSNEO_NETID_LIN2 48
#define ICSNEO_NETID_LIN3 49
#define ICSNEO_NETID_LIN4 50
@ -579,6 +587,9 @@ private:
#define ICSNEO_NETWORK_TYPE_FLEXRAY 4
#define ICSNEO_NETWORK_TYPE_MOST 5
#define ICSNEO_NETWORK_TYPE_ETHERNET 6
#define ICSNEO_NETWORK_TYPE_LSFTCAN 7
#define ICSNEO_NETWORK_TYPE_SWCAN 8
#define ICSNEO_NETWORK_TYPE_ISO9141 9
#define ICSNEO_NETWORK_TYPE_ANY 0xFE // Never actually set as type, but used as flag for filtering
#define ICSNEO_NETWORK_TYPE_OTHER 0xFF
#endif

View File

@ -0,0 +1,56 @@
#ifndef __ISO9141PACKET_H__
#define __ISO9141PACKET_H__
#ifdef __cplusplus
#include "icsneo/communication/message/iso9141message.h"
#include "icsneo/api/eventmanager.h"
#include <cstdint>
#include <memory>
#include <vector>
namespace icsneo {
typedef uint16_t icscm_bitfield;
struct HardwareISO9141Packet {
class Decoder {
public:
std::shared_ptr<ISO9141Message> decodeToMessage(const std::vector<uint8_t>& bytestream);
private:
std::shared_ptr<ISO9141Message> mMsg;
size_t mGotPackets = 0;
};
struct {
icscm_bitfield d8 : 8;
icscm_bitfield options : 4;
icscm_bitfield tx : 1;
icscm_bitfield networkIndex : 3;
} c1;
struct {
icscm_bitfield d9 : 8;
icscm_bitfield d10 : 8;
} c2;
struct {
icscm_bitfield len : 4;
icscm_bitfield extendedNetworkIndexBit2 : 1;
icscm_bitfield frm : 1;
icscm_bitfield init : 1;
icscm_bitfield extendedNetworkIndexBit : 1;
icscm_bitfield d11 : 8;
} c3;
unsigned char data[8];
uint16_t stats;
struct {
uint64_t TS : 60;
uint64_t : 3; // Reserved for future status bits
uint64_t IsExtended : 1;
} timestamp;
};
}
#endif // __cplusplus
#endif

View File

@ -12,6 +12,8 @@
#include "icsneo/communication/message/canmessage.h"
#include "icsneo/communication/message/ethernetmessage.h"
#include "icsneo/communication/message/flexray/flexraymessage.h"
#include "icsneo/communication/message/iso9141message.h"
namespace icsneo {