11 Commits
50 changed files with 3168 additions and 1804 deletions
+19 -1
View File
@@ -71,6 +71,7 @@ icsneoc2_error_t icsneoc2_error_code_get(icsneoc2_error_t error_code, char* valu
"Close failed", // icsneoc2_error_close_failed
"Reconnect failed", // icsneoc2_error_reconnect_failed
"Invalid data", // icsneoc2_error_invalid_data
"Force disk config update failed", // icsneoc2_error_force_disk_config_update_failed
};
static_assert(std::size(error_strings) == icsneoc2_error_maxsize,
"error_strings is out of sync with _icsneoc2_error_t enum - update both together");
@@ -271,7 +272,9 @@ static icsneoc2_error_t open_device_with_options(std::shared_ptr<Device> dev, ic
if(!dev) {
return icsneoc2_error_invalid_device;
}
if(!dev->enableMessagePolling(std::make_optional<MessageFilter>())) {
MessageFilter filter;
filter.includeInternalInAny = true;
if(!dev->enableMessagePolling(std::make_optional(filter))) {
return icsneoc2_error_enable_message_polling_failed;
}
if(!dev->isOpen() && !dev->open()) {
@@ -1095,6 +1098,21 @@ icsneoc2_error_t icsneoc2_device_format_disk(const icsneoc2_device_t* device, ic
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_device_force_disk_config_update(const icsneoc2_device_t* device, icsneoc2_disk_details_t* disk_details) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!disk_details || !disk_details->details) {
return icsneoc2_error_invalid_parameters;
}
if(!device->device->forceDiskConfigUpdate(*disk_details->details)) {
return icsneoc2_error_force_disk_config_update_failed;
}
return icsneoc2_error_success;
}
static icsneoc2_error_t get_supported_networks(const icsneoc2_device_t* device, const std::vector<Network>& nets, icsneoc2_netid_t* networks, size_t* count) {
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
+5
View File
@@ -48,6 +48,11 @@ typedef struct icsneoc2_chip_versions_t {
icsneoc2_chip_versions_t* next;
} icsneoc2_chip_versions_t;
typedef struct icsneoc2_termination_group_t {
std::vector<icsneoc2_netid_t> netids;
icsneoc2_termination_group_t* next;
} icsneoc2_termination_group_t;
typedef struct icsneoc2_mac_addr_entry_t {
uint16_t network_id;
uint8_t address[ICSNEO_MAC_ADDRESS_LEN];
+72 -1
View File
@@ -7,8 +7,10 @@
#include "icsneo/communication/message/message.h"
#include "icsneo/communication/message/canmessage.h"
#include "icsneo/communication/message/canerrormessage.h"
#include "icsneo/communication/message/apperrormessage.h"
#include "icsneo/communication/message/linmessage.h"
#include "icsneo/communication/message/ethernetmessage.h"
#include "icsneo/communication/message/ethernetstatusmessage.h"
#include "icsneo/communication/packet/canpacket.h"
icsneoc2_error_t icsneoc2_message_is_valid(icsneoc2_message_t* message, bool* is_valid) {
@@ -316,6 +318,44 @@ icsneoc2_error_t icsneoc2_message_can_error_props_get(
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_is_app_error(icsneoc2_message_t* message, bool* is_app_error) {
if(!message || !is_app_error) {
return icsneoc2_error_invalid_parameters;
}
*is_app_error = std::dynamic_pointer_cast<AppErrorMessage>(message->message) != nullptr;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_app_error_props_get(icsneoc2_message_t* message,
icsneoc2_app_error_type_t* error_type, icsneoc2_netid_t* error_netid) {
if(!message) {
return icsneoc2_error_invalid_parameters;
}
auto app_err = std::dynamic_pointer_cast<AppErrorMessage>(message->message);
if(!app_err) {
return icsneoc2_error_invalid_type;
}
if(error_type) {
*error_type = static_cast<icsneoc2_app_error_type_t>(app_err->getAppErrorType());
}
if(error_netid) {
*error_netid = static_cast<icsneoc2_netid_t>(app_err->errorNetID);
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_app_error_string_get(icsneoc2_message_t* message,
char* value, size_t* value_length) {
if(!message || !value_length) {
return icsneoc2_error_invalid_parameters;
}
auto app_err = std::dynamic_pointer_cast<AppErrorMessage>(message->message);
if(!app_err) {
return icsneoc2_error_invalid_type;
}
return safe_str_copy(value, value_length, app_err->getAppErrorString()) ? icsneoc2_error_success : icsneoc2_error_string_copy_failed;
}
icsneoc2_error_t icsneoc2_message_is_lin(icsneoc2_message_t* message, bool* is_lin) {
if(!message || !is_lin) {
return icsneoc2_error_invalid_parameters;
@@ -631,9 +671,40 @@ icsneoc2_error_t icsneoc2_message_eth_t1s_props_get(icsneoc2_message_t* message,
}
icsneoc2_error_t icsneoc2_message_is_ethernet(icsneoc2_message_t* message, bool* is_ethernet) {
if(!message) {
if(!message || !is_ethernet) {
return icsneoc2_error_invalid_parameters;
}
*is_ethernet = std::dynamic_pointer_cast<EthernetMessage>(message->message) != nullptr;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_is_ethernet_status(icsneoc2_message_t* message, bool* is_ethernet_status) {
if(!message || !is_ethernet_status) {
return icsneoc2_error_invalid_parameters;
}
*is_ethernet_status = std::dynamic_pointer_cast<EthernetStatusMessage>(message->message) != nullptr;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_message_eth_status_props_get(icsneoc2_message_t* message, bool* link_state, bool* duplex, icsneoc2_link_speed_t* link_speed, icsneoc2_link_mode_t* link_mode) {
if(!message) {
return icsneoc2_error_invalid_parameters;
}
auto msg = std::dynamic_pointer_cast<EthernetStatusMessage>(message->message);
if(!msg) {
return icsneoc2_error_invalid_type;
}
if(link_state) {
*link_state = msg->state;
}
if(duplex) {
*duplex = msg->duplex;
}
if(link_speed) {
*link_speed = static_cast<icsneoc2_link_speed_t>(msg->speed);
}
if(link_mode) {
*link_mode = static_cast<icsneoc2_link_mode_t>(msg->mode);
}
return icsneoc2_error_success;
}
+76
View File
@@ -179,6 +179,82 @@ icsneoc2_error_t icsneoc2_settings_termination_set(icsneoc2_device_t* device, ic
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_termination_groups_enumerate(icsneoc2_device_t* device, icsneoc2_termination_group_t** groups, size_t* count) {
// Make sure the device is valid
auto res = icsneoc2_device_is_valid(device);
if(res != icsneoc2_error_success) {
return res;
}
if(!groups) {
return icsneoc2_error_invalid_parameters;
}
auto termination_groups = device->device->settings->getTerminationGroups();
icsneoc2_termination_group_t* head = nullptr;
icsneoc2_termination_group_t* tail = nullptr;
for(const auto& group : termination_groups) {
auto* node = new (std::nothrow) icsneoc2_termination_group_t;
if(!node) {
icsneoc2_settings_termination_groups_free(head);
return icsneoc2_error_out_of_memory;
}
node->netids.reserve(group.size());
for(const auto& network : group) {
node->netids.push_back(static_cast<icsneoc2_netid_t>(network.getNetID()));
}
node->next = nullptr;
if(!head) {
head = node;
} else {
tail->next = node;
}
tail = node;
}
*groups = head;
if(count) {
*count = termination_groups.size();
}
return icsneoc2_error_success;
}
icsneoc2_termination_group_t* icsneoc2_termination_group_next(const icsneoc2_termination_group_t* group) {
if(!group) {
return nullptr;
}
return group->next;
}
icsneoc2_error_t icsneoc2_termination_group_networks_get(const icsneoc2_termination_group_t* group, icsneoc2_netid_t* networks, size_t* count) {
if(!group || !count) {
return icsneoc2_error_invalid_parameters;
}
if(!networks) {
*count = group->netids.size();
return icsneoc2_error_success;
}
size_t to_copy = std::min<size_t>(*count, group->netids.size());
for(size_t i = 0; i < to_copy; i++) {
networks[i] = group->netids[i];
}
*count = to_copy;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_termination_groups_free(icsneoc2_termination_group_t* groups) {
if(!groups) {
return icsneoc2_error_invalid_parameters;
}
while(groups) {
auto* next = groups->next;
delete groups;
groups = next;
}
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_settings_commander_resistor_enabled(icsneoc2_device_t* device, icsneoc2_netid_t netid, bool* enabled) {
// Make sure the device is valid
auto res = icsneoc2_device_is_valid(device);
@@ -5,6 +5,13 @@
#include <windows.h>
#include "icsneo/icsnVC40.h"
// Vehicle Spy 3.26.3.9 removed these legacy settings structure definitions from
// icsnVC40.h. The corresponding functions only ever treat them as opaque
// buffers, so forward declarations keep the existing API/ABI intact.
typedef struct _SFireSettings SFireSettings;
typedef struct _SVCAN3Settings SVCAN3Settings;
typedef struct _SVCANRFSettings SVCANRFSettings;
bool LoadDLLAPI(HINSTANCE &hAPIDLL);
+9 -9
View File
@@ -1035,10 +1035,10 @@ int LegacyDLLExport icsneoGetDeviceSettingsType(void* hObject, EPlasmaIonVnetCha
case NEODEVICE_ION:
*pDeviceSettingsType = DeviceFire2SettingsType; //defaults to FIRE2 vnets with libicsneo - no firevnets!
break;
case NEODEVICE_VCAN3:
*pDeviceSettingsType = DeviceVCAN3SettingsType;
case NEODEVICE_VCAN3_DEPRECATED:
*pDeviceSettingsType = DeviceVCAN3SettingsTypeDeprecated;
break;
case NEODEVICE_FIRE:
case NEODEVICE_FIRE_DEPRECATED:
*pDeviceSettingsType = DeviceFireSettingsType;
break;
case NEODEVICE_FIRE2:
@@ -1061,17 +1061,17 @@ int LegacyDLLExport icsneoGetDeviceSettingsType(void* hObject, EPlasmaIonVnetCha
case NEODEVICE_VIVIDCAN:
*pDeviceSettingsType = DeviceVividCANSettingsType;
break;
case NEODEVICE_ECU_AVB:
*pDeviceSettingsType = DeviceECU_AVBSettingsType;
case NEODEVICE_ECU_AVB_DEPRECATED:
*pDeviceSettingsType = DeviceECU_AVBSettingsTypeDeprecated;
break;
case NEODEVICE_RADSUPERMOON:
*pDeviceSettingsType = DeviceRADSuperMoonSettingsType;
case NEODEVICE_RADSUPERMOON_DEPRECATED:
*pDeviceSettingsType = DeviceRADSuperMoonSettingsTypeDeprecated;
break;
case NEODEVICE_RADMOON2:
*pDeviceSettingsType = DeviceRADMoon2SettingsType;
break;
case NEODEVICE_RADGIGALOG:
*pDeviceSettingsType = DeviceRADGigalogSettingsType;
case NEODEVICE_RADGIGALOG_DEPRECATED:
*pDeviceSettingsType = DeviceRADGigalogSettingsTypeDeprecated;
break;
case NEODEVICE_RADMOON3:
*pDeviceSettingsType = DeviceRADMoon3SettingsType;
@@ -7,7 +7,7 @@
namespace icsneo {
void init_ethernetstatusmessage(pybind11::module_& m) {
pybind11::classh<EthernetStatusMessage, Message> ethernetStatusMessage(m, "EthernetStatusMessage");
pybind11::classh<EthernetStatusMessage, RawMessage> ethernetStatusMessage(m, "EthernetStatusMessage");
pybind11::enum_<EthernetStatusMessage::LinkSpeed>(ethernetStatusMessage, "LinkSpeed")
.value("LinkSpeedAuto", EthernetStatusMessage::LinkSpeed::LinkSpeedAuto)
@@ -37,7 +37,7 @@ struct Packet {
};
#pragma pack(pop)
std::shared_ptr<Message> EthernetStatusMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
std::shared_ptr<RawMessage> EthernetStatusMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
if(bytestream.size() < sizeof(Packet)) {
return nullptr;
}
@@ -76,5 +76,5 @@ std::shared_ptr<Message> EthernetStatusMessage::DecodeToMessage(const std::vecto
break;
default: return nullptr;
}
return std::make_shared<EthernetStatusMessage>(packet->network, packet->state, speed, packet->duplex, mode);
}
return std::make_shared<EthernetStatusMessage>(packet->network, packet->state != 0, speed, packet->duplex != 0, mode);
}
+16
View File
@@ -74,6 +74,14 @@ Ethernet Receive
.. literalinclude:: ../../examples/c2/ethernet_receive/src/main.c
:language: c
Ethernet Status
===============
:download:`Download example <../../examples/c2/ethernet_status/src/main.c>`
.. literalinclude:: ../../examples/c2/ethernet_status/src/main.c
:language: c
T1S Loopback
============
@@ -106,3 +114,11 @@ PerfTest
.. literalinclude:: ../../examples/c2/perf_test/src/main.c
:language: c
Termination Groups
==================
:download:`Download example <../../examples/c2/termination/src/main.c>`
.. literalinclude:: ../../examples/c2/termination/src/main.c
:language: c
+10
View File
@@ -8,10 +8,12 @@ option(LIBICSNEO_BUILD_C2_DISKFORMAT_EXAMPLE "Build the C2 disk format example."
option(LIBICSNEO_BUILD_C2_RECONNECT_EXAMPLE "Build the C2 reconnect example." ON)
option(LIBICSNEO_BUILD_C2_DEVICE_INFO_EXAMPLE "Build the C2 device info example." ON)
option(LIBICSNEO_BUILD_C2_CHIP_VERSIONS_EXAMPLE "Build the C2 chip versions example." ON)
option(LIBICSNEO_BUILD_C2_TERMINATION_EXAMPLE "Build the C2 termination groups example." ON)
option(LIBICSNEO_BUILD_C2_LIN_EXAMPLE "Build the C2 LIN example." ON)
option(LIBICSNEO_BUILD_C2_LIN_TRANSMIT_EXAMPLE "Build the C2 LIN transmit example." ON)
option(LIBICSNEO_BUILD_C2_ETHERNET_TRANSMIT_EXAMPLE "Build the C2 ethernet transmit example." ON)
option(LIBICSNEO_BUILD_C2_ETHERNET_RECEIVE_EXAMPLE "Build the C2 ethernet receive example." ON)
option(LIBICSNEO_BUILD_C2_ETHERNET_STATUS_EXAMPLE "Build the C2 ethernet status example." ON)
option(LIBICSNEO_BUILD_C2_T1S_LOOPBACK_EXAMPLE "Build the C2 RAD-Comet3 T1S loopback example." ON)
option(LIBICSNEO_BUILD_C2_TC10_EXAMPLE "Build the C2 TC10 example." ON)
option(LIBICSNEO_BUILD_C2_GPTP_EXAMPLE "Build the C2 gPTP settings example." ON)
@@ -77,6 +79,10 @@ if(LIBICSNEO_BUILD_C2_CHIP_VERSIONS_EXAMPLE)
add_subdirectory(c2/chip_versions)
endif()
if(LIBICSNEO_BUILD_C2_TERMINATION_EXAMPLE)
add_subdirectory(c2/termination)
endif()
if(LIBICSNEO_BUILD_C2_LIN_EXAMPLE)
add_subdirectory(c2/lin)
endif()
@@ -93,6 +99,10 @@ if(LIBICSNEO_BUILD_C2_ETHERNET_RECEIVE_EXAMPLE)
add_subdirectory(c2/ethernet_receive)
endif()
if(LIBICSNEO_BUILD_C2_ETHERNET_STATUS_EXAMPLE)
add_subdirectory(c2/ethernet_status)
endif()
if(LIBICSNEO_BUILD_C2_T1S_LOOPBACK_EXAMPLE)
add_subdirectory(c2/t1s_loopback)
endif()
+5 -5
View File
@@ -58,7 +58,7 @@ int main() {
msg1.Protocol = SPY_PROTOCOL_LIN;
msg1.StatusBitField = 0;
msg1.StatusBitField2 = 0;
lNetworkID = NETID_LIN_02;
lNetworkID = NETID_LIN2;
msg1.Header[0] = 0x11; //protected ID
msg1.Header[1] = 0xaa;
msg1.Header[2] = 0xbb;
@@ -80,7 +80,7 @@ int main() {
icsSpyMessageJ1850 msg2 = {0};
msg2.Protocol = SPY_PROTOCOL_LIN;
msg2.StatusBitField = SPY_STATUS_INIT_MESSAGE;
lNetworkID = NETID_LIN_01;
lNetworkID = NETID_LIN;
msg2.Header[0] = 0x11; //protected ID
msg2.NumberBytesData = 0;
msg2.NumberBytesHeader = 1;
@@ -96,7 +96,7 @@ int main() {
msg3.Protocol = SPY_PROTOCOL_LIN;
msg3.StatusBitField = SPY_STATUS_INIT_MESSAGE;
msg3.StatusBitField2 = 0;
lNetworkID = NETID_LIN_01;
lNetworkID = NETID_LIN;
msg3.Header[0] = 0xe2; //protected ID
msg3.Header[1] = 0x44;
msg3.Header[2] = 0x33;
@@ -131,10 +131,10 @@ int main() {
const icsSpyMessageJ1850* linMsg = (icsSpyMessageJ1850*)&rxMsg[idx];
size_t frameLen = (linMsg->NumberBytesHeader + linMsg->NumberBytesData);
size_t dataLen = (frameLen > 2) ? (frameLen - 2) : 0;
if(linMsg->NetworkID == NETID_LIN_01) {
if(linMsg->NetworkID == NETID_LIN) {
printf("LIN 1 | ID: 0x%02x [%zu] ", linMsg->Header[0], dataLen);
}
else if (linMsg->NetworkID == NETID_LIN_02) {
else if (linMsg->NetworkID == NETID_LIN2) {
printf("LIN 2 | ID: 0x%02x [%zu] ", linMsg->Header[0], dataLen);
}
+79
View File
@@ -109,6 +109,85 @@ int main() {
}
}
/* Choose operation */
printf("\n\tChoose operation:\n");
printf("\t [f] Format the disk(s)\n");
printf("\t [u] Update the disk configuration without formatting\n");
printf("\t [q] Quit\n");
printf("\tSelection [f/u/q]: ");
char choice[8] = {0};
if(scanf("%7s", choice) != 1) {
choice[0] = 'q';
}
if(choice[0] == 'u' || choice[0] == 'U') {
/* Force a disk config update (e.g. changing the disk layout) without formatting.
* Unlike a format, this preserves the existing data on the disk(s). */
printf("\n\tChoose disk layout:\n");
printf("\t [s] Spanned\n");
printf("\t [r] RAID0\n");
printf("\tSelection [s/r] (current: %s): ", layout == icsneoc2_disk_layout_raid0 ? "RAID0" : "Spanned");
char layout_choice[8] = {0};
if(scanf("%7s", layout_choice) != 1) {
layout_choice[0] = '\0';
}
if(layout_choice[0] == 'r' || layout_choice[0] == 'R') {
icsneoc2_disk_details_layout_set(details, icsneoc2_disk_layout_raid0);
} else if(layout_choice[0] == 's' || layout_choice[0] == 'S') {
icsneoc2_disk_details_layout_set(details, icsneoc2_disk_layout_spanned);
} else {
printf("\tKeeping current layout.\n");
}
/* Enable/disable individual disks in the configuration. A disk's enabled
* state is carried by the FORMATTED flag; only present disks can be enabled. */
for(size_t i = 0; i < detail_count; i++) {
icsneoc2_disk_format_flags_t flags = 0;
icsneoc2_disk_details_flags_get(details, i, &flags);
if(!(flags & ICSNEOC2_DISK_FORMAT_FLAGS_PRESENT)) {
continue; /* Can't enable a disk that isn't present */
}
printf("\tEnable disk [%zu]? [y/N] (currently %s): ", i,
(flags & ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED) ? "enabled" : "disabled");
char disk_choice[8] = {0};
if(scanf("%7s", disk_choice) != 1) {
disk_choice[0] = '\0';
}
if(disk_choice[0] == 'y' || disk_choice[0] == 'Y') {
flags |= ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED;
} else {
flags &= ~(icsneoc2_disk_format_flags_t)ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED;
}
icsneoc2_disk_details_flags_set(details, i, flags);
}
icsneoc2_disk_layout_t new_layout = 0;
icsneoc2_disk_details_layout_get(details, &new_layout);
printf("\n\tForcing disk config update on %s to %s layout (no data will be erased)...\n",
description, new_layout == icsneoc2_disk_layout_raid0 ? "RAID0" : "Spanned");
res = icsneoc2_device_force_disk_config_update(device, details);
if(res != icsneoc2_error_success) {
print_error_code("\tForce disk config update failed", res);
icsneoc2_disk_details_free(details);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return -1;
}
printf("\tDisk config update complete!\n");
icsneoc2_disk_details_free(details);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return 0;
}
if(choice[0] != 'f' && choice[0] != 'F') {
printf("\tAborted.\n");
icsneoc2_disk_details_free(details);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return 0;
}
/* Build format config: mark present disks for formatting */
bool any_present = false;
for(size_t i = 0; i < detail_count; i++) {
@@ -0,0 +1,6 @@
add_executable(libicsneoc2-ethernet-status-example src/main.c)
target_link_libraries(libicsneoc2-ethernet-status-example icsneoc2-static)
if(WIN32)
target_compile_definitions(libicsneoc2-ethernet-status-example PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()
+228
View File
@@ -0,0 +1,228 @@
#include <icsneo/icsneoc2.h>
#include <icsneo/icsneoc2messages.h>
#include <stdio.h>
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
void sleep_ms(uint32_t ms) {
#ifdef _WIN32
Sleep(ms);
#else
usleep(ms * 1000);
#endif
}
int print_error_code(const char* message, icsneoc2_error_t error) {
char error_str[64] = {0};
size_t error_str_len = sizeof(error_str);
icsneoc2_error_t res = icsneoc2_error_code_get(error, error_str, &error_str_len);
if(res != icsneoc2_error_success) {
printf("%s: Failed to get string for error code %u with error code %u\n", message, error, res);
return (int)res;
}
printf("%s: \"%s\" (%u)\n", message, error_str, error);
return (int)error;
}
void print_events(void) {
icsneoc2_event_t* events[256] = {0};
size_t events_count = 256;
for(size_t i = 0; i < events_count; ++i) {
icsneoc2_error_t res = icsneoc2_event_get(&events[i], NULL);
if(res != icsneoc2_error_success) {
(void)print_error_code("\tFailed to get events", res);
return;
}
if(events[i] == NULL) {
events_count = i;
break;
}
}
for(size_t i = 0; i < events_count; i++) {
char description[255] = {0};
size_t description_length = sizeof(description);
icsneoc2_error_t res = icsneoc2_event_description_get(events[i], description, &description_length);
if(res != icsneoc2_error_success) {
(void)print_error_code("\tFailed to get event description", res);
continue;
}
printf("\tEvent %zu: %s\n", i, description);
}
for(size_t i = 0; i < events_count; i++) {
icsneoc2_event_free(events[i]);
}
if(events_count > 0) {
printf("\tReceived %zu events\n", events_count);
}
}
const char* link_speed_name(icsneoc2_link_speed_t speed) {
switch(speed) {
case icsneoc2_link_speed_auto:
return "Auto";
case icsneoc2_link_speed_10mbps:
return "10 Mbps";
case icsneoc2_link_speed_100mbps:
return "100 Mbps";
case icsneoc2_link_speed_1000mbps:
return "1000 Mbps";
case icsneoc2_link_speed_2500mbps:
return "2500 Mbps";
case icsneoc2_link_speed_5000mbps:
return "5000 Mbps";
case icsneoc2_link_speed_10000mbps:
return "10000 Mbps";
default:
return "Unknown";
}
}
const char* link_mode_name(icsneoc2_link_mode_t mode) {
switch(mode) {
case icsneoc2_link_mode_auto:
return "Auto";
case icsneoc2_link_mode_master:
return "Master";
case icsneoc2_link_mode_slave:
return "Slave";
case icsneoc2_link_mode_invalid:
return "Invalid";
case icsneoc2_link_mode_none:
return "None";
default:
return "Unknown";
}
}
int print_ethernet_status_message(icsneoc2_message_t* message, size_t index) {
icsneoc2_netid_t netid = 0;
char netid_name[128] = {0};
size_t netid_name_length = sizeof(netid_name);
bool link_state = false;
bool duplex = false;
icsneoc2_link_speed_t link_speed = icsneoc2_link_speed_auto;
icsneoc2_link_mode_t link_mode = icsneoc2_link_mode_auto;
icsneoc2_error_t res = icsneoc2_message_netid_get(message, &netid);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to get Ethernet status netid", res);
}
res = icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to get Ethernet status netid name", res);
}
res = icsneoc2_message_eth_status_props_get(message, &link_state, &duplex, &link_speed, &link_mode);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to get Ethernet status properties", res);
}
printf("\t%zu) Ethernet status on %s (0x%x)\n", index, netid_name, netid);
printf("\t Link: %s\n", link_state ? "Up" : "Down");
printf("\t Duplex: %s\n", duplex ? "Full" : "Half");
printf("\t Speed: %s (%u)\n", link_speed_name(link_speed), link_speed);
printf("\t Mode: %s (%u)\n", link_mode_name(link_mode), link_mode);
return icsneoc2_error_success;
}
int main(void) {
printf("Opening first available device offline...\n");
icsneoc2_device_t* device = NULL;
icsneoc2_open_options_t options = icsneoc2_open_options_default & ~ICSNEOC2_OPEN_OPTIONS_GO_ONLINE;
icsneoc2_error_t res = icsneoc2_device_open_first(0, options, &device);
if(res != icsneoc2_error_success) {
return print_error_code("Failed to open first device", res);
}
char description[255] = {0};
size_t description_length = sizeof(description);
res = icsneoc2_device_description_get(device, description, &description_length);
if(res != icsneoc2_error_success) {
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return print_error_code("Failed to get device description", res);
}
printf("Opened device: %s\n", description);
printf("Going online to trigger Ethernet status broadcast...\n");
res = icsneoc2_device_go_online(device, true);
if(res != icsneoc2_error_success) {
print_events();
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return print_error_code("Failed to go online", res);
}
const int listen_seconds = 6;
time_t start_time = time(NULL);
size_t status_count = 0;
size_t total_count = 0;
printf("Listening for Ethernet status messages for %d seconds...\n", listen_seconds);
while(time(NULL) - start_time < listen_seconds) {
icsneoc2_message_t* message = NULL;
res = icsneoc2_device_message_get(device, &message, 100);
if(res != icsneoc2_error_success) {
print_events();
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return print_error_code("Failed to get message", res);
}
if(message == NULL) {
sleep_ms(10);
continue;
}
total_count++;
bool is_ethernet_status = false;
res = icsneoc2_message_is_ethernet_status(message, &is_ethernet_status);
if(res != icsneoc2_error_success) {
icsneoc2_message_free(message);
print_events();
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return print_error_code("Failed to check for Ethernet status message", res);
}
if(is_ethernet_status) {
res = print_ethernet_status_message(message, status_count);
if(res != icsneoc2_error_success) {
icsneoc2_message_free(message);
print_events();
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return (int)res;
}
status_count++;
}
icsneoc2_message_free(message);
}
printf("Received %zu Ethernet status messages out of %zu total messages.\n", status_count, total_count);
if(status_count == 0) {
printf("No Ethernet status messages were seen. These messages are broadcast when the device goes online and may depend on device Ethernet support.\n");
}
print_events();
printf("Closing device...\n");
res = icsneoc2_device_close(device);
if(res != icsneoc2_error_success) {
icsneoc2_device_free(device);
return print_error_code("Failed to close device", res);
}
icsneoc2_device_free(device);
return 0;
}
+11 -2
View File
@@ -176,6 +176,7 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
// Print the type and bus type of each message
size_t tx_count = 0;
size_t can_error_count = 0;
size_t internal_count = 0;
icsneoc2_error_t res = icsneoc2_error_success;
for(size_t i = 0; i < messages_count; i++) {
icsneoc2_message_t* message = messages[i];
@@ -216,13 +217,21 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
continue;
}
// This example only cares about bus traffic, so skip internal
// device/status messages.
icsneoc2_network_type_t internal_check = icsneoc2_network_type_invalid;
res = icsneoc2_message_network_type_get(message, &internal_check);
if(res == icsneoc2_error_success && internal_check == icsneoc2_network_type_internal) {
internal_count++;
continue;
}
bool is_frame = false;
res = icsneoc2_message_is_frame(message, &is_frame);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to check if message is a frame", res);
}
if(!is_frame) {
printf("Ignoring non-frame message at index %zu\n", i);
continue;
}
icsneoc2_network_type_t network_type;
@@ -296,7 +305,7 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
printf(" ]\n");
}
}
printf("\tReceived %zu messages total, %zu were TX messages, %zu were CAN errors\n", messages_count, tx_count, can_error_count);
printf("\tReceived %zu messages total, %zu were TX messages, %zu were CAN errors, %zu internal (skipped)\n", messages_count, tx_count, can_error_count, internal_count);
return icsneoc2_error_success;
}
+33 -2
View File
@@ -359,6 +359,8 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
// Print the type and bus type of each message
size_t tx_count = 0;
size_t can_error_count = 0;
size_t app_error_count = 0;
size_t internal_count = 0;
for(size_t i = 0; i < messages_count; i++) {
icsneoc2_message_t* message = messages[i];
@@ -392,13 +394,42 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
continue;
}
// Check for application error messages
bool is_app_error = false;
res = icsneoc2_message_is_app_error(message, &is_app_error);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to check if message is an app error", res);
}
if(is_app_error) {
icsneoc2_app_error_type_t error_type = icsneoc2_app_error_type_no_error;
icsneoc2_netid_t error_netid = 0;
char description[256] = {0};
size_t description_length = sizeof(description);
res = icsneoc2_message_app_error_props_get(message, &error_type, &error_netid);
res += icsneoc2_message_app_error_string_get(message, description, &description_length);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to get app error properties", res);
}
printf("\t%zd) App Error (type %u) on netid 0x%x: %s\n", i, error_type, error_netid, description);
app_error_count++;
continue;
}
// This example only cares about bus traffic, so skip internal
// device/status messages.
icsneoc2_network_type_t internal_check = icsneoc2_network_type_invalid;
res = icsneoc2_message_network_type_get(message, &internal_check);
if(res == icsneoc2_error_success && internal_check == icsneoc2_network_type_internal) {
internal_count++;
continue;
}
bool is_frame = false;
res = icsneoc2_message_is_frame(message, &is_frame);
if(res != icsneoc2_error_success) {
return print_error_code("\tFailed to check if message is a frame", res);
}
if(!is_frame) {
printf("Ignoring non-frame message at index %zu\n", i);
continue;
}
icsneoc2_network_type_t network_type;
@@ -472,7 +503,7 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
printf(" ]\n");
}
}
printf("\tReceived %zu messages total, %zu were TX messages, %zu were CAN errors\n", messages_count, tx_count, can_error_count);
printf("\tReceived %zu messages total, %zu were TX messages, %zu were CAN errors, %zu were app errors, %zu internal (skipped)\n", messages_count, tx_count, can_error_count, app_error_count, internal_count);
return icsneoc2_error_success;
}
+6
View File
@@ -0,0 +1,6 @@
add_executable(libicsneoc2-termination-example src/main.c)
target_link_libraries(libicsneoc2-termination-example icsneoc2-static)
if(WIN32)
target_compile_definitions(libicsneoc2-termination-example PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()
+91
View File
@@ -0,0 +1,91 @@
#include <icsneo/icsneoc2.h>
#include <icsneo/icsneoc2messages.h>
#include <icsneo/icsneoc2settings.h>
#include <stdio.h>
#include <stdlib.h>
int print_error_code(const char* message, icsneoc2_error_t error) {
char error_str[64];
size_t error_str_len = sizeof(error_str);
icsneoc2_error_t res = icsneoc2_error_code_get(error, error_str, &error_str_len);
if(res != icsneoc2_error_success) {
printf("%s: Failed to get string for error code %u with error code %u\n", message, error, res);
return (int)res;
}
printf("%s: \"%s\" (%u)\n", message, error_str, error);
return (int)error;
}
int main() {
icsneoc2_error_t res;
icsneoc2_device_t* device = NULL;
res = icsneoc2_device_open_first(0, icsneoc2_open_options_default, &device);
if(res != icsneoc2_error_success) {
return print_error_code("Failed to open first device", res);
}
char description[128] = {0};
size_t description_length = sizeof(description);
icsneoc2_device_description_get(device, description, &description_length);
printf("Opened device: %s\n\n", description);
size_t count = 0;
icsneoc2_termination_group_t* groups = NULL;
res = icsneoc2_settings_termination_groups_enumerate(device, &groups, &count);
if(res != icsneoc2_error_success) {
print_error_code("Failed to enumerate termination groups", res);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return 1;
}
if(count == 0) {
printf("This device does not support software switchable termination.\n");
} else {
printf("Found %zu termination group(s) (only one network per group may be terminated at a time):\n", count);
}
size_t group_index = 0;
for(icsneoc2_termination_group_t* group = groups; group; group = icsneoc2_termination_group_next(group), group_index++) {
// First call with a NULL buffer to learn how many networks are in this group.
size_t network_count = 0;
icsneoc2_termination_group_networks_get(group, NULL, &network_count);
icsneoc2_netid_t* netids = (icsneoc2_netid_t*)malloc(network_count * sizeof(icsneoc2_netid_t));
if(!netids) {
print_error_code("Out of memory", icsneoc2_error_out_of_memory);
break;
}
// Second call to fill the buffer.
res = icsneoc2_termination_group_networks_get(group, netids, &network_count);
if(res != icsneoc2_error_success) {
print_error_code("Failed to get termination group networks", res);
free(netids);
continue;
}
printf(" Group %zu:", group_index);
for(size_t i = 0; i < network_count; i++) {
char name[64] = {0};
size_t name_length = sizeof(name);
if(icsneoc2_netid_name_get(netids[i], name, &name_length) == icsneoc2_error_success) {
printf(" %s", name);
} else {
printf(" %u", netids[i]);
}
if(i + 1 < network_count) {
printf(",");
}
}
printf("\n");
free(netids);
}
icsneoc2_settings_termination_groups_free(groups);
icsneoc2_device_close(device);
icsneoc2_device_free(device);
return 0;
}
+249
View File
@@ -0,0 +1,249 @@
// --------------------------------------------------------------------------
// COPYRIGHT INTREPID CONTROL SYSTEMS, INC. (c) 1994-20xx
// Confidential and proprietary. This document and its contents are the
// property of Intrepid Control Systems, Inc. It is not to be copied,
// distributed, or otherwise disclosed or used without the prior written
// consent of Intrepid Control Systems Inc.
// All rights reserved.
// --------------------------------------------------------------------------
// SPY Status Bit Definitions
// Generated automatically - DO NOT MODIFY
// Modify cicsSpyStatusBits_config.yml and run cicsSpyStatusBits_gen.py
// Generated on: 2025-07-14 14:31:40
#ifndef CICSSPYSTATUSBITS_H_
#define CICSSPYSTATUSBITS_H_ 1
// WARNING: The following bit conflicts were detected:
// spystatus value 0x10000000: // VSI value 'SPY_STATUS_VSI_IFR_CRC_BIT' conflicts with common value 'SPY_STATUS_PDU'
// spystatus value 0x10000000: // A2B value 'SPY_STATUS_A2B_CONTROL' conflicts with common value 'SPY_STATUS_PDU'
// spystatus value 0x08: // A2B value 'SPY_STATUS_A2B_SCF_VALID_WAITING' conflicts with common value 'SPY_STATUS_REMOTE_FRAME'
// spystatus value 0x40000000: // A2B value 'SPY_STATUS_A2B_UPSTREAM' conflicts with common value 'SPY_STATUS_HIGH_SPEED'
// spystatus value 0x10000000: // FLEXRAY value 'SPY_STATUS_FLEXRAY_PDU' conflicts with common value 'SPY_STATUS_PDU'
// spystatus value 0x40000000: // FLEXRAY value 'SPY_STATUS_FLEXRAY_PDU_UPDATE_BIT_SET' conflicts with common value 'SPY_STATUS_HIGH_SPEED'
// spystatus value 0x08: // FLEXRAY value 'SPY_STATUS_FLEXRAY_PDU_NO_UPDATE_BIT' conflicts with common value 'SPY_STATUS_REMOTE_FRAME'
// Glyph definitions
// '|' - byte divider
// '.' - nibble divider
// '-' - unused bit
// 'o' - common bit
// 'x' - protocol specific bit
// '!' - conflict bit
// SPYSTATUS bit definitions
// SPYSTATUS - Common bits
// |oo-o.oooo|oooo.oooo|oooo.oo-o|oo-o.oooo|
#define SPY_STATUS_GLOBAL_ERR 0x01 // Global error flag
#define SPY_STATUS_TX_MSG 0x02 // Transmitted message
#define SPY_STATUS_XTD_FRAME 0x04 // Extended frame
#define SPY_STATUS_REMOTE_FRAME 0x08 // Remote frame
#define SPY_STATUS_CRC_ERROR 0x10 // CRC error
#define SPY_STATUS_INCOMPLETE_FRAME 0x40 // Incomplete frame
#define SPY_STATUS_LOST_ARBITRATION 0x80 // Lost arbitration
#define SPY_STATUS_UNDEFINED_ERROR 0x0100 // Undefined error
#define SPY_STATUS_BUS_RECOVERED 0x0400 // Bus recovered
#define SPY_STATUS_BUS_SHORTED_PLUS 0x0800 // Bus shorted to plus
#define SPY_STATUS_BUS_SHORTED_GND 0x1000 // Bus shorted to ground
#define SPY_STATUS_CHECKSUM_ERROR 0x2000 // Checksum error
#define SPY_STATUS_BAD_MESSAGE_BIT_TIME_ERROR 0x4000 // Bad message bit time error
#define SPY_STATUS_TX_NOMATCH 0x8000 // TX no match
#define SPY_STATUS_COMM_IN_OVERFLOW 0x010000 // Communication input overflow
#define SPY_STATUS_EXPECTED_LEN_MISMATCH 0x020000 // Expected length mismatch
#define SPY_STATUS_MSG_NO_MATCH 0x040000 // Message no match
#define SPY_STATUS_BREAK 0x080000 // Break detected
#define SPY_STATUS_AVSI_REC_OVERFLOW 0x100000 // AVSI record overflow
#define SPY_STATUS_TEST_TRIGGER 0x200000 // Test trigger
#define SPY_STATUS_AUDIO_COMMENT 0x400000 // Audio comment
#define SPY_STATUS_GPS_DATA 0x800000 // GPS data
#define SPY_STATUS_ANALOG_DIGITAL_INPUT 0x01000000 // Analog digital input
#define SPY_STATUS_TEXT_COMMENT 0x02000000 // Text comment
#define SPY_STATUS_NETWORK_MESSAGE_TYPE 0x04000000 // Network message type
#define SPY_STATUS_VSI_TX_UNDERRUN 0x08000000 // VSI TX underrun
#define SPY_STATUS_PDU 0x10000000 // PDU message
#define SPY_STATUS_HIGH_SPEED 0x40000000 // High speed
#define SPY_STATUS_EXTENDED 0x80000000 // Extended - if this bit is set than decode StatusBitField3 in AckBytes
// SPYSTATUS - A2B protocol bits
// |o!x!.oooo|oooo.oooo|oooo.oo-o|oo-o.!ooo|
#define SPY_STATUS_A2B_SCF_VALID_WAITING 0x08 // A2B SCF valid waiting
#define SPY_STATUS_A2B_CONTROL 0x10000000 // A2B control message
#define SPY_STATUS_A2B_MONITOR 0x20000000 // A2B monitor message
#define SPY_STATUS_A2B_UPSTREAM 0x40000000 // A2B upstream message
// SPYSTATUS - CAN protocol bits
// |ooxo.oooo|oooo.oooo|oooo.ooxo|ooxo.oooo|
#define SPY_STATUS_CAN_ERROR_PASSIVE 0x20 // CAN error passive state
#define SPY_STATUS_CAN_BUS_OFF 0x0200 // CAN bus off state
#define SPY_STATUS_CANFD 0x20000000 // CAN FD frame
// SPYSTATUS - ETHERNET protocol bits
// |oo-o.oooo|oooo.oooo|oooo.oo-o|ooxo.oooo|
#define SPY_STATUS_HEADERCRC_ERROR 0x20 // Header CRC error
// SPYSTATUS - FLEXRAY protocol bits
// |o!-!.oooo|oooo.oooo|oooo.oo-o|oo-o.!ooo|
#define SPY_STATUS_FLEXRAY_PDU_NO_UPDATE_BIT 0x08 // FlexRay PDU no update bit
#define SPY_STATUS_FLEXRAY_PDU 0x10000000 // FlexRay PDU (alias for SPY_STATUS_PDU)
#define SPY_STATUS_FLEXRAY_PDU_UPDATE_BIT_SET 0x40000000 // FlexRay PDU update bit set
// SPYSTATUS - LIN protocol bits
// |ooxo.oooo|oooo.oooo|oooo.oo-o|oo-o.oooo|
#define SPY_STATUS_LIN_MASTER 0x20000000 // LIN master message
// SPYSTATUS - VSI protocol bits
// |oox!.oooo|oooo.oooo|oooo.oo-o|oo-o.oooo|
#define SPY_STATUS_VSI_IFR_CRC_BIT 0x10000000 // VSI IFR CRC bit
#define SPY_STATUS_INIT_MESSAGE 0x20000000 // Initialization message
// SPYSTATUS2 bit definitions
// SPYSTATUS2 - Common bits
// |----.----|---o.--oo|----.----|----.oooo|
#define SPY_STATUS2_HAS_VALUE 0x01
#define SPY_STATUS2_VALUE_IS_BOOLEAN 0x02
#define SPY_STATUS2_HIGH_VOLTAGE 0x04
#define SPY_STATUS2_LONG_MESSAGE 0x08
#define SPY_STATUS2_GLOBAL_CHANGE 0x010000
#define SPY_STATUS2_ERROR_FRAME 0x020000
#define SPY_STATUS2_END_OF_LONG_MESSAGE 0x100000
// SPYSTATUS2 - CAN protocol bits
// |----.----|-xxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_CAN_ISO15765_LOGICAL_FRAME 0x200000
#define SPY_STATUS2_CAN_HAVE_LINK_DATA 0x400000
// SPYSTATUS2 - ETHERNET protocol bits
// |xxxx.xxxx|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_ETHERNET_CRC_ERROR 0x200000
#define SPY_STATUS2_ETHERNET_FRAME_TOO_SHORT 0x400000
#define SPY_STATUS2_ETHERNET_FCS_AVAILABLE 0x800000 // This frame contains FCS (4 bytes) obtained from ICS Ethernet hardware (ex. RAD-STAR)
#define SPY_STATUS2_ETHERNET_NO_PADDING 0x01000000
#define SPY_STATUS2_ETHERNET_PREEMPTION_ENABLED 0x02000000
#define SPY_STATUS2_ETHERNET_UPDATE_CHECKSUMS 0x04000000
#define SPY_STATUS2_ETHERNET_MANUALFCS_ENABLED 0x08000000
#define SPY_STATUS2_ETHERNET_FCS_VERIFIED 0x10000000
#define SPY_STATUS2_ETHERNET_T1S_SYMBOL 0x20000000
#define SPY_STATUS2_ETHERNET_T1S_BURST 0x40000000
#define SPY_STATUS2_ETHERNET_T1S_ETHERNET 0x80000000
// SPYSTATUS2 - FLEXRAY protocol bits
// |----.-xxx|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_FLEXRAY_TX_AB 0x200000
#define SPY_STATUS2_FLEXRAY_TX_AB_NO_A 0x400000
#define SPY_STATUS2_FLEXRAY_TX_AB_NO_B 0x800000
#define SPY_STATUS2_FLEXRAY_TX_AB_NO_MATCH 0x01000000
#define SPY_STATUS2_FLEXRAY_NO_CRC 0x02000000
#define SPY_STATUS2_FLEXRAY_NO_HEADERCRC 0x04000000 //
// SPYSTATUS2 - I2C protocol bits
// |----.----|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_I2C_ERR_TIMEOUT 0x200000
#define SPY_STATUS2_I2C_ERR_NACK 0x400000
#define SPY_STATUS2_I2C_DIR_READ 0x800000
// SPYSTATUS2 - ISO protocol bits
// |-xxx.x---|---o.--oo|----.----|----.oooo|
#define SPY_STATUS2_ISO_FRAME_ERROR 0x08000000 // ISO frame error
#define SPY_STATUS2_ISO_OVERFLOW_ERROR 0x10000000 // ISO overflow error
#define SPY_STATUS2_ISO_PARITY_ERROR 0x20000000 // ISO parity error
#define SPY_STATUS2_ISO_RX_TIMEOUT_ERROR 0x40000000 // ISO specific timeout error
// SPYSTATUS2 - LIN protocol bits
// |xxxx.xxxx|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_LIN_ERR_RX_BREAK_NOT_0 0x200000 // LIN RX break not 0 error
#define SPY_STATUS2_LIN_ERR_RX_BREAK_TOO_SHORT 0x400000 // LIN RX break too short error
#define SPY_STATUS2_LIN_ERR_RX_SYNC_NOT_55 0x800000 // LIN RX sync not 0x55 error
#define SPY_STATUS2_LIN_ERR_RX_DATA_GREATER_8 0x01000000 // LIN RX data greater than 8 bytes error
#define SPY_STATUS2_LIN_ERR_TX_RX_MISMATCH 0x02000000 // LIN TX/RX mismatch error
#define SPY_STATUS2_LIN_ERR_MSG_ID_PARITY 0x04000000 // LIN message ID parity error
#define SPY_STATUS2_LIN_SYNC_FRAME_ERROR 0x08000000 // LIN sync frame error
#define SPY_STATUS2_LIN_ID_FRAME_ERROR 0x10000000 // LIN ID frame error
#define SPY_STATUS2_LIN_SLAVE_BYTE_ERROR 0x20000000 // LIN slave byte error
#define SPY_STATUS2_LIN_RX_TIMEOUT_ERROR 0x40000000 // RX timeout error
#define SPY_STATUS2_LIN_NO_SLAVE_DATA 0x80000000 // LIN no slave data
// SPYSTATUS2 - MDIO protocol bits
// |-xxx.xxxx|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_MDIO_ERR_TIMEOUT 0x200000
#define SPY_STATUS2_MDIO_JOB_CANCELLED 0x400000
#define SPY_STATUS2_MDIO_INVALID_BUS 0x800000
#define SPY_STATUS2_MDIO_INVALID_PHYADDR 0x01000000
#define SPY_STATUS2_MDIO_INVALID_REGADDR 0x02000000
#define SPY_STATUS2_MDIO_UNSUPPORTED_CLAUSE 0x04000000
#define SPY_STATUS2_MDIO_UNSUPPORTED_OPCODE 0x08000000
#define SPY_STATUS2_MDIO_OVERFLOW 0x10000000
#define SPY_STATUS2_MDIO_CLAUSE45 0x20000000
#define SPY_STATUS2_MDIO_READ 0x40000000
// SPYSTATUS2 - MOST protocol bits
// |xxxx.xxxx|xxxo.--oo|----.----|----.oooo|
#define SPY_STATUS2_MOST_PACKET_DATA 0x200000
#define SPY_STATUS2_MOST_STATUS 0x400000 // reflects changes in light/lock/MPR/SBC/etc...
#define SPY_STATUS2_MOST_LOW_LEVEL 0x800000 // MOST low level message, allocs, deallocs, remote requests...*/
#define SPY_STATUS2_MOST_CONTROL_DATA 0x01000000
#define SPY_STATUS2_MOST_MHP_USER_DATA 0x02000000 // MOST HIGH User Data Frame
#define SPY_STATUS2_MOST_MHP_CONTROL_DATA 0x04000000 // MOST HIGH Control Data
#define SPY_STATUS2_MOST_I2S_DUMP 0x08000000
#define SPY_STATUS2_MOST_TOO_SHORT 0x10000000
#define SPY_STATUS2_MOST_MOST50 0x20000000 // absence of MOST50 and MOST150 implies it's MOST25
#define SPY_STATUS2_MOST_MOST150 0x40000000
#define SPY_STATUS2_MOST_CHANGED_PAR 0x80000000 // first byte in ack reflects what changed.
// SPYSTATUS2 - WBMS protocol bits
// |----.----|--xo.--oo|----.----|----.oooo|
#define SPY_STATUS2_WBMS_API_IS_CALLBACK 0x200000
// SPYSTATUS3 bit definitions
// SPYSTATUS3 - CAN protocol bits
// |----.----|-xxx.xxxx|-xxx.xxxx|----.-xxx|
#define SPY_STATUS3_CAN_ERR_PASSIVE 0x01 // CAN error passive state: typically when error counter is > 127
#define SPY_STATUS3_CAN_BUS_OFF 0x02 // CAN bus off state
#define SPY_STATUS3_CAN_ERR_WARNING 0x04 // CAN error warning: typically when error counter is > 96
#define SPY_STATUS3_CAN_DATAERR_STUFF_ERROR 0x0100 // CAN stuff error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_FORM_ERROR 0x0200 // CAN form error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_ACK_ERROR 0x0400 // CAN ack error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_BIT1_ERROR 0x0800 // CAN bit1 error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_BIT0_ERROR 0x1000 // CAN bit0 error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_CRC_ERROR 0x2000 // CAN CRC error during the data payload phase
#define SPY_STATUS3_CAN_DATAERR_NOCHANGE 0x4000 // CAN data error occurred before and no change yet
#define SPY_STATUS3_CAN_GENERR_STUFF_ERROR 0x010000 // CAN stuff error at the general frame level
#define SPY_STATUS3_CAN_GENERR_FORM_ERROR 0x020000 // CAN form error at the general frame level
#define SPY_STATUS3_CAN_GENERR_ACK_ERROR 0x040000 // CAN ack error at the general frame level
#define SPY_STATUS3_CAN_GENERR_BIT1_ERROR 0x080000 // CAN bit1 error at the general frame level
#define SPY_STATUS3_CAN_GENERR_BIT0_ERROR 0x100000 // CAN bit0 error at the general frame level
#define SPY_STATUS3_CAN_GENERR_CRC_ERROR 0x200000 // CAN CRC error at the general frame level
#define SPY_STATUS3_CAN_GENERR_NOCHANGE 0x400000 // CAN frame Error occurred before and no change yet
// SPYSTATUS3 - CANFD protocol bits
// |----.----|----.----|----.----|---x.xxxx|
#define SPY_STATUS3_CANFD_ESI 0x01 // CAN FD Error State Indicator (ESI) reflects the error state of the transmitting node
#define SPY_STATUS3_CANFD_IDE 0x02 // CAN FD Identifier Extension (IDE) indicates if standard or extended IDs are in use
#define SPY_STATUS3_CANFD_RTR 0x04
#define SPY_STATUS3_CANFD_FDF 0x08 // CAN FD Format (FDF) flag -- distinguishes classic CAN from CANFD
#define SPY_STATUS3_CANFD_BRS 0x10 // CANFD Baud Rate Select (BRS) flag, indicates if the data portion transmits at a higher bitrate
// SPYSTATUS3 - ETHERNET protocol bits
// |----.----|----.----|----.----|----.--xx|
#define SPY_STATUS3_ETHERNET_TX_COLLISION 0x01
#define SPY_STATUS3_ETHERNET_T1S_WAKE 0x02
// SPYSTATUS3 - LIN protocol bits
// |----.----|----.----|----.----|----.-xxx|
#define SPY_STATUS3_LIN_JUST_BREAK_SYNC 0x01
#define SPY_STATUS3_LIN_SLAVE_DATA_TOO_SHORT 0x02
#define SPY_STATUS3_LIN_ONLY_UPDATE_SLAVE_TABLE_ONCE 0x04
// SPYSTATUS4 bit definitions
// SPYSTATUS4 - ETHERNET protocol bits
// |----.----|----.----|----.----|----.--xx|
#define SPY_STATUS4_ETH_CRC_ERROR 0x01 // Ethernet CRC error
#define SPY_STATUS4_ETH_FRAME_TOO_LONG 0x02 // Ethernet frame too long
#endif // CICSSPYSTATUSBITS_H_
+16
View File
@@ -6,6 +6,22 @@
namespace icsneo {
enum class Command : uint8_t {
// Device-originated Main51 event/error notifications (device -> host)
Main51RxBufferOverflow = 0x01,
Main51StartCmd = 0x02,
Main51TxFifoOverflow = 0x03,
Main51BulkInNoData = 0x04,
Main51SetModeComplete = 0x05,
Main51ReadEeprom = 0x06,
// 0x07, 0x08, 0x09 reserved for host->device commands below
Main51CmdDone = 0x0A,
Main51ErrStatus = 0x0B,
Main51ReadSectorBuff = 0x0C,
Main51WriteSectorBuff = 0x0D,
Main51MmcProcessDone = 0x0E,
Main51ReInitDone = 0x0F,
// Host-originated commands (host -> device)
EnableNetworkCommunication = 0x07,
EnableNetworkCommunicationEx = 0x08,
KeepAlive = 0x09,
@@ -4,6 +4,7 @@
#ifdef __cplusplus
#include "icsneo/communication/message/message.h"
#include "icsneo/icsneoc2types.h"
#include <unordered_set>
#include <memory>
#include "icsneo/api/eventmanager.h"
@@ -11,57 +12,57 @@
namespace icsneo {
enum class AppErrorType : uint16_t {
AppErrorRxMessagesFull = 0,
AppErrorTxMessagesFull = 1,
AppErrorTxReportMessagesFull = 2,
AppErrorBadCommWithDspIC = 3,
AppErrorDriverOverflow = 4,
AppErrorPCBuffOverflow = 5,
AppErrorPCChksumError = 6,
AppErrorPCMissedByte = 7,
AppErrorPCOverrunError = 8,
AppErrorSettingFailure = 9,
AppErrorTooManySelectedNetworks = 10,
AppErrorNetworkNotEnabled = 11,
AppErrorRtcNotCorrect = 12,
AppErrorLoadedDefaultSettings = 13,
AppErrorFeatureNotUnlocked = 14,
AppErrorFeatureRtcCmdDropped = 15,
AppErrorTxMessagesFlushed = 16,
AppErrorTxMessagesHalfFull = 17,
AppErrorNetworkNotValid = 18,
AppErrorTxInterfaceNotImplemented = 19,
AppErrorTxMessagesCommEnableIsOff = 20,
AppErrorRxFilterMatchCountExceeded = 21,
AppErrorEthPreemptionNotEnabled = 22,
AppErrorTxNotSupportedInMode = 23,
AppErrorJumboFramesNotSupported = 24,
AppErrorEthernetIpFragment = 25,
AppErrorTxMessagesUnderrun = 26,
AppErrorDeviceFanFailure = 27,
AppErrorDeviceOvertemperature = 28,
AppErrorTxMessageIndexOutOfRange = 29,
AppErrorUndersizedFrameDropped = 30,
AppErrorOversizedFrameDropped = 31,
AppErrorWatchdogEvent = 32,
AppErrorSystemClockFailure = 33,
AppErrorSystemClockRecovered = 34,
AppErrorSystemPeripheralReset = 35,
AppErrorSystemCommunicationFailure = 36,
AppErrorTxMessagesUnsupportedSourceOrPacketId = 37,
AppErrorWbmsManagerConnectFailed = 38,
AppErrorWbmsManagerConnectBadState = 39,
AppErrorWbmsManagerConnectTimeout = 40,
AppErrorFailedToInitializeLoggerDisk = 41,
AppErrorInvalidSetting = 42,
AppErrorSystemFailureRequestedReset = 43,
AppErrorPortKeyMistmatch = 45,
AppErrorBusFailure = 46,
AppErrorTapOverflow = 47,
AppErrorEthTxNoLink = 48,
AppErrorErrorBufferOverflow = 254,
AppNoError = 255
enum class AppErrorType : icsneoc2_app_error_type_t {
AppErrorRxMessagesFull = icsneoc2_app_error_type_rx_messages_full,
AppErrorTxMessagesFull = icsneoc2_app_error_type_tx_messages_full,
AppErrorTxReportMessagesFull = icsneoc2_app_error_type_tx_report_messages_full,
AppErrorBadCommWithDspIC = icsneoc2_app_error_type_bad_comm_with_dsp_ic,
AppErrorDriverOverflow = icsneoc2_app_error_type_driver_overflow,
AppErrorPCBuffOverflow = icsneoc2_app_error_type_pc_buff_overflow,
AppErrorPCChksumError = icsneoc2_app_error_type_pc_chksum_error,
AppErrorPCMissedByte = icsneoc2_app_error_type_pc_missed_byte,
AppErrorPCOverrunError = icsneoc2_app_error_type_pc_overrun_error,
AppErrorSettingFailure = icsneoc2_app_error_type_setting_failure,
AppErrorTooManySelectedNetworks = icsneoc2_app_error_type_too_many_selected_networks,
AppErrorNetworkNotEnabled = icsneoc2_app_error_type_network_not_enabled,
AppErrorRtcNotCorrect = icsneoc2_app_error_type_rtc_not_correct,
AppErrorLoadedDefaultSettings = icsneoc2_app_error_type_loaded_default_settings,
AppErrorFeatureNotUnlocked = icsneoc2_app_error_type_feature_not_unlocked,
AppErrorFeatureRtcCmdDropped = icsneoc2_app_error_type_feature_rtc_cmd_dropped,
AppErrorTxMessagesFlushed = icsneoc2_app_error_type_tx_messages_flushed,
AppErrorTxMessagesHalfFull = icsneoc2_app_error_type_tx_messages_half_full,
AppErrorNetworkNotValid = icsneoc2_app_error_type_network_not_valid,
AppErrorTxInterfaceNotImplemented = icsneoc2_app_error_type_tx_interface_not_implemented,
AppErrorTxMessagesCommEnableIsOff = icsneoc2_app_error_type_tx_messages_comm_enable_is_off,
AppErrorRxFilterMatchCountExceeded = icsneoc2_app_error_type_rx_filter_match_count_exceeded,
AppErrorEthPreemptionNotEnabled = icsneoc2_app_error_type_eth_preemption_not_enabled,
AppErrorTxNotSupportedInMode = icsneoc2_app_error_type_tx_not_supported_in_mode,
AppErrorJumboFramesNotSupported = icsneoc2_app_error_type_jumbo_frames_not_supported,
AppErrorEthernetIpFragment = icsneoc2_app_error_type_ethernet_ip_fragment,
AppErrorTxMessagesUnderrun = icsneoc2_app_error_type_tx_messages_underrun,
AppErrorDeviceFanFailure = icsneoc2_app_error_type_device_fan_failure,
AppErrorDeviceOvertemperature = icsneoc2_app_error_type_device_overtemperature,
AppErrorTxMessageIndexOutOfRange = icsneoc2_app_error_type_tx_message_index_out_of_range,
AppErrorUndersizedFrameDropped = icsneoc2_app_error_type_undersized_frame_dropped,
AppErrorOversizedFrameDropped = icsneoc2_app_error_type_oversized_frame_dropped,
AppErrorWatchdogEvent = icsneoc2_app_error_type_watchdog_event,
AppErrorSystemClockFailure = icsneoc2_app_error_type_system_clock_failure,
AppErrorSystemClockRecovered = icsneoc2_app_error_type_system_clock_recovered,
AppErrorSystemPeripheralReset = icsneoc2_app_error_type_system_peripheral_reset,
AppErrorSystemCommunicationFailure = icsneoc2_app_error_type_system_communication_failure,
AppErrorTxMessagesUnsupportedSourceOrPacketId = icsneoc2_app_error_type_tx_messages_unsupported_source_or_packet_id,
AppErrorWbmsManagerConnectFailed = icsneoc2_app_error_type_wbms_manager_connect_failed,
AppErrorWbmsManagerConnectBadState = icsneoc2_app_error_type_wbms_manager_connect_bad_state,
AppErrorWbmsManagerConnectTimeout = icsneoc2_app_error_type_wbms_manager_connect_timeout,
AppErrorFailedToInitializeLoggerDisk = icsneoc2_app_error_type_failed_to_initialize_logger_disk,
AppErrorInvalidSetting = icsneoc2_app_error_type_invalid_setting,
AppErrorSystemFailureRequestedReset = icsneoc2_app_error_type_system_failure_requested_reset,
AppErrorPortKeyMistmatch = icsneoc2_app_error_type_port_key_mistmatch,
AppErrorBusFailure = icsneoc2_app_error_type_bus_failure,
AppErrorTapOverflow = icsneoc2_app_error_type_tap_overflow,
AppErrorEthTxNoLink = icsneoc2_app_error_type_eth_tx_no_link,
AppErrorErrorBufferOverflow = icsneoc2_app_error_type_error_buffer_overflow,
AppNoError = icsneoc2_app_error_type_no_error
};
class AppErrorMessage : public RawMessage {
@@ -4,37 +4,41 @@
#ifdef __cplusplus
#include "icsneo/communication/message/message.h"
#include "icsneo/icsneoc2types.h"
#include <memory>
namespace icsneo {
class EthernetStatusMessage : public Message {
class EthernetStatusMessage : public RawMessage {
public:
enum class LinkSpeed {
LinkSpeedAuto,
LinkSpeed10,
LinkSpeed100,
LinkSpeed1000,
LinkSpeed2500,
LinkSpeed5000,
LinkSpeed10000,
enum class LinkSpeed: icsneoc2_link_speed_t {
LinkSpeedAuto = icsneoc2_link_speed_auto,
LinkSpeed10 = icsneoc2_link_speed_10mbps,
LinkSpeed100 = icsneoc2_link_speed_100mbps,
LinkSpeed1000 = icsneoc2_link_speed_1000mbps,
LinkSpeed2500 = icsneoc2_link_speed_2500mbps,
LinkSpeed5000 = icsneoc2_link_speed_5000mbps,
LinkSpeed10000 = icsneoc2_link_speed_10000mbps,
};
enum class LinkMode {
LinkModeAuto,
LinkModeMaster,
LinkModeSlave,
LinkModeInvalid,
LinkModeNone,
enum class LinkMode: icsneoc2_link_mode_t {
LinkModeAuto = icsneoc2_link_mode_auto,
LinkModeMaster = icsneoc2_link_mode_master,
LinkModeSlave = icsneoc2_link_mode_slave,
LinkModeInvalid = icsneoc2_link_mode_invalid,
LinkModeNone = icsneoc2_link_mode_none,
};
EthernetStatusMessage(Network net, bool state, LinkSpeed speed, bool duplex, LinkMode mode) : Message(Type::EthernetStatus),
network(net), state(state), speed(speed), duplex(duplex), mode(mode) {}
Network network;
EthernetStatusMessage(Network net, bool state, LinkSpeed speed, bool duplex, LinkMode mode) : RawMessage(Type::EthernetStatus, net),
state(state), speed(speed), duplex(duplex), mode(mode) {}
// Link State: False = Link Down, True = Link Up
bool state;
LinkSpeed speed;
// Duplex: False = Half, True = Full
bool duplex;
LinkMode mode;
static std::shared_ptr<Message> DecodeToMessage(const std::vector<uint8_t>& bytestream);
static std::shared_ptr<RawMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
};
}; // namespace icsneo
+10 -1
View File
@@ -231,9 +231,18 @@ public:
enum class OpenStatusType {
QuestionContinueSkipCancel,
QuestionContinueCancel,
Progress
Progress,
Failed
};
/**
* @brief Alias of callback function for progress of a bootloader pipeline task
*
* The progress value passed into the callback function indicates the following:
* 1) If the value is std::nullopt, this implies the status message is for an asynchronous task or a task in which the current progress is unknown.
* 2) If the value is between 0 and 1 (i.e., 0 <= progress <= 1), this implies the actual progress of the current task as a percentage.
* 3) Values not between 0 and 1 (i.e., progress < 0 or progress > 1) are undefined.
*/
using OpenStatusHandler = std::function<Device::OpenDirective(OpenStatusType type, const std::string& status, std::optional<double> progress)>;
bool open(OpenFlags flags = {}, OpenStatusHandler handler =
@@ -71,6 +71,7 @@ public:
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application, true, false)
.add<FlashPhase>(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application, false, true)
.add<FlashPhase>(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application, false, false, false)
@@ -262,18 +262,29 @@ public:
}
virtual std::vector<TerminationGroup> getTerminationGroups() const override {
// FIRE3 has two physical termination banks: DW CAN 01-08 and DW CAN 09-16.
// Termination within a bank is actually independent (any number may be
// enabled at once).
return {
{
Network(Network::NetID::DWCAN_01),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_07)
Network(Network::NetID::DWCAN_06),
Network(Network::NetID::DWCAN_07),
Network(Network::NetID::DWCAN_08)
},
{
Network(Network::NetID::DWCAN_08),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_06)
Network(Network::NetID::DWCAN_09),
Network(Network::NetID::DWCAN_10),
Network(Network::NetID::DWCAN_11),
Network(Network::NetID::DWCAN_12),
Network(Network::NetID::DWCAN_13),
Network(Network::NetID::DWCAN_14),
Network(Network::NetID::DWCAN_15),
Network(Network::NetID::DWCAN_16)
}
};
}
@@ -74,6 +74,7 @@ public:
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application, true, false)
.add<FlashPhase>(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application, false, true)
.add<FlashPhase>(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application, false, false, false)
@@ -213,18 +213,28 @@ public:
}
virtual std::vector<TerminationGroup> getTerminationGroups() const override {
// FIRE3 FlexRay has two physical termination banks: DW CAN 01-08 and
// DW CAN 09-15 (DW CAN 16 is used by FlexRay). Termination within a bank is
// actually independent (any number may be enabled at once).
return {
{
Network(Network::NetID::DWCAN_01),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_07)
Network(Network::NetID::DWCAN_06),
Network(Network::NetID::DWCAN_07),
Network(Network::NetID::DWCAN_08)
},
{
Network(Network::NetID::DWCAN_08),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_06)
Network(Network::NetID::DWCAN_09),
Network(Network::NetID::DWCAN_10),
Network(Network::NetID::DWCAN_11),
Network(Network::NetID::DWCAN_12),
Network(Network::NetID::DWCAN_13),
Network(Network::NetID::DWCAN_14),
Network(Network::NetID::DWCAN_15)
}
};
}
@@ -79,6 +79,7 @@ public:
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application, true, false)
.add<FlashPhase>(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application, false, true)
.add<FlashPhase>(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application, false, false, false)
@@ -222,18 +222,19 @@ public:
}
virtual std::vector<TerminationGroup> getTerminationGroups() const override {
// FIRE3 T1S-LIN has a single physical termination bank: DW CAN 01-08.
// Termination within the bank is actually independent (any number may be
// enabled at once).
return {
{
Network(Network::NetID::DWCAN_01),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_07)
},
{
Network(Network::NetID::DWCAN_08),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_06)
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_06),
Network(Network::NetID::DWCAN_07),
Network(Network::NetID::DWCAN_08)
}
};
}
@@ -56,6 +56,7 @@ public:
BootloaderPipeline getBootloader() override {
return BootloaderPipeline()
.add<EnterBootloaderPhase>()
.add<FlashPhase>(ChipID::neoVIFIRE3_ZCHIP, BootloaderCommunication::Application, true, false)
.add<FlashPhase>(ChipID::neoVIFIRE3_SCHIP, BootloaderCommunication::Application, false, true)
.add<FlashPhase>(ChipID::neoVIFIRE3_LINUX, BootloaderCommunication::Application, false, false, false)
@@ -175,18 +175,19 @@ public:
}
virtual std::vector<TerminationGroup> getTerminationGroups() const override {
// RED2 has a single physical termination bank: DW CAN 01-08. Termination
// within the bank is actually independent (any number may be enabled at
// once).
return {
{
Network(Network::NetID::DWCAN_01),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_07)
},
{
Network(Network::NetID::DWCAN_08),
Network(Network::NetID::DWCAN_02),
Network(Network::NetID::DWCAN_03),
Network(Network::NetID::DWCAN_04),
Network(Network::NetID::DWCAN_06)
Network(Network::NetID::DWCAN_05),
Network(Network::NetID::DWCAN_06),
Network(Network::NetID::DWCAN_07),
Network(Network::NetID::DWCAN_08)
}
};
}
@@ -42,6 +42,8 @@ public:
size_t getEthernetActivationLineCount() const override { return 1; }
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADA2B;
}
@@ -47,6 +47,8 @@ public:
bool supportsTC10() const override { return true; }
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADComet2;
}
@@ -54,6 +54,8 @@ public:
bool supportsTC10() const override { return true; }
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADComet3;
}
@@ -63,6 +63,7 @@ public:
size_t getEthernetActivationLineCount() const override { return 1; }
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADGalaxy;
@@ -71,6 +71,8 @@ public:
bool supportsTC10() const override { return true; }
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADGalaxy2;
}
@@ -24,6 +24,8 @@ public:
bool supportsTC10() const override { return true; }
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADGigastar;
}
@@ -89,6 +89,8 @@ public:
bool supportsTC10() const override { return true; }
bool supportsGPTP() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADGigastar2;
}
@@ -59,6 +59,9 @@ public:
bool getEthPhyRegControlSupported() const override { return true; }
// Covers RADMoon2 and RADMoon2ZL; firmware reboots and ignores the safe flag
bool supportsReboot() const override { return true; }
virtual uint8_t getPhyAddrOrPort() const = 0;
protected:
@@ -30,6 +30,8 @@ public:
bool supportsTC10() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADMoon3;
}
@@ -34,6 +34,8 @@ public:
bool supportsTC10() const override { return true; }
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADMoonT1S;
}
@@ -32,6 +32,8 @@ public:
return supportedNetworks;
}
bool supportsReboot() const override { return true; }
ProductID getProductID() const override {
return ProductID::RADStar2;
}
+2 -1
View File
@@ -18,7 +18,8 @@ enum class DiskLayout : uint8_t {
struct DiskInfo {
bool present; // Disk is connected
bool initialized; // Disk is initialized
bool formatted; // Disk is formatted
// getDiskDetails: disk is formatted | formatDisk: disk to format | forceDiskConfigUpdate: disk enabled in layout (also reported as formatted)
bool formatted;
uint64_t sectors;
uint32_t bytesPerSector;
+1511 -1677
View File
File diff suppressed because it is too large Load Diff
+19
View File
@@ -47,6 +47,7 @@ typedef enum _icsneoc2_error_t {
icsneoc2_error_close_failed, // Failed to close device
icsneoc2_error_reconnect_failed, // Failed to reconnect to device
icsneoc2_error_invalid_data, // Failed to get/set data due to invalid data pointer or size
icsneoc2_error_force_disk_config_update_failed, // Failed to force a disk config update
// NOTE: Any new values added here should be updated in icsneoc2_error_code_get
icsneoc2_error_maxsize
} _icsneoc2_error_t;
@@ -846,6 +847,24 @@ icsneoc2_error_t icsneoc2_disk_details_full_format_set(const icsneoc2_disk_detai
*/
icsneoc2_error_t icsneoc2_device_format_disk(const icsneoc2_device_t* device, icsneoc2_disk_details_t* disk_details, icsneoc2_disk_format_progress_fn progress_callback, void* user_data);
/**
* Force a disk layout/configuration change on a device without formatting.
*
* Unlike icsneoc2_device_format_disk(), this applies the configuration described by the
* disk details handle (such as the disk layout) and enables the change without erasing data.
*
* @param[in] device The device whose disk configuration should be updated.
* @param[in] disk_details A disk details handle describing the desired configuration.
* Use icsneoc2_device_disk_details_get() to obtain a handle, then modify it
* (e.g. set the layout with icsneoc2_disk_details_layout_set()).
* In this context the per-disk ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED flag
* selects whether that disk is enabled in the layout (no formatting occurs).
*
* @return icsneoc2_error_t icsneoc2_error_success if successful,
* icsneoc2_error_force_disk_config_update_failed otherwise.
*/
icsneoc2_error_t icsneoc2_device_force_disk_config_update(const icsneoc2_device_t* device, icsneoc2_disk_details_t* disk_details);
/**
* Get the list of networks this device supports for receiving.
*
+60 -5
View File
@@ -298,10 +298,32 @@ icsneoc2_error_t icsneoc2_message_eth_t1s_props_get(icsneoc2_message_t* message,
*/
icsneoc2_error_t icsneoc2_message_is_ethernet(icsneoc2_message_t* message, bool* is_ethernet);
/**
* Check if a message is an Ethernet status message
*
* @param[in] message The message to check.
* @param[out] is_ethernet_status Pointer to a bool to copy the Ethernet status of the message into.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_message_is_ethernet_status(icsneoc2_message_t* message, bool* is_ethernet_status);
/**
* Get the Ethernet status properties from an Ethernet status message
*
* @param[in] message The message to check.
* @param[out] link_state Pointer to a bool to copy the link state into. True if the link is up, false if it's down. If NULL, it's ignored.
* @param[out] duplex Pointer to a bool to copy the duplex state into. True if the link is full duplex, false if it's half duplex. If NULL, it's ignored.
* @param[out] link_speed Pointer to a icsneoc2_link_speed_t to copy the link speed into. If NULL, it's ignored.
* @param[out] link_mode Pointer to a icsneoc2_link_mode_t to copy the link mode into. If NULL, it's ignored.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters, icsneoc2_error_invalid_type otherwise.
*/
icsneoc2_error_t icsneoc2_message_eth_status_props_get(icsneoc2_message_t* message, bool* link_state, bool* duplex, icsneoc2_link_speed_t* link_speed, icsneoc2_link_mode_t* link_mode);
/**
* Check if a message is valid
*
* @param[in] device The device to check against.
* @param[in] message The message to check.
* @param[out] is_valid Pointer to a bool to copy the validity of the message into.
*
@@ -312,7 +334,6 @@ icsneoc2_error_t icsneoc2_message_is_valid(icsneoc2_message_t* message, bool* is
/**
* Check if a message is a raw message (message with data)
*
* @param[in] device The device to check against.
* @param[in] message The message to check.
* @param[out] is_raw Pointer to a bool to copy the raw status of the message into.
*
@@ -323,7 +344,6 @@ icsneoc2_error_t icsneoc2_message_is_raw(icsneoc2_message_t* message, bool* is_r
/**
* Check if a message is a frame message (message with data)
*
* @param[in] device The device to check against.
* @param[in] message The message to check.
* @param[out] is_frame Pointer to a bool to copy the frame status of the message into.
*
@@ -333,8 +353,7 @@ icsneoc2_error_t icsneoc2_message_is_frame(icsneoc2_message_t* message, bool* is
/**
* Check if a message is a CAN message
*
* @param[in] device The device to check against.
*
* @param[in] message The message to check.
* @param[out] is_can Pointer to a bool to copy the CAN status of the message into.
*
@@ -516,6 +535,42 @@ icsneoc2_error_t icsneoc2_message_can_error_props_get(
icsneoc2_can_error_code_t *data_error_code,
icsneoc2_message_can_error_flags_t *flags);
/**
* Check if a message is an application error message
*
* @param[in] message The message to check.
* @param[out] is_app_error Pointer to a bool to copy the app error status of the message into.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_message_is_app_error(icsneoc2_message_t* message, bool* is_app_error);
/**
* Get the application error specific properties of a message
*
* @param[in] message The message to check.
* @param[out] error_type Pointer to a icsneoc2_app_error_type_t to copy the error type into. If NULL, it's ignored.
* @param[out] error_netid Pointer to a icsneoc2_netid_t to copy the associated network ID into. If NULL, it's ignored.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_invalid_type otherwise.
*
* @see icsneoc2_app_error_type_t, icsneoc2_message_app_error_string_get
*/
icsneoc2_error_t icsneoc2_message_app_error_props_get(icsneoc2_message_t* message,
icsneoc2_app_error_type_t* error_type, icsneoc2_netid_t* error_netid);
/**
* Get a human-readable description string for an application error message
*
* @param[in] message The message to check.
* @param[out] value Pointer to a char buffer to copy the description into.
* @param[in,out] value_length On input, the size of the value buffer; on output, the length of the copied string.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters, icsneoc2_error_invalid_type, or icsneoc2_error_string_copy_failed otherwise.
*/
icsneoc2_error_t icsneoc2_message_app_error_string_get(icsneoc2_message_t* message,
char* value, size_t* value_length);
#ifdef __cplusplus
}
#endif
+55 -1
View File
@@ -140,7 +140,61 @@ icsneoc2_error_t icsneoc2_settings_termination_is_enabled(icsneoc2_device_t* dev
*/
icsneoc2_error_t icsneoc2_settings_termination_set(icsneoc2_device_t* device, icsneoc2_netid_t netid, bool enable);
// TODO: getTerminationGroups
/**
* Enumerate the termination groups for a device.
*
* Some devices have groupings of networks where software switchable termination
* can only be applied to one network in the group at a time. This enumerates
* those groups. Use icsneoc2_termination_group_next() to walk the list and
* icsneoc2_termination_group_networks_get() to read each group's networks.
*
* These groups apply to the CAN termination controlled by the
* icsneoc2_settings_termination_* functions. 10BASE-T1S termination
* (icsneoc2_settings_t1s_*) is per-network and is never grouped.
*
* If the device does not support software switchable termination, the list is
* empty (*groups is set to NULL and *count, if provided, is set to 0).
*
* @param[in] device The device to query.
* @param[out] groups Receives a newly allocated termination group handle, or NULL if there are no groups. The caller owns this handle and must free it with icsneoc2_settings_termination_groups_free() when done.
* @param[out] count Receives the number of termination groups. May be NULL if not needed.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_out_of_memory otherwise.
*/
icsneoc2_error_t icsneoc2_settings_termination_groups_enumerate(icsneoc2_device_t* device, icsneoc2_termination_group_t** groups, size_t* count);
/**
* Advance to the next termination group in an enumeration list.
*
* @param[in] group The current termination group handle.
*
* @return The next termination group handle, or NULL at the end of the list.
*/
icsneoc2_termination_group_t* icsneoc2_termination_group_next(const icsneoc2_termination_group_t* group);
/**
* Get the networks belonging to a termination group.
*
* Call with networks set to NULL to query the number of networks in the group;
* *count will be set to the required size. Then call again with a buffer of at
* least that size. On success *count is updated with the number of netids written.
*
* @param[in] group The termination group handle to query.
* @param[out] networks Pointer to a buffer to copy the group's netids into. May be NULL to query the required size.
* @param[in,out] count On input, the capacity of the networks buffer. On output, the number of netids written (or required, if networks is NULL).
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_termination_group_networks_get(const icsneoc2_termination_group_t* group, icsneoc2_netid_t* networks, size_t* count);
/**
* Free a termination group list returned by icsneoc2_settings_termination_groups_enumerate().
*
* @param[in] groups The termination group handle to free. Passing NULL returns icsneoc2_error_invalid_parameters.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_settings_termination_groups_free(icsneoc2_termination_group_t* groups);
/**
* Check if the commander resistor is currently enabled for a network.
+86 -1
View File
@@ -413,7 +413,7 @@ typedef uint8_t icsneoc2_disk_layout_t;
#define ICSNEOC2_DISK_FORMAT_FLAGS_PRESENT 0x1 // Indicates that the disk is present
#define ICSNEOC2_DISK_FORMAT_FLAGS_INITIALIZED 0x2 // Indicates that the disk is initialized
#define ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED 0x4 // Indicates that the disk is already formatted
#define ICSNEOC2_DISK_FORMAT_FLAGS_FORMATTED 0x4 // disk_details_get: disk is formatted | format_disk: disk to format | force_disk_config_update: disk enabled in layout (also reported as formatted)
typedef uint32_t icsneoc2_disk_format_flags_t;
@@ -465,6 +465,61 @@ typedef uint8_t icsneoc2_can_error_code_t;
#define ICSNEOC2_MESSAGE_CAN_ERROR_FLAGS_ERROR_PASSIVE 0x02 // Error passive state
#define ICSNEOC2_MESSAGE_CAN_ERROR_FLAGS_ERROR_WARN 0x04 // Error warning state
typedef enum _icsneoc2_app_error_type_t {
icsneoc2_app_error_type_rx_messages_full = 0,
icsneoc2_app_error_type_tx_messages_full = 1,
icsneoc2_app_error_type_tx_report_messages_full = 2,
icsneoc2_app_error_type_bad_comm_with_dsp_ic = 3,
icsneoc2_app_error_type_driver_overflow = 4,
icsneoc2_app_error_type_pc_buff_overflow = 5,
icsneoc2_app_error_type_pc_chksum_error = 6,
icsneoc2_app_error_type_pc_missed_byte = 7,
icsneoc2_app_error_type_pc_overrun_error = 8,
icsneoc2_app_error_type_setting_failure = 9,
icsneoc2_app_error_type_too_many_selected_networks = 10,
icsneoc2_app_error_type_network_not_enabled = 11,
icsneoc2_app_error_type_rtc_not_correct = 12,
icsneoc2_app_error_type_loaded_default_settings = 13,
icsneoc2_app_error_type_feature_not_unlocked = 14,
icsneoc2_app_error_type_feature_rtc_cmd_dropped = 15,
icsneoc2_app_error_type_tx_messages_flushed = 16,
icsneoc2_app_error_type_tx_messages_half_full = 17,
icsneoc2_app_error_type_network_not_valid = 18,
icsneoc2_app_error_type_tx_interface_not_implemented = 19,
icsneoc2_app_error_type_tx_messages_comm_enable_is_off = 20,
icsneoc2_app_error_type_rx_filter_match_count_exceeded = 21,
icsneoc2_app_error_type_eth_preemption_not_enabled = 22,
icsneoc2_app_error_type_tx_not_supported_in_mode = 23,
icsneoc2_app_error_type_jumbo_frames_not_supported = 24,
icsneoc2_app_error_type_ethernet_ip_fragment = 25,
icsneoc2_app_error_type_tx_messages_underrun = 26,
icsneoc2_app_error_type_device_fan_failure = 27,
icsneoc2_app_error_type_device_overtemperature = 28,
icsneoc2_app_error_type_tx_message_index_out_of_range = 29,
icsneoc2_app_error_type_undersized_frame_dropped = 30,
icsneoc2_app_error_type_oversized_frame_dropped = 31,
icsneoc2_app_error_type_watchdog_event = 32,
icsneoc2_app_error_type_system_clock_failure = 33,
icsneoc2_app_error_type_system_clock_recovered = 34,
icsneoc2_app_error_type_system_peripheral_reset = 35,
icsneoc2_app_error_type_system_communication_failure = 36,
icsneoc2_app_error_type_tx_messages_unsupported_source_or_packet_id = 37,
icsneoc2_app_error_type_wbms_manager_connect_failed = 38,
icsneoc2_app_error_type_wbms_manager_connect_bad_state = 39,
icsneoc2_app_error_type_wbms_manager_connect_timeout = 40,
icsneoc2_app_error_type_failed_to_initialize_logger_disk = 41,
icsneoc2_app_error_type_invalid_setting = 42,
icsneoc2_app_error_type_system_failure_requested_reset = 43,
icsneoc2_app_error_type_port_key_mistmatch = 45,
icsneoc2_app_error_type_bus_failure = 46,
icsneoc2_app_error_type_tap_overflow = 47,
icsneoc2_app_error_type_eth_tx_no_link = 48,
icsneoc2_app_error_type_error_buffer_overflow = 254,
icsneoc2_app_error_type_no_error = 255
} _icsneoc2_app_error_type_t;
typedef uint16_t icsneoc2_app_error_type_t;
typedef uint64_t icsneoc2_message_can_error_flags_t;
typedef enum _icsneoc2_tc10_wake_status_t {
@@ -491,6 +546,8 @@ typedef uint8_t icsneoc2_tc10_sleep_status_t;
typedef struct icsneoc2_chip_versions_t icsneoc2_chip_versions_t;
typedef struct icsneoc2_termination_group_t icsneoc2_termination_group_t;
typedef enum _icsneoc2_chip_id_t {
icsneoc2_chip_id_neovifire_mchip = 0,
icsneoc2_chip_id_neovifire_lchip = 1,
@@ -628,6 +685,34 @@ typedef enum _icsneoc2_chip_id_t {
typedef uint8_t icsneoc2_chip_id_t;
typedef enum _icsneoc2_link_speed_t {
icsneoc2_link_speed_auto = 0,
icsneoc2_link_speed_10mbps,
icsneoc2_link_speed_100mbps,
icsneoc2_link_speed_1000mbps,
icsneoc2_link_speed_2500mbps,
icsneoc2_link_speed_5000mbps,
icsneoc2_link_speed_10000mbps,
// Must be last entry.
icsneoc2_link_speed_maxsize
} _icsneoc2_link_speed_t;
typedef uint8_t icsneoc2_link_speed_t;
typedef enum _icsneoc2_link_mode_t {
icsneoc2_link_mode_auto = 0,
icsneoc2_link_mode_master,
icsneoc2_link_mode_slave,
icsneoc2_link_mode_invalid,
icsneoc2_link_mode_none,
// Must be last entry.
icsneoc2_link_mode_maxsize
} _icsneoc2_link_mode_t;
typedef uint8_t icsneoc2_link_mode_t;
typedef struct icsneoc2_mac_addr_entry_t icsneoc2_mac_addr_entry_t;
#ifdef __cplusplus
+21
View File
@@ -9,6 +9,27 @@
typedef uint8_t byte; // Typedef helper for the following include
#include "icsneo/icsnVC40.h" // Definitions for structs
// Vehicle Spy 3.26.3.9 removed these legacy settings structure definitions from
// icsnVC40.h. The corresponding functions only ever treat them as opaque
// buffers, so forward declarations keep the existing API/ABI intact.
typedef struct _SFireSettings SFireSettings;
typedef struct _SVCAN3Settings SVCAN3Settings;
typedef struct _SVCANRFSettings SVCANRFSettings;
// Vehicle Spy 3.26.3.9 moved icsSpyTime out of icsnVC40.h; icsneoGetRTC and
// icsneoSetRTC access its members, so the definition (identical layout, 6
// bytes) is carried here.
typedef struct
{
uint8_t sec; // --- Seconds (00-59)
uint8_t min; // --- (00-59)
uint8_t hour; // --- (00-23)
uint8_t day; // --- (01-31)
uint8_t month; // --- (01-12)
uint8_t year; // --- (00-99)
} icsSpyTime;
#define icsSpyTime_SIZE 6
// From coremini.h
#define MAX_BIT_SMASH_ARBIDS (4)
#define BIT_SMASH_OPTION_EXTENDED (1)
+314
View File
@@ -9,6 +9,9 @@
#include <icsneo/communication/message/linmessage.h>
#include <icsneo/communication/message/canmessage.h>
#include <icsneo/communication/message/canerrormessage.h>
#include <icsneo/communication/message/apperrormessage.h>
#include <icsneo/communication/message/ethernetstatusmessage.h>
#include <icsneo/communication/message/filter/messagefilter.h>
#include <vector>
@@ -174,6 +177,9 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_is_valid(NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_is_can_error(NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_can_error_props_get(NULL, NULL, NULL, NULL, NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_is_app_error(NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_app_error_props_get(NULL, NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_app_error_string_get(NULL, NULL, NULL));
// LIN message NULL parameter checks
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_is_lin(NULL, NULL));
@@ -255,6 +261,13 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_termination_can_enable(NULL, 0, &placeholderBool));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_termination_is_enabled(NULL, 0, &placeholderBool));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_termination_set(NULL, 0, false));
{
icsneoc2_termination_group_t* placeholderGroups = nullptr;
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_termination_groups_enumerate(NULL, &placeholderGroups, &placeholderSizeT));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_termination_group_networks_get(NULL, NULL, &placeholderSizeT));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_termination_groups_free(NULL));
ASSERT_EQ(nullptr, icsneoc2_termination_group_next(NULL));
}
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_commander_resistor_enabled(NULL, 0, &placeholderBool));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_commander_resistor_set(NULL, 0, false));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_lin_mode_get(NULL, 0, &placeholderLinMode));
@@ -332,6 +345,7 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_supports_disk_formatting(NULL, &placeholderBool));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_disk_details_get(NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_format_disk(NULL, NULL, NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_force_disk_config_update(NULL, NULL));
// Disk details accessors with NULL details
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_disk_details_count_get(NULL, &placeholderSizeT));
@@ -403,6 +417,8 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_eth_t1s_props_set(NULL, NULL, NULL, NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_eth_t1s_props_get(NULL, NULL, NULL, NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_is_ethernet(NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_is_ethernet_status(NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_eth_status_props_get(NULL, NULL, NULL, NULL, NULL));
}
TEST(icsneoc2, test_icsneoc2_devicetype_t)
@@ -1134,12 +1150,147 @@ TEST(icsneoc2, test_icsneoc2_chip_versions_free_list)
ASSERT_EQ(icsneoc2_error_success, icsneoc2_chip_versions_free(head));
}
TEST(icsneoc2, test_icsneoc2_termination_group_walk_and_networks)
{
// Build an in-memory list of two termination groups:
// group A: { DWCAN_01, DWCAN_02 }
// group B: { DWCAN_03 }
icsneoc2_termination_group_t second{};
second.netids = { icsneoc2_netid_dwcan_03 };
second.next = nullptr;
icsneoc2_termination_group_t first{};
first.netids = { icsneoc2_netid_dwcan_01, icsneoc2_netid_dwcan_02 };
first.next = &second;
// next() walks the list
ASSERT_EQ(&second, icsneoc2_termination_group_next(&first));
ASSERT_EQ(nullptr, icsneoc2_termination_group_next(&second));
// networks_get with NULL buffer reports the required count
size_t count = 0;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_termination_group_networks_get(&first, NULL, &count));
ASSERT_EQ(count, 2u);
// networks_get fills the buffer and updates count
icsneoc2_netid_t netids[2] = {0, 0};
count = 2;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_termination_group_networks_get(&first, netids, &count));
ASSERT_EQ(count, 2u);
ASSERT_EQ(netids[0], icsneoc2_netid_dwcan_01);
ASSERT_EQ(netids[1], icsneoc2_netid_dwcan_02);
// second group has a single network
count = 0;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_termination_group_networks_get(&second, NULL, &count));
ASSERT_EQ(count, 1u);
// a buffer smaller than the group truncates to capacity
icsneoc2_netid_t one[1] = {0};
count = 1;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_termination_group_networks_get(&first, one, &count));
ASSERT_EQ(count, 1u);
ASSERT_EQ(one[0], icsneoc2_netid_dwcan_01);
}
TEST(icsneoc2, test_icsneoc2_termination_groups_free_list)
{
// Allocate a two-node list the same way the API does, so free() walks and deletes it.
auto* head = new icsneoc2_termination_group_t{};
head->netids = { icsneoc2_netid_dwcan_01 };
head->next = new icsneoc2_termination_group_t{};
head->next->netids = { icsneoc2_netid_dwcan_02 };
head->next->next = nullptr;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_settings_termination_groups_free(head));
// Freeing an empty (NULL) list returns invalid_parameters, matching chip_versions_free.
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_termination_groups_free(nullptr));
}
TEST(icsneoc2, test_icsneoc2_open_options_default)
{
icsneoc2_open_options_t expected = ICSNEOC2_OPEN_OPTIONS_GO_ONLINE | ICSNEOC2_OPEN_OPTIONS_SYNC_RTC | ICSNEOC2_OPEN_OPTIONS_ENABLE_AUTO_UPDATE;
ASSERT_EQ(icsneoc2_open_options_default, expected);
}
TEST(icsneoc2, test_message_filter_c2_includes_internal_messages)
{
ASSERT_EQ(static_cast<neomessagetype_t>(icsneo::Message::Type::EthernetStatus), 0x8014);
auto ethernetStatus = std::make_shared<icsneo::EthernetStatusMessage>(
icsneo::Network::NetID::ETHERNET_01,
true,
icsneo::EthernetStatusMessage::LinkSpeed::LinkSpeed1000,
true,
icsneo::EthernetStatusMessage::LinkMode::LinkModeMaster
);
auto deviceMessage = std::make_shared<icsneo::RawMessage>(icsneo::Network::NetID::Device);
auto deviceStatusMessage = std::make_shared<icsneo::RawMessage>(icsneo::Network::NetID::DeviceStatus);
auto internalStatusMessage = std::make_shared<icsneo::Message>(icsneo::Message::Type::TC10Status);
auto canMessage = std::make_shared<icsneo::CANMessage>();
icsneo::MessageFilter defaultFilter;
ASSERT_FALSE(defaultFilter.match(ethernetStatus));
ASSERT_FALSE(defaultFilter.match(deviceMessage));
ASSERT_FALSE(defaultFilter.match(deviceStatusMessage));
ASSERT_FALSE(defaultFilter.match(internalStatusMessage));
ASSERT_TRUE(defaultFilter.match(canMessage));
icsneo::MessageFilter c2Filter;
c2Filter.includeInternalInAny = true;
ASSERT_TRUE(c2Filter.match(ethernetStatus));
ASSERT_TRUE(c2Filter.match(deviceMessage));
ASSERT_TRUE(c2Filter.match(deviceStatusMessage));
ASSERT_TRUE(c2Filter.match(internalStatusMessage));
ASSERT_TRUE(c2Filter.match(canMessage));
}
TEST(icsneoc2, test_icsneoc2_ethernet_status_props_get)
{
icsneoc2_message_t message;
message.message = std::make_shared<icsneo::EthernetStatusMessage>(
icsneo::Network::NetID::ETHERNET_01,
true,
icsneo::EthernetStatusMessage::LinkSpeed::LinkSpeed1000,
false,
icsneo::EthernetStatusMessage::LinkMode::LinkModeMaster
);
bool isEthernetStatus = false;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_is_ethernet_status(&message, &isEthernetStatus));
ASSERT_TRUE(isEthernetStatus);
bool linkState = false;
bool duplex = true;
icsneoc2_link_speed_t linkSpeed = icsneoc2_link_speed_auto;
icsneoc2_link_mode_t linkMode = icsneoc2_link_mode_auto;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_eth_status_props_get(&message, &linkState, &duplex, &linkSpeed, &linkMode));
ASSERT_TRUE(linkState);
ASSERT_FALSE(duplex);
ASSERT_EQ(linkSpeed, icsneoc2_link_speed_1000mbps);
ASSERT_EQ(linkMode, icsneoc2_link_mode_master);
icsneoc2_netid_t netid = icsneoc2_netid_invalid;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_netid_get(&message, &netid));
ASSERT_EQ(netid, icsneoc2_netid_ethernet_01);
size_t dataLength = 1;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_data_get(&message, nullptr, &dataLength));
ASSERT_EQ(dataLength, 0);
// A non-Ethernet-status message must be rejected by the props getter and
// reported as not-an-Ethernet-status by the predicate.
icsneoc2_message_t can_message;
can_message.message = std::make_shared<CANMessage>();
bool isEthernetStatusWrongType = true;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_is_ethernet_status(&can_message, &isEthernetStatusWrongType));
ASSERT_FALSE(isEthernetStatusWrongType);
ASSERT_EQ(icsneoc2_error_invalid_type, icsneoc2_message_eth_status_props_get(&can_message, &linkState, &duplex, &linkSpeed, &linkMode));
}
TEST(icsneoc2, test_icsneoc2_message_is_error)
{
icsneoc2_message_t message;
@@ -1223,6 +1374,51 @@ TEST(icsneoc2, test_icsneoc2_message_can_error_props_get_invalid_type_for_can_me
icsneoc2_message_can_error_props_get(&message, &tx_err_count, &rx_err_count, &error_code, &data_error_code, &flags));
}
TEST(icsneoc2, test_icsneoc2_message_app_error_props_get_invalid_type_for_can_message)
{
icsneoc2_message_t message;
message.message = std::make_shared<CANMessage>();
bool is_app_error = true;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_is_app_error(&message, &is_app_error));
ASSERT_FALSE(is_app_error);
icsneoc2_app_error_type_t error_type = icsneoc2_app_error_type_no_error;
icsneoc2_netid_t error_netid = 0;
ASSERT_EQ(icsneoc2_error_invalid_type,
icsneoc2_message_app_error_props_get(&message, &error_type, &error_netid));
}
TEST(icsneoc2, test_icsneoc2_message_app_error_props_get)
{
auto app_err = std::make_shared<icsneo::AppErrorMessage>();
app_err->errorType = icsneoc2_app_error_type_pc_buff_overflow;
app_err->errorNetID = icsneo::Network::NetID::DWCAN_01;
icsneoc2_message_t message;
message.message = app_err;
bool is_app_error = false;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_is_app_error(&message, &is_app_error));
ASSERT_TRUE(is_app_error);
icsneoc2_app_error_type_t error_type = icsneoc2_app_error_type_no_error;
icsneoc2_netid_t error_netid = 0;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_app_error_props_get(&message, &error_type, &error_netid));
ASSERT_EQ(error_type, icsneoc2_app_error_type_pc_buff_overflow);
ASSERT_EQ(error_netid, static_cast<icsneoc2_netid_t>(icsneo::Network::NetID::DWCAN_01));
// NULL out-params are ignored
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_app_error_props_get(&message, NULL, NULL));
// String getter returns the human-readable description
char buf[128] = {0};
size_t buf_len = sizeof(buf);
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_app_error_string_get(&message, buf, &buf_len));
ASSERT_STREQ(buf, "PC buffer overflow");
ASSERT_EQ(buf_len, sizeof("PC buffer overflow") - 1);
}
TEST(icsneoc2, test_icsneoc2_disk_format_enums)
{
// Disk layout enum values
@@ -1261,6 +1457,16 @@ TEST(icsneoc2, test_icsneoc2_format_disk_error_code)
ASSERT_STREQ(error_str, "Disk format failed");
}
TEST(icsneoc2, test_icsneoc2_force_disk_config_update_error_code)
{
// Verify the new error code exists and has a valid string
char error_str[64] = {0};
size_t error_str_len = sizeof(error_str);
ASSERT_EQ(icsneoc2_error_success, icsneoc2_error_code_get(icsneoc2_error_force_disk_config_update_failed, error_str, &error_str_len));
ASSERT_GT(error_str_len, 0u);
ASSERT_STREQ(error_str, "Force disk config update failed");
}
TEST(icsneoc2, test_icsneoc2_memory_type_enums)
{
// Memory type enum values should match Disk::MemoryType
@@ -1301,6 +1507,114 @@ TEST(icsneoc2, test_icsneoc2_can_error_code_t)
ASSERT_EQ(sizeof(icsneoc2_message_can_error_flags_t), sizeof(uint64_t));
}
TEST(icsneoc2, test_icsneoc2_app_error_type_t)
{
ASSERT_EQ(sizeof(icsneoc2_app_error_type_t), sizeof(uint16_t));
ASSERT_EQ(icsneoc2_app_error_type_rx_messages_full, 0);
ASSERT_EQ(icsneoc2_app_error_type_tx_messages_full, 1);
ASSERT_EQ(icsneoc2_app_error_type_tx_report_messages_full, 2);
ASSERT_EQ(icsneoc2_app_error_type_bad_comm_with_dsp_ic, 3);
ASSERT_EQ(icsneoc2_app_error_type_driver_overflow, 4);
ASSERT_EQ(icsneoc2_app_error_type_pc_buff_overflow, 5);
ASSERT_EQ(icsneoc2_app_error_type_pc_chksum_error, 6);
ASSERT_EQ(icsneoc2_app_error_type_pc_missed_byte, 7);
ASSERT_EQ(icsneoc2_app_error_type_pc_overrun_error, 8);
ASSERT_EQ(icsneoc2_app_error_type_setting_failure, 9);
ASSERT_EQ(icsneoc2_app_error_type_too_many_selected_networks, 10);
ASSERT_EQ(icsneoc2_app_error_type_network_not_enabled, 11);
ASSERT_EQ(icsneoc2_app_error_type_rtc_not_correct, 12);
ASSERT_EQ(icsneoc2_app_error_type_loaded_default_settings, 13);
ASSERT_EQ(icsneoc2_app_error_type_feature_not_unlocked, 14);
ASSERT_EQ(icsneoc2_app_error_type_feature_rtc_cmd_dropped, 15);
ASSERT_EQ(icsneoc2_app_error_type_tx_messages_flushed, 16);
ASSERT_EQ(icsneoc2_app_error_type_tx_messages_half_full, 17);
ASSERT_EQ(icsneoc2_app_error_type_network_not_valid, 18);
ASSERT_EQ(icsneoc2_app_error_type_tx_interface_not_implemented, 19);
ASSERT_EQ(icsneoc2_app_error_type_tx_messages_comm_enable_is_off, 20);
ASSERT_EQ(icsneoc2_app_error_type_rx_filter_match_count_exceeded, 21);
ASSERT_EQ(icsneoc2_app_error_type_eth_preemption_not_enabled, 22);
ASSERT_EQ(icsneoc2_app_error_type_tx_not_supported_in_mode, 23);
ASSERT_EQ(icsneoc2_app_error_type_jumbo_frames_not_supported, 24);
ASSERT_EQ(icsneoc2_app_error_type_ethernet_ip_fragment, 25);
ASSERT_EQ(icsneoc2_app_error_type_tx_messages_underrun, 26);
ASSERT_EQ(icsneoc2_app_error_type_device_fan_failure, 27);
ASSERT_EQ(icsneoc2_app_error_type_device_overtemperature, 28);
ASSERT_EQ(icsneoc2_app_error_type_tx_message_index_out_of_range, 29);
ASSERT_EQ(icsneoc2_app_error_type_undersized_frame_dropped, 30);
ASSERT_EQ(icsneoc2_app_error_type_oversized_frame_dropped, 31);
ASSERT_EQ(icsneoc2_app_error_type_watchdog_event, 32);
ASSERT_EQ(icsneoc2_app_error_type_system_clock_failure, 33);
ASSERT_EQ(icsneoc2_app_error_type_system_clock_recovered, 34);
ASSERT_EQ(icsneoc2_app_error_type_system_peripheral_reset, 35);
ASSERT_EQ(icsneoc2_app_error_type_system_communication_failure, 36);
ASSERT_EQ(icsneoc2_app_error_type_tx_messages_unsupported_source_or_packet_id, 37);
ASSERT_EQ(icsneoc2_app_error_type_wbms_manager_connect_failed, 38);
ASSERT_EQ(icsneoc2_app_error_type_wbms_manager_connect_bad_state, 39);
ASSERT_EQ(icsneoc2_app_error_type_wbms_manager_connect_timeout, 40);
ASSERT_EQ(icsneoc2_app_error_type_failed_to_initialize_logger_disk, 41);
ASSERT_EQ(icsneoc2_app_error_type_invalid_setting, 42);
ASSERT_EQ(icsneoc2_app_error_type_system_failure_requested_reset, 43);
ASSERT_EQ(icsneoc2_app_error_type_port_key_mistmatch, 45);
ASSERT_EQ(icsneoc2_app_error_type_bus_failure, 46);
ASSERT_EQ(icsneoc2_app_error_type_tap_overflow, 47);
ASSERT_EQ(icsneoc2_app_error_type_eth_tx_no_link, 48);
ASSERT_EQ(icsneoc2_app_error_type_error_buffer_overflow, 254);
ASSERT_EQ(icsneoc2_app_error_type_no_error, 255);
using _T = icsneo::AppErrorType;
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorRxMessagesFull), icsneoc2_app_error_type_rx_messages_full);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTxMessagesFull), icsneoc2_app_error_type_tx_messages_full);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTxReportMessagesFull), icsneoc2_app_error_type_tx_report_messages_full);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorBadCommWithDspIC), icsneoc2_app_error_type_bad_comm_with_dsp_ic);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorDriverOverflow), icsneoc2_app_error_type_driver_overflow);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorPCBuffOverflow), icsneoc2_app_error_type_pc_buff_overflow);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorPCChksumError), icsneoc2_app_error_type_pc_chksum_error);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorPCMissedByte), icsneoc2_app_error_type_pc_missed_byte);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorPCOverrunError), icsneoc2_app_error_type_pc_overrun_error);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorSettingFailure), icsneoc2_app_error_type_setting_failure);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTooManySelectedNetworks), icsneoc2_app_error_type_too_many_selected_networks);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorNetworkNotEnabled), icsneoc2_app_error_type_network_not_enabled);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorRtcNotCorrect), icsneoc2_app_error_type_rtc_not_correct);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorLoadedDefaultSettings), icsneoc2_app_error_type_loaded_default_settings);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorFeatureNotUnlocked), icsneoc2_app_error_type_feature_not_unlocked);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorFeatureRtcCmdDropped), icsneoc2_app_error_type_feature_rtc_cmd_dropped);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTxMessagesFlushed), icsneoc2_app_error_type_tx_messages_flushed);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTxMessagesHalfFull), icsneoc2_app_error_type_tx_messages_half_full);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorNetworkNotValid), icsneoc2_app_error_type_network_not_valid);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTxInterfaceNotImplemented), icsneoc2_app_error_type_tx_interface_not_implemented);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTxMessagesCommEnableIsOff), icsneoc2_app_error_type_tx_messages_comm_enable_is_off);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorRxFilterMatchCountExceeded), icsneoc2_app_error_type_rx_filter_match_count_exceeded);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorEthPreemptionNotEnabled), icsneoc2_app_error_type_eth_preemption_not_enabled);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTxNotSupportedInMode), icsneoc2_app_error_type_tx_not_supported_in_mode);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorJumboFramesNotSupported), icsneoc2_app_error_type_jumbo_frames_not_supported);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorEthernetIpFragment), icsneoc2_app_error_type_ethernet_ip_fragment);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTxMessagesUnderrun), icsneoc2_app_error_type_tx_messages_underrun);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorDeviceFanFailure), icsneoc2_app_error_type_device_fan_failure);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorDeviceOvertemperature), icsneoc2_app_error_type_device_overtemperature);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTxMessageIndexOutOfRange), icsneoc2_app_error_type_tx_message_index_out_of_range);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorUndersizedFrameDropped), icsneoc2_app_error_type_undersized_frame_dropped);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorOversizedFrameDropped), icsneoc2_app_error_type_oversized_frame_dropped);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorWatchdogEvent), icsneoc2_app_error_type_watchdog_event);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorSystemClockFailure), icsneoc2_app_error_type_system_clock_failure);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorSystemClockRecovered), icsneoc2_app_error_type_system_clock_recovered);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorSystemPeripheralReset), icsneoc2_app_error_type_system_peripheral_reset);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorSystemCommunicationFailure), icsneoc2_app_error_type_system_communication_failure);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTxMessagesUnsupportedSourceOrPacketId), icsneoc2_app_error_type_tx_messages_unsupported_source_or_packet_id);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorWbmsManagerConnectFailed), icsneoc2_app_error_type_wbms_manager_connect_failed);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorWbmsManagerConnectBadState), icsneoc2_app_error_type_wbms_manager_connect_bad_state);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorWbmsManagerConnectTimeout), icsneoc2_app_error_type_wbms_manager_connect_timeout);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorFailedToInitializeLoggerDisk), icsneoc2_app_error_type_failed_to_initialize_logger_disk);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorInvalidSetting), icsneoc2_app_error_type_invalid_setting);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorSystemFailureRequestedReset), icsneoc2_app_error_type_system_failure_requested_reset);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorPortKeyMistmatch), icsneoc2_app_error_type_port_key_mistmatch);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorBusFailure), icsneoc2_app_error_type_bus_failure);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorTapOverflow), icsneoc2_app_error_type_tap_overflow);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorEthTxNoLink), icsneoc2_app_error_type_eth_tx_no_link);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppErrorErrorBufferOverflow), icsneoc2_app_error_type_error_buffer_overflow);
ASSERT_EQ(static_cast<icsneoc2_app_error_type_t>(_T::AppNoError), icsneoc2_app_error_type_no_error);
}
TEST(icsneoc2, test_icsneoc2_message_can_flags_t)
{
ASSERT_EQ(ICSNEOC2_MESSAGE_CAN_FLAGS_RTR, 0x01);