diff --git a/api/icsneo/icsneo.cpp b/api/icsneo/icsneo.cpp index 57fd579..35cacdf 100644 --- a/api/icsneo/icsneo.cpp +++ b/api/icsneo/icsneo.cpp @@ -413,6 +413,140 @@ ICSNEO_API icsneo_error_t icsneo_message_get_bus_type(icsneo_device_t* device, i return icsneo_error_success; } +ICSNEO_API icsneo_error_t icsneo_message_get_data(icsneo_device_t* device, icsneo_message_t* message, uint8_t* data, uint32_t* data_length) { + if (!device || !message || !data || !data_length) { + return icsneo_error_invalid_parameters; + } + // TODO: Check if device is valid + // TODO: Check if message is valid + // Make sure the message has the data field, internal and bus currently have this. + if (message->message->getMsgType() != icsneo_msg_type_internal && message->message->getMsgType() != icsneo_msg_type_bus) { + return icsneo_error_invalid_type; + } + auto* data_message = dynamic_cast(message->message.get()); + if (!data_message) { + return icsneo_error_invalid_type; + } + auto min_length = std::minmax(static_cast(data_message->data.size()), *data_length).first; + *data_length = min_length; + std::copy(data_message->data.begin(), data_message->data.begin() + min_length, data); + + return icsneo_error_success; +} + + +ICSNEO_API icsneo_error_t icsneo_can_message_arbid(icsneo_device_t* device, icsneo_message_t* message, uint32_t* value) { + if (!device || !message || !value) { + return icsneo_error_invalid_parameters; + } + // TODO: Check if device is valid + // TODO: Check if message is valid + const auto* can_message = dynamic_cast(message->message.get()); + if (!can_message) { + return icsneo_error_invalid_type; + } + + *value = can_message->arbid; + + return icsneo_error_success; +} + +ICSNEO_API icsneo_error_t icsneo_can_message_dlc_on_wire(icsneo_device_t* device, icsneo_message_t* message, uint32_t* value) { + if (!device || !message || !value) { + return icsneo_error_invalid_parameters; + } + // TODO: Check if device is valid + // TODO: Check if message is valid + const auto* can_message = dynamic_cast(message->message.get()); + if (!can_message) { + return icsneo_error_invalid_type; + } + + *value = static_cast(can_message->dlcOnWire); + + return icsneo_error_success; +} + +ICSNEO_API icsneo_error_t icsneo_can_message_is_remote(icsneo_device_t* device, icsneo_message_t* message, bool* value) { + if (!device || !message || !value) { + return icsneo_error_invalid_parameters; + } + // TODO: Check if device is valid + // TODO: Check if message is valid + const auto* can_message = dynamic_cast(message->message.get()); + if (!can_message) { + return icsneo_error_invalid_type; + } + + *value = can_message->isRemote; + + return icsneo_error_success; +} + +ICSNEO_API icsneo_error_t icsneo_can_message_is_extended(icsneo_device_t* device, icsneo_message_t* message, bool* value) { + if (!device || !message || !value) { + return icsneo_error_invalid_parameters; + } + // TODO: Check if device is valid + // TODO: Check if message is valid + const auto* can_message = dynamic_cast(message->message.get()); + if (!can_message) { + return icsneo_error_invalid_type; + } + + *value = can_message->isExtended; + + return icsneo_error_success; +} + +ICSNEO_API icsneo_error_t icsneo_can_message_is_canfd(icsneo_device_t* device, icsneo_message_t* message, bool* value) { + if (!device || !message || !value) { + return icsneo_error_invalid_parameters; + } + // TODO: Check if device is valid + // TODO: Check if message is valid + const auto* can_message = dynamic_cast(message->message.get()); + if (!can_message) { + return icsneo_error_invalid_type; + } + + *value = can_message->isCANFD; + + return icsneo_error_success; +} + +ICSNEO_API icsneo_error_t icsneo_can_message_baudrate_switch(icsneo_device_t* device, icsneo_message_t* message, bool* value) { + if (!device || !message || !value) { + return icsneo_error_invalid_parameters; + } + // TODO: Check if device is valid + // TODO: Check if message is valid + const auto* can_message = dynamic_cast(message->message.get()); + if (!can_message) { + return icsneo_error_invalid_type; + } + + *value = can_message->baudrateSwitch; + + return icsneo_error_success; +} + +ICSNEO_API icsneo_error_t icsneo_can_message_error_state_indicator(icsneo_device_t* device, icsneo_message_t* message, bool* value) { + if (!device || !message || !value) { + return icsneo_error_invalid_parameters; + } + // TODO: Check if device is valid + // TODO: Check if message is valid + const auto* can_message = dynamic_cast(message->message.get()); + if (!can_message) { + return icsneo_error_invalid_type; + } + + *value = can_message->errorStateIndicator; + + return icsneo_error_success; +} + ICSNEO_API icsneo_error_t icsneo_get_events(icsneo_event_t** events, uint32_t* events_count) { if (!events || !events_count) { return icsneo_error_invalid_parameters; diff --git a/examples/c/simple/src/main.c b/examples/c/simple/src/main.c index 2c145db..c75b8e1 100644 --- a/examples/c/simple/src/main.c +++ b/examples/c/simple/src/main.c @@ -103,7 +103,7 @@ int main(int argc, char* argv[]) { return print_error_code("Failed to get open options", res); } // Disable Syncing RTC - //options &= ~icsneo_open_options_sync_rtc; + options &= ~icsneo_open_options_sync_rtc; res = icsneo_set_open_options(device, options); if (res != icsneo_error_success) { print_device_events(device, description); @@ -206,7 +206,34 @@ int process_messages(icsneo_device_t* device, icsneo_message_t** messages, uint3 if (res != icsneo_error_success) { return print_error_code("Failed to get message bus type", res); } - printf("%d Message type: %u bus type: %u\n", i, msg_type, bus_type); + printf("\t%d) Message type: %u bus type: %u\n", i, msg_type, bus_type); + if (bus_type == icsneo_msg_bus_type_can) { + uint32_t arbid = 0; + uint32_t dlc = 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_arbid(device, message, &arbid); + result += icsneo_can_message_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 Data: ["); + for (uint32_t x = 0; x < data_length; x++) { + printf(" 0x%x", data[x]); + } + printf(" ]\n"); + continue; + } + } return icsneo_error_success; diff --git a/include/icsneo/icsneo.h b/include/icsneo/icsneo.h index 0a0b8cb..ca0fcb3 100644 --- a/include/icsneo/icsneo.h +++ b/include/icsneo/icsneo.h @@ -327,6 +327,98 @@ ICSNEO_API icsneo_error_t icsneo_message_get_type(icsneo_device_t* device, icsne */ ICSNEO_API icsneo_error_t icsneo_message_get_bus_type(icsneo_device_t* device, icsneo_message_t* message, icsneo_msg_bus_type_t* bus_type); +/** @brief Get the data bytes of a message + * + * @param[in] icsneo_device_t* device The device to check against. + * @param[in] icsneo_message_t* message The message to check. + * @param[out] uint8_t* data Pointer to a uint8_t to copy the data bytes into. + * @param[out] uint32_t* data_length Pointer to a uint32_t to copy the length of the data into. + * + * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. +*/ +ICSNEO_API icsneo_error_t icsneo_message_get_data(icsneo_device_t* device, icsneo_message_t* message, uint8_t* data, uint32_t* data_length); + +/** @brief Get the Arbitration ID of a CAN message + * + * @param[in] icsneo_device_t* device The device to check against. + * @param[in] icsneo_message_t* message The message to check. + * @param[out] uint32_t* value Pointer to a uint32_t to copy the Arbitration ID into. + * + * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. +*/ +ICSNEO_API icsneo_error_t icsneo_can_message_arbid(icsneo_device_t* device, icsneo_message_t* message, uint32_t* value); + +/** @brief Get the DLC on wire of a CAN message + * + * @param[in] icsneo_device_t* device The device to check against. + * @param[in] icsneo_message_t* message The message to check. + * @param[out] uint32_t* value Pointer to a uint32_t to copy the DLC on wire into. + * + * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. +*/ +ICSNEO_API icsneo_error_t icsneo_can_message_dlc_on_wire(icsneo_device_t* device, icsneo_message_t* message, uint32_t* value); + +/** @brief Get the remote status of a CAN message + * + * @param[in] icsneo_device_t* device The device to check against. + * @param[in] icsneo_message_t* message The message to check. + * @param[out] bool* value Pointer to a uint32_t to copy the remote status into. + * + * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. +*/ +ICSNEO_API icsneo_error_t icsneo_can_message_is_remote(icsneo_device_t* device, icsneo_message_t* message, bool* value); + +/** @brief Get the extended status of a CAN message + * + * @param[in] icsneo_device_t* device The device to check against. + * @param[in] icsneo_message_t* message The message to check. + * @param[out] bool* value Pointer to a uint32_t to copy the extended status into. + * + * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. +*/ +ICSNEO_API icsneo_error_t icsneo_can_message_is_extended(icsneo_device_t* device, icsneo_message_t* message, bool* value); + +/** @brief Get the CANFD status of a CAN message + * + * @param[in] icsneo_device_t* device The device to check against. + * @param[in] icsneo_message_t* message The message to check. + * @param[out] bool* value Pointer to a uint32_t to copy the CANFD status into. + * + * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. +*/ +ICSNEO_API icsneo_error_t icsneo_can_message_is_canfd(icsneo_device_t* device, icsneo_message_t* message, bool* value); + +/** @brief Get the baudrate switch status of a CAN message + * + * @param[in] icsneo_device_t* device The device to check against. + * @param[in] icsneo_message_t* message The message to check. + * @param[out] bool* value Pointer to a uint32_t to copy the baudrate switch status into. + * + * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. +*/ +ICSNEO_API icsneo_error_t icsneo_can_message_baudrate_switch(icsneo_device_t* device, icsneo_message_t* message, bool* value); + +/** @brief Get the error state indicator status of a CAN message + * + * @param[in] icsneo_device_t* device The device to check against. + * @param[in] icsneo_message_t* message The message to check. + * @param[out] bool* value Pointer to a uint32_t to copy the error state indicator status into. + * + * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. +*/ +ICSNEO_API icsneo_error_t icsneo_can_message_error_state_indicator(icsneo_device_t* device, icsneo_message_t* message, bool* value); + + +/* + uint32_t arbid; + uint8_t dlcOnWire; + bool isRemote = false; // Not allowed if CAN FD + bool isExtended = false; + bool isCANFD = false; + bool baudrateSwitch = false; // CAN FD only + bool errorStateIndicator = false; // CAN FD only +*/ + /** @brief Get the global events not specifically related to a device. * * @param[out] icsneo_event_t** events Pointer to an array of icsneo_event_t to copy the events into.