mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-04-15 09:38:16 +00:00
715 lines
24 KiB
C++
715 lines
24 KiB
C++
/********************************************************************************
|
|
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
|
*
|
|
* This program and the accompanying materials are made available under the
|
|
* terms of the Apache License Version 2.0 which is available at
|
|
* https://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Contributors:
|
|
* Erik Verhoeven - initial API and implementation
|
|
********************************************************************************/
|
|
|
|
#include "app_settings.h"
|
|
#include "toml_parser/parser_toml.h"
|
|
#include "../../global/flags.h"
|
|
#include "../../global/exec_dir_helper.h"
|
|
#include "../../global/ipc_named_mutex.h"
|
|
#include <support/toml.h>
|
|
|
|
CAppSettings& GetAppSettings()
|
|
{
|
|
static CAppSettings app_settings;
|
|
return app_settings;
|
|
}
|
|
|
|
CAppSettings::CAppSettings()
|
|
{}
|
|
|
|
CAppSettings::~CAppSettings()
|
|
{}
|
|
|
|
bool CAppSettings::ProcessAppStartupConfig(const sdv::u8string& rssConfig)
|
|
{
|
|
toml_parser::CParser parserStartupConfig;
|
|
std::string ssError;
|
|
try
|
|
{
|
|
// Read the configuration
|
|
if (!parserStartupConfig.Process(rssConfig))
|
|
return false;
|
|
}
|
|
catch (const sdv::toml::XTOMLParseException& rexcept)
|
|
{
|
|
ssError = std::string("ERROR: Failed to parse application configuration: ") + rexcept.what();
|
|
}
|
|
|
|
sdv::toml::CNodeCollection tableStartupConfig(&parserStartupConfig.Root());
|
|
|
|
// Get the reporting settings (if this succeeded at all...)
|
|
m_bSilent = tableStartupConfig.GetDirect("Console.Report").GetValue().get<std::string>() == "Silent";
|
|
m_bVerbose = tableStartupConfig.GetDirect("Console.Report").GetValue().get<std::string>() == "Verbose";
|
|
|
|
// Report the outstanding error (if there is one...)
|
|
if (!ssError.empty())
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << ssError << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// Allow a custom logger to be defined
|
|
m_pathLoggerModule = tableStartupConfig.GetDirect("LogHandler.Path").GetValue().get<std::string>();
|
|
m_ssLoggerClass = tableStartupConfig.GetDirect("LogHandler.Class").GetValue().get<std::string>();
|
|
if (m_ssLoggerClass.empty())
|
|
m_ssLoggerClass = "DefaultLoggerService";
|
|
|
|
// Get an optional program tag for the logger
|
|
m_ssProgramTag = tableStartupConfig.GetDirect("LogHandler.Tag").GetValue().get<std::string>();
|
|
|
|
// Get the application-mode
|
|
std::string ssApplication = tableStartupConfig.GetDirect("Application.Mode").GetValue();
|
|
if (ssApplication.empty()) ssApplication = "Standalone";
|
|
if (ssApplication == "Standalone")
|
|
m_eContextMode = sdv::app::EAppContext::standalone;
|
|
else if (ssApplication == "External")
|
|
m_eContextMode = sdv::app::EAppContext::external;
|
|
else if (ssApplication == "Isolated")
|
|
m_eContextMode = sdv::app::EAppContext::isolated;
|
|
else if (ssApplication == "Main")
|
|
m_eContextMode = sdv::app::EAppContext::main;
|
|
else if (ssApplication == "Essential")
|
|
m_eContextMode = sdv::app::EAppContext::essential;
|
|
else if (ssApplication == "Maintenance")
|
|
m_eContextMode = sdv::app::EAppContext::maintenance;
|
|
else
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << "ERROR: Failed to process startup config: invalid application-mode specified for core library: "
|
|
<< ssApplication << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// Get the severity level filter for the logger
|
|
auto fnTranslateSevFilter = [this](const std::string& rssLogFilter, const sdv::core::ELogSeverity eDefault)
|
|
{
|
|
sdv::core::ELogSeverity eSeverityFilter = eDefault;
|
|
if (rssLogFilter == "Trace")
|
|
eSeverityFilter = sdv::core::ELogSeverity::trace;
|
|
else if (rssLogFilter == "Debug")
|
|
eSeverityFilter = sdv::core::ELogSeverity::debug;
|
|
else if (rssLogFilter == "Info")
|
|
eSeverityFilter = sdv::core::ELogSeverity::info;
|
|
else if (rssLogFilter == "Warning")
|
|
eSeverityFilter = sdv::core::ELogSeverity::warning;
|
|
else if (rssLogFilter == "Error")
|
|
eSeverityFilter = sdv::core::ELogSeverity::error;
|
|
else if (rssLogFilter == "Fatal")
|
|
eSeverityFilter = sdv::core::ELogSeverity::fatal;
|
|
else if (!rssLogFilter.empty())
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << "ERROR: Failed to process application log: invalid severity level filter: '" << rssLogFilter << "'"
|
|
<< std::endl;
|
|
}
|
|
return eSeverityFilter;
|
|
};
|
|
sdv::core::ELogSeverity eLogDefaultViewSeverityFilter = sdv::core::ELogSeverity::error;
|
|
if (IsMainApplication() || IsIsolatedApplication()) eLogDefaultViewSeverityFilter = sdv::core::ELogSeverity::info;
|
|
m_eSeverityFilter = fnTranslateSevFilter(tableStartupConfig.GetDirect("LogHandler.Filter").GetValue(),
|
|
sdv::core::ELogSeverity::info);
|
|
m_eSeverityViewFilter = fnTranslateSevFilter(
|
|
tableStartupConfig.GetDirect("LogHandler.ViewFilter").GetValue(), eLogDefaultViewSeverityFilter);
|
|
|
|
// Get the optional instance ID.
|
|
sdv::any_t anyInstanceID = tableStartupConfig.GetDirect("Application.Instance").GetValue();
|
|
if (anyInstanceID) m_uiInstanceID = anyInstanceID;
|
|
else
|
|
m_uiInstanceID = 1000u;
|
|
|
|
// Number of attempts to establish a connection to a running instance.
|
|
m_uiRetries = tableStartupConfig.GetDirect("Application.Retries").GetValue();
|
|
if (m_uiRetries > 30)
|
|
m_uiRetries = 30;
|
|
else if (m_uiRetries < 3)
|
|
m_uiRetries = 3;
|
|
|
|
// Main and isolated apps specific information.
|
|
if (IsMainApplication() || IsIsolatedApplication() || IsMaintenanceApplication())
|
|
{
|
|
// Get the optional installation directory.
|
|
m_pathRootDir = tableStartupConfig.GetDirect("Application.InstallDir").GetValueAsPath();
|
|
if (!m_pathRootDir.empty())
|
|
{
|
|
if (m_pathRootDir.is_relative())
|
|
m_pathRootDir = GetExecDirectory() / m_pathRootDir;
|
|
}
|
|
else
|
|
m_pathRootDir = GetExecDirectory();
|
|
m_pathInstallDir = m_pathRootDir / std::to_string(m_uiInstanceID);
|
|
try
|
|
{
|
|
std::filesystem::create_directories(m_pathInstallDir);
|
|
}
|
|
catch (const std::filesystem::filesystem_error& rexcept)
|
|
{
|
|
if (!m_bSilent)
|
|
{
|
|
std::cerr << "Cannot create installation directory: " << m_pathInstallDir << std::endl;
|
|
std::cerr << " Reason: " << rexcept.what() << std::endl;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Maintenance, main and isolated applications cannot load specific configs. The others can specify a configuration file, but
|
|
// not auto-updateable.
|
|
if (!IsMainApplication() && !IsMaintenanceApplication() && !IsIsolatedApplication())
|
|
m_pathUserConfig = tableStartupConfig.GetDirect("Application.Config").GetValueAsPath();
|
|
|
|
// Read the settings... if existing. And only for the main application
|
|
if (IsMainApplication() && !LoadSettingsFile())
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CAppSettings::LoadSettingsFile()
|
|
{
|
|
// Check for the proper context
|
|
switch (m_eContextMode)
|
|
{
|
|
case sdv::app::EAppContext::main:
|
|
case sdv::app::EAppContext::isolated:
|
|
case sdv::app::EAppContext::maintenance:
|
|
break;
|
|
default:
|
|
return true; // Not an error...
|
|
}
|
|
|
|
// If the template is not existing, this is not an error...
|
|
if (!std::filesystem::exists(m_pathInstallDir / "settings.toml"))
|
|
return true;
|
|
|
|
std::ifstream fstream(m_pathInstallDir / "settings.toml");
|
|
std::string ssSettings((std::istreambuf_iterator<char>(fstream)), std::istreambuf_iterator<char>());
|
|
fstream.close();
|
|
|
|
try
|
|
{
|
|
// Read the configuration
|
|
toml_parser::CParser parserSettings(ssSettings);
|
|
|
|
// If there is no "Settings" table, this is not an error...
|
|
sdv::toml::CNodeCollection tableSettings(parserSettings.Root().GetNodeDirect("Settings"));
|
|
if (!tableSettings) return true;
|
|
|
|
// Check for the version
|
|
uint32_t uiVersion = tableSettings.GetDirect("Version").GetValue();
|
|
if (uiVersion != SDVFrameworkInterfaceVersion)
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << "ERROR: Invalid version of application settings file (expected version "
|
|
<< SDVFrameworkInterfaceVersion << ", but available version " << uiVersion << ")" << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// Get the platform config - but only when not specified over the app-control-config.
|
|
if (m_pathPlatformConfig.empty())
|
|
m_pathPlatformConfig = tableSettings.GetDirect("PlatformConfig").GetValueAsPath();
|
|
|
|
// Get the vehicle interface config - but only when not specified over the app-control-config.
|
|
if (m_pathVehIfcConfig.empty())
|
|
m_pathVehIfcConfig = tableSettings.GetDirect("VehIfcConfig").GetValueAsPath();
|
|
|
|
// Get the vehicle abstraction config - but only when not specified over the app-control-config.
|
|
if (m_pathVehAbstrConfig.empty())
|
|
m_pathVehAbstrConfig = tableSettings.GetDirect("VehAbstrConfig").GetValueAsPath();
|
|
|
|
// Get the application config - but only when not specified over the app-control-config.
|
|
if (m_pathUserConfig.empty())
|
|
m_pathUserConfig = tableSettings.GetDirect("AppConfig").GetValueAsPath();
|
|
}
|
|
catch (const sdv::toml::XTOMLParseException& rexcept)
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << "ERROR: Failed to parse application settings: " << rexcept.what() << std::endl;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CAppSettings::SaveSettingsFile()
|
|
{
|
|
// Check for the proper context
|
|
switch (m_eContextMode)
|
|
{
|
|
case sdv::app::EAppContext::main:
|
|
case sdv::app::EAppContext::isolated:
|
|
case sdv::app::EAppContext::maintenance:
|
|
break;
|
|
default:
|
|
return true; // Not an error...
|
|
}
|
|
|
|
// Protect against multiple write actions at the same time.
|
|
ipc::named_mutex mtx("LockSdvAppSettings_" + std::to_string(m_uiInstanceID));
|
|
// Warning of cppcheck for locking a local mutex, which doesn't have any effect. Since this is a named mutex between
|
|
// applciations, the warning is not correct. Suppress warning.
|
|
// cppcheck-suppress localMutex
|
|
std::unique_lock<ipc::named_mutex> lock(mtx);
|
|
|
|
const std::string ssSettingsTemplate = R"toml(# Settings file
|
|
[Settings]
|
|
Version = )toml" + std::to_string(SDVFrameworkInterfaceVersion) + R"toml(
|
|
|
|
# The system configuration is divided into:
|
|
# platform config - containing all the components needed to interact with the OS,
|
|
# middleware, vehicle bus, Ethernet.
|
|
# vehicle interface - containing the vehicle bus interpretation components like data link
|
|
# based on DBC and devices for their abstraction.
|
|
# vehicle abstraction - containing the vehicle abstraction services
|
|
# The configuration files are loaded exactly in that order, allowing the vehicle interface to
|
|
# depend on the platform and the vehicle abstraction to depend on the vehicle interface.
|
|
# The configurations are loaded if the PlatformConfig, VehIfcConfig and VehAbstrConfig keywords
|
|
# are present and describe a valid configuration file.
|
|
# A relative path is relative to the installation directory (being "exe_location/instance_id").
|
|
#
|
|
# Example:
|
|
# PlatformConfig = "platform.toml"
|
|
# VehIfcConfig = "vehicle_ifc.toml"
|
|
# VehAbstrConfig = "vehicle_abstract.toml"
|
|
#
|
|
PlatformConfig = ""
|
|
VehIfcConfig = ""
|
|
VehAbstrConfig = ""
|
|
|
|
# The application config contains the configuration file that can be updated when services and
|
|
# apps are being added to the system (or being removed from the system). Load the application
|
|
# config by providing the "AppConfig" keyword as a string value. A relative path is relative to
|
|
# the installation directory (being "exe_location/instance_id").
|
|
#
|
|
# Example
|
|
# AppConfig = "app_config.toml"
|
|
AppConfig = ""
|
|
)toml";
|
|
|
|
// If the template is not existing, create a default settings file...
|
|
std::string ssSettings;
|
|
bool bChangeDetected = false;
|
|
if (!std::filesystem::exists(m_pathInstallDir / "settings.toml"))
|
|
{
|
|
bChangeDetected = true;
|
|
ssSettings = std::move(ssSettingsTemplate);
|
|
m_bPlatformConfig = true;
|
|
m_bVehIfcConfig = true;
|
|
m_bVehAbstrConfig = true;
|
|
m_bUserConfig = true;
|
|
}
|
|
else
|
|
{
|
|
// Open the existing settings file
|
|
std::ifstream fstream(m_pathInstallDir / "settings.toml");
|
|
if (!fstream.is_open())
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << "ERROR: Cannot open the application settings file." << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// Read the settings file
|
|
ssSettings = std::string((std::istreambuf_iterator<char>(fstream)), std::istreambuf_iterator<char>());
|
|
if (ssSettings.empty())
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << "ERROR: Cannot read the application settings file; will use default." << std::endl;
|
|
ssSettings = std::move(ssSettingsTemplate);
|
|
bChangeDetected = true;
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
// Read the settings
|
|
toml_parser::CParser parserSettings(ssSettings);
|
|
|
|
// Check for the version
|
|
sdv::toml::CNodeCollection tableRoot(&parserSettings.Root());
|
|
if (!tableRoot)
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << "ERROR: Invalid TOML file '" << (m_pathInstallDir / "settings.toml").generic_u8string() << "'"
|
|
<<
|
|
std::endl;
|
|
return false;
|
|
}
|
|
sdv::toml::CNodeCollection tableSettings = tableRoot.GetDirect("Settings");
|
|
if (!tableSettings)
|
|
tableSettings = tableRoot.AddTable("Settings");
|
|
if (!tableSettings)
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << "ERROR: Invalid 'Settings' table." << std::endl;
|
|
return false;
|
|
}
|
|
|
|
uint32_t uiVersion = tableSettings.GetDirect("Version").GetValue();
|
|
if (uiVersion != SDVFrameworkInterfaceVersion)
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << "ERROR: Invalid version of application settings file (expected version "
|
|
<< SDVFrameworkInterfaceVersion << ", but available version " << uiVersion << ")" << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// Generic update config file function
|
|
auto fnUpdateConfig = [&](const std::string &rssConfigKey, const std::filesystem::path& rpathConfigFile)
|
|
{
|
|
sdv::toml::CNode nodeUserConfig = tableSettings.GetDirect(rssConfigKey);
|
|
if (nodeUserConfig.GetValue().empty())
|
|
{
|
|
bChangeDetected = true;
|
|
if (nodeUserConfig)
|
|
nodeUserConfig.Delete();
|
|
nodeUserConfig = tableSettings.AddValue(rssConfigKey, rpathConfigFile);
|
|
if (!nodeUserConfig)
|
|
{
|
|
if (!m_bSilent) std::cerr << "ERROR: Cannot insert the \"Settings." << rssConfigKey <<
|
|
"\" value; cannot process further." << std::endl;
|
|
return false;
|
|
}
|
|
}
|
|
else if (nodeUserConfig.GetValue() != rpathConfigFile)
|
|
{
|
|
bChangeDetected = true;
|
|
if (!nodeUserConfig.SetValue(rpathConfigFile))
|
|
{
|
|
if (!m_bSilent) std::cerr << "ERROR: Cannot update the \"Settings." << rssConfigKey <<
|
|
"\" value; cannot process further." << std::endl;
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
|
|
// Update the configuration path values.
|
|
if (m_bPlatformConfig && !fnUpdateConfig("PlatformConfig", m_pathPlatformConfig)) return false;
|
|
if (m_bVehIfcConfig && !fnUpdateConfig("VehIfcConfig", m_pathVehIfcConfig)) return false;
|
|
if (m_bVehAbstrConfig && !fnUpdateConfig("VehAbstrConfig", m_pathVehAbstrConfig)) return false;
|
|
if (m_bUserConfig && !fnUpdateConfig("AppConfig", m_pathUserConfig)) return false;
|
|
|
|
// Save the settings file if needed
|
|
if (bChangeDetected)
|
|
{
|
|
std::ofstream fstream(m_pathInstallDir / "settings.toml", std::ios::trunc);
|
|
if (!fstream.is_open())
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << "ERROR: Cannot write the application settings file." << std::endl;
|
|
return false;
|
|
}
|
|
fstream << parserSettings.GenerateTOML();
|
|
|
|
m_bPlatformConfig = false;
|
|
m_bVehIfcConfig = false;
|
|
m_bVehAbstrConfig = false;
|
|
m_bUserConfig = false;
|
|
}
|
|
}
|
|
catch (const sdv::toml::XTOMLParseException& rexcept)
|
|
{
|
|
if (!m_bSilent)
|
|
std::cerr << "ERROR: Failed to parse application settings: " << rexcept.what() << std::endl;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CAppSettings::IsMainApplication() const
|
|
{
|
|
return m_eContextMode == sdv::app::EAppContext::main;
|
|
}
|
|
|
|
bool CAppSettings::IsIsolatedApplication() const
|
|
{
|
|
return m_eContextMode == sdv::app::EAppContext::isolated;
|
|
}
|
|
|
|
bool CAppSettings::IsStandaloneApplication() const
|
|
{
|
|
return m_eContextMode == sdv::app::EAppContext::standalone;
|
|
}
|
|
|
|
bool CAppSettings::IsEssentialApplication() const
|
|
{
|
|
return m_eContextMode == sdv::app::EAppContext::essential;
|
|
}
|
|
|
|
bool CAppSettings::IsMaintenanceApplication() const
|
|
{
|
|
return m_eContextMode == sdv::app::EAppContext::maintenance;
|
|
}
|
|
|
|
bool CAppSettings::IsExternalApplication() const
|
|
{
|
|
return m_eContextMode == sdv::app::EAppContext::external;
|
|
}
|
|
|
|
sdv::app::EAppContext CAppSettings::GetContextType() const
|
|
{
|
|
return m_eContextMode;
|
|
}
|
|
|
|
uint32_t CAppSettings::GetInstanceID() const
|
|
{
|
|
return m_uiInstanceID;
|
|
}
|
|
|
|
uint32_t CAppSettings::GetRetries() const
|
|
{
|
|
return m_uiRetries;
|
|
}
|
|
|
|
std::string CAppSettings::GetLoggerClass() const
|
|
{
|
|
return m_ssLoggerClass;
|
|
}
|
|
|
|
std::filesystem::path CAppSettings::GetLoggerModulePath() const
|
|
{
|
|
return m_pathLoggerModule;
|
|
}
|
|
|
|
std::string CAppSettings::GetLoggerProgramTag() const
|
|
{
|
|
return m_ssProgramTag;
|
|
}
|
|
|
|
sdv::core::ELogSeverity CAppSettings::GetLoggerSeverityFilter() const
|
|
{
|
|
return m_eSeverityFilter;
|
|
}
|
|
|
|
sdv::core::ELogSeverity CAppSettings::GetConsoleSeverityFilter() const
|
|
{
|
|
return m_eSeverityViewFilter;
|
|
}
|
|
|
|
bool CAppSettings::IsConsoleSilent() const
|
|
{
|
|
return m_bSilent;
|
|
}
|
|
|
|
bool CAppSettings::IsConsoleVerbose() const
|
|
{
|
|
return m_bVerbose;
|
|
}
|
|
|
|
std::filesystem::path CAppSettings::GetRootDir() const
|
|
{
|
|
return m_pathRootDir;
|
|
}
|
|
|
|
std::filesystem::path CAppSettings::GetInstallDir() const
|
|
{
|
|
return m_pathInstallDir;
|
|
}
|
|
|
|
std::vector<std::filesystem::path> CAppSettings::GetSystemConfigPaths() const
|
|
{
|
|
std::vector<std::filesystem::path> vecSysConfigs;
|
|
if (!m_pathPlatformConfig.empty())
|
|
vecSysConfigs.push_back(m_pathPlatformConfig);
|
|
if (!m_pathVehIfcConfig.empty())
|
|
vecSysConfigs.push_back(m_pathVehIfcConfig);
|
|
if (!m_pathVehAbstrConfig.empty())
|
|
vecSysConfigs.push_back(m_pathVehAbstrConfig);
|
|
return vecSysConfigs;
|
|
}
|
|
|
|
std::filesystem::path CAppSettings::GetConfigPath(EConfigType eType) const
|
|
{
|
|
// Is running as main application?
|
|
if (!IsMainApplication() && !IsMaintenanceApplication()) return {};
|
|
|
|
switch (eType)
|
|
{
|
|
case EConfigType::platform_config:
|
|
if (!m_pathPlatformConfig.empty()) return m_pathPlatformConfig;
|
|
return "platform.toml";
|
|
case EConfigType::vehicle_interface_config:
|
|
if (!m_pathVehIfcConfig.empty()) return m_pathVehIfcConfig;
|
|
return "vehicle_ifc.toml";
|
|
case EConfigType::vehicle_abstraction_config:
|
|
if (!m_pathVehAbstrConfig.empty()) return m_pathVehAbstrConfig;
|
|
return "vehicle_abstract.toml";
|
|
case EConfigType::user_config:
|
|
if (!m_pathUserConfig.empty()) return m_pathUserConfig;
|
|
return "app_config.toml";
|
|
default:
|
|
return {};
|
|
}
|
|
}
|
|
|
|
|
|
bool CAppSettings::EnableConfig(EConfigType eType)
|
|
{
|
|
// Is running as main application?
|
|
if (!IsMainApplication() && !IsMaintenanceApplication()) return false;
|
|
|
|
switch (eType)
|
|
{
|
|
case EConfigType::platform_config:
|
|
m_bPlatformConfig = true;
|
|
if (!m_pathPlatformConfig.empty()) return true;
|
|
m_pathPlatformConfig = "platform.toml";
|
|
break;
|
|
case EConfigType::vehicle_interface_config:
|
|
m_bVehIfcConfig = true;
|
|
if (!m_pathVehIfcConfig.empty()) return true;
|
|
m_pathVehIfcConfig = "vehicle_ifc.toml";
|
|
break;
|
|
case EConfigType::vehicle_abstraction_config:
|
|
m_bVehAbstrConfig = true;
|
|
if (!m_pathVehAbstrConfig.empty()) return true;
|
|
m_pathVehAbstrConfig = "vehicle_abstract.toml";
|
|
break;
|
|
case EConfigType::user_config:
|
|
m_bUserConfig = true;
|
|
if (!m_pathUserConfig.empty()) return true;
|
|
m_pathUserConfig = "app_config.toml";
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CAppSettings::DisableConfig(EConfigType eType)
|
|
{
|
|
// Is running as main application?
|
|
if (!IsMainApplication() && !IsMaintenanceApplication()) return false;
|
|
|
|
switch (eType)
|
|
{
|
|
case EConfigType::platform_config:
|
|
m_pathPlatformConfig.clear();
|
|
m_bPlatformConfig = true;
|
|
break;
|
|
case EConfigType::vehicle_interface_config:
|
|
m_pathVehIfcConfig.clear();
|
|
m_bVehIfcConfig = true;
|
|
break;
|
|
case EConfigType::vehicle_abstraction_config:
|
|
m_pathVehAbstrConfig.clear();
|
|
m_bVehAbstrConfig = true;
|
|
break;
|
|
case EConfigType::user_config:
|
|
m_pathUserConfig.clear();
|
|
m_bUserConfig = true;
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
std::filesystem::path CAppSettings::GetUserConfigPath() const
|
|
{
|
|
return m_pathUserConfig;
|
|
}
|
|
|
|
bool CAppSettings::SetUserConfigPath(const std::filesystem::path& rpathConfig)
|
|
{
|
|
// Is running as server application? Then the user configuration is limited to a filename only.
|
|
if (IsMainApplication() || IsMaintenanceApplication() || IsIsolatedApplication())
|
|
{
|
|
// Must be a filename only.
|
|
if (!rpathConfig.has_filename() || rpathConfig.has_parent_path())
|
|
return false;
|
|
}
|
|
|
|
// Assign the path
|
|
m_pathUserConfig = rpathConfig;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CAppSettings::RemoveUserConfigPath()
|
|
{
|
|
// Is running as main application?
|
|
if (!IsMainApplication()) return false;
|
|
|
|
// Clear the path
|
|
m_pathUserConfig.clear();
|
|
|
|
return true;
|
|
}
|
|
|
|
sdv::sequence<sdv::u8string> CAppSettings::GetNames() const
|
|
{
|
|
sdv::sequence<sdv::u8string> seqNames = {"app.instance_id", "console.info_level"};
|
|
return seqNames;
|
|
}
|
|
|
|
sdv::any_t CAppSettings::Get(/*in*/ const sdv::u8string& ssAttribute) const
|
|
{
|
|
if (ssAttribute == "app.instance_id")
|
|
return sdv::any_t(m_uiInstanceID);
|
|
if (ssAttribute == "console.info_level")
|
|
{
|
|
if (m_bSilent)
|
|
return "silent";
|
|
if (m_bVerbose)
|
|
return "verbose";
|
|
return "normal";
|
|
}
|
|
return {};
|
|
}
|
|
|
|
bool CAppSettings::Set(/*in*/ const sdv::u8string& /*ssAttribute*/, /*in*/ sdv::any_t /*anyAttribute*/)
|
|
{
|
|
// Currently there are not setting attributes...
|
|
return false;
|
|
}
|
|
|
|
uint32_t CAppSettings::GetFlags(/*in*/ const sdv::u8string& ssAttribute) const
|
|
{
|
|
if (ssAttribute == "app.instance_id")
|
|
return hlpr::flags<sdv::EAttributeFlags>(sdv::EAttributeFlags::read_only);
|
|
if (ssAttribute == "console.info_level")
|
|
return hlpr::flags<sdv::EAttributeFlags>(sdv::EAttributeFlags::read_only);
|
|
return 0u;
|
|
}
|
|
|
|
void CAppSettings::Reset()
|
|
{
|
|
m_eContextMode = sdv::app::EAppContext::no_context;
|
|
m_pathLoggerModule.clear();
|
|
m_ssLoggerClass.clear();
|
|
m_ssProgramTag.clear();
|
|
m_eSeverityFilter = sdv::core::ELogSeverity::info;
|
|
m_eSeverityViewFilter = sdv::core::ELogSeverity::error;
|
|
m_uiInstanceID = 0u;
|
|
m_bSilent = false;
|
|
m_bVerbose = false;
|
|
m_pathRootDir.clear();
|
|
m_pathInstallDir.clear();
|
|
m_pathPlatformConfig.clear();
|
|
m_pathVehIfcConfig.clear();
|
|
m_pathVehAbstrConfig.clear();
|
|
m_pathUserConfig.clear();
|
|
m_bPlatformConfig = false;
|
|
m_bVehIfcConfig = false;
|
|
m_bVehAbstrConfig = false;
|
|
m_bUserConfig = false;
|
|
}
|
|
|
|
CAppSettings& CAppSettingsService::GetAppSettings()
|
|
{
|
|
return ::GetAppSettings();
|
|
}
|