From eda4a30dcdecfa3e9b35123c61a8dd622d4d58dd Mon Sep 17 00:00:00 2001 From: Paul Hollinsky Date: Mon, 14 Sep 2020 12:45:32 -0400 Subject: [PATCH] Add ValueCAN 4 Industrial --- device/devicefinder.cpp | 16 ++++ .../settings/valuecan4industrialsettings.h | 46 +++++++++++ .../valuecan4/settings/valuecan4settings.h | 43 +++++++++- .../tree/valuecan4/valuecan4industrial.h | 27 +++++++ .../tree/valuecan4/valuecan4industrialeth.h | 78 +++++++++++++++++++ .../tree/valuecan4/valuecan4industrialusb.h | 54 +++++++++++++ include/icsneo/platform/posix/devices.h | 2 + include/icsneo/platform/windows/devices.h | 2 + 8 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 include/icsneo/device/tree/valuecan4/settings/valuecan4industrialsettings.h create mode 100644 include/icsneo/device/tree/valuecan4/valuecan4industrial.h create mode 100644 include/icsneo/device/tree/valuecan4/valuecan4industrialeth.h create mode 100644 include/icsneo/device/tree/valuecan4/valuecan4industrialusb.h diff --git a/device/devicefinder.cpp b/device/devicefinder.cpp index 5aa19e3..9215058 100644 --- a/device/devicefinder.cpp +++ b/device/devicefinder.cpp @@ -106,6 +106,14 @@ static std::vector supportedDevices = { ValueCAN4_4::DEVICE_TYPE, #endif + #ifdef __VALUECAN4INDUSTRIAL_ETH_H_ + ValueCAN4IndustrialETH::DEVICE_TYPE, + #endif + + #ifdef __VALUECAN4INDUSTRIAL_USB_H_ + ValueCAN4IndustrialUSB::DEVICE_TYPE, + #endif + #ifdef __VIVIDCAN_H_ VividCAN::DEVICE_TYPE, #endif @@ -220,6 +228,14 @@ std::vector> DeviceFinder::FindAll() { findResults.push_back(ValueCAN4_4::Find()); #endif + #ifdef __VALUECAN4INDUSTRIAL_ETH_H_ + findResults.push_back(ValueCAN4IndustrialETH::Find(pcapDevices)); + #endif + + #ifdef __VALUECAN4INDUSTRIAL_USB_H_ + findResults.push_back(ValueCAN4IndustrialUSB::Find()); + #endif + #ifdef __VIVIDCAN_H_ findResults.push_back(VividCAN::Find()); #endif diff --git a/include/icsneo/device/tree/valuecan4/settings/valuecan4industrialsettings.h b/include/icsneo/device/tree/valuecan4/settings/valuecan4industrialsettings.h new file mode 100644 index 0000000..d566976 --- /dev/null +++ b/include/icsneo/device/tree/valuecan4/settings/valuecan4industrialsettings.h @@ -0,0 +1,46 @@ +#ifndef __VALUECAN4_INDUSTRIAL_SETTINGS_H_ +#define __VALUECAN4_INDUSTRIAL_SETTINGS_H_ + +#include "icsneo/device/idevicesettings.h" +#include "icsneo/device/tree/valuecan4/settings/valuecan4settings.h" + +#ifdef __cplusplus + +namespace icsneo { + +class ValueCAN4IndustrialSettings : public IDeviceSettings { +public: + ValueCAN4IndustrialSettings(std::shared_ptr com) : IDeviceSettings(com, sizeof(valuecan4_industrial_settings_t)) {} + const CAN_SETTINGS* getCANSettingsFor(Network net) const override { + auto cfg = getStructurePointer(); + if(cfg == nullptr) + return nullptr; + switch(net.getNetID()) { + case Network::NetID::HSCAN: + return &(cfg->can1); + case Network::NetID::HSCAN2: + return &(cfg->can2); + default: + return nullptr; + } + } + const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override { + auto cfg = getStructurePointer(); + if(cfg == nullptr) + return nullptr; + switch(net.getNetID()) { + case Network::NetID::HSCAN: + return &(cfg->canfd1); + case Network::NetID::HSCAN2: + return &(cfg->canfd2); + default: + return nullptr; + } + } +}; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/device/tree/valuecan4/settings/valuecan4settings.h b/include/icsneo/device/tree/valuecan4/settings/valuecan4settings.h index 24e0bfa..301d84b 100644 --- a/include/icsneo/device/tree/valuecan4/settings/valuecan4settings.h +++ b/include/icsneo/device/tree/valuecan4/settings/valuecan4settings.h @@ -11,7 +11,7 @@ namespace icsneo { #endif // This is where the actual settings structures for all the ValueCAN 4 line live -// ValueCAN 4-1 and 4-2 share a structure, and 4-4 shares with 4-2EL +// ValueCAN 4-1 and 4-2 share a structure, and 4-4 shares with 4-2EL, Industrial has its own #pragma pack(push, 2) typedef struct { @@ -75,10 +75,51 @@ typedef struct { uint16_t pwr_man_enable; uint16_t pwr_man_timeout; } valuecan4_4_2el_settings_t, valuecan4_4_settings_t, valuecan4_2el_settings_t; + +typedef struct { + CAN_SETTINGS can1; + CANFD_SETTINGS canfd1; + CAN_SETTINGS can2; + CANFD_SETTINGS canfd2; + ETHERNET_SETTINGS ethernet; + LIN_SETTINGS lin1; + ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings; + uint16_t iso_parity; + uint16_t iso_msg_termination; + + uint32_t pwr_man_timeout; + uint16_t pwr_man_enable; + uint16_t perf_en; + int16_t iso15765_separation_time_offset; + uint16_t network_enabled_on_boot; + + union { + uint64_t word; + struct + { + uint16_t network_enables; + uint16_t network_enables_2; + uint16_t network_enables_3; + }; + } network_enables; + uint64_t termination_enables; + struct + { + uint32_t disableUsbCheckOnBoot : 1; + uint32_t enableLatencyTest : 1; + uint32_t busMessagesToAndroid : 1; + uint32_t enablePcEthernetComm : 1; + uint32_t reserved : 28; + } flags; +} valuecan4_industrial_settings_t; #pragma pack(pop) #ifdef __cplusplus +static_assert(sizeof(valuecan4_1_2_settings_t) == 148, "ValueCAN 4-1 / 4-2 Settings are not packed correctly!"); +static_assert(sizeof(valuecan4_4_2el_settings_t) == 326, "ValueCAN 4-4 / 4-2EL Settings are not packed correctly!"); +static_assert(sizeof(valuecan4_industrial_settings_t) == 212, "ValueCAN 4 Industrial Settings are not packed correctly!"); + } // End of namespace #endif // __cplusplus diff --git a/include/icsneo/device/tree/valuecan4/valuecan4industrial.h b/include/icsneo/device/tree/valuecan4/valuecan4industrial.h new file mode 100644 index 0000000..6abf963 --- /dev/null +++ b/include/icsneo/device/tree/valuecan4/valuecan4industrial.h @@ -0,0 +1,27 @@ +#ifndef __VALUECAN4INDUSTRIAL_H_ +#define __VALUECAN4INDUSTRIAL_H_ + +#ifdef __cplusplus + +#include "icsneo/device/tree/valuecan4/valuecan4.h" +#include "icsneo/device/tree/valuecan4/settings/valuecan4industrialsettings.h" + +namespace icsneo { + +class ValueCAN4Industrial : public ValueCAN4 { +public: + // Serial numbers start with IV for Industrial + static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::VCAN4_IND; + static constexpr const char* SERIAL_START = "IV"; + +protected: + ValueCAN4Industrial(neodevice_t neodevice) : ValueCAN4(neodevice) { + getWritableNeoDevice().type = DEVICE_TYPE; + } +}; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/device/tree/valuecan4/valuecan4industrialeth.h b/include/icsneo/device/tree/valuecan4/valuecan4industrialeth.h new file mode 100644 index 0000000..3eb1539 --- /dev/null +++ b/include/icsneo/device/tree/valuecan4/valuecan4industrialeth.h @@ -0,0 +1,78 @@ +#ifndef __VALUECAN4INDUSTRIAL_ETH_H_ +#define __VALUECAN4INDUSTRIAL_ETH_H_ + +#ifdef __cplusplus + +#include "icsneo/device/tree/valuecan4/valuecan4industrial.h" +#include "icsneo/platform/pcap.h" +#include + +namespace icsneo { + +class ValueCAN4IndustrialETH : public ValueCAN4Industrial { +public: + static constexpr const uint16_t ETH_PRODUCT_ID = 0x0012; + + static std::vector> Find(const std::vector& pcapDevices) { + std::vector> found; + + for(auto& foundDev : pcapDevices) { + auto fakedev = std::shared_ptr(new ValueCAN4IndustrialETH({})); + for (auto& payload : foundDev.discoveryPackets) + fakedev->com->packetizer->input(payload); + for (auto& packet : fakedev->com->packetizer->output()) { + std::shared_ptr msg; + if (!fakedev->com->decoder->decode(msg, packet)) + continue; // We failed to decode this packet + + if(!msg || msg->network.getNetID() != Network::NetID::Main51) + continue; // Not a message we care about + auto sn = std::dynamic_pointer_cast(msg); + if(!sn) + continue; // Not a serial number message + + if(sn->deviceSerial.length() < 2) + continue; + if(sn->deviceSerial.substr(0, 2) != SERIAL_START) + continue; // Not a ValueCAN 4 Industrial + + auto device = foundDev.device; + device.serial[sn->deviceSerial.copy(device.serial, sizeof(device.serial))] = '\0'; + found.push_back(std::shared_ptr(new ValueCAN4IndustrialETH(std::move(device)))); + break; + } + } + + return found; + } + + static const std::vector& GetSupportedNetworks() { + static std::vector supportedNetworks = { + Network::NetID::HSCAN, + Network::NetID::HSCAN2, + + // No Network::NetID::Ethernet, since we're communicating over it instead + }; + return supportedNetworks; + } + +protected: + virtual void setupSupportedRXNetworks(std::vector& rxNetworks) override { + for(auto& netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + virtual void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } + +private: + ValueCAN4IndustrialETH(neodevice_t neodevice) : ValueCAN4Industrial(neodevice) { + initialize(); + } +}; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/device/tree/valuecan4/valuecan4industrialusb.h b/include/icsneo/device/tree/valuecan4/valuecan4industrialusb.h new file mode 100644 index 0000000..554af32 --- /dev/null +++ b/include/icsneo/device/tree/valuecan4/valuecan4industrialusb.h @@ -0,0 +1,54 @@ +#ifndef __VALUECAN4INDUSTRIAL_USB_H_ +#define __VALUECAN4INDUSTRIAL_USB_H_ + +#ifdef __cplusplus + +#include "icsneo/device/tree/valuecan4/valuecan4industrial.h" +#include "icsneo/platform/stm32.h" +#include + +namespace icsneo { + +class ValueCAN4IndustrialUSB : public ValueCAN4Industrial { +public: + static std::vector> Find() { + std::vector> found; + + for(auto neodevice : STM32::FindByProduct(USB_PRODUCT_ID)) { + if(std::string(neodevice.serial).substr(0, 2) == SERIAL_START) + found.emplace_back(new ValueCAN4IndustrialUSB(neodevice)); + } + + return found; + } + + static const std::vector& GetSupportedNetworks() { + static std::vector supportedNetworks = { + Network::NetID::HSCAN, + Network::NetID::HSCAN2, + + Network::NetID::Ethernet + }; + return supportedNetworks; + } + +protected: + virtual void setupSupportedRXNetworks(std::vector& rxNetworks) override { + for(auto& netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + virtual void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } + +private: + ValueCAN4IndustrialUSB(neodevice_t neodevice) : ValueCAN4Industrial(neodevice) { + initialize(); + } +}; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/platform/posix/devices.h b/include/icsneo/platform/posix/devices.h index a4f3629..90149d4 100644 --- a/include/icsneo/platform/posix/devices.h +++ b/include/icsneo/platform/posix/devices.h @@ -26,6 +26,8 @@ #include "icsneo/device/tree/valuecan4/valuecan4-2eleth.h" #include "icsneo/device/tree/valuecan4/valuecan4-2elusb.h" #include "icsneo/device/tree/valuecan4/valuecan4-4.h" +#include "icsneo/device/tree/valuecan4/valuecan4industrialeth.h" +#include "icsneo/device/tree/valuecan4/valuecan4industrialusb.h" #include "icsneo/device/tree/vividcan/vividcan.h" #endif \ No newline at end of file diff --git a/include/icsneo/platform/windows/devices.h b/include/icsneo/platform/windows/devices.h index d1b408b..2c7b882 100644 --- a/include/icsneo/platform/windows/devices.h +++ b/include/icsneo/platform/windows/devices.h @@ -26,6 +26,8 @@ #include "icsneo/device/tree/valuecan4/valuecan4-2eleth.h" #include "icsneo/device/tree/valuecan4/valuecan4-2elusb.h" #include "icsneo/device/tree/valuecan4/valuecan4-4.h" +#include "icsneo/device/tree/valuecan4/valuecan4industrialeth.h" +#include "icsneo/device/tree/valuecan4/valuecan4industrialusb.h" #include "icsneo/device/tree/vividcan/vividcan.h" #endif \ No newline at end of file