Device: Add T1S extended settings
parent
6f2ad54adc
commit
146ddaf23c
|
|
@ -104,6 +104,18 @@ void init_idevicesettings(pybind11::module_& m) {
|
|||
.def("set_t1s_max_burst", &IDeviceSettings::setT1SMaxBurstFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_t1s_burst_timer", &IDeviceSettings::getT1SBurstTimerFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_t1s_burst_timer", &IDeviceSettings::setT1SBurstTimerFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_t1s_local_id_alternate", &IDeviceSettings::getT1SLocalIDAlternateFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_t1s_local_id_alternate", &IDeviceSettings::setT1SLocalIDAlternateFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("is_t1s_termination_enabled", &IDeviceSettings::isT1STerminationEnabledFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_t1s_termination", &IDeviceSettings::setT1STerminationFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("is_t1s_bus_decoding_beacons_enabled", &IDeviceSettings::isT1SBusDecodingBeaconsEnabledFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_t1s_bus_decoding_beacons", &IDeviceSettings::setT1SBusDecodingBeaconsFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("is_t1s_bus_decoding_all_enabled", &IDeviceSettings::isT1SBusDecodingAllEnabledFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_t1s_bus_decoding_all", &IDeviceSettings::setT1SBusDecodingAllFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_t1s_multi_id_enable_mask", &IDeviceSettings::getT1SMultiIDEnableMaskFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_t1s_multi_id_enable_mask", &IDeviceSettings::setT1SMultiIDEnableMaskFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_t1s_multi_id", &IDeviceSettings::getT1SMultiIDFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_t1s_multi_id", &IDeviceSettings::setT1SMultiIDFor, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
|
||||
.def("set_misc_io_analog_output_enabled", &IDeviceSettings::setMiscIOAnalogOutputEnabled, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_misc_io_analog_output", &IDeviceSettings::setMiscIOAnalogOutput, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ option(LIBICSNEO_BUILD_CPP_SPI_EXAMPLE "Build the SPI example." ON)
|
|||
option(LIBICSNEO_BUILD_CPP_MUTEX_EXAMPLE "Build the NetworkMutex example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_ANALOG_OUT_EXAMPLE "Build the analog output example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_DISKFORMAT_EXAMPLE "Build the disk format example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_T1S_EXAMPLE "Build the T1S example." ON)
|
||||
|
||||
add_compile_options(${LIBICSNEO_COMPILER_WARNINGS})
|
||||
|
||||
|
|
@ -105,3 +106,7 @@ endif()
|
|||
if(LIBICSNEO_BUILD_CPP_DISKFORMAT_EXAMPLE)
|
||||
add_subdirectory(cpp/diskformat)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_CPP_T1S_EXAMPLE)
|
||||
add_subdirectory(cpp/t1s)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
add_executable(libicsneocpp-t1s-settings src/T1SSettingsExample.cpp)
|
||||
target_link_libraries(libicsneocpp-t1s-settings icsneocpp)
|
||||
|
||||
add_executable(libicsneocpp-t1s-symbol-decoding src/T1SSymbolDecodingExample.cpp)
|
||||
target_link_libraries(libicsneocpp-t1s-symbol-decoding icsneocpp)
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "icsneo/icsneocpp.h"
|
||||
|
||||
template<typename T>
|
||||
std::string optToString(const std::optional<T>& opt) {
|
||||
if (!opt.has_value())
|
||||
return "N/A";
|
||||
if constexpr (std::is_same_v<T, bool>)
|
||||
return opt.value() ? "true" : "false";
|
||||
else
|
||||
return std::to_string(opt.value());
|
||||
}
|
||||
|
||||
bool getUserConfirmation(const std::string& prompt) {
|
||||
std::string input;
|
||||
std::cout << prompt << " (y/n): " << std::flush;
|
||||
std::getline(std::cin, input);
|
||||
if (!input.empty()) {
|
||||
char c = std::tolower(input[0]);
|
||||
return (c == 'y');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<icsneo::Network::NetID> selectNetworks(const std::vector<icsneo::Network::NetID>& availableNetworks) {
|
||||
std::vector<icsneo::Network::NetID> selectedNetworks;
|
||||
|
||||
std::cout << "\n" << std::string(70, '=') << std::endl;
|
||||
std::cout << "Select T1S Networks to Configure" << std::endl;
|
||||
std::cout << std::string(70, '=') << std::endl;
|
||||
|
||||
for (size_t i = 0; i < availableNetworks.size(); i++) {
|
||||
std::cout << " [" << (i + 1) << "] " << icsneo::Network(availableNetworks[i]) << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "\nEnter network numbers to configure (e.g., '1,3' or '1-3' or 'all'): " << std::flush;
|
||||
std::string input;
|
||||
std::getline(std::cin, input);
|
||||
|
||||
if (input.empty())
|
||||
return selectedNetworks;
|
||||
|
||||
std::transform(input.begin(), input.end(), input.begin(), ::tolower);
|
||||
|
||||
if (input == "all") {
|
||||
return availableNetworks;
|
||||
}
|
||||
|
||||
std::stringstream ss(input);
|
||||
std::string token;
|
||||
while (std::getline(ss, token, ',')) {
|
||||
token.erase(0, token.find_first_not_of(" \t"));
|
||||
token.erase(token.find_last_not_of(" \t") + 1);
|
||||
|
||||
size_t dashPos = token.find('-');
|
||||
if (dashPos != std::string::npos) {
|
||||
try {
|
||||
int start = std::stoi(token.substr(0, dashPos));
|
||||
int end = std::stoi(token.substr(dashPos + 1));
|
||||
for (int i = start; i <= end; i++) {
|
||||
if (i >= 1 && i <= (int)availableNetworks.size()) {
|
||||
selectedNetworks.push_back(availableNetworks[i - 1]);
|
||||
}
|
||||
}
|
||||
} catch (...) {}
|
||||
} else {
|
||||
try {
|
||||
int num = std::stoi(token);
|
||||
if (num >= 1 && num <= (int)availableNetworks.size()) {
|
||||
selectedNetworks.push_back(availableNetworks[num - 1]);
|
||||
}
|
||||
} catch (...) {}
|
||||
}
|
||||
}
|
||||
|
||||
return selectedNetworks;
|
||||
}
|
||||
|
||||
uint8_t getUint8Input(const std::string& prompt, uint8_t defaultValue) {
|
||||
std::string input;
|
||||
std::cout << prompt << " [" << (int)defaultValue << "]: " << std::flush;
|
||||
std::getline(std::cin, input);
|
||||
if (input.empty())
|
||||
return defaultValue;
|
||||
try {
|
||||
int val = std::stoi(input);
|
||||
if (val >= 0 && val <= 255)
|
||||
return static_cast<uint8_t>(val);
|
||||
} catch (...) {}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
uint16_t getUint16Input(const std::string& prompt, uint16_t defaultValue) {
|
||||
std::string input;
|
||||
std::cout << prompt << " [" << (int)defaultValue << "]: " << std::flush;
|
||||
std::getline(std::cin, input);
|
||||
if (input.empty())
|
||||
return defaultValue;
|
||||
try {
|
||||
int val = std::stoi(input);
|
||||
if (val >= 0 && val <= 65535)
|
||||
return static_cast<uint16_t>(val);
|
||||
} catch (...) {}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
void displayT1SSettings(const std::shared_ptr<icsneo::Device>& device, icsneo::Network::NetID netId) {
|
||||
std::cout << "\t" << icsneo::Network(netId) << " T1S Settings:" << std::endl;
|
||||
|
||||
std::cout << "\t PLCA Enabled: " << optToString(device->settings->isT1SPLCAEnabledFor(netId)) << std::endl;
|
||||
std::cout << "\t Local ID: " << optToString(device->settings->getT1SLocalIDFor(netId)) << std::endl;
|
||||
std::cout << "\t Max Nodes: " << optToString(device->settings->getT1SMaxNodesFor(netId)) << std::endl;
|
||||
std::cout << "\t TX Opp Timer: " << optToString(device->settings->getT1STxOppTimerFor(netId)) << std::endl;
|
||||
std::cout << "\t Max Burst: " << optToString(device->settings->getT1SMaxBurstFor(netId)) << std::endl;
|
||||
std::cout << "\t Burst Timer: " << optToString(device->settings->getT1SBurstTimerFor(netId)) << std::endl;
|
||||
|
||||
auto termEnabled = device->settings->isT1STerminationEnabledFor(netId);
|
||||
if (termEnabled.has_value())
|
||||
std::cout << "\t Termination: " << optToString(termEnabled) << std::endl;
|
||||
|
||||
auto localIdAlt = device->settings->getT1SLocalIDAlternateFor(netId);
|
||||
if (localIdAlt.has_value()) {
|
||||
std::cout << "\t Local ID Alternate: " << optToString(localIdAlt) << std::endl;
|
||||
std::cout << "\t Bus Dec Beacons: " << optToString(device->settings->isT1SBusDecodingBeaconsEnabledFor(netId)) << std::endl;
|
||||
std::cout << "\t Bus Dec All: " << optToString(device->settings->isT1SBusDecodingAllEnabledFor(netId)) << std::endl;
|
||||
|
||||
auto multiIdMask = device->settings->getT1SMultiIDEnableMaskFor(netId);
|
||||
if (multiIdMask.has_value()) {
|
||||
std::cout << "\t Multi-ID Mask: 0x" << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< (int)multiIdMask.value() << std::dec << std::endl;
|
||||
std::cout << "\t Multi-IDs: ";
|
||||
for (uint8_t i = 0; i < 7; i++) {
|
||||
if (i > 0) std::cout << ", ";
|
||||
auto multiId = device->settings->getT1SMultiIDFor(netId, i);
|
||||
std::cout << "[" << (int)i << "]=" << optToString(multiId);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void configureT1SNetwork(std::shared_ptr<icsneo::Device>& device, icsneo::Network::NetID netId) {
|
||||
std::cout << "\n" << std::string(70, '=') << std::endl;
|
||||
std::cout << "Configuring T1S Network: " << icsneo::Network(netId) << std::endl;
|
||||
std::cout << std::string(70, '=') << std::endl;
|
||||
|
||||
std::cout << "\n--- Basic PLCA Settings ---" << std::endl;
|
||||
bool plcaEnabled = getUserConfirmation("Enable PLCA");
|
||||
device->settings->setT1SPLCAFor(netId, plcaEnabled);
|
||||
|
||||
uint8_t localId = getUint8Input("Local ID (0-255)", 1);
|
||||
device->settings->setT1SLocalIDFor(netId, localId);
|
||||
|
||||
uint8_t maxNodes = getUint8Input("Max Nodes (0-255)", 8);
|
||||
device->settings->setT1SMaxNodesFor(netId, maxNodes);
|
||||
|
||||
uint8_t txOppTimer = getUint8Input("TX Opportunity Timer (0-255)", 20);
|
||||
device->settings->setT1STxOppTimerFor(netId, txOppTimer);
|
||||
|
||||
uint16_t maxBurst = getUint16Input("Max Burst (0-65535)", 128);
|
||||
device->settings->setT1SMaxBurstFor(netId, maxBurst);
|
||||
|
||||
uint16_t burstTimer = getUint16Input("Burst Timer (0-65535)", 64);
|
||||
device->settings->setT1SBurstTimerFor(netId, burstTimer);
|
||||
|
||||
if (device->settings->isT1STerminationEnabledFor(netId).has_value()) {
|
||||
std::cout << "\n--- Termination Settings ---" << std::endl;
|
||||
bool termEnabled = getUserConfirmation("Enable Termination");
|
||||
device->settings->setT1STerminationFor(netId, termEnabled);
|
||||
}
|
||||
|
||||
if (device->settings->getT1SLocalIDAlternateFor(netId).has_value()) {
|
||||
std::cout << "\n--- Extended Settings ---" << std::endl;
|
||||
uint8_t localIdAlt = getUint8Input("Local ID Alternate (0-255)", 0);
|
||||
device->settings->setT1SLocalIDAlternateFor(netId, localIdAlt);
|
||||
|
||||
bool busDecBeacons = getUserConfirmation("Enable Bus Decoding (Beacons)");
|
||||
device->settings->setT1SBusDecodingBeaconsFor(netId, busDecBeacons);
|
||||
|
||||
bool busDecAll = getUserConfirmation("Enable Bus Decoding (All Symbols)");
|
||||
device->settings->setT1SBusDecodingAllFor(netId, busDecAll);
|
||||
|
||||
if (getUserConfirmation("Configure Multi-ID settings?")) {
|
||||
uint8_t multiIdMask = getUint8Input("Multi-ID Enable Mask (0x00-0xFF, hex)", 0x00);
|
||||
device->settings->setT1SMultiIDEnableMaskFor(netId, multiIdMask);
|
||||
|
||||
std::cout << "Configure Multi-IDs (7 slots):" << std::endl;
|
||||
for (uint8_t i = 0; i < 7; i++) {
|
||||
uint8_t multiId = getUint8Input(" Multi-ID [" + std::to_string(i) + "]", 0);
|
||||
device->settings->setT1SMultiIDFor(netId, i, multiId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\n✓ Configuration complete for " << icsneo::Network(netId) << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "\n" << std::string(70, '=') << std::endl;
|
||||
std::cout << "10BASE-T1S SETTINGS CONFIGURATION EXAMPLE" << std::endl;
|
||||
std::cout << std::string(70, '=') << std::endl;
|
||||
std::cout << "libicsneo " << icsneo::GetVersion() << std::endl;
|
||||
std::cout << std::string(70, '=') << std::endl;
|
||||
|
||||
std::cout << "\nFinding devices... " << std::flush;
|
||||
auto devices = icsneo::FindAllDevices();
|
||||
std::cout << "OK, " << devices.size() << " device" << (devices.size() == 1 ? "" : "s") << " found" << std::endl;
|
||||
|
||||
if (devices.empty()) {
|
||||
std::cout << "No devices found!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(auto& device : devices)
|
||||
std::cout << " " << device->describe() << std::endl;
|
||||
|
||||
std::shared_ptr<icsneo::Device> selectedDevice;
|
||||
for(auto& device : devices) {
|
||||
if (device->getType() == icsneo::DeviceType::RADComet3) {
|
||||
selectedDevice = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedDevice && !devices.empty())
|
||||
selectedDevice = devices[0];
|
||||
|
||||
if (!selectedDevice) {
|
||||
std::cout << "No suitable device found!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "\nSelected device: " << selectedDevice->describe() << std::endl;
|
||||
std::cout << "Serial: " << selectedDevice->getSerial() << std::endl;
|
||||
|
||||
std::cout << "\nOpening device... " << std::flush;
|
||||
if (!selectedDevice->open()) {
|
||||
std::cout << "✗ Failed" << std::endl;
|
||||
std::cout << icsneo::GetLastError() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << "✓" << std::endl;
|
||||
|
||||
std::vector<icsneo::Network::NetID> candidateNetworks = {
|
||||
icsneo::Network::NetID::AE_01, icsneo::Network::NetID::AE_02,
|
||||
icsneo::Network::NetID::AE_03, icsneo::Network::NetID::AE_04,
|
||||
icsneo::Network::NetID::AE_05, icsneo::Network::NetID::AE_06,
|
||||
icsneo::Network::NetID::AE_07, icsneo::Network::NetID::AE_08,
|
||||
icsneo::Network::NetID::AE_09, icsneo::Network::NetID::AE_10
|
||||
};
|
||||
|
||||
std::vector<icsneo::Network::NetID> t1sNetworks;
|
||||
for (auto netId : candidateNetworks) {
|
||||
auto localId = selectedDevice->settings->getT1SLocalIDFor(netId);
|
||||
if (localId.has_value())
|
||||
t1sNetworks.push_back(netId);
|
||||
}
|
||||
|
||||
if (t1sNetworks.empty()) {
|
||||
std::cout << "No T1S networks found on this device" << std::endl;
|
||||
selectedDevice->close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "\nFound " << t1sNetworks.size() << " T1S network"
|
||||
<< (t1sNetworks.size() == 1 ? "" : "s") << ":" << std::endl;
|
||||
for (size_t i = 0; i < t1sNetworks.size(); i++)
|
||||
std::cout << " [" << (i + 1) << "] " << icsneo::Network(t1sNetworks[i]) << std::endl;
|
||||
|
||||
std::cout << "\n" << std::string(70, '-') << std::endl;
|
||||
std::cout << "Current T1S Settings:" << std::endl;
|
||||
std::cout << std::string(70, '-') << std::endl;
|
||||
for (auto netId : t1sNetworks)
|
||||
displayT1SSettings(selectedDevice, netId);
|
||||
|
||||
auto networksToConfig = selectNetworks(t1sNetworks);
|
||||
|
||||
if (networksToConfig.empty()) {
|
||||
std::cout << "\nNo networks selected for configuration." << std::endl;
|
||||
std::cout << "Closing device... " << std::flush;
|
||||
selectedDevice->close();
|
||||
std::cout << "✓" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::cout << "\nConfiguring " << networksToConfig.size() << " network"
|
||||
<< (networksToConfig.size() == 1 ? "" : "s") << "..." << std::endl;
|
||||
|
||||
for (auto netId : networksToConfig)
|
||||
configureT1SNetwork(selectedDevice, netId);
|
||||
|
||||
std::cout << "\n" << std::string(70, '=') << std::endl;
|
||||
bool saveToEEPROM = getUserConfirmation("Save settings to EEPROM (permanent)?");
|
||||
std::cout << std::string(70, '=') << std::endl;
|
||||
|
||||
std::cout << "\nApplying settings" << (saveToEEPROM ? " to EEPROM" : " temporarily") << "... " << std::flush;
|
||||
bool success = selectedDevice->settings->apply(!saveToEEPROM);
|
||||
if (!success) {
|
||||
std::cout << "✗ Failed" << std::endl;
|
||||
std::cout << icsneo::GetLastError() << std::endl;
|
||||
selectedDevice->close();
|
||||
return 1;
|
||||
}
|
||||
std::cout << "✓" << std::endl;
|
||||
|
||||
std::cout << "\n" << std::string(70, '-') << std::endl;
|
||||
std::cout << "Updated T1S Settings:" << std::endl;
|
||||
std::cout << std::string(70, '-') << std::endl;
|
||||
for (auto netId : t1sNetworks)
|
||||
displayT1SSettings(selectedDevice, netId);
|
||||
|
||||
std::cout << "Closing device... " << std::flush;
|
||||
selectedDevice->close();
|
||||
std::cout << "✓" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,357 @@
|
|||
// 10BASE-T1S Symbol Decoding Example
|
||||
// Demonstrates T1S bus symbol decoding and analysis
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <atomic>
|
||||
|
||||
#include "icsneo/icsneocpp.h"
|
||||
|
||||
enum class T1SSymbol : uint8_t {
|
||||
SSD = 0x04,
|
||||
ESDOK = 0x07,
|
||||
BEACON = 0x08,
|
||||
ESD = 0x0D,
|
||||
ESDERR = 0x11,
|
||||
SYNC = 0x18,
|
||||
ESDJAB = 0x19,
|
||||
SILENCE = 0x1F
|
||||
};
|
||||
|
||||
std::string getSymbolName(uint8_t value) {
|
||||
switch(static_cast<T1SSymbol>(value)) {
|
||||
case T1SSymbol::SSD: return "SSD";
|
||||
case T1SSymbol::ESDOK: return "ESDOK";
|
||||
case T1SSymbol::BEACON: return "BEACON";
|
||||
case T1SSymbol::ESD: return "ESD";
|
||||
case T1SSymbol::ESDERR: return "ESDERR";
|
||||
case T1SSymbol::SYNC: return "SYNC";
|
||||
case T1SSymbol::ESDJAB: return "ESDJAB";
|
||||
case T1SSymbol::SILENCE: return "SILENCE";
|
||||
default:
|
||||
if (value <= 0x0F) {
|
||||
std::stringstream ss;
|
||||
ss << "DATA(0x" << std::hex << std::uppercase << (int)value << ")";
|
||||
return ss.str();
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << "UNKNOWN(0x" << std::hex << std::uppercase << std::setw(2)
|
||||
<< std::setfill('0') << (int)value << std::setfill(' ') << ")";
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
|
||||
struct T1SStatistics {
|
||||
std::atomic<uint64_t> symbolCount{0};
|
||||
std::atomic<uint64_t> beaconCount{0};
|
||||
std::atomic<uint64_t> wakeCount{0};
|
||||
std::atomic<uint64_t> burstCount{0};
|
||||
std::atomic<uint64_t> dataFrameCount{0};
|
||||
std::map<std::string, uint64_t> symbolStats;
|
||||
|
||||
void reset() {
|
||||
symbolCount = 0;
|
||||
beaconCount = 0;
|
||||
wakeCount = 0;
|
||||
burstCount = 0;
|
||||
dataFrameCount = 0;
|
||||
symbolStats.clear();
|
||||
}
|
||||
|
||||
void print() const {
|
||||
std::cout << std::setfill(' ');
|
||||
|
||||
std::cout << "\n" << std::string(70, '=') << std::endl;
|
||||
std::cout << "T1S SYMBOL DECODING STATISTICS" << std::endl;
|
||||
std::cout << std::string(70, '=') << std::endl;
|
||||
|
||||
std::cout << "Total Symbols: " << symbolCount << std::endl;
|
||||
std::cout << "Total Beacons: " << beaconCount << std::endl;
|
||||
std::cout << "Total Wake Signals: " << wakeCount << std::endl;
|
||||
std::cout << "Total Bursts: " << burstCount << std::endl;
|
||||
std::cout << "Total Data Frames: " << dataFrameCount << std::endl;
|
||||
|
||||
if (!symbolStats.empty()) {
|
||||
std::cout << "\n" << std::string(70, '-') << std::endl;
|
||||
std::cout << "Symbol Type Breakdown:" << std::endl;
|
||||
std::cout << std::string(70, '-') << std::endl;
|
||||
std::vector<std::pair<std::string, uint64_t>> sortedStats(
|
||||
symbolStats.begin(), symbolStats.end());
|
||||
std::sort(sortedStats.begin(), sortedStats.end(),
|
||||
[](const auto& a, const auto& b) { return a.second > b.second; });
|
||||
|
||||
for (const auto& [name, count] : sortedStats) {
|
||||
std::cout << " " << std::left << std::setw(20) << name
|
||||
<< std::right << std::setw(10) << count << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << std::string(70, '=') << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
bool getUserConfirmation(const std::string& prompt) {
|
||||
std::string input;
|
||||
std::cout << prompt << " (y/n): " << std::flush;
|
||||
std::getline(std::cin, input);
|
||||
if (!input.empty()) {
|
||||
char c = std::tolower(input[0]);
|
||||
return (c == 'y');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool configureT1SDecoding(std::shared_ptr<icsneo::Device>& device, icsneo::Network::NetID network,
|
||||
bool enableSymbols, bool enableBeacons) {
|
||||
std::cout << "\nConfiguring T1S decoding on network " << icsneo::Network(network) << "..." << std::endl;
|
||||
if (!device->settings->setT1SBusDecodingAllFor(network, enableSymbols)) {
|
||||
std::cerr << " ✗ Failed to set T1S symbol decoding" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (enableSymbols) {
|
||||
std::cout << " ✓ Enabled decoding of all T1S symbols" << std::endl;
|
||||
} else {
|
||||
std::cout << " • T1S symbol decoding disabled" << std::endl;
|
||||
}
|
||||
|
||||
if (!device->settings->setT1SBusDecodingBeaconsFor(network, enableBeacons)) {
|
||||
std::cerr << " ✗ Failed to set T1S beacon decoding" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (enableBeacons) {
|
||||
std::cout << " ✓ Enabled T1S beacon decoding" << std::endl;
|
||||
} else {
|
||||
std::cout << " • T1S beacon decoding disabled" << std::endl;
|
||||
}
|
||||
|
||||
if (!device->settings->apply(true)) {
|
||||
std::cerr << " ✗ Failed to apply settings to device" << std::endl;
|
||||
std::cerr << " " << icsneo::GetLastError() << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << " ✓ Settings applied successfully" << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setupSymbolMonitoring(std::shared_ptr<icsneo::Device>& device,
|
||||
icsneo::Network::NetID network,
|
||||
T1SStatistics& stats) {
|
||||
|
||||
auto callback = std::make_shared<icsneo::MessageCallback>(
|
||||
icsneo::MessageFilter(network),
|
||||
[&stats](std::shared_ptr<icsneo::Message> message) {
|
||||
if (message->type != icsneo::Message::Type::Frame)
|
||||
return;
|
||||
|
||||
auto frame = std::static_pointer_cast<icsneo::Frame>(message);
|
||||
auto netType = frame->network.getType();
|
||||
if (netType != icsneo::Network::Type::Ethernet && netType != icsneo::Network::Type::AutomotiveEthernet)
|
||||
return;
|
||||
|
||||
auto ethMsg = std::static_pointer_cast<icsneo::EthernetMessage>(frame);
|
||||
|
||||
if (!ethMsg->isT1S)
|
||||
return;
|
||||
|
||||
double timestamp_ms = ethMsg->timestamp / 1000000.0;
|
||||
|
||||
if (ethMsg->isT1SSymbol) {
|
||||
size_t numSymbols = ethMsg->data.size();
|
||||
|
||||
std::cout << std::fixed << std::setprecision(3)
|
||||
<< "[" << std::setw(12) << timestamp_ms << " ms] "
|
||||
<< "T1S Symbols";
|
||||
|
||||
if (numSymbols > 0) {
|
||||
std::cout << " (" << numSymbols << " symbol" << (numSymbols > 1 ? "s" : "") << ")";
|
||||
}
|
||||
std::cout << " | Node ID: " << (int)ethMsg->t1sNodeId << std::endl;
|
||||
|
||||
for (size_t i = 0; i < numSymbols; i++) {
|
||||
uint8_t symbolValue = ethMsg->data[i];
|
||||
std::string symbolName = getSymbolName(symbolValue);
|
||||
|
||||
stats.symbolCount++;
|
||||
stats.symbolStats[symbolName]++;
|
||||
|
||||
if (symbolValue == static_cast<uint8_t>(T1SSymbol::BEACON)) {
|
||||
stats.beaconCount++;
|
||||
}
|
||||
|
||||
std::cout << " [" << i << "] " << std::left << std::setw(10) << symbolName << std::right
|
||||
<< " = 0x" << std::hex << std::uppercase << std::setw(2)
|
||||
<< std::setfill('0') << (int)symbolValue << std::setfill(' ')
|
||||
<< std::dec << std::endl;
|
||||
}
|
||||
|
||||
if (numSymbols == 0 && ethMsg->t1sSymbolType != 0) {
|
||||
uint8_t symbolValue = ethMsg->t1sSymbolType;
|
||||
std::string symbolName = getSymbolName(symbolValue);
|
||||
|
||||
stats.symbolCount++;
|
||||
stats.symbolStats[symbolName]++;
|
||||
|
||||
if (symbolValue == static_cast<uint8_t>(T1SSymbol::BEACON)) {
|
||||
stats.beaconCount++;
|
||||
}
|
||||
|
||||
std::cout << " " << std::left << std::setw(10) << symbolName << std::right
|
||||
<< " = 0x" << std::hex << std::uppercase << std::setw(2)
|
||||
<< std::setfill('0') << (int)symbolValue << std::setfill(' ')
|
||||
<< std::dec << " (from t1sSymbolType field)" << std::endl;
|
||||
}
|
||||
}
|
||||
else if (ethMsg->isT1SBurst) {
|
||||
stats.burstCount++;
|
||||
std::cout << std::fixed << std::setprecision(3)
|
||||
<< "[" << std::setw(12) << timestamp_ms << " ms] "
|
||||
<< "BURST | "
|
||||
<< "Node ID: " << (int)ethMsg->t1sNodeId << " | "
|
||||
<< "Burst Count: " << (int)ethMsg->t1sBurstCount << std::endl;
|
||||
}
|
||||
else if (ethMsg->isT1SWake) {
|
||||
stats.wakeCount++;
|
||||
std::cout << std::fixed << std::setprecision(3)
|
||||
<< "[" << std::setw(12) << timestamp_ms << " ms] "
|
||||
<< "WAKE signal detected | "
|
||||
<< "Node ID: " << (int)ethMsg->t1sNodeId << std::endl;
|
||||
}
|
||||
else {
|
||||
stats.dataFrameCount++;
|
||||
std::cout << std::fixed << std::setprecision(3)
|
||||
<< "[" << std::setw(12) << timestamp_ms << " ms] "
|
||||
<< "T1S Data Frame | "
|
||||
<< "Length: " << ethMsg->data.size() << " bytes | "
|
||||
<< "Node ID: " << (int)ethMsg->t1sNodeId << std::endl;
|
||||
|
||||
if (!ethMsg->data.empty()) {
|
||||
std::cout << " Data: ";
|
||||
size_t preview_len = std::min(ethMsg->data.size(), size_t(16));
|
||||
for (size_t i = 0; i < preview_len; i++) {
|
||||
std::cout << std::hex << std::uppercase << std::setw(2)
|
||||
<< std::setfill('0') << (int)ethMsg->data[i] << " ";
|
||||
}
|
||||
if (ethMsg->data.size() > 16)
|
||||
std::cout << "...";
|
||||
std::cout << std::setfill(' ') << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
device->addMessageCallback(callback);
|
||||
}
|
||||
|
||||
int main() {
|
||||
const icsneo::Network::NetID MONITOR_NETWORK = icsneo::Network::NetID::AE_02;
|
||||
const int MONITOR_DURATION_SECONDS = 30;
|
||||
|
||||
std::cout << "\n" << std::string(70, '=') << std::endl;
|
||||
std::cout << "10BASE-T1S SYMBOL DECODING EXAMPLE" << std::endl;
|
||||
std::cout << std::string(70, '=') << std::endl;
|
||||
std::cout << "libicsneo " << icsneo::GetVersion() << std::endl;
|
||||
std::cout << std::string(70, '=') << std::endl;
|
||||
|
||||
std::cout << "\nFinding devices... " << std::flush;
|
||||
auto devices = icsneo::FindAllDevices();
|
||||
std::cout << "OK, " << devices.size() << " device" << (devices.size() == 1 ? "" : "s") << " found" << std::endl;
|
||||
|
||||
if (devices.empty()) {
|
||||
std::cerr << "No devices found!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// List devices
|
||||
for (const auto& device : devices) {
|
||||
std::cout << " " << device->describe() << std::endl;
|
||||
}
|
||||
|
||||
std::shared_ptr<icsneo::Device> device;
|
||||
for (auto& dev : devices) {
|
||||
if (dev->getType() == icsneo::DeviceType::RADComet3) {
|
||||
device = dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!device && !devices.empty())
|
||||
device = devices[0];
|
||||
|
||||
if (!device) {
|
||||
std::cerr << "No suitable device found!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "\nSelected device: " << device->describe() << std::endl;
|
||||
std::cout << "Serial: " << device->getSerial() << std::endl;
|
||||
|
||||
std::cout << "\n" << std::string(70, '-') << std::endl;
|
||||
std::cout << "T1S DECODING CONFIGURATION" << std::endl;
|
||||
std::cout << std::string(70, '-') << std::endl;
|
||||
bool enableSymbols = getUserConfirmation("Enable T1S symbol decoding (all symbols)");
|
||||
bool enableBeacons = getUserConfirmation("Enable T1S beacon decoding");
|
||||
std::cout << std::string(70, '-') << std::endl;
|
||||
|
||||
std::cout << "\nOpening device... " << std::flush;
|
||||
if (!device->open()) {
|
||||
std::cerr << "✗ Failed" << std::endl;
|
||||
std::cerr << " " << icsneo::GetLastError() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << "✓" << std::endl;
|
||||
|
||||
std::cout << "Enabling message polling... " << std::flush;
|
||||
if (!device->enableMessagePolling()) {
|
||||
std::cerr << "✗ Failed" << std::endl;
|
||||
std::cerr << " " << icsneo::GetLastError() << std::endl;
|
||||
device->close();
|
||||
return 1;
|
||||
}
|
||||
device->setPollingMessageLimit(100000);
|
||||
std::cout << "✓" << std::endl;
|
||||
|
||||
if (!configureT1SDecoding(device, MONITOR_NETWORK, enableSymbols, enableBeacons)) {
|
||||
device->close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Going online... " << std::flush;
|
||||
if (!device->goOnline()) {
|
||||
std::cerr << "✗ Failed" << std::endl;
|
||||
std::cerr << " " << icsneo::GetLastError() << std::endl;
|
||||
device->close();
|
||||
return 1;
|
||||
}
|
||||
std::cout << "✓" << std::endl;
|
||||
|
||||
T1SStatistics stats;
|
||||
setupSymbolMonitoring(device, MONITOR_NETWORK, stats);
|
||||
|
||||
std::cout << "\n" << std::string(70, '-') << std::endl;
|
||||
std::cout << "Monitoring T1S traffic for " << MONITOR_DURATION_SECONDS << " seconds..." << std::endl;
|
||||
std::cout << std::string(70, '-') << std::endl;
|
||||
|
||||
auto startTime = std::chrono::steady_clock::now();
|
||||
std::vector<std::shared_ptr<icsneo::Message>> messages;
|
||||
messages.reserve(10000);
|
||||
|
||||
while (std::chrono::steady_clock::now() - startTime < std::chrono::seconds(MONITOR_DURATION_SECONDS)) {
|
||||
device->getMessages(messages);
|
||||
messages.clear();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
std::cout << "\n" << std::string(70, '-') << std::endl;
|
||||
std::cout << "Closing device... " << std::flush;
|
||||
device->close();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
std::cout << "✓" << std::endl;
|
||||
|
||||
stats.print();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,325 @@
|
|||
"""
|
||||
10BASE-T1S Settings Configuration Example
|
||||
Demonstrates interactive T1S network configuration
|
||||
"""
|
||||
|
||||
import icsneopy
|
||||
|
||||
|
||||
def get_user_confirmation(prompt):
|
||||
"""Get yes/no confirmation from user."""
|
||||
response = input(f"{prompt} (y/n): ").strip().lower()
|
||||
return response == 'y'
|
||||
|
||||
|
||||
def select_networks(available_networks):
|
||||
"""Let user select which networks to configure."""
|
||||
print("\n" + "=" * 70)
|
||||
print("Select T1S Networks to Configure")
|
||||
print("=" * 70)
|
||||
|
||||
for i, net_id in enumerate(available_networks, 1):
|
||||
print(f" [{i}] {net_id}")
|
||||
|
||||
response = input("\nEnter network numbers to configure (e.g., '1,3' or '1-3' or 'all'): ").strip().lower()
|
||||
|
||||
if not response:
|
||||
return []
|
||||
|
||||
if response == 'all':
|
||||
return available_networks
|
||||
|
||||
selected = []
|
||||
tokens = response.split(',')
|
||||
|
||||
for token in tokens:
|
||||
token = token.strip()
|
||||
|
||||
if '-' in token:
|
||||
try:
|
||||
parts = token.split('-')
|
||||
start = int(parts[0])
|
||||
end = int(parts[1])
|
||||
for i in range(start, end + 1):
|
||||
if 1 <= i <= len(available_networks):
|
||||
selected.append(available_networks[i - 1])
|
||||
except (ValueError, IndexError):
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
num = int(token)
|
||||
if 1 <= num <= len(available_networks):
|
||||
selected.append(available_networks[num - 1])
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return selected
|
||||
|
||||
|
||||
def get_uint8_input(prompt, default_value):
|
||||
"""Get uint8 input from user with default."""
|
||||
response = input(f"{prompt} [{default_value}]: ").strip()
|
||||
if not response:
|
||||
return default_value
|
||||
try:
|
||||
val = int(response)
|
||||
if 0 <= val <= 255:
|
||||
return val
|
||||
except ValueError:
|
||||
pass
|
||||
return default_value
|
||||
|
||||
|
||||
def get_uint16_input(prompt, default_value):
|
||||
"""Get uint16 input from user with default."""
|
||||
response = input(f"{prompt} [{default_value}]: ").strip()
|
||||
if not response:
|
||||
return default_value
|
||||
try:
|
||||
val = int(response)
|
||||
if 0 <= val <= 65535:
|
||||
return val
|
||||
except ValueError:
|
||||
pass
|
||||
return default_value
|
||||
|
||||
|
||||
def opt_to_string(opt):
|
||||
"""Convert optional value to string for display."""
|
||||
if opt is None:
|
||||
return "N/A"
|
||||
if isinstance(opt, bool):
|
||||
return "true" if opt else "false"
|
||||
return str(opt)
|
||||
|
||||
|
||||
def display_t1s_settings(device, network):
|
||||
"""Display T1S settings for a network."""
|
||||
print(f"\t{network} T1S Settings:")
|
||||
|
||||
settings = device.get_settings()
|
||||
if not settings:
|
||||
print("\t Unable to read settings")
|
||||
return
|
||||
|
||||
print(f"\t PLCA Enabled: {opt_to_string(settings.get_t1s_plca_enabled(network))}")
|
||||
print(f"\t Local ID: {opt_to_string(settings.get_t1s_local_id(network))}")
|
||||
print(f"\t Max Nodes: {opt_to_string(settings.get_t1s_max_nodes(network))}")
|
||||
print(f"\t TX Opp Timer: {opt_to_string(settings.get_t1s_tx_opp_timer(network))}")
|
||||
print(f"\t Max Burst: {opt_to_string(settings.get_t1s_max_burst(network))}")
|
||||
print(f"\t Burst Timer: {opt_to_string(settings.get_t1s_burst_timer(network))}")
|
||||
|
||||
term_enabled = settings.get_t1s_termination_enabled(network)
|
||||
if term_enabled is not None:
|
||||
print(f"\t Termination: {opt_to_string(term_enabled)}")
|
||||
|
||||
local_id_alt = settings.get_t1s_local_id_alternate(network)
|
||||
if local_id_alt is not None:
|
||||
print(f"\t Local ID Alternate: {opt_to_string(local_id_alt)}")
|
||||
print(f"\t Bus Dec Beacons: {opt_to_string(settings.get_t1s_bus_decoding_beacons_enabled(network))}")
|
||||
print(f"\t Bus Dec All: {opt_to_string(settings.get_t1s_bus_decoding_all_enabled(network))}")
|
||||
|
||||
multi_id_mask = settings.get_t1s_multi_id_enable_mask(network)
|
||||
if multi_id_mask is not None:
|
||||
print(f"\t Multi-ID Mask: 0x{multi_id_mask:02X}")
|
||||
print("\t Multi-IDs: ", end="")
|
||||
multi_ids = []
|
||||
for i in range(7):
|
||||
multi_id = settings.get_t1s_multi_id(network, i)
|
||||
multi_ids.append(f"[{i}]={opt_to_string(multi_id)}")
|
||||
print(", ".join(multi_ids))
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def configure_t1s_network(device, network):
|
||||
"""Interactively configure T1S settings for a network."""
|
||||
print("\n" + "=" * 70)
|
||||
print(f"Configuring T1S Network: {network}")
|
||||
print("=" * 70)
|
||||
|
||||
settings = device.get_settings()
|
||||
if not settings:
|
||||
print("Unable to read settings")
|
||||
return
|
||||
|
||||
print("\n--- Basic PLCA Settings ---")
|
||||
plca_enabled = get_user_confirmation("Enable PLCA")
|
||||
settings.set_t1s_plca(network, plca_enabled)
|
||||
|
||||
local_id = get_uint8_input("Local ID (0-255)", 1)
|
||||
settings.set_t1s_local_id(network, local_id)
|
||||
|
||||
max_nodes = get_uint8_input("Max Nodes (0-255)", 8)
|
||||
settings.set_t1s_max_nodes(network, max_nodes)
|
||||
|
||||
tx_opp_timer = get_uint8_input("TX Opportunity Timer (0-255)", 20)
|
||||
settings.set_t1s_tx_opp_timer(network, tx_opp_timer)
|
||||
|
||||
max_burst = get_uint16_input("Max Burst (0-65535)", 128)
|
||||
settings.set_t1s_max_burst(network, max_burst)
|
||||
|
||||
burst_timer = get_uint16_input("Burst Timer (0-65535)", 64)
|
||||
settings.set_t1s_burst_timer(network, burst_timer)
|
||||
|
||||
if settings.get_t1s_termination_enabled(network) is not None:
|
||||
print("\n--- Termination Settings ---")
|
||||
term_enabled = get_user_confirmation("Enable Termination")
|
||||
settings.set_t1s_termination(network, term_enabled)
|
||||
|
||||
if settings.get_t1s_local_id_alternate(network) is not None:
|
||||
print("\n--- Extended Settings ---")
|
||||
local_id_alt = get_uint8_input("Local ID Alternate (0-255)", 0)
|
||||
settings.set_t1s_local_id_alternate(network, local_id_alt)
|
||||
|
||||
bus_dec_beacons = get_user_confirmation("Enable Bus Decoding (Beacons)")
|
||||
settings.set_t1s_bus_decoding_beacons(network, bus_dec_beacons)
|
||||
|
||||
bus_dec_all = get_user_confirmation("Enable Bus Decoding (All Symbols)")
|
||||
settings.set_t1s_bus_decoding_all(network, bus_dec_all)
|
||||
|
||||
if get_user_confirmation("Configure Multi-ID settings?"):
|
||||
multi_id_mask = get_uint8_input("Multi-ID Enable Mask (0x00-0xFF, hex)", 0x00)
|
||||
settings.set_t1s_multi_id_enable_mask(network, multi_id_mask)
|
||||
|
||||
print("Configure Multi-IDs (7 slots):")
|
||||
for i in range(7):
|
||||
multi_id = get_uint8_input(f" Multi-ID [{i}]", 0)
|
||||
settings.set_t1s_multi_id(network, i, multi_id)
|
||||
|
||||
if not device.set_settings(settings):
|
||||
print("✗ Failed to update device settings")
|
||||
else:
|
||||
print(f"\n✓ Configuration complete for {network}")
|
||||
|
||||
|
||||
def main():
|
||||
"""Main T1S settings configuration example."""
|
||||
device = None
|
||||
|
||||
try:
|
||||
print("\n" + "=" * 70)
|
||||
print("10BASE-T1S SETTINGS CONFIGURATION EXAMPLE")
|
||||
print("=" * 70)
|
||||
print(f"libicsneo {icsneopy.get_version()}")
|
||||
print("=" * 70)
|
||||
|
||||
print("\nFinding devices... ", end="", flush=True)
|
||||
devices = icsneopy.find_all_devices()
|
||||
print(f"OK, {len(devices)} device{'s' if len(devices) != 1 else ''} found")
|
||||
|
||||
if not devices:
|
||||
print("No devices found!")
|
||||
return 1
|
||||
|
||||
for d in devices:
|
||||
print(f" {d}")
|
||||
|
||||
device = None
|
||||
for d in devices:
|
||||
if d.get_type() == icsneopy.DeviceType.RADComet3:
|
||||
device = d
|
||||
break
|
||||
|
||||
if not device and devices:
|
||||
device = devices[0]
|
||||
|
||||
if not device:
|
||||
print("No suitable device found!")
|
||||
return 1
|
||||
|
||||
print(f"\nSelected device: {device}")
|
||||
print(f"Serial: {device.get_serial()}")
|
||||
|
||||
print("\nOpening device... ", end="", flush=True)
|
||||
if not device.open():
|
||||
print("✗ Failed")
|
||||
return 1
|
||||
print("✓")
|
||||
|
||||
candidate_networks = [
|
||||
icsneopy.Network.NetID.AE_01, icsneopy.Network.NetID.AE_02,
|
||||
icsneopy.Network.NetID.AE_03, icsneopy.Network.NetID.AE_04,
|
||||
icsneopy.Network.NetID.AE_05, icsneopy.Network.NetID.AE_06,
|
||||
icsneopy.Network.NetID.AE_07, icsneopy.Network.NetID.AE_08,
|
||||
icsneopy.Network.NetID.AE_09, icsneopy.Network.NetID.AE_10
|
||||
]
|
||||
|
||||
settings = device.get_settings()
|
||||
t1s_networks = []
|
||||
for net_id in candidate_networks:
|
||||
local_id = settings.get_t1s_local_id(net_id)
|
||||
if local_id is not None:
|
||||
t1s_networks.append(net_id)
|
||||
|
||||
if not t1s_networks:
|
||||
print("No T1S networks found on this device")
|
||||
device.close()
|
||||
return 1
|
||||
|
||||
print(f"\nFound {len(t1s_networks)} T1S network{'s' if len(t1s_networks) != 1 else ''}:")
|
||||
for i, net_id in enumerate(t1s_networks, 1):
|
||||
print(f" [{i}] {net_id}")
|
||||
|
||||
print("\n" + "-" * 70)
|
||||
print("Current T1S Settings:")
|
||||
print("-" * 70)
|
||||
for net_id in t1s_networks:
|
||||
display_t1s_settings(device, net_id)
|
||||
|
||||
networks_to_config = select_networks(t1s_networks)
|
||||
|
||||
if not networks_to_config:
|
||||
print("\nNo networks selected for configuration.")
|
||||
print("Closing device... ", end="", flush=True)
|
||||
device.close()
|
||||
print("✓")
|
||||
return 0
|
||||
|
||||
print(f"\nConfiguring {len(networks_to_config)} network{'s' if len(networks_to_config) != 1 else ''}...")
|
||||
|
||||
for net_id in networks_to_config:
|
||||
configure_t1s_network(device, net_id)
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
save_to_eeprom = get_user_confirmation("Save settings to EEPROM (permanent)?")
|
||||
print("=" * 70)
|
||||
|
||||
settings = device.get_settings()
|
||||
print(f"\nApplying settings{' to EEPROM' if save_to_eeprom else ' temporarily'}... ", end="", flush=True)
|
||||
success = settings.apply(not save_to_eeprom)
|
||||
if not success:
|
||||
print("✗ Failed")
|
||||
device.close()
|
||||
return 1
|
||||
print("✓")
|
||||
|
||||
print("\n" + "-" * 70)
|
||||
print("Updated T1S Settings:")
|
||||
print("-" * 70)
|
||||
for net_id in t1s_networks:
|
||||
display_t1s_settings(device, net_id)
|
||||
|
||||
print("Closing device... ", end="", flush=True)
|
||||
device.close()
|
||||
print("✓")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n\nInterrupted by user")
|
||||
return 1
|
||||
|
||||
except Exception as e:
|
||||
print(f"\nError: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return 1
|
||||
|
||||
finally:
|
||||
if device and device.is_open():
|
||||
device.close()
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
||||
|
|
@ -0,0 +1,282 @@
|
|||
"""
|
||||
10BASE-T1S Symbol Decoding Example
|
||||
Demonstrates T1S bus symbol decoding and analysis
|
||||
"""
|
||||
|
||||
import icsneopy
|
||||
import time
|
||||
from enum import IntEnum
|
||||
|
||||
|
||||
class T1SSymbol(IntEnum):
|
||||
"""10BASE-T1S Symbol Types"""
|
||||
SSD = 0x04
|
||||
ESDOK = 0x07
|
||||
BEACON = 0x08
|
||||
ESD = 0x0D
|
||||
ESDERR = 0x11
|
||||
SYNC = 0x18
|
||||
ESDJAB = 0x19
|
||||
SILENCE = 0x1F
|
||||
|
||||
@classmethod
|
||||
def get_name(cls, value):
|
||||
"""Get human-readable name for symbol value."""
|
||||
try:
|
||||
return cls(value).name
|
||||
except ValueError:
|
||||
if 0x00 <= value <= 0x0F:
|
||||
return f"DATA(0x{value:X})"
|
||||
return f"UNKNOWN(0x{value:02X})"
|
||||
|
||||
|
||||
def get_user_confirmation(prompt):
|
||||
"""Get yes/no confirmation from user."""
|
||||
response = input(f"{prompt} (y/n): ").strip().lower()
|
||||
return response == 'y'
|
||||
|
||||
|
||||
def configure_t1s_decoding(device, network, enable_symbols, enable_beacons):
|
||||
"""Configure T1S bus decoding settings."""
|
||||
settings = device.get_settings()
|
||||
if not settings:
|
||||
raise RuntimeError("Failed to get device settings")
|
||||
|
||||
print(f"\nConfiguring T1S decoding on network {network}...")
|
||||
|
||||
if not settings.set_t1s_bus_decoding_all(network, enable_symbols):
|
||||
raise RuntimeError("Failed to set T1S symbol decoding")
|
||||
if enable_symbols:
|
||||
print(" ✓ Enabled decoding of all T1S symbols")
|
||||
else:
|
||||
print(" • T1S symbol decoding disabled")
|
||||
|
||||
if not settings.set_t1s_bus_decoding_beacons(network, enable_beacons):
|
||||
raise RuntimeError("Failed to set T1S beacon decoding")
|
||||
if enable_beacons:
|
||||
print(" ✓ Enabled T1S beacon decoding")
|
||||
else:
|
||||
print(" • T1S beacon decoding disabled")
|
||||
|
||||
if not device.set_settings(settings):
|
||||
raise RuntimeError("Failed to apply settings to device")
|
||||
print(" ✓ Settings applied successfully")
|
||||
|
||||
|
||||
def setup_symbol_monitoring(device, network):
|
||||
"""Setup callback to monitor and decode T1S symbols."""
|
||||
state = {
|
||||
'symbol_count': 0,
|
||||
'beacon_count': 0,
|
||||
'wake_count': 0,
|
||||
'burst_count': 0,
|
||||
'symbol_stats': {},
|
||||
'data_frame_count': 0
|
||||
}
|
||||
|
||||
def symbol_handler(msg):
|
||||
"""Handle incoming T1S messages."""
|
||||
if not isinstance(msg, icsneopy.EthernetMessage):
|
||||
return
|
||||
|
||||
if not msg.isT1S:
|
||||
return
|
||||
|
||||
timestamp_ms = msg.timestamp / 1000000.0
|
||||
|
||||
if msg.isT1SSymbol:
|
||||
num_symbols = len(msg.data)
|
||||
|
||||
print(f"[{timestamp_ms:12.3f} ms] T1S Symbols", end="")
|
||||
if num_symbols > 0:
|
||||
print(f" ({num_symbols} symbol{'s' if num_symbols > 1 else ''})", end="")
|
||||
print(f" | Node ID: {msg.t1sNodeId}")
|
||||
|
||||
for i, symbol_value in enumerate(msg.data):
|
||||
symbol_name = T1SSymbol.get_name(symbol_value)
|
||||
|
||||
state['symbol_count'] += 1
|
||||
if symbol_name not in state['symbol_stats']:
|
||||
state['symbol_stats'][symbol_name] = 0
|
||||
state['symbol_stats'][symbol_name] += 1
|
||||
|
||||
if symbol_value == T1SSymbol.BEACON:
|
||||
state['beacon_count'] += 1
|
||||
|
||||
print(f" [{i}] {symbol_name:10s} = 0x{symbol_value:02X}")
|
||||
|
||||
if num_symbols == 0 and msg.t1sSymbolType != 0:
|
||||
symbol_value = msg.t1sSymbolType
|
||||
symbol_name = T1SSymbol.get_name(symbol_value)
|
||||
|
||||
state['symbol_count'] += 1
|
||||
if symbol_name not in state['symbol_stats']:
|
||||
state['symbol_stats'][symbol_name] = 0
|
||||
state['symbol_stats'][symbol_name] += 1
|
||||
|
||||
if symbol_value == T1SSymbol.BEACON:
|
||||
state['beacon_count'] += 1
|
||||
|
||||
print(f" {symbol_name:10s} = 0x{symbol_value:02X} (from t1sSymbolType field)")
|
||||
|
||||
elif msg.isT1SBurst:
|
||||
state['burst_count'] += 1
|
||||
print(f"[{timestamp_ms:12.3f} ms] BURST | "
|
||||
f"Node ID: {msg.t1sNodeId} | "
|
||||
f"Burst Count: {msg.t1sBurstCount}")
|
||||
|
||||
elif msg.isT1SWake:
|
||||
state['wake_count'] += 1
|
||||
print(f"[{timestamp_ms:12.3f} ms] WAKE signal detected | "
|
||||
f"Node ID: {msg.t1sNodeId}")
|
||||
|
||||
else:
|
||||
state['data_frame_count'] += 1
|
||||
print(f"[{timestamp_ms:12.3f} ms] T1S Data Frame | "
|
||||
f"Length: {len(msg.data)} bytes | "
|
||||
f"Node ID: {msg.t1sNodeId}")
|
||||
|
||||
if msg.data and len(msg.data) > 0:
|
||||
preview = ' '.join([f"{b:02X}" for b in msg.data[:16]])
|
||||
if len(msg.data) > 16:
|
||||
preview += " ..."
|
||||
print(f" Data: {preview}")
|
||||
|
||||
frame_filter = icsneopy.MessageFilter(network)
|
||||
callback = icsneopy.MessageCallback(symbol_handler, frame_filter)
|
||||
device.add_message_callback(callback)
|
||||
|
||||
return state
|
||||
|
||||
|
||||
def print_statistics(state):
|
||||
"""Print monitoring statistics."""
|
||||
print("\n" + "=" * 70)
|
||||
print("T1S SYMBOL DECODING STATISTICS")
|
||||
print("=" * 70)
|
||||
print(f"Total Symbols: {state['symbol_count']}")
|
||||
print(f"Total Beacons: {state['beacon_count']}")
|
||||
print(f"Total Wake Signals: {state['wake_count']}")
|
||||
print(f"Total Bursts: {state['burst_count']}")
|
||||
print(f"Total Data Frames: {state['data_frame_count']}")
|
||||
|
||||
if state['symbol_stats']:
|
||||
print("\n" + "-" * 70)
|
||||
print("Symbol Type Breakdown:")
|
||||
print("-" * 70)
|
||||
for symbol_name, count in sorted(state['symbol_stats'].items(),
|
||||
key=lambda x: x[1], reverse=True):
|
||||
print(f" {symbol_name:20s}{count:>10d}")
|
||||
print("=" * 70)
|
||||
|
||||
|
||||
def main():
|
||||
"""Main T1S symbol decoding example."""
|
||||
device = None
|
||||
|
||||
try:
|
||||
MONITOR_NETWORK = icsneopy.Network.NetID.AE_02
|
||||
MONITOR_DURATION = 30
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("10BASE-T1S SYMBOL DECODING EXAMPLE")
|
||||
print("=" * 70)
|
||||
print(f"libicsneo {icsneopy.get_version()}")
|
||||
print("=" * 70)
|
||||
|
||||
print("\nFinding devices... ", end="", flush=True)
|
||||
devices = icsneopy.find_all_devices()
|
||||
print(f"OK, {len(devices)} device{'s' if len(devices) != 1 else ''} found")
|
||||
|
||||
if not devices:
|
||||
print("No devices found!")
|
||||
return 1
|
||||
|
||||
for d in devices:
|
||||
print(f" {d}")
|
||||
|
||||
device = None
|
||||
for d in devices:
|
||||
if d.get_type() == icsneopy.DeviceType.RADComet3:
|
||||
device = d
|
||||
break
|
||||
|
||||
if not device and devices:
|
||||
device = devices[0]
|
||||
|
||||
if not device:
|
||||
print("No suitable device found!")
|
||||
return 1
|
||||
|
||||
print(f"\nSelected device: {device}")
|
||||
print(f"Serial: {device.get_serial()}")
|
||||
|
||||
print("\n" + "-" * 70)
|
||||
print("T1S DECODING CONFIGURATION")
|
||||
print("-" * 70)
|
||||
enable_symbols = get_user_confirmation("Enable T1S symbol decoding (all symbols)")
|
||||
enable_beacons = get_user_confirmation("Enable T1S beacon decoding")
|
||||
print("-" * 70)
|
||||
|
||||
print("\nOpening device... ", end="", flush=True)
|
||||
if not device.open():
|
||||
print("✗ Failed")
|
||||
return 1
|
||||
print("✓")
|
||||
|
||||
print("Enabling message polling... ", end="", flush=True)
|
||||
if not device.enable_message_polling():
|
||||
print("✗ Failed")
|
||||
device.close()
|
||||
return 1
|
||||
device.set_polling_message_limit(100000)
|
||||
print("✓")
|
||||
|
||||
configure_t1s_decoding(device, MONITOR_NETWORK, enable_symbols, enable_beacons)
|
||||
|
||||
print("Going online... ", end="", flush=True)
|
||||
if not device.go_online():
|
||||
print("✗ Failed")
|
||||
device.close()
|
||||
return 1
|
||||
print("✓")
|
||||
|
||||
state = setup_symbol_monitoring(device, MONITOR_NETWORK)
|
||||
|
||||
print("\n" + "-" * 70)
|
||||
print(f"Monitoring T1S traffic for {MONITOR_DURATION} seconds...")
|
||||
print("-" * 70)
|
||||
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < MONITOR_DURATION:
|
||||
device.get_messages()
|
||||
time.sleep(0.01)
|
||||
|
||||
print("\n" + "-" * 70)
|
||||
print("Closing device... ", end="", flush=True)
|
||||
device.close()
|
||||
time.sleep(0.1)
|
||||
print("✓")
|
||||
|
||||
print_statistics(state)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n\nMonitoring interrupted by user")
|
||||
if 'state' in locals():
|
||||
print_statistics(state)
|
||||
|
||||
except Exception as e:
|
||||
print(f"\nError: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return 1
|
||||
|
||||
finally:
|
||||
if device and device.is_open():
|
||||
device.close()
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
||||
|
|
@ -1194,6 +1194,77 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual std::optional<uint8_t> getT1SLocalIDAlternateFor(Network net) const {
|
||||
(void)net;
|
||||
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
virtual bool setT1SLocalIDAlternateFor(Network net, uint8_t id) {
|
||||
(void)net; (void)id;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual std::optional<bool> isT1STerminationEnabledFor(Network net) const {
|
||||
(void)net;
|
||||
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
virtual bool setT1STerminationFor(Network net, bool enable) {
|
||||
(void)net; (void)enable;
|
||||
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual std::optional<bool> isT1SBusDecodingBeaconsEnabledFor(Network net) const {
|
||||
(void)net;
|
||||
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
virtual bool setT1SBusDecodingBeaconsFor(Network net, bool enable) {
|
||||
(void)net; (void)enable;
|
||||
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual std::optional<bool> isT1SBusDecodingAllEnabledFor(Network net) const {
|
||||
(void)net;
|
||||
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
virtual bool setT1SBusDecodingAllFor(Network net, bool enable) {
|
||||
(void)net; (void)enable;
|
||||
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual std::optional<uint8_t> getT1SMultiIDEnableMaskFor(Network net) const {
|
||||
(void)net;
|
||||
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
virtual bool setT1SMultiIDEnableMaskFor(Network net, uint8_t mask) {
|
||||
(void)net; (void)mask;
|
||||
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual std::optional<uint8_t> getT1SMultiIDFor(Network net, uint8_t index) const {
|
||||
(void)net; (void)index;
|
||||
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
virtual bool setT1SMultiIDFor(Network net, uint8_t index, uint8_t id) {
|
||||
(void)net; (void)index; (void)id;
|
||||
report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool setMiscIOAnalogOutputEnabled(uint8_t pin, bool enabled);
|
||||
virtual bool setMiscIOAnalogOutput(uint8_t pin, MiscIOAnalogVoltage voltage);
|
||||
|
||||
|
|
|
|||
|
|
@ -363,6 +363,109 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SLocalIDAlternateFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional(t1s->local_id_alternate);
|
||||
}
|
||||
|
||||
bool setT1SLocalIDAlternateFor(Network net, uint8_t id) override {
|
||||
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return false;
|
||||
|
||||
t1s->local_id_alternate = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> isT1SBusDecodingBeaconsEnabledFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS) != 0);
|
||||
}
|
||||
|
||||
bool setT1SBusDecodingBeaconsFor(Network net, bool enable) override {
|
||||
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return false;
|
||||
|
||||
if(enable)
|
||||
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
|
||||
else
|
||||
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> isT1SBusDecodingAllEnabledFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL) != 0);
|
||||
}
|
||||
|
||||
bool setT1SBusDecodingAllFor(Network net, bool enable) override {
|
||||
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return false;
|
||||
|
||||
if(enable)
|
||||
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
|
||||
else
|
||||
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SMultiIDEnableMaskFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional(t1sExt->enable_multi_id);
|
||||
}
|
||||
|
||||
bool setT1SMultiIDEnableMaskFor(Network net, uint8_t mask) override {
|
||||
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return false;
|
||||
|
||||
t1sExt->enable_multi_id = mask;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SMultiIDFor(Network net, uint8_t index) const override {
|
||||
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
if(index >= 7) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::make_optional(t1sExt->multi_id[index]);
|
||||
}
|
||||
|
||||
bool setT1SMultiIDFor(Network net, uint8_t index, uint8_t id) override {
|
||||
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return false;
|
||||
|
||||
if(index >= 7) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
t1sExt->multi_id[index] = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
|
||||
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
|
||||
|
|
@ -404,6 +507,46 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
const ETHERNET10T1S_SETTINGS_EXT* getT1SSettingsExtFor(Network net) const {
|
||||
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return nullptr;
|
||||
|
||||
switch(net.getNetID()) {
|
||||
case Network::NetID::AE_03: return &(cfg->t1s1Ext);
|
||||
case Network::NetID::AE_04: return &(cfg->t1s2Ext);
|
||||
case Network::NetID::AE_05: return &(cfg->t1s3Ext);
|
||||
case Network::NetID::AE_06: return &(cfg->t1s4Ext);
|
||||
case Network::NetID::AE_07: return &(cfg->t1s5Ext);
|
||||
case Network::NetID::AE_08: return &(cfg->t1s6Ext);
|
||||
case Network::NetID::AE_09: return &(cfg->t1s7Ext);
|
||||
case Network::NetID::AE_10: return &(cfg->t1s8Ext);
|
||||
default:
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ETHERNET10T1S_SETTINGS_EXT* getMutableT1SSettingsExtFor(Network net) {
|
||||
auto cfg = getMutableStructurePointer<neovifire3t1slin_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return nullptr;
|
||||
|
||||
switch(net.getNetID()) {
|
||||
case Network::NetID::AE_03: return &(cfg->t1s1Ext);
|
||||
case Network::NetID::AE_04: return &(cfg->t1s2Ext);
|
||||
case Network::NetID::AE_05: return &(cfg->t1s3Ext);
|
||||
case Network::NetID::AE_06: return &(cfg->t1s4Ext);
|
||||
case Network::NetID::AE_07: return &(cfg->t1s5Ext);
|
||||
case Network::NetID::AE_08: return &(cfg->t1s6Ext);
|
||||
case Network::NetID::AE_09: return &(cfg->t1s7Ext);
|
||||
case Network::NetID::AE_10: return &(cfg->t1s8Ext);
|
||||
default:
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const override {
|
||||
auto cfg = getStructurePointer<neovifire3t1slin_settings_t>();
|
||||
|
|
|
|||
|
|
@ -223,6 +223,27 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> isT1STerminationEnabledFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_TERMINATION) != 0);
|
||||
}
|
||||
|
||||
bool setT1STerminationFor(Network net, bool enable) override {
|
||||
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return false;
|
||||
|
||||
if(enable)
|
||||
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_TERMINATION;
|
||||
else
|
||||
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_TERMINATION;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
|
||||
auto cfg = getStructurePointer<radcomet_settings_t>();
|
||||
|
|
|
|||
|
|
@ -258,6 +258,109 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SLocalIDAlternateFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional(t1s->local_id_alternate);
|
||||
}
|
||||
|
||||
bool setT1SLocalIDAlternateFor(Network net, uint8_t id) override {
|
||||
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return false;
|
||||
|
||||
t1s->local_id_alternate = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> isT1SBusDecodingBeaconsEnabledFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS) != 0);
|
||||
}
|
||||
|
||||
bool setT1SBusDecodingBeaconsFor(Network net, bool enable) override {
|
||||
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return false;
|
||||
|
||||
if(enable)
|
||||
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
|
||||
else
|
||||
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> isT1SBusDecodingAllEnabledFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL) != 0);
|
||||
}
|
||||
|
||||
bool setT1SBusDecodingAllFor(Network net, bool enable) override {
|
||||
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return false;
|
||||
|
||||
if(enable)
|
||||
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
|
||||
else
|
||||
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SMultiIDEnableMaskFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional(t1sExt->enable_multi_id);
|
||||
}
|
||||
|
||||
bool setT1SMultiIDEnableMaskFor(Network net, uint8_t mask) override {
|
||||
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return false;
|
||||
|
||||
t1sExt->enable_multi_id = mask;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SMultiIDFor(Network net, uint8_t index) const override {
|
||||
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
if(index >= 7) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::make_optional(t1sExt->multi_id[index]);
|
||||
}
|
||||
|
||||
bool setT1SMultiIDFor(Network net, uint8_t index, uint8_t id) override {
|
||||
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return false;
|
||||
|
||||
if(index >= 7) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
t1sExt->multi_id[index] = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setPhyRoleFor(Network net, AELinkMode mode) override {
|
||||
if (mode != AE_LINK_AUTO && mode != AE_LINK_MASTER && mode != AE_LINK_SLAVE) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
|
|
@ -571,6 +674,42 @@ private:
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const ETHERNET10T1S_SETTINGS_EXT* getT1SSettingsExtFor(Network net) const {
|
||||
auto cfg = getStructurePointer<radcomet3_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return nullptr;
|
||||
|
||||
switch(net.getNetID()) {
|
||||
case Network::NetID::AE_02: return &(cfg->t1s1Ext);
|
||||
case Network::NetID::AE_03: return &(cfg->t1s2Ext);
|
||||
case Network::NetID::AE_04: return &(cfg->t1s3Ext);
|
||||
case Network::NetID::AE_05: return &(cfg->t1s4Ext);
|
||||
case Network::NetID::AE_06: return &(cfg->t1s5Ext);
|
||||
case Network::NetID::AE_07: return &(cfg->t1s6Ext);
|
||||
default:
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ETHERNET10T1S_SETTINGS_EXT* getMutableT1SSettingsExtFor(Network net) {
|
||||
auto cfg = getMutableStructurePointer<radcomet3_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return nullptr;
|
||||
|
||||
switch(net.getNetID()) {
|
||||
case Network::NetID::AE_02: return &(cfg->t1s1Ext);
|
||||
case Network::NetID::AE_03: return &(cfg->t1s2Ext);
|
||||
case Network::NetID::AE_04: return &(cfg->t1s3Ext);
|
||||
case Network::NetID::AE_05: return &(cfg->t1s4Ext);
|
||||
case Network::NetID::AE_06: return &(cfg->t1s5Ext);
|
||||
case Network::NetID::AE_07: return &(cfg->t1s6Ext);
|
||||
default:
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,6 +355,130 @@ namespace icsneo
|
|||
return true;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SLocalIDAlternateFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional(t1s->local_id_alternate);
|
||||
}
|
||||
|
||||
bool setT1SLocalIDAlternateFor(Network net, uint8_t id) override {
|
||||
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return false;
|
||||
|
||||
t1s->local_id_alternate = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> isT1STerminationEnabledFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_TERMINATION) != 0);
|
||||
}
|
||||
|
||||
bool setT1STerminationFor(Network net, bool enable) override {
|
||||
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return false;
|
||||
|
||||
if(enable)
|
||||
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_TERMINATION;
|
||||
else
|
||||
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_TERMINATION;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> isT1SBusDecodingBeaconsEnabledFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS) != 0);
|
||||
}
|
||||
|
||||
bool setT1SBusDecodingBeaconsFor(Network net, bool enable) override {
|
||||
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return false;
|
||||
|
||||
if(enable)
|
||||
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
|
||||
else
|
||||
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> isT1SBusDecodingAllEnabledFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS* t1s = getT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional<bool>((t1s->flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL) != 0);
|
||||
}
|
||||
|
||||
bool setT1SBusDecodingAllFor(Network net, bool enable) override {
|
||||
ETHERNET10T1S_SETTINGS* t1s = getMutableT1SSettingsFor(net);
|
||||
if(t1s == nullptr)
|
||||
return false;
|
||||
|
||||
if(enable)
|
||||
t1s->flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
|
||||
else
|
||||
t1s->flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SMultiIDEnableMaskFor(Network net) const override {
|
||||
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_optional(t1sExt->enable_multi_id);
|
||||
}
|
||||
|
||||
bool setT1SMultiIDEnableMaskFor(Network net, uint8_t mask) override {
|
||||
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return false;
|
||||
|
||||
t1sExt->enable_multi_id = mask;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SMultiIDFor(Network net, uint8_t index) const override {
|
||||
const ETHERNET10T1S_SETTINGS_EXT* t1sExt = getT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
if(index >= 7) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::make_optional(t1sExt->multi_id[index]);
|
||||
}
|
||||
|
||||
bool setT1SMultiIDFor(Network net, uint8_t index, uint8_t id) override {
|
||||
ETHERNET10T1S_SETTINGS_EXT* t1sExt = getMutableT1SSettingsExtFor(net);
|
||||
if(t1sExt == nullptr)
|
||||
return false;
|
||||
|
||||
if(index >= 7) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
t1sExt->multi_id[index] = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const ETHERNET10T1S_SETTINGS* getT1SSettingsFor(Network net) const {
|
||||
auto cfg = getStructurePointer<radgigastar2_settings_t>();
|
||||
|
|
@ -396,6 +520,46 @@ namespace icsneo
|
|||
}
|
||||
}
|
||||
|
||||
const ETHERNET10T1S_SETTINGS_EXT* getT1SSettingsExtFor(Network net) const {
|
||||
auto cfg = getStructurePointer<radgigastar2_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return nullptr;
|
||||
|
||||
switch(net.getNetID()) {
|
||||
case Network::NetID::AE_03: return &(cfg->t1s1Ext);
|
||||
case Network::NetID::AE_04: return &(cfg->t1s2Ext);
|
||||
case Network::NetID::AE_05: return &(cfg->t1s3Ext);
|
||||
case Network::NetID::AE_06: return &(cfg->t1s4Ext);
|
||||
case Network::NetID::AE_07: return &(cfg->t1s5Ext);
|
||||
case Network::NetID::AE_08: return &(cfg->t1s6Ext);
|
||||
case Network::NetID::AE_09: return &(cfg->t1s7Ext);
|
||||
case Network::NetID::AE_10: return &(cfg->t1s8Ext);
|
||||
default:
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ETHERNET10T1S_SETTINGS_EXT* getMutableT1SSettingsExtFor(Network net) {
|
||||
auto cfg = getMutableStructurePointer<radgigastar2_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return nullptr;
|
||||
|
||||
switch(net.getNetID()) {
|
||||
case Network::NetID::AE_03: return &(cfg->t1s1Ext);
|
||||
case Network::NetID::AE_04: return &(cfg->t1s2Ext);
|
||||
case Network::NetID::AE_05: return &(cfg->t1s3Ext);
|
||||
case Network::NetID::AE_06: return &(cfg->t1s4Ext);
|
||||
case Network::NetID::AE_07: return &(cfg->t1s5Ext);
|
||||
case Network::NetID::AE_08: return &(cfg->t1s6Ext);
|
||||
case Network::NetID::AE_09: return &(cfg->t1s7Ext);
|
||||
case Network::NetID::AE_10: return &(cfg->t1s8Ext);
|
||||
default:
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
ICSNEO_UNALIGNED(const uint64_t *)
|
||||
getTerminationEnables() const override
|
||||
|
|
|
|||
|
|
@ -210,10 +210,163 @@ private:
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SLocalIDAlternateFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radmoont1s_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
if(net.getNetID() != Network::NetID::AE_01) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::make_optional(cfg->t1s.local_id_alternate);
|
||||
}
|
||||
|
||||
bool setT1SLocalIDAlternateFor(Network net, uint8_t id) override {
|
||||
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return false;
|
||||
|
||||
if(net.getNetID() != Network::NetID::AE_01) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
cfg->t1s.local_id_alternate = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> isT1SBusDecodingBeaconsEnabledFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radmoont1s_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
if(net.getNetID() != Network::NetID::AE_01) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::make_optional<bool>((cfg->t1s.flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS) != 0);
|
||||
}
|
||||
|
||||
bool setT1SBusDecodingBeaconsFor(Network net, bool enable) override {
|
||||
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return false;
|
||||
|
||||
if(net.getNetID() != Network::NetID::AE_01) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(enable)
|
||||
cfg->t1s.flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
|
||||
else
|
||||
cfg->t1s.flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> isT1SBusDecodingAllEnabledFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radmoont1s_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
if(net.getNetID() != Network::NetID::AE_01) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::make_optional<bool>((cfg->t1s.flags & ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL) != 0);
|
||||
}
|
||||
|
||||
bool setT1SBusDecodingAllFor(Network net, bool enable) override {
|
||||
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return false;
|
||||
|
||||
if(net.getNetID() != Network::NetID::AE_01) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(enable)
|
||||
cfg->t1s.flags |= ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
|
||||
else
|
||||
cfg->t1s.flags &= ~ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SMultiIDEnableMaskFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radmoont1s_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
if(net.getNetID() != Network::NetID::AE_01) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::make_optional(cfg->t1sExt.enable_multi_id);
|
||||
}
|
||||
|
||||
bool setT1SMultiIDEnableMaskFor(Network net, uint8_t mask) override {
|
||||
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return false;
|
||||
|
||||
if(net.getNetID() != Network::NetID::AE_01) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
cfg->t1sExt.enable_multi_id = mask;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> getT1SMultiIDFor(Network net, uint8_t index) const override {
|
||||
auto cfg = getStructurePointer<radmoont1s_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
if(net.getNetID() != Network::NetID::AE_01) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if(index >= 7) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::make_optional(cfg->t1sExt.multi_id[index]);
|
||||
}
|
||||
|
||||
bool setT1SMultiIDFor(Network net, uint8_t index, uint8_t id) override {
|
||||
auto cfg = getMutableStructurePointer<radmoont1s_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return false;
|
||||
|
||||
if(net.getNetID() != Network::NetID::AE_01) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(index >= 7) {
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
cfg->t1sExt.multi_id[index] = id;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __RADMOONT1SSETTINGS_H_
|
||||
#endif // __RADMOONT1SSETTINGS_H_
|
||||
Loading…
Reference in New Issue