diff --git a/api/icsneoc2/icsneoc2settings.cpp b/api/icsneoc2/icsneoc2settings.cpp index 76376c67..1fe68bb0 100644 --- a/api/icsneoc2/icsneoc2settings.cpp +++ b/api/icsneoc2/icsneoc2settings.cpp @@ -867,6 +867,90 @@ icsneoc2_error_t icsneoc2_settings_misc_io_analog_output_set(icsneoc2_device_t* return icsneoc2_error_success; } +icsneoc2_error_t icsneoc2_settings_linux_boot_enabled_get(icsneoc2_device_t* device, bool* value) { + // Make sure the device is valid + auto res = icsneoc2_device_is_valid(device); + if(res != icsneoc2_error_success) { + return res; + } + if(!value) { + return icsneoc2_error_invalid_parameters; + } + if(auto result = device->device->settings->getLinuxBootEnabled(); result.has_value()) { + *value = result.value(); + return icsneoc2_error_success; + } + return icsneoc2_error_get_settings_failure; +} + +icsneoc2_error_t icsneoc2_settings_linux_boot_enabled_set(icsneoc2_device_t* device, bool value) { + // Make sure the device is valid + auto res = icsneoc2_device_is_valid(device); + if(res != icsneoc2_error_success) { + return res; + } + if(!device->device->settings->setLinuxBootEnabled(value)) { + return icsneoc2_error_set_settings_failure; + } + return icsneoc2_error_success; +} + +icsneoc2_error_t icsneoc2_settings_external_wifi_antenna_enabled_get(icsneoc2_device_t* device, bool* value) { + // Make sure the device is valid + auto res = icsneoc2_device_is_valid(device); + if(res != icsneoc2_error_success) { + return res; + } + if(!value) { + return icsneoc2_error_invalid_parameters; + } + if(auto result = device->device->settings->getExternalWifiAntennaEnabled(); result.has_value()) { + *value = result.value(); + return icsneoc2_error_success; + } + return icsneoc2_error_get_settings_failure; +} + +icsneoc2_error_t icsneoc2_settings_external_wifi_antenna_enabled_set(icsneoc2_device_t* device, bool value) { + // Make sure the device is valid + auto res = icsneoc2_device_is_valid(device); + if(res != icsneoc2_error_success) { + return res; + } + if(!device->device->settings->setExternalWifiAntennaEnabled(value)) { + return icsneoc2_error_set_settings_failure; + } + return icsneoc2_error_success; +} + +icsneoc2_error_t icsneoc2_settings_linux_configuration_port_get(icsneoc2_device_t* device, icsneoc2_linux_configuration_port_t* value) { + // Make sure the device is valid + auto res = icsneoc2_device_is_valid(device); + if(res != icsneoc2_error_success) { + return res; + } + if(!value) { + return icsneoc2_error_invalid_parameters; + } + if(auto result = device->device->settings->getLinuxConfigurationPort(); result.has_value()) { + *value = static_cast(result.value()); + return icsneoc2_error_success; + } + return icsneoc2_error_get_settings_failure; +} + +icsneoc2_error_t icsneoc2_settings_linux_configuration_port_set(icsneoc2_device_t* device, icsneoc2_linux_configuration_port_t value) { + // Make sure the device is valid + auto res = icsneoc2_device_is_valid(device); + if(res != icsneoc2_error_success) { + return res; + } + if(!device->device->settings->setLinuxConfigurationPort(static_cast(value))) { + return icsneoc2_error_set_settings_failure; + } + return icsneoc2_error_success; +} + icsneoc2_error_t icsneoc2_settings_disabled_get(icsneoc2_device_t* device, bool* value) { if(!value) { return icsneoc2_error_invalid_parameters; diff --git a/bindings/python/icsneopy/device/idevicesettings.cpp b/bindings/python/icsneopy/device/idevicesettings.cpp index db273c78..71ad4788 100644 --- a/bindings/python/icsneopy/device/idevicesettings.cpp +++ b/bindings/python/icsneopy/device/idevicesettings.cpp @@ -58,6 +58,10 @@ void init_idevicesettings(pybind11::module_& m) { .value("V4", MiscIOAnalogVoltage::V4) .value("V5", MiscIOAnalogVoltage::V5); + pybind11::enum_(settings, "LinuxConfigurationPort") + .value("USB", LinuxConfigurationPort::USB) + .value("ETH01", LinuxConfigurationPort::ETH01); + pybind11::classh(m, "IDeviceSettings") .def("apply", &IDeviceSettings::apply, pybind11::arg("temporary") = 0, pybind11::call_guard()) .def("apply_defaults", &IDeviceSettings::applyDefaults, pybind11::arg("temporary") = 0, pybind11::call_guard()) @@ -142,7 +146,15 @@ void init_idevicesettings(pybind11::module_& m) { .def("set_gptp_enabled_port", &IDeviceSettings::setGPTPEnabledPort, pybind11::call_guard()) .def("is_gptp_clock_syntonization_enabled", &IDeviceSettings::isGPTPClockSyntonizationEnabled, pybind11::call_guard()) .def("set_gptp_clock_syntonization_enabled", &IDeviceSettings::setGPTPClockSyntonizationEnabled, pybind11::call_guard()) - + + // Linux operating-system settings (Fire3 family devices) + .def("get_linux_boot_enabled", &IDeviceSettings::getLinuxBootEnabled, pybind11::call_guard()) + .def("set_linux_boot_enabled", &IDeviceSettings::setLinuxBootEnabled, pybind11::call_guard()) + .def("get_external_wifi_antenna_enabled", &IDeviceSettings::getExternalWifiAntennaEnabled, pybind11::call_guard()) + .def("set_external_wifi_antenna_enabled", &IDeviceSettings::setExternalWifiAntennaEnabled, pybind11::call_guard()) + .def("get_linux_configuration_port", &IDeviceSettings::getLinuxConfigurationPort, pybind11::call_guard()) + .def("set_linux_configuration_port", &IDeviceSettings::setLinuxConfigurationPort, pybind11::call_guard()) + // Status properties .def_readonly("disabled", &IDeviceSettings::disabled) .def_readonly("readonly", &IDeviceSettings::readonly); diff --git a/device/idevicesettings.cpp b/device/idevicesettings.cpp index 06963468..54c5f510 100644 --- a/device/idevicesettings.cpp +++ b/device/idevicesettings.cpp @@ -1035,3 +1035,74 @@ bool IDeviceSettings::setGPTPClockSyntonizationEnabled(bool enable) { gptp->enableClockSyntonization = enable ? 1 : 0; return true; } + +std::optional IDeviceSettings::getLinuxBootEnabled() { + const auto* os = getLinuxSettings(); + if(os == nullptr) { + report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning); + return std::nullopt; + } + return os->allowBoot != 0; +} + +bool IDeviceSettings::setLinuxBootEnabled(bool enabled) { + auto os = getMutableLinuxSettings(); + if(!os) { + report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error); + return false; + } + (*os)->allowBoot = enabled ? 1 : 0; + return true; +} + +std::optional IDeviceSettings::getExternalWifiAntennaEnabled() { + const auto* os = getLinuxSettings(); + if(os == nullptr) { + report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning); + return std::nullopt; + } + return os->useExternalWifiAntenna != 0; +} + +bool IDeviceSettings::setExternalWifiAntennaEnabled(bool enabled) { + auto os = getMutableLinuxSettings(); + if(!os) { + report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error); + return false; + } + (*os)->useExternalWifiAntenna = enabled ? 1 : 0; + return true; +} + +std::optional IDeviceSettings::getLinuxConfigurationPort() { + const auto* os = getLinuxSettings(); + if(os == nullptr) { + report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::EventWarning); + return std::nullopt; + } + switch(static_cast(os->ethConfigurationPort)) { + case LinuxConfigurationPort::ETH01: + return LinuxConfigurationPort::ETH01; + case LinuxConfigurationPort::USB: + default: // Any other value means the configuration interface is over USB + return LinuxConfigurationPort::USB; + } +} + +bool IDeviceSettings::setLinuxConfigurationPort(LinuxConfigurationPort port) { + switch(port) { + case LinuxConfigurationPort::USB: + case LinuxConfigurationPort::ETH01: + break; + default: + report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error); + return false; + } + auto os = getMutableLinuxSettings(); + if(!os) { + report(APIEvent::Type::SettingNotAvaiableDevice, APIEvent::Severity::Error); + return false; + } + (*os)->ethConfigurationPort = static_cast(port); + return true; +} diff --git a/include/icsneo/device/idevicesettings.h b/include/icsneo/device/idevicesettings.h index 20ff84fc..50a2faa6 100644 --- a/include/icsneo/device/idevicesettings.h +++ b/include/icsneo/device/idevicesettings.h @@ -773,6 +773,13 @@ enum class MiscIOAnalogVoltage : uint8_t V5 = icsneoc2_misc_io_analog_voltage_v5 }; +// Selects which Ethernet port(s) are reserved for the Linux configuration interface. +enum class LinuxConfigurationPort : icsneoc2_linux_configuration_port_t +{ + USB = icsneoc2_linux_configuration_port_usb, // Linux configuration interface accessed over USB (default) + ETH01 = icsneoc2_linux_configuration_port_eth01 // ETH 01 reserved for Linux configuration +}; + class IDeviceSettings { public: using TerminationGroup = std::vector; @@ -1302,6 +1309,20 @@ public: virtual const RAD_GPTP_SETTINGS* getGPTPSettings() const { return nullptr; } virtual RAD_GPTP_SETTINGS* getMutableGPTPSettings() { return nullptr; } + /* Linux operating-system settings (Fire3 family devices) */ + + // Whether the device is allowed to boot its Linux operating system. + std::optional getLinuxBootEnabled(); + bool setLinuxBootEnabled(bool enabled); + + // Whether the external WiFi antenna is used (true) instead of the internal antenna (false). + std::optional getExternalWifiAntennaEnabled(); + bool setExternalWifiAntennaEnabled(bool enabled); + + // Which Ethernet port(s) are reserved for the Linux configuration interface. + std::optional getLinuxConfigurationPort(); + bool setLinuxConfigurationPort(LinuxConfigurationPort port); + const void* getRawStructurePointer() const { return settingsInDeviceRAM.data(); } void* getMutableRawStructurePointer() { return settings.data(); } template const T* getStructurePointer() const { return reinterpret_cast(getRawStructurePointer()); } @@ -1334,6 +1355,12 @@ protected: IDeviceSettings(warn_t createInoperableSettings, std::shared_ptr com) : disabled(true), readonly(true), report(com->report), structSize(0) { (void)createInoperableSettings; } + // Devices that embed a Fire3LinuxSettings block in their settings structure override these to + // expose it; all other devices report not-available (nullptr / nullopt) and the Linux accessors + // report not-available in turn. + virtual const Fire3LinuxSettings* getLinuxSettings() const { return nullptr; } + virtual std::optional getMutableLinuxSettings() { return std::nullopt; } + virtual ICSNEO_UNALIGNED(const uint64_t*) getTerminationEnables() const { return nullptr; } virtual ICSNEO_UNALIGNED(uint64_t*) getMutableTerminationEnables() { if(disabled || readonly) diff --git a/include/icsneo/device/tree/neoviconnect/neoviconnectsettings.h b/include/icsneo/device/tree/neoviconnect/neoviconnectsettings.h index 3c491f78..a7edd9e8 100644 --- a/include/icsneo/device/tree/neoviconnect/neoviconnectsettings.h +++ b/include/icsneo/device/tree/neoviconnect/neoviconnectsettings.h @@ -89,6 +89,16 @@ static_assert(sizeof(neoviconnect_settings_t) == 628, "NeoVIConnect settings siz class NeoVIConnectSettings : public IDeviceSettings { public: NeoVIConnectSettings(std::shared_ptr com) : IDeviceSettings(com, sizeof(neoviconnect_settings_t)) {} + const Fire3LinuxSettings* getLinuxSettings() const override { + auto cfg = getStructurePointer(); + return cfg ? &cfg->os_settings : nullptr; + } + std::optional getMutableLinuxSettings() override { + auto cfg = getMutableStructurePointer(); + if(cfg == nullptr) + return std::nullopt; + return &cfg->os_settings; + } const CAN_SETTINGS* getCANSettingsFor(Network net) const override { auto cfg = getStructurePointer(); if(cfg == nullptr) diff --git a/include/icsneo/device/tree/neovifire3/neovifire3settings.h b/include/icsneo/device/tree/neovifire3/neovifire3settings.h index 442434c6..b46835f9 100644 --- a/include/icsneo/device/tree/neovifire3/neovifire3settings.h +++ b/include/icsneo/device/tree/neovifire3/neovifire3settings.h @@ -167,6 +167,16 @@ static_assert(sizeof(neovifire3_settings_t) == 1722, "NeoVIFire3 settings size m class NeoVIFIRE3Settings : public IDeviceSettings { public: NeoVIFIRE3Settings(std::shared_ptr com) : IDeviceSettings(com, sizeof(neovifire3_settings_t)) {} + const Fire3LinuxSettings* getLinuxSettings() const override { + auto cfg = getStructurePointer(); + return cfg ? &cfg->os_settings : nullptr; + } + std::optional getMutableLinuxSettings() override { + auto cfg = getMutableStructurePointer(); + if(cfg == nullptr) + return std::nullopt; + return &cfg->os_settings; + } const CAN_SETTINGS* getCANSettingsFor(Network net) const override { auto cfg = getStructurePointer(); if(cfg == nullptr) diff --git a/include/icsneo/device/tree/neovifire3flexray/neovifire3flexraysettings.h b/include/icsneo/device/tree/neovifire3flexray/neovifire3flexraysettings.h index 62e698d8..cb610f2a 100644 --- a/include/icsneo/device/tree/neovifire3flexray/neovifire3flexraysettings.h +++ b/include/icsneo/device/tree/neovifire3flexray/neovifire3flexraysettings.h @@ -150,6 +150,16 @@ static_assert(sizeof(neovifire3flexray_settings_t) == 1372, "NeoVIFire3Flexray s class NeoVIFIRE3FlexRaySettings : public IDeviceSettings { public: NeoVIFIRE3FlexRaySettings(std::shared_ptr com) : IDeviceSettings(com, sizeof(neovifire3flexray_settings_t)) {} + const Fire3LinuxSettings* getLinuxSettings() const override { + auto cfg = getStructurePointer(); + return cfg ? &cfg->os_settings : nullptr; + } + std::optional getMutableLinuxSettings() override { + auto cfg = getMutableStructurePointer(); + if(cfg == nullptr) + return std::nullopt; + return &cfg->os_settings; + } const CAN_SETTINGS* getCANSettingsFor(Network net) const override { auto cfg = getStructurePointer(); if(cfg == nullptr) diff --git a/include/icsneo/device/tree/neovifire3t1slin/neovifire3t1slinsettings.h b/include/icsneo/device/tree/neovifire3t1slin/neovifire3t1slinsettings.h index 08595d7d..80a5bd10 100644 --- a/include/icsneo/device/tree/neovifire3t1slin/neovifire3t1slinsettings.h +++ b/include/icsneo/device/tree/neovifire3t1slin/neovifire3t1slinsettings.h @@ -159,6 +159,16 @@ static_assert(sizeof(neovifire3t1slin_settings_t) == 1594, "NeoVIFire3T1SLIN set class NeoVIFIRE3T1SLINSettings : public IDeviceSettings { public: NeoVIFIRE3T1SLINSettings(std::shared_ptr com) : IDeviceSettings(com, sizeof(neovifire3t1slin_settings_t)) {} + const Fire3LinuxSettings* getLinuxSettings() const override { + auto cfg = getStructurePointer(); + return cfg ? &cfg->os_settings : nullptr; + } + std::optional getMutableLinuxSettings() override { + auto cfg = getMutableStructurePointer(); + if(cfg == nullptr) + return std::nullopt; + return &cfg->os_settings; + } const CAN_SETTINGS* getCANSettingsFor(Network net) const override { auto cfg = getStructurePointer(); if(cfg == nullptr) diff --git a/include/icsneo/device/tree/neovired2/neovired2settings.h b/include/icsneo/device/tree/neovired2/neovired2settings.h index d21c9d8e..d2c90da4 100644 --- a/include/icsneo/device/tree/neovired2/neovired2settings.h +++ b/include/icsneo/device/tree/neovired2/neovired2settings.h @@ -112,6 +112,16 @@ static_assert(sizeof(neovired2_settings_t) == 918, "NeoVIRED2 settings size mism class NeoVIRED2Settings : public IDeviceSettings { public: NeoVIRED2Settings(std::shared_ptr com) : IDeviceSettings(com, sizeof(neovired2_settings_t)) {} + const Fire3LinuxSettings* getLinuxSettings() const override { + auto cfg = getStructurePointer(); + return cfg ? &cfg->os_settings : nullptr; + } + std::optional getMutableLinuxSettings() override { + auto cfg = getMutableStructurePointer(); + if(cfg == nullptr) + return std::nullopt; + return &cfg->os_settings; + } const CAN_SETTINGS* getCANSettingsFor(Network net) const override { auto cfg = getStructurePointer(); if(cfg == nullptr) diff --git a/include/icsneo/icsneoc2settings.h b/include/icsneo/icsneoc2settings.h index 616efc91..602492e0 100644 --- a/include/icsneo/icsneoc2settings.h +++ b/include/icsneo/icsneoc2settings.h @@ -656,6 +656,66 @@ icsneoc2_error_t icsneoc2_settings_misc_io_analog_output_enabled_set(icsneoc2_de */ icsneoc2_error_t icsneoc2_settings_misc_io_analog_output_set(icsneoc2_device_t* device, uint8_t pin, icsneoc2_misc_io_analog_voltage_t value); +/** + * Get whether the device is allowed to boot its Linux operating system (Fire3 family devices). + * + * @param[in] device The device to query. + * @param[out] value Pointer to a bool to copy the value into. + * + * @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_get_settings_failure otherwise. + */ +icsneoc2_error_t icsneoc2_settings_linux_boot_enabled_get(icsneoc2_device_t* device, bool* value); + +/** + * Set whether the device is allowed to boot its Linux operating system (Fire3 family devices). + * + * @param[in] device The device to configure. + * @param[in] value true to allow Linux to boot, false to prevent it. + * + * @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_set_settings_failure otherwise. + */ +icsneoc2_error_t icsneoc2_settings_linux_boot_enabled_set(icsneoc2_device_t* device, bool value); + +/** + * Get whether the external WiFi antenna is used instead of the internal antenna (Fire3 family devices). + * + * @param[in] device The device to query. + * @param[out] value Pointer to a bool to copy the value into (true for external, false for internal). + * + * @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_get_settings_failure otherwise. + */ +icsneoc2_error_t icsneoc2_settings_external_wifi_antenna_enabled_get(icsneoc2_device_t* device, bool* value); + +/** + * Set whether the external WiFi antenna is used instead of the internal antenna (Fire3 family devices). + * + * @param[in] device The device to configure. + * @param[in] value true to use the external antenna, false to use the internal antenna. + * + * @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_set_settings_failure otherwise. + */ +icsneoc2_error_t icsneoc2_settings_external_wifi_antenna_enabled_set(icsneoc2_device_t* device, bool value); + +/** + * Get which Ethernet port(s) are reserved for the Linux configuration interface (Fire3 family devices). + * + * @param[in] device The device to query. + * @param[out] value Pointer to a icsneoc2_linux_configuration_port_t to copy the value into. + * + * @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_get_settings_failure otherwise. + */ +icsneoc2_error_t icsneoc2_settings_linux_configuration_port_get(icsneoc2_device_t* device, icsneoc2_linux_configuration_port_t* value); + +/** + * Set which Ethernet port(s) are reserved for the Linux configuration interface (Fire3 family devices). + * + * @param[in] device The device to configure. + * @param[in] value The configuration port selection to set. + * + * @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_set_settings_failure otherwise. + */ +icsneoc2_error_t icsneoc2_settings_linux_configuration_port_set(icsneoc2_device_t* device, icsneoc2_linux_configuration_port_t value); + /** * Check if settings are disabled. * diff --git a/include/icsneo/icsneoc2types.h b/include/icsneo/icsneoc2types.h index d7848ddf..b3bf15cc 100644 --- a/include/icsneo/icsneoc2types.h +++ b/include/icsneo/icsneoc2types.h @@ -387,6 +387,16 @@ typedef struct icsneoc2_gptp_status_t { uint8_t short_format; // Non-zero if firmware returned a partial response } icsneoc2_gptp_status_t; +typedef enum _icsneoc2_linux_configuration_port_t { + icsneoc2_linux_configuration_port_usb = 0, // Linux configuration interface accessed over USB (default) + icsneoc2_linux_configuration_port_eth01 = 1, // ETH 01 reserved for the Linux configuration interface + + // Must be last entry. Don't use as a configuration port. + icsneoc2_linux_configuration_port_maxsize +} _icsneoc2_linux_configuration_port_t; + +typedef uint32_t icsneoc2_linux_configuration_port_t; + typedef struct icsneoc2_disk_details_t icsneoc2_disk_details_t; typedef enum _icsneoc2_disk_layout_t { diff --git a/test/unit/icsneoc2.cpp b/test/unit/icsneoc2.cpp index 74d7a556..c36ade50 100644 --- a/test/unit/icsneoc2.cpp +++ b/test/unit/icsneoc2.cpp @@ -139,6 +139,7 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device) icsneoc2_eth_phy_link_mode_t placeholderEthPhyLinkMode = 0; icsneoc2_eth_phy_link_mode_t* placeholderEthPhyLinkModePtr = nullptr; icsneoc2_misc_io_analog_voltage_t placeholderMiscIoAnalogVoltage = 0; + icsneoc2_linux_configuration_port_t placeholderLinuxConfigPort = 0; // All of these don't have a device parameter ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_enumerate(0, NULL)); @@ -296,6 +297,12 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device) ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_t1s_multi_id_set(NULL, 0, 0, placeholderInteger8)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_misc_io_analog_output_enabled_set(NULL, 0, placeholderInteger8)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_misc_io_analog_output_set(NULL, 0, placeholderMiscIoAnalogVoltage)); + ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_linux_boot_enabled_get(NULL, &placeholderBool)); + ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_linux_boot_enabled_set(NULL, false)); + ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_external_wifi_antenna_enabled_get(NULL, &placeholderBool)); + ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_external_wifi_antenna_enabled_set(NULL, false)); + ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_linux_configuration_port_get(NULL, &placeholderLinuxConfigPort)); + ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_linux_configuration_port_set(NULL, placeholderLinuxConfigPort)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_disabled_get(NULL, &placeholderBool)); ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_settings_readonly_get(NULL, &placeholderBool));