C2: Add Supported Device Types"

pull/86/head
David Rebbe 2026-05-14 23:08:11 +00:00 committed by Kyle Schwarz
parent c3762bbf22
commit b3bb033ecb
8 changed files with 207 additions and 0 deletions

View File

@ -84,6 +84,61 @@ icsneoc2_error_t icsneoc2_error_code_get(icsneoc2_error_t error_code, char* valu
return safe_str_copy(value, value_length, error_strings[error_code]) ? icsneoc2_error_success : icsneoc2_error_string_copy_failed; return safe_str_copy(value, value_length, error_strings[error_code]) ? icsneoc2_error_success : icsneoc2_error_string_copy_failed;
} }
icsneoc2_error_t icsneoc2_supported_devices_enumerate(icsneoc2_supported_device_t** supported_devices) {
if(!supported_devices) {
return icsneoc2_error_invalid_parameters;
}
auto device_types = DeviceFinder::GetSupportedDevices();
icsneoc2_supported_device_t* head = nullptr;
icsneoc2_supported_device_t* tail = nullptr;
for(auto& device_type : device_types) {
auto* node = new (std::nothrow) icsneoc2_supported_device_t;
if(!node) {
return icsneoc2_error_out_of_memory;
}
node->device_type = device_type;
node->next = nullptr;
if(!head) {
head = node;
} else {
tail->next = node;
}
tail = node;
}
*supported_devices = head;
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_supported_devices_free(icsneoc2_supported_device_t* supported_devices) {
if(!supported_devices) {
return icsneoc2_error_invalid_parameters;
}
while(supported_devices) {
auto* next = supported_devices->next;
delete supported_devices;
supported_devices = next;
}
return icsneoc2_error_success;
}
icsneoc2_supported_device_t* icsneoc2_supported_devices_next(const icsneoc2_supported_device_t* supported_device) {
if(!supported_device) {
return nullptr;
}
return supported_device->next;
}
icsneoc2_error_t icsneoc2_supported_device_get(const icsneoc2_supported_device_t* supported_device, icsneoc2_devicetype_t* device_type) {
if(!supported_device || !device_type) {
return icsneoc2_error_invalid_parameters;
}
*device_type = static_cast<icsneoc2_devicetype_t>(supported_device->device_type);
return icsneoc2_error_success;
}
icsneoc2_error_t icsneoc2_device_type_name_get(icsneoc2_devicetype_t device_type, char* value, size_t* value_length) { icsneoc2_error_t icsneoc2_device_type_name_get(icsneoc2_devicetype_t device_type, char* value, size_t* value_length) {
if(!value || !value_length) { if(!value || !value_length) {
return icsneoc2_error_invalid_parameters; return icsneoc2_error_invalid_parameters;

View File

@ -13,6 +13,11 @@
using namespace icsneo; using namespace icsneo;
typedef struct icsneoc2_supported_device_t {
DeviceType device_type;
icsneoc2_supported_device_t* next;
} icsneoc2_supported_device_t;
typedef struct icsneoc2_message_t { typedef struct icsneoc2_message_t {
std::shared_ptr<Message> message; std::shared_ptr<Message> message;
} icsneoc2_message_t; } icsneoc2_message_t;

View File

@ -10,6 +10,14 @@ Simple
.. literalinclude:: ../../examples/c2/simple/src/main.c .. literalinclude:: ../../examples/c2/simple/src/main.c
:language: c :language: c
Supported Devices
=================
:download:`Download example <../../examples/c2/supported_devices/src/main.c>`
.. literalinclude:: ../../examples/c2/supported_devices/src/main.c
:language: c
Disk Format Disk Format
=========== ===========

View File

@ -2,6 +2,7 @@ option(LIBICSNEO_BUILD_C_INTERACTIVE_EXAMPLE "Build the command-line interactive
option(LIBICSNEO_BUILD_C_SIMPLE_EXAMPLE "Build the command-line simple C example." ON) option(LIBICSNEO_BUILD_C_SIMPLE_EXAMPLE "Build the command-line simple C example." ON)
option(LIBICSNEO_BUILD_C_LEGACY_EXAMPLE "Build the command-line simple C example." ON) option(LIBICSNEO_BUILD_C_LEGACY_EXAMPLE "Build the command-line simple C example." ON)
option(LIBICSNEO_BUILD_C2_SIMPLE_EXAMPLE "Build the simple C2 example." ON) option(LIBICSNEO_BUILD_C2_SIMPLE_EXAMPLE "Build the simple C2 example." ON)
option(LIBICSNEO_BUILD_C2_SUPPORTED_DEVICES_EXAMPLE "Build the C2 supported devices example." ON)
option(LIBICSNEO_BUILD_C2_READ_MESSAGES_EXAMPLE "Build the C2 read messages example." ON) option(LIBICSNEO_BUILD_C2_READ_MESSAGES_EXAMPLE "Build the C2 read messages example." ON)
option(LIBICSNEO_BUILD_C2_DISKFORMAT_EXAMPLE "Build the C2 disk format example." ON) option(LIBICSNEO_BUILD_C2_DISKFORMAT_EXAMPLE "Build the C2 disk format example." ON)
option(LIBICSNEO_BUILD_C2_RECONNECT_EXAMPLE "Build the C2 reconnect example." ON) option(LIBICSNEO_BUILD_C2_RECONNECT_EXAMPLE "Build the C2 reconnect example." ON)
@ -48,6 +49,10 @@ if(LIBICSNEO_BUILD_C2_SIMPLE_EXAMPLE)
add_subdirectory(c2/simple) add_subdirectory(c2/simple)
endif() endif()
if(LIBICSNEO_BUILD_C2_SUPPORTED_DEVICES_EXAMPLE)
add_subdirectory(c2/supported_devices)
endif()
if(LIBICSNEO_BUILD_C2_READ_MESSAGES_EXAMPLE) if(LIBICSNEO_BUILD_C2_READ_MESSAGES_EXAMPLE)
add_subdirectory(c2/read_messages) add_subdirectory(c2/read_messages)
endif() endif()

View File

@ -0,0 +1,6 @@
add_executable(libicsneoc2-supported-devices-example src/main.c)
target_link_libraries(libicsneoc2-supported-devices-example icsneoc2-static)
if(WIN32)
target_compile_definitions(libicsneoc2-supported-devices-example PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()

View File

@ -0,0 +1,55 @@
#include <icsneo/icsneoc2.h>
#include <stdio.h>
static 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\n", message, error);
return (int)res;
}
printf("%s: %s (%u)\n", message, error_str, error);
return (int)error;
}
int main(void) {
icsneoc2_supported_device_t* supported_devices = NULL;
icsneoc2_error_t res = icsneoc2_supported_devices_enumerate(&supported_devices);
if(res != icsneoc2_error_success) {
return print_error_code("Failed to enumerate supported devices", res);
}
if(!supported_devices) {
printf("No supported devices found.\n");
return 0;
}
printf("Supported devices:\n");
for(icsneoc2_supported_device_t* cur = supported_devices; cur != NULL; cur = icsneoc2_supported_devices_next(cur)) {
icsneoc2_devicetype_t device_type = 0;
res = icsneoc2_supported_device_get(cur, &device_type);
if(res != icsneoc2_error_success) {
icsneoc2_supported_devices_free(supported_devices);
return print_error_code("Failed to get supported device type", res);
}
char name[128] = {0};
size_t name_len = sizeof(name);
res = icsneoc2_device_type_name_get(device_type, name, &name_len);
if(res != icsneoc2_error_success) {
icsneoc2_supported_devices_free(supported_devices);
return print_error_code("Failed to get supported device type name", res);
}
printf(" %s (%u)\n", name, (unsigned int)device_type);
}
res = icsneoc2_supported_devices_free(supported_devices);
if(res != icsneoc2_error_success) {
return print_error_code("Failed to free supported device list", res);
}
return 0;
}

View File

@ -19,6 +19,8 @@ typedef struct icsneoc2_message_t icsneoc2_message_t;
typedef struct icsneoc2_event_t icsneoc2_event_t; typedef struct icsneoc2_event_t icsneoc2_event_t;
typedef struct icsneoc2_supported_device_t icsneoc2_supported_device_t;
typedef enum _icsneoc2_error_t { typedef enum _icsneoc2_error_t {
icsneoc2_error_success, // Function was successful icsneoc2_error_success, // Function was successful
icsneoc2_error_invalid_parameters, // Invalid parameters, typically because of a NULL reference. icsneoc2_error_invalid_parameters, // Invalid parameters, typically because of a NULL reference.
@ -65,6 +67,44 @@ static const icsneoc2_open_options_t icsneoc2_open_options_default =
*/ */
icsneoc2_error_t icsneoc2_error_code_get(icsneoc2_error_t error_code, char* value, size_t* value_length); icsneoc2_error_t icsneoc2_error_code_get(icsneoc2_error_t error_code, char* value, size_t* value_length);
/**
* Enumerate supported device types.
*
* @param[out] supported_devices Pointer to receive the head of the supported device types linked list. Must be freed with icsneoc2_supported_devices_free().
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_supported_devices_enumerate(icsneoc2_supported_device_t** supported_devices);
/**
* Free a supported device types list returned by icsneoc2_supported_devices_enumerate().
*
* @param[in] supported_devices The head of the supported device types linked list to free.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_supported_devices_free(icsneoc2_supported_device_t* supported_devices);
/**
* Advance to the next supported device type in a list.
*
* @param[in] supported_device The current supported device type node.
*
* @return The next supported device type node, or NULL at the end of the list.
*/
icsneoc2_supported_device_t* icsneoc2_supported_devices_next(const icsneoc2_supported_device_t* supported_device);
/**
* Get the device type from a supported device node.
*
* @param[in] supported_device The supported device node.
* @param[out] device_type Pointer to receive the device type.
*
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
*/
icsneoc2_error_t icsneoc2_supported_device_get(const icsneoc2_supported_device_t* supported_device, icsneoc2_devicetype_t* device_type);
/** /**
* Get the device type string for a icsneoc2_devicetype_t. * Get the device type string for a icsneoc2_devicetype_t.
* *

View File

@ -3,6 +3,7 @@
#include <icsneo/icsneoc2settings.h> #include <icsneo/icsneoc2settings.h>
#include <icsneo/icsneoc2messages.h> #include <icsneo/icsneoc2messages.h>
#include "../../api/icsneoc2/icsneoc2_internal.h" #include "../../api/icsneoc2/icsneoc2_internal.h"
#include <icsneo/device/devicefinder.h>
#include <icsneo/device/devicetype.h> #include <icsneo/device/devicetype.h>
#include <icsneo/device/chipid.h> #include <icsneo/device/chipid.h>
#include <icsneo/communication/message/linmessage.h> #include <icsneo/communication/message/linmessage.h>
@ -90,6 +91,34 @@ TEST(icsneoc2, test_icsneoc2_device_enumerate)
icsneoc2_enumeration_free(devices); icsneoc2_enumeration_free(devices);
} }
TEST(icsneoc2, test_icsneoc2_supported_devices_enumerate)
{
icsneoc2_supported_device_t* supported_devices = nullptr;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_supported_devices_enumerate(&supported_devices));
ASSERT_NE(nullptr, supported_devices);
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_supported_device_get(supported_devices, nullptr));
const auto& expected_devices = icsneo::DeviceFinder::GetSupportedDevices();
size_t count = 0;
for(icsneoc2_supported_device_t* cur = supported_devices; cur != nullptr; cur = icsneoc2_supported_devices_next(cur)) {
ASSERT_LT(count, expected_devices.size());
icsneoc2_devicetype_t device_type = 0;
ASSERT_EQ(icsneoc2_error_success, icsneoc2_supported_device_get(cur, &device_type));
ASSERT_EQ(static_cast<icsneoc2_devicetype_t>(expected_devices[count].getDeviceType()), device_type);
char name[ICSNEO_DEVICETYPE_LONGEST_NAME] = {0};
size_t name_len = sizeof(name);
ASSERT_EQ(icsneoc2_error_success, icsneoc2_device_type_name_get(device_type, name, &name_len));
ASSERT_STREQ(icsneo::DeviceType::GetGenericProductName(expected_devices[count].getDeviceType()), name);
count++;
}
ASSERT_EQ(expected_devices.size(), count);
ASSERT_EQ(icsneoc2_error_success, icsneoc2_supported_devices_free(supported_devices));
}
TEST(icsneoc2, test_icsneoc2_device_is_valid) TEST(icsneoc2, test_icsneoc2_device_is_valid)
{ {
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_is_valid(NULL)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_is_valid(NULL));
@ -113,6 +142,10 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
// All of these don't have a device parameter // All of these don't have a device parameter
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_enumerate(0, NULL)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_enumerate(0, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_supported_devices_enumerate(NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_supported_devices_free(NULL));
ASSERT_EQ(nullptr, icsneoc2_supported_devices_next(NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_supported_device_get(NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_network_type_name_get(0, NULL, NULL)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_network_type_name_get(0, NULL, NULL));
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_event_description_get(eventPlaceHolder, placeholderStr, &placeholderSizeT)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_event_description_get(eventPlaceHolder, placeholderStr, &placeholderSizeT));