summaryrefslogtreecommitdiff
path: root/settings
diff options
context:
space:
mode:
authorFeist, James <james.feist@linux.intel.com>2019-06-13 04:47:08 +0300
committerJames Feist <james.feist@linux.intel.com>2019-06-20 04:07:06 +0300
commit3528ca7e866109a6017316c0207627ea59aff51f (patch)
tree3b4373673cc5d32f5845c00f9eddc4ae739fc50f /settings
parent071b13905c27df3b3eb913e22ff85e079173ca34 (diff)
downloadprovingground-3528ca7e866109a6017316c0207627ea59aff51f.tar.xz
Non-yaml Settingsd implementation
This implements an asio based, non-yaml settingsd. This should make it so we don't have to go through the process of creating yaml anymore. Tested: Modifed thermal_mode setting and on reboot it persisted Change-Id: Ie385064aa07838acb16ecd6cc86778d570d586cc Signed-off-by: Feist, James <james.feist@linux.intel.com>
Diffstat (limited to 'settings')
-rw-r--r--settings/.clang-format85
-rw-r--r--settings/.gitignore1
-rw-r--r--settings/CMakeLists.txt82
-rw-r--r--settings/cmake-format.json12
-rw-r--r--settings/include/defaults.hpp217
-rw-r--r--settings/include/interface.hpp200
-rw-r--r--settings/include/utils.hpp29
-rw-r--r--settings/settings.service11
-rw-r--r--settings/src/main.cpp31
9 files changed, 668 insertions, 0 deletions
diff --git a/settings/.clang-format b/settings/.clang-format
new file mode 100644
index 0000000..bbc1bb1
--- /dev/null
+++ b/settings/.clang-format
@@ -0,0 +1,85 @@
+---
+Language: Cpp
+# BasedOnStyle: LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: true
+ AfterControlStatement: true
+ AfterEnum: true
+ AfterFunction: true
+ AfterNamespace: true
+ AfterObjCDeclaration: true
+ AfterStruct: true
+ AfterUnion: true
+ BeforeCatch: true
+ BeforeElse: true
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: AfterColon
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: true
+PointerAlignment: Left
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IndentCaseLabels: true
+IndentWidth: 4
+IndentWrappedFunctionNames: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+ReflowComments: true
+SortIncludes: false
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 4
+UseTab: Never
+...
+
diff --git a/settings/.gitignore b/settings/.gitignore
new file mode 100644
index 0000000..a007fea
--- /dev/null
+++ b/settings/.gitignore
@@ -0,0 +1 @@
+build/*
diff --git a/settings/CMakeLists.txt b/settings/CMakeLists.txt
new file mode 100644
index 0000000..3e8145c
--- /dev/null
+++ b/settings/CMakeLists.txt
@@ -0,0 +1,82 @@
+cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
+set (BUILD_SHARED_LIBRARIES OFF)
+include (ExternalProject)
+set (CMAKE_CXX_STANDARD 17)
+set (CMAKE_CXX_STANDARD_REQUIRED ON)
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lstdc++fs -Werror")
+set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti")
+
+option (YOCTO "Enable Building in Yocto" OFF)
+option (USE_OVERLAYS "Enable Overlay Usage" ON)
+
+if (NOT YOCTO)
+ externalproject_add (
+ Boost URL
+ https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz
+ URL_MD5 d275cd85b00022313c171f602db59fc5 SOURCE_DIR
+ "${CMAKE_BINARY_DIR}/boost-src" BINARY_DIR
+ "${CMAKE_BINARY_DIR}/boost-build" CONFIGURE_COMMAND "" BUILD_COMMAND ""
+ INSTALL_COMMAND mkdir -p "${CMAKE_BINARY_DIR}/prefix/include/" && cp -R
+ ${CMAKE_BINARY_DIR}/boost-src/boost ${CMAKE_BINARY_DIR}/prefix/include
+ )
+
+ externalproject_add (
+ nlohmann-json GIT_REPOSITORY "https://github.com/nlohmann/json.git"
+ GIT_TAG d2dd27dc3b8472dbaa7d66f83619b3ebcd9185fe SOURCE_DIR
+ "${CMAKE_BINARY_DIR}/nlohmann-json-src" BINARY_DIR
+ "${CMAKE_BINARY_DIR}/nlohmann-json-build" CONFIGURE_COMMAND ""
+ BUILD_COMMAND "" INSTALL_COMMAND mkdir -p
+ "${CMAKE_BINARY_DIR}/nlohmann/include/nlohmann" && cp -r
+ "${CMAKE_BINARY_DIR}/nlohmann-json-src/single_include/nlohmann"
+ "${CMAKE_BINARY_DIR}/nlohmann/include"
+ )
+
+ # requires apt install autoconf-archive and autoconf
+ externalproject_add (sdbusplus-project PREFIX
+ ${CMAKE_BINARY_DIR}/sdbusplus-project GIT_REPOSITORY
+ https://github.com/openbmc/sdbusplus.git GIT_TAG
+ 076d14af2b3e29e48471ffb7fab632317da0fc21 SOURCE_DIR
+ ${CMAKE_BINARY_DIR}/sdbusplus-src BINARY_DIR
+ ${CMAKE_BINARY_DIR}/sdbusplus-build CONFIGURE_COMMAND
+ "" BUILD_COMMAND cd ${CMAKE_BINARY_DIR}/sdbusplus-src
+ && ./bootstrap.sh && ./configure --enable-transaction
+ && make -j libsdbusplus.la INSTALL_COMMAND ""
+ LOG_DOWNLOAD ON)
+
+ include_directories (${CMAKE_BINARY_DIR}/sdbusplus-src)
+ include_directories (${CMAKE_BINARY_DIR}/nlohmann/include)
+ include_directories (${CMAKE_BINARY_DIR}/nlohmann/include/nlohmann)
+
+ link_directories (${CMAKE_BINARY_DIR}/sdbusplus-src/.libs)
+
+ include_directories (${CMAKE_BINARY_DIR}/boost-src)
+ set (CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}/boost-src ${CMAKE_PREFIX_PATH})
+endif ()
+
+add_definitions (-DBOOST_ERROR_CODE_HEADER_ONLY)
+add_definitions (-DBOOST_SYSTEM_NO_DEPRECATED)
+add_definitions (-DBOOST_ALL_NO_LIB)
+add_definitions (-DBOOST_NO_RTTI)
+add_definitions (-DBOOST_NO_TYPEID)
+add_definitions (-DBOOST_ASIO_DISABLE_THREADS)
+
+include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include)
+include_directories (${Boost_INCLUDE_DIRS})
+
+add_executable (settings src/main.cpp)
+
+target_link_libraries (settings -lsystemd)
+target_link_libraries (settings ${Boost_LIBRARIES})
+target_link_libraries (settings stdc++fs)
+target_link_libraries (settings sdbusplus)
+
+if (NOT YOCTO)
+ add_dependencies (settings nlohmann-json)
+ add_dependencies (settings sdbusplus-project)
+ add_dependencies (settings Boost)
+endif ()
+
+install (TARGETS settings DESTINATION bin)
+install (FILES settings.service DESTINATION /lib/systemd/system/) \ No newline at end of file
diff --git a/settings/cmake-format.json b/settings/cmake-format.json
new file mode 100644
index 0000000..4a701ae
--- /dev/null
+++ b/settings/cmake-format.json
@@ -0,0 +1,12 @@
+{
+ "enum_char": ".",
+ "line_ending": "unix",
+ "bullet_char": "*",
+ "max_subargs_per_line": 99,
+ "command_case": "lower",
+ "tab_size": 4,
+ "line_width": 80,
+ "separate_fn_name_with_space": true,
+ "dangle_parens": true,
+ "separate_ctrl_name_with_space": true
+}
diff --git a/settings/include/defaults.hpp b/settings/include/defaults.hpp
new file mode 100644
index 0000000..0b3c9a3
--- /dev/null
+++ b/settings/include/defaults.hpp
@@ -0,0 +1,217 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#pragma once
+#include "interface.hpp"
+
+// this file is vendor specific, other vendors should replace this file using a
+// bbappend
+
+inline void loadSettings(sdbusplus::asio::object_server &objectServer,
+ std::vector<SettingsInterface> &settings)
+{
+
+ SettingsInterface *setting = nullptr;
+ setting = &settings.emplace_back(
+ objectServer,
+ "/xyz/openbmc_project/control/minimum_ship_level_required",
+ "xyz.openbmc_project.Control.MinimumShipLevel");
+
+ setting->addProperty("MinimumShipLevelRequired", true);
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/host0/auto_reboot",
+ "xyz.openbmc_project.Control.Boot.RebootPolicy");
+
+ setting->addProperty("AutoReboot", false);
+
+ setting = &settings.emplace_back(objectServer,
+ "/xyz/openbmc_project/control/host0/boot",
+ "xyz.openbmc_project.Control.Boot.Source");
+
+ setting->addProperty(
+ "BootSource",
+ "xyz.openbmc_project.Control.Boot.Source.Sources.Default");
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/host0/boot/one_time",
+ "xyz.openbmc_project.Control.Boot.Source");
+
+ setting->addProperty(
+ "BootSource",
+ "xyz.openbmc_project.Control.Boot.Source.Sources.Default");
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/host0/power_cap",
+ "xyz.openbmc_project.Control.Power.Cap");
+
+ setting->addProperty("PowerCap", static_cast<uint32_t>(0));
+ setting->addProperty("PowerCapEnable", false);
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/host0/power_restore_policy",
+ "xyz.openbmc_project.Control.Power.RestorePolicy");
+
+ setting->addProperty(
+ "PowerRestorePolicy",
+ "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff");
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/power_restore_delay",
+ "xyz.openbmc_project.Control.Power.RestoreDelay");
+
+ setting->addProperty("PowerRestoreDelay", static_cast<uint16_t>(0));
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/host0/acpi_power_state",
+ "xyz.openbmc_project.Control.Power.ACPIPowerState");
+
+ setting->addProperty(
+ "SysACPIStatus",
+ "xyz.openbmc_project.Control.Power.ACPIPowerState.ACPI.Unknown");
+ setting->addProperty(
+ "DevACPIStatus",
+ "xyz.openbmc_project.Control.Power.ACPIPowerState.ACPI.Unknown");
+
+ setting =
+ &settings.emplace_back(objectServer, "/xyz/openbmc_project/time/owner",
+ "xyz.openbmc_project.Time.Owner");
+
+ setting->addProperty("TimeOwner",
+ "xyz.openbmc_project.Time.Owner.Owners.BMC");
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/time/sync_method",
+ "xyz.openbmc_project.Time.Synchronization");
+
+ setting->addProperty("TimeSyncMethod",
+ "xyz.openbmc_project.Time.Synchronization.Method.NTP");
+
+ setting = &settings.emplace_back(objectServer,
+ "/xyz/openbmc_project/network/host0/intf",
+ "xyz.openbmc_project.Network.MACAddress");
+
+ setting->addProperty("MACAddress", "00:00:00:00:00:00");
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/network/host0/intf/addr",
+ "xyz.openbmc_project.Network.IP");
+
+ setting->addProperty("Address", "0.0.0.0");
+ setting->addProperty("PrefixLength", static_cast<uint8_t>(0));
+ setting->addProperty("Origin",
+ "xyz.openbmc_project.Network.IP.AddressOrigin.Static");
+ setting->addProperty("Gateway", "0.0.0.0");
+ setting->addProperty("Type",
+ "xyz.openbmc_project.Network.IP.Protocol.IPv4");
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/host0/restriction_mode",
+ "xyz.openbmc_project.Control.Security.RestrictionMode");
+
+ setting->addProperty("RestrictionMode",
+ "xyz.openbmc_project.Control.Security.RestrictionMode."
+ "Modes.Provisioning");
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/host0/TPMEnable",
+ "xyz.openbmc_project.Control.TPM.Policy");
+
+ setting->addProperty("TPMEnable", false);
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/power_supply_redundancy",
+ "xyz.openbmc_project.Control.PowerSupplyRedundancy");
+
+ setting->addProperty("PowerSupplyRedundancyEnabled", true);
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/host0/turbo_allowed",
+ "xyz.openbmc_project.Control.Host.TurboAllowed");
+
+ setting->addProperty("TurboAllowed", true);
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/host0/systemGUID",
+ "xyz.openbmc_project.Common.UUID");
+
+ setting->addProperty("UUID", "00000000-0000-0000-0000-000000000000");
+
+ setting = &settings.emplace_back(objectServer, "/xyz/openbmc_project/bios",
+ "xyz.openbmc_project.Inventory.Item.Bios");
+
+ setting->addProperty("BiosId", "NA");
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/processor_error_config",
+ "xyz.openbmc_project.Control.Processor.ErrConfig");
+
+ setting->addProperty("ResetCfg", static_cast<uint8_t>(0));
+ setting->addProperty("ResetErrorOccurrenceCounts", static_cast<uint8_t>(0));
+
+ setting = &settings.emplace_back(
+ objectServer, "/com/intel/control/ocotshutdown_policy_config",
+ "com.intel.Control.OCOTShutdownPolicy");
+
+ setting->addProperty(
+ "OCOTPolicy",
+ "com.intel.Control.OCOTShutdownPolicy.Policy.NoShutdownOnOCOT");
+
+ setting = &settings.emplace_back(
+ objectServer,
+ "/xyz/openbmc_project/control/chassis_capabilities_config",
+ "xyz.openbmc_project.Control.ChassisCapabilities");
+
+ setting->addProperty("CapabilitiesFlags", static_cast<uint8_t>(0));
+ setting->addProperty("FRUDeviceAddress", static_cast<uint8_t>(32));
+ setting->addProperty("SDRDeviceAddress", static_cast<uint8_t>(32));
+ setting->addProperty("SELDeviceAddress", static_cast<uint8_t>(32));
+ setting->addProperty("SMDeviceAddress", static_cast<uint8_t>(32));
+ setting->addProperty("BridgeDeviceAddress", static_cast<uint8_t>(32));
+
+ setting = &settings.emplace_back(
+ objectServer, "/xyz/openbmc_project/control/thermal_mode",
+ "xyz.openbmc_project.Control.ThermalMode");
+
+ setting->addProperty("Current", "Performance");
+ setting->addProperty("Supported",
+ std::vector<std::string>{"Acoustic", "Performance"});
+
+ setting = &settings.emplace_back(objectServer,
+ "/xyz/openbmc_project/control/cfm_limit",
+ "xyz.openbmc_project.Control.CFMLimit");
+
+ setting->addProperty("Limit", static_cast<double>(0));
+
+ setting =
+ &settings.emplace_back(objectServer, "/xyz/openbmc_project/ipmi/sol",
+ "xyz.openbmc_project.Ipmi.SOL");
+
+ setting->addProperty("Progress", static_cast<uint8_t>(0));
+ setting->addProperty("Enable", true);
+ setting->addProperty("ForceEncryption", true);
+ setting->addProperty("ForceAuthentication", true);
+ setting->addProperty("Privilege", static_cast<uint8_t>(4));
+ setting->addProperty("AccumulateIntervalMS", static_cast<uint8_t>(12));
+ setting->addProperty("Threshold", static_cast<uint8_t>(96));
+ setting->addProperty("RetryCount", static_cast<uint8_t>(6));
+ setting->addProperty("RetryIntervalMS", static_cast<uint8_t>(20));
+
+ for (SettingsInterface &s : settings)
+ {
+ s.initialize();
+ }
+}
diff --git a/settings/include/interface.hpp b/settings/include/interface.hpp
new file mode 100644
index 0000000..987f8e4
--- /dev/null
+++ b/settings/include/interface.hpp
@@ -0,0 +1,200 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+
+constexpr const char *prefix = "/var/lib/phosphor-settings-manager/settings";
+
+#include "utils.hpp"
+
+#include <fstream>
+#include <iostream>
+#include <stdexcept>
+#include <filesystem>
+#include <nlohmann/json.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+struct SettingsInterface
+{
+
+ SettingsInterface(sdbusplus::asio::object_server &objectServer,
+ const std::string &objectPath, const std::string &iface) :
+ objectServer(objectServer),
+ path(std::make_shared<std::string>(objectPath))
+ {
+ interface = objectServer.add_interface(*path, iface);
+ }
+ ~SettingsInterface()
+ {
+ objectServer.remove_interface(interface);
+ }
+
+ template <typename T>
+ std::optional<T> getOptional(const nlohmann::json &data)
+ {
+ std::optional<T> resp;
+
+ if constexpr (std::is_floating_point_v<T>)
+ {
+ const double *val = data.get_ptr<const double *>();
+ if (val != nullptr)
+ {
+ resp = *val;
+ }
+ return resp;
+ }
+ else if constexpr (std::is_same_v<bool, std::decay_t<T>>)
+ {
+ const bool *val = data.get_ptr<const bool *>();
+ if (val != nullptr)
+ {
+ resp = *val;
+ }
+ return resp;
+ }
+ else if constexpr (std::is_unsigned_v<T>)
+ {
+ const uint64_t *val = data.get_ptr<const uint64_t *>();
+ if (val != nullptr)
+ {
+ resp = *val;
+ }
+ return resp;
+ }
+ else if constexpr (std::is_signed_v<T>)
+ {
+ const int64_t *val = data.get_ptr<const int64_t *>();
+ if (val != nullptr)
+ {
+ resp = *val;
+ }
+ return resp;
+ }
+ else if constexpr (is_vector_v<T>)
+ {
+ resp = {};
+ for (const auto &val : data)
+ {
+ using SubType = typename T::value_type;
+
+ std::optional<SubType> opt = getOptional<SubType>(val);
+ if (!opt)
+ {
+ return std::optional<T>(std::nullopt);
+ }
+ resp->emplace_back(*opt);
+ }
+ return resp;
+ }
+ else if constexpr (std::is_same_v<std::string, std::decay_t<T>>)
+ {
+ const std::string *val = data.get_ptr<const std::string *>();
+ if (val != nullptr)
+ {
+ resp = *val;
+ }
+ return resp;
+ }
+ else
+ {
+ static_assert(!std::is_same_v<T, T>, "Unsupported Type");
+ }
+ }
+
+ // specialization for char * as std::string is the nlohmann type
+ void addProperty(const std::string &name, const char *value)
+ {
+ addProperty(name, std::string(value));
+ }
+
+ template <typename T> void addProperty(const std::string &name, T value)
+ {
+
+ std::ifstream current(std::string(prefix) + *path);
+ if (current.good())
+ {
+ nlohmann::json data =
+ nlohmann::json::parse(current, nullptr, false);
+ if (data.is_discarded())
+ {
+ std::cerr << "Persisted data at " << *path << " corrupted\n";
+ }
+ else
+ {
+ auto find = data.find(name);
+ if (find != data.end())
+ {
+ auto val = getOptional<T>(*find);
+ if (!val)
+ {
+ std::cerr << "Persisted data at " << *path
+ << " corrupted, type changed for " << name
+ << "\n";
+ }
+ else
+ {
+ value = *val;
+ }
+ }
+ }
+ }
+
+ interface->register_property(
+ name, value,
+ [path = std::shared_ptr<std::string>(path), name](const T &req,
+ T &old) {
+ nlohmann::json data;
+
+ { // context is here for raii to close the file
+ std::ifstream current(std::string(prefix) + *path);
+ if (current.good())
+ {
+ data = nlohmann::json::parse(current, nullptr, false);
+ if (data.is_discarded())
+ {
+ std::cerr << "Persisted data at " << *path
+ << " corrupted\n";
+ throw std::runtime_error("Persisting Error");
+ }
+ }
+ }
+
+ data[name] = req;
+ std::filesystem::create_directories(
+ std::filesystem::path(std::string(prefix) + *path)
+ .parent_path());
+ std::ofstream output(std::string(prefix) + *path);
+ if (!output.good())
+ {
+ std::cerr << "Cannot write data at " << *path << "\n";
+ throw std::runtime_error("Persisting Error");
+ }
+ output << data;
+
+ old = req;
+
+ return 1;
+ });
+ }
+ void initialize()
+ {
+ interface->initialize();
+ }
+
+ sdbusplus::asio::object_server &objectServer;
+ std::shared_ptr<std::string> path; // shared ptr so this object can be moved
+ std::shared_ptr<sdbusplus::asio::dbus_interface> interface;
+};
diff --git a/settings/include/utils.hpp b/settings/include/utils.hpp
new file mode 100644
index 0000000..8012308
--- /dev/null
+++ b/settings/include/utils.hpp
@@ -0,0 +1,29 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#pragma once
+
+#include <vector>
+
+template <typename T> struct is_vector : std::false_type
+{
+};
+
+template <typename T> struct is_vector<std::vector<T>> : std::true_type
+{
+};
+
+template <typename T> constexpr bool is_vector_v = is_vector<T>::value;
diff --git a/settings/settings.service b/settings/settings.service
new file mode 100644
index 0000000..4b8ddb5
--- /dev/null
+++ b/settings/settings.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Settings
+
+[Service]
+ExecStart=/usr/bin/settings
+Restart=always
+BusName=xyz.openbmc_project.Settings
+Type=dbus
+
+[Install]
+WantedBy=multi-user.target
diff --git a/settings/src/main.cpp b/settings/src/main.cpp
new file mode 100644
index 0000000..1a46ae9
--- /dev/null
+++ b/settings/src/main.cpp
@@ -0,0 +1,31 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include "interface.hpp"
+#include "defaults.hpp"
+
+int main()
+{
+ boost::asio::io_context io;
+ auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
+ systemBus->request_name("xyz.openbmc_project.Settings");
+
+ sdbusplus::asio::object_server objServer(systemBus);
+
+ std::vector<SettingsInterface> settings;
+ loadSettings(objServer, settings);
+ io.run();
+} \ No newline at end of file