#include #include #include "icsneo/device/devicefinder.h" #include #include #include using namespace icsneo; typedef struct icsneo_device_t { std::shared_ptr device; icsneo_open_options_t options; } icsneo_device_t; static std::deque> g_devices; ICSNEO_API icsneo_error_t icsneo_find(icsneo_device_t** devices, uint32_t* devices_count, void* reserved) { if (!devices || !devices_count) { return icsneo_error_invalid_parameters; } // Find devices auto found_devices = DeviceFinder::FindAll(); // Remove all devices that have been closed or are no longer connected for (auto it = g_devices.begin(); it != g_devices.end();) { if (!it->get()->device) { it = g_devices.erase(it); } else { ++it; } } // Add new devices for (auto& found_device : found_devices) { if (std::none_of(g_devices.begin(), g_devices.end(), [&](const auto& device) { return device->device == found_device; })) { auto device = std::make_shared(); device->device = found_device; device->options = icsneo_open_options_go_online | icsneo_open_options_enable_message_polling | icsneo_open_options_sync_rtc | icsneo_open_options_enable_auto_update; g_devices.push_back(device); } } // Determine how many we can return to the caller auto min_size = std::minmax(static_cast(found_devices.size()), *devices_count).first; *devices_count = min_size; // Return the devices to the caller for (uint32_t i = 0; i < min_size; i++) { devices[i] = g_devices[i].get(); } // Winner winner chicken dinner return icsneo_error_success; } ICSNEO_API icsneo_error_t icsneo_device_is_valid(icsneo_device_t* device) { if (!device) { return icsneo_error_invalid_parameters; } return !device->device ? icsneo_error_invalid_parameters : icsneo_error_success; } ICSNEO_API icsneo_error_t icsneo_get_open_options(icsneo_device_t* device, icsneo_open_options_t* options) { if (!device || !options) { return icsneo_error_invalid_parameters; } *options = device->options; return icsneo_error_success; } ICSNEO_API icsneo_error_t icsneo_set_open_options(icsneo_device_t* device, icsneo_open_options_t options) { if (!device) { return icsneo_error_invalid_parameters; } device->options = options; return icsneo_error_success; } ICSNEO_API icsneo_error_t icsneo_open(icsneo_device_t* device) { if (!device || !device->device) { return icsneo_error_invalid_parameters; } // Open the device auto dev = device->device; // Nothing to do if we are already open if (dev->isOpen()) { return icsneo_error_success; } // TODO: OpenFlags and OpenStatusHandler // Open the device if (!dev->open()) { return icsneo_error_open_failed; } // Go online if ((device->options & icsneo_open_options_go_online) == icsneo_open_options_go_online && !dev->goOnline()) { dev->close(); return icsneo_error_open_gonline_failed; } // Enable message polling if ((device->options & icsneo_open_options_enable_message_polling) == icsneo_open_options_enable_message_polling && !dev->enableMessagePolling()) { dev->close(); return icsneo_error_open_message_polling_failed; } // Sync RTC if ((device->options & icsneo_open_options_sync_rtc) == icsneo_open_options_sync_rtc && !dev->setRTC(std::chrono::system_clock::now())) { dev->close(); return icsneo_error_open_sync_rtc_failed; } return icsneo_error_success; } ICSNEO_API icsneo_error_t icsneo_close(icsneo_device_t* device) { if (!device || !device->device) { return icsneo_error_invalid_parameters; } auto dev = device->device; if (!dev->isOpen()) { return icsneo_error_success; } dev->close(); return icsneo_error_success; } ICSNEO_API icsneo_error_t icsneo_device_describe(icsneo_device_t* device, const char* value, uint32_t* value_length) { if (!device || !device->device) { return icsneo_error_invalid_parameters; } auto dev = device->device; // Get and set the length auto min_length = std::minmax(static_cast(dev->describe().length()), *value_length).first; *value_length = min_length; // Copy the string into value strncpy(const_cast(value), dev->describe().c_str(), min_length); return icsneo_error_success; } ICSNEO_API icsneo_error_t icsneo_device_type(icsneo_device_t* device, icsneo_devicetype_t* value) { if (!device || !device->device) { return icsneo_error_invalid_parameters; } auto dev = device->device; // TODO: We should expose these types *value = dev->getType().getDeviceType(); return icsneo_error_success; } ICSNEO_API icsneo_error_t icsneo_device_serial(icsneo_device_t* device, const char* value, uint32_t* value_length) { if (!device || !device->device) { return icsneo_error_invalid_parameters; } auto dev = device->device; // Get and set the length auto min_length = std::minmax(static_cast(dev->getSerial().length()), *value_length).first; *value_length = min_length; // Copy the string into value strncpy(const_cast(value), dev->getSerial().c_str(), min_length); return icsneo_error_success; }