1 /** 2 * Copyright © 2024 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include "chassis.hpp" 19 #include "chassis_status_monitor.hpp" 20 #include "power_sequencer_device.hpp" 21 #include "rail.hpp" 22 23 #include <nlohmann/json.hpp> 24 25 #include <cstdint> 26 #include <filesystem> 27 #include <functional> // for reference_wrapper 28 #include <map> 29 #include <memory> 30 #include <string> 31 #include <tuple> 32 #include <vector> 33 34 using json = nlohmann::json; 35 36 namespace phosphor::power::sequencer::config_file_parser 37 { 38 39 /** 40 * Standard JSON configuration file directory on the BMC. 41 */ 42 extern const std::filesystem::path standardConfigFileDirectory; 43 44 /** 45 * Default JSON configuration file name. 46 */ 47 extern const std::string defaultConfigFileName; 48 49 /** 50 * Returns the path to the default JSON configuration file. 51 * 52 * @return default config file path 53 */ 54 std::filesystem::path getDefaultConfigFilePath(); 55 56 /** 57 * Finds the JSON configuration file for the current system based on the 58 * specified compatible system types. 59 * 60 * This is required when a single BMC firmware image supports multiple system 61 * types and some system types require different configuration files. 62 * 63 * The compatible system types must be ordered from most to least specific. 64 * Example: 65 * - com.acme.Hardware.Chassis.Model.MegaServer4CPU 66 * - com.acme.Hardware.Chassis.Model.MegaServer 67 * - com.acme.Hardware.Chassis.Model.Server 68 * 69 * Throws an exception if an error occurs. 70 * 71 * @param compatibleSystemTypes compatible system types for the current system 72 * ordered from most to least specific 73 * @param configFileDir directory containing configuration files 74 * @return path to the JSON configuration file, or an empty path if none was 75 * found 76 */ 77 std::filesystem::path find( 78 const std::vector<std::string>& compatibleSystemTypes, 79 const std::filesystem::path& configFileDir = standardConfigFileDirectory); 80 81 /** 82 * Parses the specified JSON configuration file. 83 * 84 * Returns the corresponding C++ Chassis objects. 85 * 86 * Throws a ConfigFileParserError if an error occurs. 87 * 88 * @param pathName configuration file path name 89 * @return vector of Chassis objects 90 */ 91 std::vector<std::unique_ptr<Chassis>> parse( 92 const std::filesystem::path& pathName); 93 94 /* 95 * Internal implementation details for parse() 96 */ 97 namespace internal 98 { 99 100 using JSONRefWrapper = std::reference_wrapper<const json>; 101 102 /** 103 * Parses a JSON element containing a chassis object. 104 * 105 * Returns the corresponding C++ Chassis object. 106 * 107 * Throws an exception if parsing fails. 108 * 109 * @param element JSON element 110 * @param chassisTemplates chassis templates map 111 * @return Chassis object 112 */ 113 std::unique_ptr<Chassis> parseChassis( 114 const json& element, 115 const std::map<std::string, JSONRefWrapper>& chassisTemplates); 116 117 /** 118 * Parses a JSON element containing an array of chassis objects. 119 * 120 * Returns the corresponding C++ Chassis objects. 121 * 122 * Throws an exception if parsing fails. 123 * 124 * @param element JSON element 125 * @param chassisTemplates chassis templates map 126 * @return vector of Chassis objects 127 */ 128 std::vector<std::unique_ptr<Chassis>> parseChassisArray( 129 const json& element, 130 const std::map<std::string, JSONRefWrapper>& chassisTemplates); 131 132 /** 133 * Parses a JSON element containing the properties of a chassis. 134 * 135 * The JSON element may be a chassis object or chassis_template object. 136 * 137 * Returns the corresponding C++ Chassis object. 138 * 139 * Throws an exception if parsing fails. 140 * 141 * @param element JSON element 142 * @param isChassisTemplate specifies whether element is a chassis_template 143 * @param variables variables map used to expand variables in element value 144 * @return Chassis object 145 */ 146 std::unique_ptr<Chassis> parseChassisProperties( 147 const json& element, bool isChassisTemplate, 148 const std::map<std::string, std::string>& variables); 149 150 /** 151 * Parses a JSON element containing a chassis_template object. 152 * 153 * Returns the template ID and a C++ reference_wrapper to the JSON element. 154 * 155 * A chassis_template object cannot be fully parsed in isolation. It is a 156 * template that contains variables. 157 * 158 * The chassis_template object is used by one or more chassis objects to avoid 159 * duplicate JSON. The chassis objects define chassis-specific values for the 160 * template variables. 161 * 162 * When the chassis object is parsed, the chassis_template JSON will be 163 * re-parsed, and the template variables will be replaced with the 164 * chassis-specific values. 165 * 166 * Throws an exception if parsing fails. 167 * 168 * @param element JSON element 169 * @return template ID and reference_wrapper to JSON element 170 */ 171 std::tuple<std::string, JSONRefWrapper> parseChassisTemplate( 172 const json& element); 173 174 /** 175 * Parses a JSON element containing an array of chassis_template objects. 176 * 177 * Returns a map of template IDs to chassis_template JSON elements. 178 * 179 * Note that chassis_template objects cannot be fully parsed in isolation. See 180 * parseChassisTemplate() for more information. 181 * 182 * Throws an exception if parsing fails. 183 * 184 * @param element JSON element 185 * @return chassis templates map 186 */ 187 std::map<std::string, JSONRefWrapper> parseChassisTemplateArray( 188 const json& element); 189 190 /** 191 * Parses a JSON element containing chassis status monitoring options. 192 * 193 * Returns the corresponding C++ ChassisStatusMonitorOptions object. 194 * 195 * Throws an exception if parsing fails. 196 * 197 * @param element JSON element 198 * @param variables variables map used to expand variables in element value 199 * @return ChassisStatusMonitorOptions object 200 */ 201 ChassisStatusMonitorOptions parseStatusMonitoring( 202 const json& element, const std::map<std::string, std::string>& variables); 203 204 /** 205 * Parses a JSON element containing a gpio object. 206 * 207 * Returns the corresponding C++ PgoodGPIO object. 208 * 209 * Throws an exception if parsing fails. 210 * 211 * @param element JSON element 212 * @param variables variables map used to expand variables in element value 213 * @return PgoodGPIO object 214 */ 215 PgoodGPIO parseGPIO(const json& element, 216 const std::map<std::string, std::string>& variables); 217 218 /** 219 * Parses a JSON element containing an i2c_interface object. 220 * 221 * Returns the corresponding I2C bus and address. 222 * 223 * Throws an exception if parsing fails. 224 * 225 * @param element JSON element 226 * @param variables variables map used to expand variables in element value 227 * @return tuple containing bus and address 228 */ 229 std::tuple<uint8_t, uint16_t> parseI2CInterface( 230 const json& element, const std::map<std::string, std::string>& variables); 231 232 /** 233 * Parses a JSON element containing a power_sequencer object. 234 * 235 * Returns the corresponding C++ PowerSequencerDevice object. 236 * 237 * Throws an exception if parsing fails. 238 * 239 * @param element JSON element 240 * @param variables variables map used to expand variables in element value 241 * @return PowerSequencerDevice object 242 */ 243 std::unique_ptr<PowerSequencerDevice> parsePowerSequencer( 244 const json& element, const std::map<std::string, std::string>& variables); 245 246 /** 247 * Parses a JSON element containing an array of power_sequencer objects. 248 * 249 * Returns the corresponding C++ PowerSequencerDevice objects. 250 * 251 * Throws an exception if parsing fails. 252 * 253 * @param element JSON element 254 * @param variables variables map used to expand variables in element value 255 * @return vector of PowerSequencerDevice objects 256 */ 257 std::vector<std::unique_ptr<PowerSequencerDevice>> parsePowerSequencerArray( 258 const json& element, const std::map<std::string, std::string>& variables); 259 260 /** 261 * Parses a JSON element containing a rail. 262 * 263 * Returns the corresponding C++ Rail object. 264 * 265 * Throws an exception if parsing fails. 266 * 267 * @param element JSON element 268 * @param variables variables map used to expand variables in element value 269 * @return Rail object 270 */ 271 std::unique_ptr<Rail> parseRail( 272 const json& element, const std::map<std::string, std::string>& variables); 273 274 /** 275 * Parses a JSON element containing an array of rails. 276 * 277 * Returns the corresponding C++ Rail objects. 278 * 279 * Throws an exception if parsing fails. 280 * 281 * @param element JSON element 282 * @param variables variables map used to expand variables in element value 283 * @return vector of Rail objects 284 */ 285 std::vector<std::unique_ptr<Rail>> parseRailArray( 286 const json& element, const std::map<std::string, std::string>& variables); 287 288 /** 289 * Parses the JSON root element of the entire configuration file. 290 * 291 * Returns the corresponding C++ Chassis objects. 292 * 293 * Throws an exception if parsing fails. 294 * 295 * @param element JSON element 296 * @return vector of Chassis objects 297 */ 298 std::vector<std::unique_ptr<Chassis>> parseRoot(const json& element); 299 300 /** 301 * Parses a JSON element containing an object with variable names and values. 302 * 303 * Returns the corresponding C++ map of variable names and values. 304 * 305 * Throws an exception if parsing fails. 306 * 307 * @param element JSON element 308 * @return map of variable names and values 309 */ 310 std::map<std::string, std::string> parseVariables(const json& element); 311 312 } // namespace internal 313 314 } // namespace phosphor::power::sequencer::config_file_parser 315