From fbeea2f79dece5b065d9d541d26b5481678bf730 Mon Sep 17 00:00:00 2001 From: David Rebbe Date: Tue, 3 Dec 2024 17:34:09 -0500 Subject: [PATCH] added timeout to get messages and copied messages over. --- api/icsneo/icsneo.cpp | 21 ++++++++++++++--- examples/c/simple/src/main.c | 45 +++++++++++++++++++++++++++++++++++- include/icsneo/icsneo.h | 3 ++- 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/api/icsneo/icsneo.cpp b/api/icsneo/icsneo.cpp index 97b84cc..2c34594 100644 --- a/api/icsneo/icsneo.cpp +++ b/api/icsneo/icsneo.cpp @@ -316,11 +316,21 @@ ICSNEO_API icsneo_error_t icsneo_get_timestamp_resolution(icsneo_device_t* devic return icsneo_error_success; } -ICSNEO_API icsneo_error_t icsneo_get_messages(icsneo_device_t* device, icsneo_message_t** messages, uint32_t* messages_count) { +ICSNEO_API icsneo_error_t icsneo_get_messages(icsneo_device_t* device, icsneo_message_t** messages, uint32_t* messages_count, uint32_t timeout_ms) { if (!device || !messages || !messages_count) { return icsneo_error_invalid_parameters; } auto dev = device->device; + // Wait for messages + auto start_time = std::chrono::steady_clock::now(); + while (timeout_ms && std::chrono::duration_cast( + std::chrono::steady_clock::now() - start_time) + .count() < timeout_ms && + dev->getCurrentMessageCount() == 0) { + // Lets make sure we don't busy loop, we don't have any messages yet + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + continue; + } // Get the messages auto results = dev->getMessages(); auto& queried_messages = results.first; @@ -329,8 +339,8 @@ ICSNEO_API icsneo_error_t icsneo_get_messages(icsneo_device_t* device, icsneo_me return icsneo_error_get_messages_failed; } // Find the minimum number of messages - uint32_t message_size = std::minmax(static_cast(queried_messages.size()), *messages_count).first; - *messages_count = message_size; + uint32_t min_size = std::minmax(static_cast(queried_messages.size()), *messages_count).first; + *messages_count = min_size; // Copy the messages into our global message container g_messages.clear(); @@ -339,6 +349,11 @@ ICSNEO_API icsneo_error_t icsneo_get_messages(icsneo_device_t* device, icsneo_me message_t->message = message; g_messages.push_back(message_t); } + + // Copy the messages into the output array + for (uint32_t i = 0; i < min_size; i++) { + messages[i] = g_messages[i].get(); + } return icsneo_error_success; } diff --git a/examples/c/simple/src/main.c b/examples/c/simple/src/main.c index c81822d..dac7c87 100644 --- a/examples/c/simple/src/main.c +++ b/examples/c/simple/src/main.c @@ -2,6 +2,38 @@ #include +#if defined(_WIN32) || defined(_WIN64) +#include +#else +#include +#endif + + +/** + * @brief Sleeps for a specified number of milliseconds. + * + * Sleeps for a specified number of milliseconds using Sleep() on Windows and sleep() on *nix. + * + * @param ms The number of milliseconds to sleep. + */ +void sleep_ms(uint32_t ms) { +#if defined(_WIN32) || defined(_WIN64) + Sleep(ms); +#else + sleep(ms); +#endif +} + +/** + * @brief Prints an error message with the given string and error code. + * + * If the error code is not icsneo_error_success, prints the error string for the given error code + * and returns the error code. + * + * @param message The message to print. + * @param error The error code to print. + * @return error as int + */ int print_error_code(const char* message, icsneo_error_t error) { char error_str[256] = {0}; uint32_t error_length = 256; @@ -44,7 +76,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) { return print_error_code("Failed to set open options", res); @@ -56,6 +88,17 @@ int main(int argc, char* argv[]) { return print_error_code("Failed to open device", res); }; + printf("Waiting 3 seconds for messages...\n"); + sleep_ms(3000); + + icsneo_message_t* messages[20000] = {0}; + uint32_t message_count = 20000; + res = icsneo_get_messages(device, messages, &message_count, 3000); + if (res != icsneo_error_success) { + return print_error_code("Failed to get messages from device", res); + }; + printf("Received %u messages\n", message_count); + printf("Closing device: %s...\n", description); res = icsneo_close(device); if (res != icsneo_error_success) { diff --git a/include/icsneo/icsneo.h b/include/icsneo/icsneo.h index c0617a7..6731811 100644 --- a/include/icsneo/icsneo.h +++ b/include/icsneo/icsneo.h @@ -270,10 +270,11 @@ ICSNEO_API icsneo_error_t icsneo_get_timestamp_resolution(icsneo_device_t* devic * @param[out] icsneo_message_t** messages Pointer to an array of icsneo_message_t to copy the messages into. * Undefined behaviour if index is out of range of messages_count. * @param[in,out] uint32_t* messages_count Size of the messages array. Modified with the number of messages found. + * @param[in] uint32_t timeout_ms The timeout in milliseconds to wait for messages. A value of 0 indicates a non-blocking call. * * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. */ -ICSNEO_API icsneo_error_t icsneo_get_messages(icsneo_device_t* device, icsneo_message_t** messages, uint32_t* messages_count); +ICSNEO_API icsneo_error_t icsneo_get_messages(icsneo_device_t* device, icsneo_message_t** messages, uint32_t* messages_count, uint32_t timeout_ms); /** @brief Check if a message is valid *