From 1ca9f0fdb4200e27a8db275733d92724528340be Mon Sep 17 00:00:00 2001 From: David Rebbe Date: Mon, 9 Dec 2024 09:38:01 -0500 Subject: [PATCH] added icsneo_message_get_netid and icsneo_get_netid_name --- api/icsneo/icsneo.cpp | 51 ++++++++++++++++++++++++++++-------- examples/c/simple/src/main.c | 13 +++++---- include/icsneo/icsneo.h | 25 +++++++++++++++++- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/api/icsneo/icsneo.cpp b/api/icsneo/icsneo.cpp index ae78c72..5664c1d 100644 --- a/api/icsneo/icsneo.cpp +++ b/api/icsneo/icsneo.cpp @@ -59,7 +59,7 @@ static std::vector g_events; * Safely copies a std::string to a char array. * * @param dest The buffer to copy the string into - * @param dest_size The size of the buffer + * @param dest_size* The size of the buffer. Will be modified to the length of the string * @param src The string to copy * * @return true if the string was successfully copied, false otherwise @@ -67,13 +67,17 @@ static std::vector g_events; * @note This function always null terminates the buffer, even if the string is too long. * This is done for security reasons, not performance. */ -bool safe_str_copy(const char* dest, uint32_t dest_size, std::string src) { +bool safe_str_copy(const char* dest, uint32_t* const dest_size, std::string src) { + if (!dest || !dest_size) { + return false; + } // zero terminate the entire string, this is done for security not for performance - memset(const_cast(dest), 0, dest_size); + memset(const_cast(dest), 0, *dest_size); // Need to save room for the null terminator - dest_size -= 1; + *dest_size -= 1; try { - auto copied = src.copy(const_cast(dest), static_cast(dest_size), 0); + auto copied = src.copy(const_cast(dest), static_cast(*dest_size), 0); + *dest_size = static_cast(copied); // Somehow we didn't copy the number of bytes we needed to? This check probably isn't needed. if (copied != src.length()) { return false; @@ -126,7 +130,7 @@ ICSNEO_API icsneo_error_t icsneo_get_error_code(icsneo_error_t error_code, const // Don't default, let the compiler warn us if we forget to handle an error code } // Copy the string into value - return safe_str_copy(value, *value_length, error) ? icsneo_error_success : icsneo_error_string_copy_failed; + return safe_str_copy(value, value_length, error) ? icsneo_error_success : icsneo_error_string_copy_failed; } ICSNEO_API icsneo_error_t icsneo_device_type_from_type(icsneo_devicetype_t device_type, const char* value, uint32_t* value_length) { @@ -136,7 +140,7 @@ ICSNEO_API icsneo_error_t icsneo_device_type_from_type(icsneo_devicetype_t devic auto device_type_str = DeviceType::getGenericProductName(device_type); // Copy the string into value - return safe_str_copy(value, *value_length, device_type_str) ? icsneo_error_success : icsneo_error_string_copy_failed; + return safe_str_copy(value, value_length, device_type_str) ? icsneo_error_success : icsneo_error_string_copy_failed; } ICSNEO_API icsneo_error_t icsneo_device_find_all(icsneo_device_t** devices, uint32_t* devices_count, void* reserved) { @@ -257,7 +261,7 @@ ICSNEO_API icsneo_error_t icsneo_device_get_description(icsneo_device_t* device, } auto dev = device->device; // Copy the string into value - return safe_str_copy(value, *value_length, dev->describe()) ? icsneo_error_success : icsneo_error_string_copy_failed; + return safe_str_copy(value, value_length, dev->describe()) ? icsneo_error_success : icsneo_error_string_copy_failed; } ICSNEO_API icsneo_error_t icsneo_device_get_type(icsneo_device_t* device, icsneo_devicetype_t* value) { @@ -276,7 +280,7 @@ ICSNEO_API icsneo_error_t icsneo_device_get_serial(icsneo_device_t* device, cons } auto dev = device->device; // Copy the string into value - return safe_str_copy(value, *value_length, dev->getSerial()) ? icsneo_error_success : icsneo_error_string_copy_failed; + return safe_str_copy(value, value_length, dev->getSerial()) ? icsneo_error_success : icsneo_error_string_copy_failed; } @@ -493,7 +497,32 @@ ICSNEO_API icsneo_error_t icsneo_get_bus_type_name(icsneo_msg_bus_type_t* bus_ty } auto bus_type_str = std::string(Network::GetTypeString(*bus_type)); // Copy the string into value - return safe_str_copy(value, *value_length, bus_type_str) ? icsneo_error_success : icsneo_error_string_copy_failed; + return safe_str_copy(value, value_length, bus_type_str) ? icsneo_error_success : icsneo_error_string_copy_failed; +} + +ICSNEO_API icsneo_error_t icsneo_message_get_netid(icsneo_device_t* device, icsneo_message_t* message, icsneo_netid_t* netid) { + if (!device || !message || !netid) { + return icsneo_error_invalid_parameters; + } + // TODO: Check if message is valid + + // Make sure the message is a bus message + if (message->message->getMsgType() != icsneo_msg_type_bus) { + return icsneo_error_invalid_type; + } + // We can static cast here because we are relying on the type being correct at this point + auto bus_message = static_cast(message->message.get()); + *netid = static_cast(bus_message->network.getNetID()); + return icsneo_error_success; +} + +ICSNEO_API icsneo_error_t icsneo_get_netid_name(icsneo_netid_t netid, const char* value, uint32_t* value_length) { + if (!netid || !value || !value_length) { + return icsneo_error_invalid_parameters; + } + auto netid_str = std::string(Network::GetNetIDString(static_cast<_icsneo_netid_t>(netid), true)); + // Copy the string into value + return safe_str_copy(value, value_length, netid_str) ? icsneo_error_success : icsneo_error_string_copy_failed; } ICSNEO_API icsneo_error_t icsneo_message_get_data(icsneo_device_t* device, icsneo_message_t* message, uint8_t* data, uint32_t* data_length) { @@ -714,7 +743,7 @@ ICSNEO_API icsneo_error_t icsneo_event_get_description(icsneo_event_t* event, co // TODO: Check if event is valid auto ev = event->event; // Copy the string into value - return safe_str_copy(value, *value_length, ev.describe()) ? icsneo_error_success : icsneo_error_string_copy_failed; + return safe_str_copy(value, value_length, ev.describe()) ? icsneo_error_success : icsneo_error_string_copy_failed; } ICSNEO_API icsneo_error_t icsneo_device_get_rtc(icsneo_device_t* device, int64_t* unix_epoch) { diff --git a/examples/c/simple/src/main.c b/examples/c/simple/src/main.c index b2248b2..c189ee6 100644 --- a/examples/c/simple/src/main.c +++ b/examples/c/simple/src/main.c @@ -208,7 +208,7 @@ int process_messages(icsneo_device_t* device, icsneo_message_t** messages, uint3 } const char bus_name[128] = {0}; uint32_t bus_name_length = 128; - res += icsneo_get_bus_type_name(&bus_type, bus_name, &bus_name_length); + res = icsneo_get_bus_type_name(&bus_type, bus_name, &bus_name_length); if (res != icsneo_error_success) { return print_error_code("Failed to get message bus type name", res); } @@ -217,24 +217,27 @@ int process_messages(icsneo_device_t* device, icsneo_message_t** messages, uint3 if (bus_type == icsneo_msg_bus_type_can) { uint32_t arbid = 0; uint32_t dlc = 0; + icsneo_netid_t netid = 0; bool is_remote = false; bool is_canfd = false; bool is_extended = false; uint8_t data[64] = {0}; uint32_t data_length = 64; - - uint32_t result = icsneo_can_message_get_arbid(device, message, &arbid); + const char netid_name[128] = {0}; + uint32_t netid_name_length = 128; + uint32_t result = icsneo_message_get_netid(device, message, &netid); + result += icsneo_get_netid_name(netid, netid_name, &netid_name_length); + result += icsneo_can_message_get_arbid(device, message, &arbid); result += icsneo_can_message_get_dlc_on_wire(device, message, &dlc); result += icsneo_can_message_is_remote(device, message, &is_remote); result += icsneo_can_message_is_canfd(device, message, &is_canfd); result += icsneo_can_message_is_extended(device, message, &is_extended); result += icsneo_message_get_data(device, message, data, &data_length); - if (result != icsneo_error_success) { printf("\tFailed get get CAN parameters (error: %u) for index %u\n", result, i); continue; } - printf("\t ArbID: 0x%x\t DLC: %u\t Remote: %d\t CANFD: %d\t Extended: %d\t Data length: %u\n", arbid, dlc, is_remote, is_canfd, is_extended, data_length); + printf("\t NetID: %s (0x%x)\tArbID: 0x%x\t DLC: %u\t Remote: %d\t CANFD: %d\t Extended: %d\t Data length: %u\n", netid_name, netid, arbid, dlc, is_remote, is_canfd, is_extended, data_length); printf("\t Data: ["); for (uint32_t x = 0; x < data_length; x++) { printf(" 0x%x", data[x]); diff --git a/include/icsneo/icsneo.h b/include/icsneo/icsneo.h index 703e030..424f7b7 100644 --- a/include/icsneo/icsneo.h +++ b/include/icsneo/icsneo.h @@ -357,7 +357,7 @@ ICSNEO_API icsneo_error_t icsneo_message_get_bus_type(icsneo_device_t* device, i /** @brief Get the bus type string for a icsneo_msg_bus_type_t. * - * @param[in] icsneo_event_t* event The event to get the description of. + * @param[in] icsneo_msg_bus_type_t* bus_type The bus type to get the description of. * @param[out] const char* value Pointer to a buffer to copy the description into. Null terminated. * @param[in,out] uint32_t* value_length Size of the value buffer. Modified with the length of the description. * @@ -365,6 +365,29 @@ ICSNEO_API icsneo_error_t icsneo_message_get_bus_type(icsneo_device_t* device, i */ ICSNEO_API icsneo_error_t icsneo_get_bus_type_name(icsneo_msg_bus_type_t* bus_type, const char* value, uint32_t* value_length); +/** @brief Get the Network ID (netid) of a bus message + * + * @param[in] icsneo_device_t* device The device to check against. + * @param[in] icsneo_message_t* message The message to check. + * @param[out] icsneo_netid_t* netid Pointer to a icsneo_netid_t to copy the type of the value into. + * + * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters or icsneo_error_invalid_type otherwise. + * + * @see icsneo_netid_t, icsneo_get_netid_name + */ +ICSNEO_API icsneo_error_t icsneo_message_get_netid(icsneo_device_t* device, icsneo_message_t* message, icsneo_netid_t* netid); + +/** @brief Get the netid string for a icsneo_netid_t. + * + * @param[in] icsneo_netid_t netid The network id to get the description of. + * @param[out] const char* value Pointer to a buffer to copy the description into. Null terminated. + * @param[in,out] uint32_t* value_length Size of the value buffer. Modified with the length of the description. + * + * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. + */ +ICSNEO_API icsneo_error_t icsneo_get_netid_name(icsneo_netid_t netid, const char* value, uint32_t* value_length); + + /** @brief Get the data bytes of a message * * @param[in] icsneo_device_t* device The device to check against.