15de0957cSDeepak Kodihalli ## This file is a template. The comment below is emitted 25de0957cSDeepak Kodihalli ## into the rendered file; feel free to edit this file. 35de0957cSDeepak Kodihalli // WARNING: Generated header. Do not edit! 45de0957cSDeepak Kodihalli <% 561d3b6a1SDhruvaraj Subhashchandran import re 67a6f2526SDeepak Kodihalli from collections import defaultdict 7bcf95781SPatrick Williams from sdbusplus.namedelement import NamedElement 82b7152fbSPatrick Williams objects = settingsDict.keys() 97a6f2526SDeepak Kodihalli sdbusplus_includes = [] 107a6f2526SDeepak Kodihalli props = defaultdict(list) 1161d3b6a1SDhruvaraj Subhashchandran validators = defaultdict(tuple) 125de0957cSDeepak Kodihalli 137a6f2526SDeepak Kodihalli def get_setting_sdbusplus_type(setting_intf): 145de0957cSDeepak Kodihalli setting = "sdbusplus::" + setting_intf.replace('.', '::') 155de0957cSDeepak Kodihalli i = setting.rfind('::') 165de0957cSDeepak Kodihalli setting = setting[:i] + '::server::' + setting[i+2:] 175de0957cSDeepak Kodihalli return setting 187a6f2526SDeepak Kodihalli 19db838626SDeepak Kodihalli def get_setting_type(path): 20db838626SDeepak Kodihalli path = path[1:] 21db838626SDeepak Kodihalli path = path.replace('/', '::') 22db838626SDeepak Kodihalli return path 23ffdf8658SMatt Spinler 24ffdf8658SMatt Spinler def get_default_value(object, interface, prop): 25ffdf8658SMatt Spinler default_value = None 26ffdf8658SMatt Spinler for item in settingsDict[object]: 27ffdf8658SMatt Spinler if item['Interface'] == interface: 28ffdf8658SMatt Spinler default_value = item['Properties'][prop]['Default'] 29ffdf8658SMatt Spinler break 30ffdf8658SMatt Spinler 31ffdf8658SMatt Spinler if isinstance(default_value, str) and not \ 32ffdf8658SMatt Spinler default_value.startswith('"') and '::' in default_value: 33ffdf8658SMatt Spinler ns = get_setting_sdbusplus_type(interface) 34ffdf8658SMatt Spinler i = ns.rfind('::') 35ffdf8658SMatt Spinler default_value = "{}::{}".format(ns[:i], default_value) 36ffdf8658SMatt Spinler 37ffdf8658SMatt Spinler return default_value 385de0957cSDeepak Kodihalli %>\ 395de0957cSDeepak Kodihalli #pragma once 405de0957cSDeepak Kodihalli 415de0957cSDeepak Kodihalli % for object in objects: 42db838626SDeepak Kodihalli % for item in settingsDict[object]: 435de0957cSDeepak Kodihalli <% 44db838626SDeepak Kodihalli include = item['Interface'] 455de0957cSDeepak Kodihalli include = include.replace('.', '/') 465de0957cSDeepak Kodihalli include = include + "/server.hpp" 477a6f2526SDeepak Kodihalli sdbusplus_includes.append(include) 485de0957cSDeepak Kodihalli %>\ 495de0957cSDeepak Kodihalli % endfor 50db838626SDeepak Kodihalli % endfor 517a6f2526SDeepak Kodihalli #include <cereal/archives/json.hpp> 5274e3be7dSJames Feist #include <cereal/types/vector.hpp> 537a6f2526SDeepak Kodihalli #include <fstream> 547a6f2526SDeepak Kodihalli #include <utility> 556306e5e4SPatrick Williams #include <filesystem> 5661d3b6a1SDhruvaraj Subhashchandran #include <regex> 5761d3b6a1SDhruvaraj Subhashchandran #include <phosphor-logging/elog.hpp> 5861d3b6a1SDhruvaraj Subhashchandran #include <phosphor-logging/elog-errors.hpp> 59c2f84c7bSMatt Spinler #include <phosphor-logging/lg2.hpp> 6061d3b6a1SDhruvaraj Subhashchandran #include <xyz/openbmc_project/Common/error.hpp> 617a6f2526SDeepak Kodihalli 624d28bcd3SJagpal Singh Gill /* The DBus busname to own */ 634d28bcd3SJagpal Singh Gill #define SETTINGS_BUSNAME "xyz.openbmc_project.Settings" 644d28bcd3SJagpal Singh Gill /* Path of directory housing persisted settings */ 654d28bcd3SJagpal Singh Gill #define SETTINGS_PERSIST_PATH "/var/lib/phosphor-settings-manager/settings" 664d28bcd3SJagpal Singh Gill 674d28bcd3SJagpal Singh Gill /* Class version to register with Cereal */ 68c2f84c7bSMatt Spinler static constexpr size_t CLASS_VERSION = 2; 69c2f84c7bSMatt Spinler static constexpr size_t CLASS_VERSION_WITH_NVP = 2; 704d28bcd3SJagpal Singh Gill 717a6f2526SDeepak Kodihalli % for i in set(sdbusplus_includes): 725de0957cSDeepak Kodihalli #include "${i}" 735de0957cSDeepak Kodihalli % endfor 745de0957cSDeepak Kodihalli 755de0957cSDeepak Kodihalli namespace phosphor 765de0957cSDeepak Kodihalli { 775de0957cSDeepak Kodihalli namespace settings 785de0957cSDeepak Kodihalli { 795de0957cSDeepak Kodihalli 806306e5e4SPatrick Williams namespace fs = std::filesystem; 817a6f2526SDeepak Kodihalli 82242bc77cSDeepak Kodihalli namespace persistent 83242bc77cSDeepak Kodihalli { 84242bc77cSDeepak Kodihalli 85242bc77cSDeepak Kodihalli // A setting d-bus object /foo/bar/baz is persisted in the filesystem with the 86242bc77cSDeepak Kodihalli // same path. This eases re-construction of settings objects when we restore 87242bc77cSDeepak Kodihalli // from the filesystem. This can be a problem though when you have two objects 88242bc77cSDeepak Kodihalli // such as - /foo/bar and /foo/bar/baz. This is because 'bar' will be treated as 89242bc77cSDeepak Kodihalli // a file in the first case, and a subdir in the second. To solve this, suffix 90242bc77cSDeepak Kodihalli // files with a trailing __. The __ is a safe character sequence to use, because 91242bc77cSDeepak Kodihalli // we won't have d-bus object paths ending with this. 92242bc77cSDeepak Kodihalli // With this the objects would be persisted as - /foo/bar__ and /foo/bar/baz__. 93242bc77cSDeepak Kodihalli constexpr auto fileSuffix = "__"; 94242bc77cSDeepak Kodihalli 95242bc77cSDeepak Kodihalli } 96242bc77cSDeepak Kodihalli 97fb1ad7ccSMatt Spinler static fs::path getFilePath(const fs::path& objectPath) 98fb1ad7ccSMatt Spinler { 99fb1ad7ccSMatt Spinler fs::path p(SETTINGS_PERSIST_PATH); 100fb1ad7ccSMatt Spinler p /= objectPath.relative_path(); 101fb1ad7ccSMatt Spinler p += persistent::fileSuffix; 102fb1ad7ccSMatt Spinler return p; 103fb1ad7ccSMatt Spinler } 104fb1ad7ccSMatt Spinler 1057a6f2526SDeepak Kodihalli % for object in objects: 1067a6f2526SDeepak Kodihalli <% 107db838626SDeepak Kodihalli ns = object.split('/') 108db838626SDeepak Kodihalli ns.pop(0) 1097a6f2526SDeepak Kodihalli %>\ 1107a6f2526SDeepak Kodihalli % for n in ns: 1117a6f2526SDeepak Kodihalli namespace ${n} 1127a6f2526SDeepak Kodihalli { 1137a6f2526SDeepak Kodihalli % endfor 114db838626SDeepak Kodihalli <% 115db838626SDeepak Kodihalli interfaces = [] 116db838626SDeepak Kodihalli aliases = [] 117db838626SDeepak Kodihalli for item in settingsDict[object]: 118db838626SDeepak Kodihalli interfaces.append(item['Interface']) 119db838626SDeepak Kodihalli for name, meta in item['Properties'].items(): 120db838626SDeepak Kodihalli if 'Validation' in meta: 121db838626SDeepak Kodihalli dict = meta['Validation'] 122db838626SDeepak Kodihalli if dict['Type'] == "range": 123db838626SDeepak Kodihalli validators[name] = (dict['Type'], dict['Validator'], dict['Unit']) 124db838626SDeepak Kodihalli else: 125db838626SDeepak Kodihalli validators[name] = (dict['Type'], dict['Validator']) 126db838626SDeepak Kodihalli %> 127db838626SDeepak Kodihalli % for index, intf in enumerate(interfaces): 128db838626SDeepak Kodihalli using Iface${index} = ${get_setting_sdbusplus_type(intf)}; 129db838626SDeepak Kodihalli <% aliases.append("Iface" + str(index)) %>\ 130db838626SDeepak Kodihalli % endfor 131db838626SDeepak Kodihalli <% 1327c4181cfSPatrick Williams parent = "sdbusplus::server::object_t" + "<" + ", ".join(aliases) + ">" 133db838626SDeepak Kodihalli %>\ 1347a6f2526SDeepak Kodihalli using Parent = ${parent}; 1357a6f2526SDeepak Kodihalli 1367a6f2526SDeepak Kodihalli class Impl : public Parent 1377a6f2526SDeepak Kodihalli { 1387a6f2526SDeepak Kodihalli public: 1397c4181cfSPatrick Williams Impl(sdbusplus::bus_t& bus, const char* path): 14074c4f3b1SPatrick Williams Parent(bus, path, Parent::action::defer_emit), 1417a6f2526SDeepak Kodihalli path(path) 1427a6f2526SDeepak Kodihalli { 1437a6f2526SDeepak Kodihalli } 1447a6f2526SDeepak Kodihalli virtual ~Impl() = default; 1457a6f2526SDeepak Kodihalli 146fb1ad7ccSMatt Spinler void setInitialVersion(std::uint32_t v) 147fb1ad7ccSMatt Spinler { 148fb1ad7ccSMatt Spinler initialVersion = v; 149fb1ad7ccSMatt Spinler } 150fb1ad7ccSMatt Spinler 151fb1ad7ccSMatt Spinler std::uint32_t getInitialVersion() const 152fb1ad7ccSMatt Spinler { 153fb1ad7ccSMatt Spinler return initialVersion; 154fb1ad7ccSMatt Spinler } 155fb1ad7ccSMatt Spinler 156fb1ad7ccSMatt Spinler bool deserialize() 157fb1ad7ccSMatt Spinler { 158fb1ad7ccSMatt Spinler auto p = getFilePath(path); 159fb1ad7ccSMatt Spinler if (fs::exists(p)) 160fb1ad7ccSMatt Spinler { 161fb1ad7ccSMatt Spinler std::ifstream is(p.c_str(), std::ios::in); 162fb1ad7ccSMatt Spinler cereal::JSONInputArchive iarchive(is); 163fb1ad7ccSMatt Spinler iarchive(*this); 164fb1ad7ccSMatt Spinler return true; 165fb1ad7ccSMatt Spinler } 166fb1ad7ccSMatt Spinler return false; 167fb1ad7ccSMatt Spinler } 168fb1ad7ccSMatt Spinler 169fb1ad7ccSMatt Spinler void serialize() 170fb1ad7ccSMatt Spinler { 171fb1ad7ccSMatt Spinler auto p = getFilePath(path); 172fb1ad7ccSMatt Spinler if (!fs::exists(p.parent_path())) 173fb1ad7ccSMatt Spinler { 174fb1ad7ccSMatt Spinler fs::create_directories(p.parent_path()); 175fb1ad7ccSMatt Spinler } 176fb1ad7ccSMatt Spinler std::ofstream os(p.c_str(), std::ios::binary); 177fb1ad7ccSMatt Spinler cereal::JSONOutputArchive oarchive(os); 178fb1ad7ccSMatt Spinler oarchive(*this); 179fb1ad7ccSMatt Spinler } 180fb1ad7ccSMatt Spinler 181fb1ad7ccSMatt Spinler void removeFile() const 182fb1ad7ccSMatt Spinler { 183fb1ad7ccSMatt Spinler std::error_code ec; 184fb1ad7ccSMatt Spinler fs::remove(getFilePath(path), ec); 185fb1ad7ccSMatt Spinler } 186fb1ad7ccSMatt Spinler 187db838626SDeepak Kodihalli % for index, item in enumerate(settingsDict[object]): 188db838626SDeepak Kodihalli % for propName, metaDict in item['Properties'].items(): 189bcf95781SPatrick Williams <% t = NamedElement(name=propName).camelCase %>\ 190db838626SDeepak Kodihalli <% fname = "validate" + propName %>\ 191db838626SDeepak Kodihalli decltype(std::declval<Iface${index}>().${t}()) ${t}(decltype(std::declval<Iface${index}>().${t}()) value) override 1927a6f2526SDeepak Kodihalli { 193db838626SDeepak Kodihalli auto result = Iface${index}::${t}(); 1947a6f2526SDeepak Kodihalli if (value != result) 1957a6f2526SDeepak Kodihalli { 196db838626SDeepak Kodihalli % if propName in validators: 19761d3b6a1SDhruvaraj Subhashchandran if (!${fname}(value)) 19861d3b6a1SDhruvaraj Subhashchandran { 19961d3b6a1SDhruvaraj Subhashchandran namespace error = 20061d3b6a1SDhruvaraj Subhashchandran sdbusplus::xyz::openbmc_project::Common::Error; 20161d3b6a1SDhruvaraj Subhashchandran namespace metadata = 20261d3b6a1SDhruvaraj Subhashchandran phosphor::logging::xyz::openbmc_project::Common; 20361d3b6a1SDhruvaraj Subhashchandran phosphor::logging::report<error::InvalidArgument>( 20461d3b6a1SDhruvaraj Subhashchandran metadata::InvalidArgument::ARGUMENT_NAME("${t}"), 205db838626SDeepak Kodihalli % if validators[propName][0] != "regex": 20661d3b6a1SDhruvaraj Subhashchandran metadata::InvalidArgument::ARGUMENT_VALUE(std::to_string(value).c_str())); 20761d3b6a1SDhruvaraj Subhashchandran % else: 20861d3b6a1SDhruvaraj Subhashchandran metadata::InvalidArgument::ARGUMENT_VALUE(value.c_str())); 20961d3b6a1SDhruvaraj Subhashchandran % endif 21061d3b6a1SDhruvaraj Subhashchandran return result; 21161d3b6a1SDhruvaraj Subhashchandran } 21261d3b6a1SDhruvaraj Subhashchandran % endif 213db838626SDeepak Kodihalli result = Iface${index}::${t}(value); 214fb1ad7ccSMatt Spinler serialize(); 2157a6f2526SDeepak Kodihalli } 2167a6f2526SDeepak Kodihalli return result; 2177a6f2526SDeepak Kodihalli } 218db838626SDeepak Kodihalli using Iface${index}::${t}; 2197a6f2526SDeepak Kodihalli 220c15990a3SAndrew Geissler % endfor 221db838626SDeepak Kodihalli % endfor 2227a6f2526SDeepak Kodihalli private: 2237a6f2526SDeepak Kodihalli fs::path path; 224fb1ad7ccSMatt Spinler std::uint32_t initialVersion = 0; 225db838626SDeepak Kodihalli % for index, item in enumerate(settingsDict[object]): 226db838626SDeepak Kodihalli % for propName, metaDict in item['Properties'].items(): 227bcf95781SPatrick Williams <% t = NamedElement(name=propName).camelCase %>\ 228db838626SDeepak Kodihalli <% fname = "validate" + propName %>\ 229db838626SDeepak Kodihalli % if propName in validators: 23061d3b6a1SDhruvaraj Subhashchandran 231db838626SDeepak Kodihalli bool ${fname}(decltype(std::declval<Iface${index}>().${t}()) value) 23261d3b6a1SDhruvaraj Subhashchandran { 23361d3b6a1SDhruvaraj Subhashchandran bool matched = false; 234db838626SDeepak Kodihalli % if (validators[propName][0] == 'regex'): 235db838626SDeepak Kodihalli std::regex regexToCheck("${validators[propName][1]}"); 23661d3b6a1SDhruvaraj Subhashchandran matched = std::regex_search(value, regexToCheck); 23761d3b6a1SDhruvaraj Subhashchandran if (!matched) 23861d3b6a1SDhruvaraj Subhashchandran { 239*e568fcadSMatt Spinler lg2::error("Input parameter for ${propName} is invalid. " 240*e568fcadSMatt Spinler "Input '{VALUE}' not in the format of this regex: " 241*e568fcadSMatt Spinler "${validators[propName][1]}", "VALUE", value); 24261d3b6a1SDhruvaraj Subhashchandran } 243db838626SDeepak Kodihalli % elif (validators[propName][0] == 'range'): 244db838626SDeepak Kodihalli <% lowhigh = re.split('\.\.', validators[propName][1]) %>\ 245cfd49eb8SJagpal Singh Gill % if lowhigh[0] == '0': 246cfd49eb8SJagpal Singh Gill if (value <= ${lowhigh[1]}) 247cfd49eb8SJagpal Singh Gill % else: 24861d3b6a1SDhruvaraj Subhashchandran if ((value <= ${lowhigh[1]}) && (value >= ${lowhigh[0]})) 249cfd49eb8SJagpal Singh Gill % endif 25061d3b6a1SDhruvaraj Subhashchandran { 25161d3b6a1SDhruvaraj Subhashchandran matched = true; 25261d3b6a1SDhruvaraj Subhashchandran } 25361d3b6a1SDhruvaraj Subhashchandran else 25461d3b6a1SDhruvaraj Subhashchandran { 255*e568fcadSMatt Spinler lg2::error("Input parameter for ${propName} is invalid. " 256*e568fcadSMatt Spinler "Input '{VALUE}' with unit '${validators[propName][2]}' " 257*e568fcadSMatt Spinler "is not in range ${validators[propName][1]}", 258*e568fcadSMatt Spinler "VALUE", std::to_string(value)); 25961d3b6a1SDhruvaraj Subhashchandran } 260db838626SDeepak Kodihalli % else: 261db838626SDeepak Kodihalli <% assert("Unknown validation type: propName") %>\ 26261d3b6a1SDhruvaraj Subhashchandran % endif 26361d3b6a1SDhruvaraj Subhashchandran return matched; 26461d3b6a1SDhruvaraj Subhashchandran } 26561d3b6a1SDhruvaraj Subhashchandran % endif 26661d3b6a1SDhruvaraj Subhashchandran % endfor 267db838626SDeepak Kodihalli % endfor 2687a6f2526SDeepak Kodihalli }; 2697a6f2526SDeepak Kodihalli 2707a6f2526SDeepak Kodihalli template<class Archive> 2717a6f2526SDeepak Kodihalli void save(Archive& a, 272a29a3eb7SVishwanatha Subbanna const Impl& setting, 273cfd49eb8SJagpal Singh Gill [[maybe_unused]] const std::uint32_t version) 2747a6f2526SDeepak Kodihalli { 2757a6f2526SDeepak Kodihalli <% 276db838626SDeepak Kodihalli props = [] 277db838626SDeepak Kodihalli for index, item in enumerate(settingsDict[object]): 278c2f84c7bSMatt Spinler props.extend(item['Properties'].keys()) 2797a6f2526SDeepak Kodihalli %>\ 280c2f84c7bSMatt Spinler ## Since the iface isn't saved, property names need to be unique on 281c2f84c7bSMatt Spinler ## the object path. This could be supported by providing unique 282c2f84c7bSMatt Spinler ## field names to make_nvp() if ever necessary. 283c2f84c7bSMatt Spinler % if len(set(props)) != len(props): 284c2f84c7bSMatt Spinler #error Duplicate property names on object path ${object} 285c0ce992fSLei YU %endif 286c2f84c7bSMatt Spinler <% 287c2f84c7bSMatt Spinler args = [] 288c2f84c7bSMatt Spinler for prop in props: 289c2f84c7bSMatt Spinler t = "setting." + NamedElement(name=prop).camelCase + "()" 290c2f84c7bSMatt Spinler args.append(f"cereal::make_nvp(\"{prop}\", {t})") 291c2f84c7bSMatt Spinler args = ", ".join(args) 292c2f84c7bSMatt Spinler %>\ 293c2f84c7bSMatt Spinler a(${args}); 2947a6f2526SDeepak Kodihalli } 2957a6f2526SDeepak Kodihalli 2967a6f2526SDeepak Kodihalli template<class Archive> 2977a6f2526SDeepak Kodihalli void load(Archive& a, 298a29a3eb7SVishwanatha Subbanna Impl& setting, 299c2f84c7bSMatt Spinler const std::uint32_t version) 3007a6f2526SDeepak Kodihalli { 301fb1ad7ccSMatt Spinler setting.setInitialVersion(version); 3027a6f2526SDeepak Kodihalli <% 303c2f84c7bSMatt Spinler props = [] 304c2f84c7bSMatt Spinler for index, item in enumerate(settingsDict[object]): 305c2f84c7bSMatt Spinler for prop in item['Properties'].keys(): 306bcf95781SPatrick Williams t = "setting." + NamedElement(name=prop).camelCase + "()" 307c2f84c7bSMatt Spinler props.append({'prop' : prop, 'iface': item['Interface'], 'func': t}) 3087a6f2526SDeepak Kodihalli %>\ 309c2f84c7bSMatt Spinler % for p in props: 310c2f84c7bSMatt Spinler decltype(${p['func']}) ${p['prop']}{}; 311db838626SDeepak Kodihalli % endfor 312c2f84c7bSMatt Spinler <% propList = ', '.join([p['prop'] for p in props]) %> 313c2f84c7bSMatt Spinler % if propList: 314c2f84c7bSMatt Spinler if (version < CLASS_VERSION_WITH_NVP) 315c2f84c7bSMatt Spinler { 316c2f84c7bSMatt Spinler a(${propList}); 317c2f84c7bSMatt Spinler } 318c2f84c7bSMatt Spinler else 319c2f84c7bSMatt Spinler { 320c2f84c7bSMatt Spinler % for p in props: 321c2f84c7bSMatt Spinler try 322c2f84c7bSMatt Spinler { 323c2f84c7bSMatt Spinler a(CEREAL_NVP(${p['prop']})); 324c2f84c7bSMatt Spinler } 325c2f84c7bSMatt Spinler catch (const cereal::Exception& e) 326c2f84c7bSMatt Spinler { 327c2f84c7bSMatt Spinler lg2::info("Could not restore property ${p['prop']} on ${object}, setting to default value"); 328c2f84c7bSMatt Spinler ${p['prop']} = ${get_default_value(object, p['iface'], p['prop'])}; 329c2f84c7bSMatt Spinler } 330db838626SDeepak Kodihalli % endfor 331c2f84c7bSMatt Spinler } 332c0ce992fSLei YU % endif 333db838626SDeepak Kodihalli <% props = [] %> 334db838626SDeepak Kodihalli % for index, item in enumerate(settingsDict[object]): 335db838626SDeepak Kodihalli % for prop, metaDict in item['Properties'].items(): 336db838626SDeepak Kodihalli <% 337bcf95781SPatrick Williams t = "setting." + NamedElement(name=prop).camelCase + "(" + prop + ")" 338db838626SDeepak Kodihalli %>\ 3397a6f2526SDeepak Kodihalli ${t}; 3407a6f2526SDeepak Kodihalli % endfor 341db838626SDeepak Kodihalli % endfor 3427a6f2526SDeepak Kodihalli } 3437a6f2526SDeepak Kodihalli 3447a6f2526SDeepak Kodihalli % for n in reversed(ns): 3457a6f2526SDeepak Kodihalli } // namespace ${n} 3467a6f2526SDeepak Kodihalli % endfor 347db838626SDeepak Kodihalli 3487a6f2526SDeepak Kodihalli % endfor 3497a6f2526SDeepak Kodihalli 3505de0957cSDeepak Kodihalli /** @class Manager 3515de0957cSDeepak Kodihalli * 3525de0957cSDeepak Kodihalli * @brief Compose settings objects and put them on the bus. 3535de0957cSDeepak Kodihalli */ 3545de0957cSDeepak Kodihalli class Manager 3555de0957cSDeepak Kodihalli { 3565de0957cSDeepak Kodihalli public: 3575de0957cSDeepak Kodihalli Manager() = delete; 3585de0957cSDeepak Kodihalli Manager(const Manager&) = delete; 3595de0957cSDeepak Kodihalli Manager& operator=(const Manager&) = delete; 3605de0957cSDeepak Kodihalli Manager(Manager&&) = delete; 3615de0957cSDeepak Kodihalli Manager& operator=(Manager&&) = delete; 3625de0957cSDeepak Kodihalli virtual ~Manager() = default; 3635de0957cSDeepak Kodihalli 3645de0957cSDeepak Kodihalli /** @brief Constructor to put settings objects on to the bus. 3655de0957cSDeepak Kodihalli * @param[in] bus - Bus to attach to. 3665de0957cSDeepak Kodihalli */ 3677c4181cfSPatrick Williams explicit Manager(sdbusplus::bus_t& bus) : 3680f6903dbSPatrick Williams settings( 3695de0957cSDeepak Kodihalli std::make_tuple( 370db838626SDeepak Kodihalli % for index, path in enumerate(objects): 371db838626SDeepak Kodihalli <% type = get_setting_type(path) + "::Impl" %>\ 3725de0957cSDeepak Kodihalli std::make_unique<${type}>( 3735de0957cSDeepak Kodihalli bus, 3745de0957cSDeepak Kodihalli % if index < len(settingsDict) - 1: 375db838626SDeepak Kodihalli "${path}"), 3765de0957cSDeepak Kodihalli % else: 3770f6903dbSPatrick Williams "${path}") 3785de0957cSDeepak Kodihalli % endif 3795de0957cSDeepak Kodihalli % endfor 3800f6903dbSPatrick Williams ) 3810f6903dbSPatrick Williams ) 3820f6903dbSPatrick Williams { 383db838626SDeepak Kodihalli % for index, path in enumerate(objects): 3844636e07cSTom Joseph auto initSetting${index} = [&]() 3857a6f2526SDeepak Kodihalli { 386db838626SDeepak Kodihalli % for item in settingsDict[path]: 387db838626SDeepak Kodihalli % for propName, metaDict in item['Properties'].items(): 388bcf95781SPatrick Williams <% p = NamedElement(name=propName).camelCase %>\ 389ffdf8658SMatt Spinler <% defaultValue = get_default_value(path, item['Interface'], propName) %>\ 3905de0957cSDeepak Kodihalli std::get<${index}>(settings)-> 391db838626SDeepak Kodihalli ${get_setting_sdbusplus_type(item['Interface'])}::${p}(${defaultValue}); 3925de0957cSDeepak Kodihalli % endfor 393db838626SDeepak Kodihalli % endfor 3944636e07cSTom Joseph }; 3954636e07cSTom Joseph 3964636e07cSTom Joseph try 3974636e07cSTom Joseph { 398fb1ad7ccSMatt Spinler if (std::get<${index}>(settings)->deserialize()) 3994636e07cSTom Joseph { 400fb1ad7ccSMatt Spinler /* Update the archive to use name/value pairs if it isn't. */ 401fb1ad7ccSMatt Spinler if (std::get<${index}>(settings)->getInitialVersion() < CLASS_VERSION_WITH_NVP) 402fb1ad7ccSMatt Spinler { 403fb1ad7ccSMatt Spinler std::get<${index}>(settings)->serialize(); 404fb1ad7ccSMatt Spinler } 4054636e07cSTom Joseph } 4064636e07cSTom Joseph else 4074636e07cSTom Joseph { 4084636e07cSTom Joseph initSetting${index}(); 4094636e07cSTom Joseph } 4104636e07cSTom Joseph } 411b6fa9bb1SPatrick Williams catch (const cereal::Exception& e) 4124636e07cSTom Joseph { 413*e568fcadSMatt Spinler lg2::error("Cereal exception on ${path}: {ERROR}", "ERROR", e); 414fb1ad7ccSMatt Spinler std::get<${index}>(settings)->removeFile(); 4154636e07cSTom Joseph initSetting${index}(); 416db838626SDeepak Kodihalli } 4177a6f2526SDeepak Kodihalli std::get<${index}>(settings)->emit_object_added(); 4185de0957cSDeepak Kodihalli 4195de0957cSDeepak Kodihalli % endfor 4205de0957cSDeepak Kodihalli } 4215de0957cSDeepak Kodihalli 4225de0957cSDeepak Kodihalli private: 4235de0957cSDeepak Kodihalli /* @brief Composition of settings objects. */ 4245de0957cSDeepak Kodihalli std::tuple< 425db838626SDeepak Kodihalli % for index, path in enumerate(objects): 426db838626SDeepak Kodihalli <% type = get_setting_type(path) + "::Impl" %>\ 4275de0957cSDeepak Kodihalli % if index < len(settingsDict) - 1: 4285de0957cSDeepak Kodihalli std::unique_ptr<${type}>, 4295de0957cSDeepak Kodihalli % else: 4305de0957cSDeepak Kodihalli std::unique_ptr<${type}>> settings; 4315de0957cSDeepak Kodihalli % endif 4325de0957cSDeepak Kodihalli % endfor 4335de0957cSDeepak Kodihalli }; 4345de0957cSDeepak Kodihalli 4355de0957cSDeepak Kodihalli } // namespace settings 4365de0957cSDeepak Kodihalli } // namespace phosphor 437a29a3eb7SVishwanatha Subbanna 438a29a3eb7SVishwanatha Subbanna // Now register the class version with Cereal 439a29a3eb7SVishwanatha Subbanna % for object in objects: 440a29a3eb7SVishwanatha Subbanna <% 441a29a3eb7SVishwanatha Subbanna classname = "phosphor::settings" 442a29a3eb7SVishwanatha Subbanna ns = object.split('/') 443a29a3eb7SVishwanatha Subbanna ns.pop(0) 444a29a3eb7SVishwanatha Subbanna %>\ 445a29a3eb7SVishwanatha Subbanna % for n in ns: 446a29a3eb7SVishwanatha Subbanna <% 447a29a3eb7SVishwanatha Subbanna classname += "::" + n 448a29a3eb7SVishwanatha Subbanna %>\ 449a29a3eb7SVishwanatha Subbanna % endfor 450a29a3eb7SVishwanatha Subbanna CEREAL_CLASS_VERSION(${classname + "::Impl"}, CLASS_VERSION); 451a29a3eb7SVishwanatha Subbanna % endfor 452