blob: 9fca3daeb3b6f7e56e1a2a122fd21f972f57a5b4 [file] [log] [blame]
Deepak Kodihalli5de09572017-05-16 23:53:40 -05001## This file is a template. The comment below is emitted
2## into the rendered file; feel free to edit this file.
3// WARNING: Generated header. Do not edit!
Deepak Kodihalli5de09572017-05-16 23:53:40 -05004<%
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -05005import re
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -05006from collections import defaultdict
Deepak Kodihalli5de09572017-05-16 23:53:40 -05007objects = list(settingsDict.viewkeys())
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -05008sdbusplus_namespaces = []
9sdbusplus_includes = []
10interfaces = []
11props = defaultdict(list)
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -050012validators = defaultdict(tuple)
Deepak Kodihalli5de09572017-05-16 23:53:40 -050013
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -050014def get_setting_sdbusplus_type(setting_intf):
Deepak Kodihalli5de09572017-05-16 23:53:40 -050015 setting = "sdbusplus::" + setting_intf.replace('.', '::')
16 i = setting.rfind('::')
17 setting = setting[:i] + '::server::' + setting[i+2:]
18 return setting
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -050019
20def get_setting_type(setting_intf):
21 setting = setting_intf.replace('.', '::')
22 return setting
Deepak Kodihalli5de09572017-05-16 23:53:40 -050023%>\
24#pragma once
25
26% for object in objects:
27<%
Deepak Kodihalli5de09572017-05-16 23:53:40 -050028 include = settingsDict[object]['Interface']
29 include = include.replace('.', '/')
30 include = include + "/server.hpp"
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -050031 sdbusplus_includes.append(include)
Deepak Kodihalli5de09572017-05-16 23:53:40 -050032%>\
33% endfor
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -050034#include <cereal/archives/json.hpp>
35#include <fstream>
36#include <utility>
37#include <experimental/filesystem>
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -050038#include <regex>
39#include <phosphor-logging/elog.hpp>
40#include <phosphor-logging/elog-errors.hpp>
41#include <phosphor-logging/log.hpp>
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -050042#include "config.h"
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -050043#include <xyz/openbmc_project/Common/error.hpp>
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -050044
45% for i in set(sdbusplus_includes):
Deepak Kodihalli5de09572017-05-16 23:53:40 -050046#include "${i}"
47% endfor
48
49% for object in objects:
50<%
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -050051 ns = get_setting_sdbusplus_type(settingsDict[object]['Interface'])
Deepak Kodihalli5de09572017-05-16 23:53:40 -050052 i = ns.rfind('::')
53 ns = ns[:i]
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -050054 sdbusplus_namespaces.append(ns)
Deepak Kodihalli5de09572017-05-16 23:53:40 -050055%>\
56% endfor
Deepak Kodihalli5de09572017-05-16 23:53:40 -050057
58namespace phosphor
59{
60namespace settings
61{
62
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -050063namespace fs = std::experimental::filesystem;
64
65% for n in set(sdbusplus_namespaces):
66using namespace ${n};
67% endfor
68
69% for object in objects:
70<%
71 intf = settingsDict[object]['Interface']
72 interfaces.append(intf)
73 if intf not in props:
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -050074 for property, property_metadata in settingsDict[object]['Properties'].items():
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -050075 props[intf].append(property)
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -050076 for attribute, value in property_metadata.items():
77 if attribute == 'Validation':
78 if value['Type'] == "range":
79 validators[property] = (value['Type'], value['Validator'], value['Unit'])
80 else:
81 validators[property] = (value['Type'], value['Validator'])
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -050082%>\
83% endfor
84% for intf in set(interfaces):
85<%
86 ns = intf.split(".")
87 sdbusplus_type = get_setting_sdbusplus_type(intf)
88%>\
89% for n in ns:
90namespace ${n}
91{
92% endfor
93
94using Base = ${sdbusplus_type};
95<% parent = "sdbusplus::server::object::object" + "<" + sdbusplus_type + ">" %>\
96using Parent = ${parent};
97
98class Impl : public Parent
99{
100 public:
101 Impl(sdbusplus::bus::bus& bus, const char* path):
102 Parent(bus, path, true),
103 path(path)
104 {
105 }
106 virtual ~Impl() = default;
107
108% for arg in props[intf]:
109<% t = arg[:1].lower() + arg[1:] %>\
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -0500110<% fname = "validate"+arg %>\
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -0500111 decltype(std::declval<Base>().${t}()) ${t}(decltype(std::declval<Base>().${t}()) value) override
112 {
113 auto result = Base::${t}();
114 if (value != result)
115 {
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -0500116 % if arg in validators.keys():
117 if (!${fname}(value))
118 {
119 namespace error =
120 sdbusplus::xyz::openbmc_project::Common::Error;
121 namespace metadata =
122 phosphor::logging::xyz::openbmc_project::Common;
123 phosphor::logging::report<error::InvalidArgument>(
124 metadata::InvalidArgument::ARGUMENT_NAME("${t}"),
125 % if validators[arg][0] != "regex":
126 metadata::InvalidArgument::ARGUMENT_VALUE(std::to_string(value).c_str()));
127 % else:
128 metadata::InvalidArgument::ARGUMENT_VALUE(value.c_str()));
129 % endif
130 return result;
131 }
132 % endif
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -0500133 fs::path p(SETTINGS_PERSIST_PATH);
134 p /= path;
135 fs::create_directories(p.parent_path());
136 std::ofstream os(p.c_str(), std::ios::binary);
137 cereal::JSONOutputArchive oarchive(os);
138 result = Base::${t}(value);
139 oarchive(*this);
140 }
141 return result;
142 }
143 using Base::${t};
144
Andrew Geisslerc15990a2017-07-06 11:36:31 -0500145% endfor
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -0500146 private:
147 fs::path path;
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -0500148% for arg in props[intf]:
149% if arg in validators.keys():
150<% funcName = "validate"+arg %>\
151<% t = arg[:1].lower() + arg[1:] %>\
152
153 bool ${funcName}(decltype(std::declval<Base>().${t}()) value)
154 {
155 bool matched = false;
156 % if (arg in validators.keys()) and (validators[arg][0] == 'regex'):
157 std::regex regexToCheck("${validators[arg][1]}");
158 matched = std::regex_search(value, regexToCheck);
159 if (!matched)
160 {
161 std::string err = "Input parameter for ${arg} is invalid "
162 "Input: " + value + " not in the format of this regex: "
163 "${validators[arg][1]}";
164 using namespace phosphor::logging;
165 log<level::ERR>(err.c_str());
166 }
167 % elif (arg in validators.keys()) and (validators[arg][0] == 'range'):
168<% lowhigh = re.split('\.\.', validators[arg][1]) %>\
169 if ((value <= ${lowhigh[1]}) && (value >= ${lowhigh[0]}))
170 {
171 matched = true;
172 }
173 else
174 {
175 std::string err = "Input parameter for ${arg} is invalid "
176 "Input: " + std::to_string(value) + "in uint: "
177 "${validators[arg][2]} is not in range:${validators[arg][1]}";
178 using namespace phosphor::logging;
179 log<level::ERR>(err.c_str());
180 }
181 % elif (arg in validators.keys()):
182 <% assert("Unknown validation type: arg") %>\
183 % endif
184 return matched;
185 }
186% endif
187% endfor
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -0500188};
189
190template<class Archive>
191void save(Archive& a,
192 const Impl& setting)
193{
194<%
195 args = ["setting." + p[:1].lower() + p[1:] + "()" for p in props[intf]]
196 args = ','.join(args)
197%>\
198 a(${args});
199}
200
201template<class Archive>
202void load(Archive& a,
203 Impl& setting)
204{
205% for arg in props[intf]:
206<% t = "setting." + arg[:1].lower() + arg[1:] + "()" %>\
207 decltype(${t}) ${arg}{};
208% endfor
209<%
210 args = ','.join(props[intf])
211%>\
212 a(${args});
213% for arg in props[intf]:
214<% t = "setting." + arg[:1].lower() + arg[1:] + "(" + arg + ")" %>\
215 ${t};
216% endfor
217}
218
219% for n in reversed(ns):
220} // namespace ${n}
221% endfor
222% endfor
223
Deepak Kodihalli5de09572017-05-16 23:53:40 -0500224/** @class Manager
225 *
226 * @brief Compose settings objects and put them on the bus.
227 */
228class Manager
229{
230 public:
231 Manager() = delete;
232 Manager(const Manager&) = delete;
233 Manager& operator=(const Manager&) = delete;
234 Manager(Manager&&) = delete;
235 Manager& operator=(Manager&&) = delete;
236 virtual ~Manager() = default;
237
238 /** @brief Constructor to put settings objects on to the bus.
239 * @param[in] bus - Bus to attach to.
240 */
241 Manager(sdbusplus::bus::bus& bus)
242 {
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -0500243 fs::path path{};
Deepak Kodihalli5de09572017-05-16 23:53:40 -0500244 settings =
245 std::make_tuple(
246% for index, object in enumerate(objects):
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -0500247<% type = get_setting_type(settingsDict[object]['Interface']) + "::Impl" %>\
Deepak Kodihalli5de09572017-05-16 23:53:40 -0500248 std::make_unique<${type}>(
249 bus,
250 % if index < len(settingsDict) - 1:
251 "${object}"),
252 % else:
253 "${object}"));
254 % endif
255% endfor
256
257% for index, object in enumerate(objects):
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -0500258 % for property, value in settingsDict[object]['Properties'].items():
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -0500259<% p = property[:1].lower() + property[1:] %>\
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -0500260<% defaultValue = value['Default'] %>\
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -0500261 path = fs::path(SETTINGS_PERSIST_PATH) / "${object}";
262 if (fs::exists(path))
263 {
264 std::ifstream is(path.c_str(), std::ios::in);
265 cereal::JSONInputArchive iarchive(is);
266 iarchive(*std::get<${index}>(settings));
267 }
268 else
269 {
270 std::get<${index}>(settings)->
Dhruvaraj Subhashchandran61d3b6a2017-07-25 09:36:54 -0500271 ${get_setting_sdbusplus_type(settingsDict[object]['Interface'])}::${p}(${defaultValue});
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -0500272 }
273 % endfor
274 std::get<${index}>(settings)->emit_object_added();
Deepak Kodihalli5de09572017-05-16 23:53:40 -0500275
276% endfor
277 }
278
279 private:
280 /* @brief Composition of settings objects. */
281 std::tuple<
282% for index, object in enumerate(objects):
Deepak Kodihalli7a6f2522017-06-23 23:05:47 -0500283<% type = get_setting_type(settingsDict[object]['Interface']) + "::Impl" %>\
Deepak Kodihalli5de09572017-05-16 23:53:40 -0500284 % if index < len(settingsDict) - 1:
285 std::unique_ptr<${type}>,
286 % else:
287 std::unique_ptr<${type}>> settings;
288 % endif
289% endfor
290};
291
292} // namespace settings
293} // namespace phosphor