blob: 1829e232628ca75e9b4cb8df8293a50339eacbb3 [file] [log] [blame]
Shawn McCarney0e8c68a2020-03-27 01:44:48 -05001/**
2 * Copyright © 2020 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 "action.hpp"
Bob King3a787542020-04-14 13:45:01 +080019#include "and_action.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050020#include "chassis.hpp"
Bob Kingb267b7e2020-04-22 14:42:39 +080021#include "compare_presence_action.hpp"
Bob Kingf2134322020-04-27 14:14:56 +080022#include "compare_vpd_action.hpp"
Bob King9c36c5f2020-04-06 11:34:09 +080023#include "configuration.hpp"
Bob King0e701132020-04-03 21:50:31 +080024#include "device.hpp"
Shawn McCarney91f87a52021-09-07 09:59:57 -050025#include "i2c_capture_bytes_action.hpp"
Bob Kingf09bfe02020-04-13 17:21:15 +080026#include "i2c_compare_bit_action.hpp"
27#include "i2c_compare_byte_action.hpp"
28#include "i2c_compare_bytes_action.hpp"
Bob King9c36c5f2020-04-06 11:34:09 +080029#include "i2c_interface.hpp"
Bob Kingf617f892020-03-30 19:03:35 +080030#include "i2c_write_bit_action.hpp"
Bob King87ff9d72020-03-31 14:02:55 +080031#include "i2c_write_byte_action.hpp"
Bob Kingbafcb862020-03-31 16:39:00 +080032#include "i2c_write_bytes_action.hpp"
Bob King93a89d72020-04-15 15:11:11 +080033#include "if_action.hpp"
Shawn McCarney11157852021-09-07 14:04:36 -050034#include "log_phase_fault_action.hpp"
Bob Kingf1b58dc2020-04-14 14:53:10 +080035#include "not_action.hpp"
Bob King0b51a9b2020-04-15 13:24:18 +080036#include "or_action.hpp"
Shawn McCarneyb70370b2021-09-07 12:07:40 -050037#include "phase_fault.hpp"
Shawn McCarney39eb08a2021-09-07 16:34:49 -050038#include "phase_fault_detection.hpp"
Bob King84614882020-04-30 13:13:48 +080039#include "pmbus_read_sensor_action.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050040#include "pmbus_write_vout_command_action.hpp"
Bob King9c36c5f2020-04-06 11:34:09 +080041#include "presence_detection.hpp"
42#include "rail.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050043#include "rule.hpp"
Bob King315b0b62020-04-03 21:47:58 +080044#include "run_rule_action.hpp"
Bob Kinga2f2a0d2020-04-09 13:32:14 +080045#include "sensor_monitoring.hpp"
Shawn McCarney2f9e14f2021-04-29 02:45:18 -050046#include "sensors.hpp"
Bob King18a68502020-04-17 14:19:56 +080047#include "set_device_action.hpp"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050048
49#include <nlohmann/json.hpp>
50
51#include <cstdint>
52#include <filesystem>
53#include <memory>
54#include <stdexcept>
55#include <string>
56#include <tuple>
57#include <vector>
58
59namespace phosphor::power::regulators::config_file_parser
60{
61
62/**
63 * Parses the specified JSON configuration file.
64 *
65 * Returns the corresponding C++ Rule and Chassis objects.
66 *
67 * Throws a ConfigFileParserError if an error occurs.
68 *
69 * @param pathName configuration file path name
70 * @return tuple containing vectors of Rule and Chassis objects
71 */
72std::tuple<std::vector<std::unique_ptr<Rule>>,
73 std::vector<std::unique_ptr<Chassis>>>
74 parse(const std::filesystem::path& pathName);
75
76/*
77 * Internal implementation details for parse()
78 */
79namespace internal
80{
81
82/**
83 * Returns the specified property of the specified JSON element.
84 *
85 * Throws an invalid_argument exception if the property does not exist.
86 *
87 * @param element JSON element
88 * @param property property name
89 */
Patrick Williams974a7942023-05-31 20:18:53 -050090#pragma GCC diagnostic push
91#pragma GCC diagnostic ignored "-Wdangling-reference"
Shawn McCarney0e8c68a2020-03-27 01:44:48 -050092inline const nlohmann::json& getRequiredProperty(const nlohmann::json& element,
93 const std::string& property)
94{
95 auto it = element.find(property);
96 if (it == element.end())
97 {
98 throw std::invalid_argument{"Required property missing: " + property};
99 }
100 return *it;
101}
Patrick Williams974a7942023-05-31 20:18:53 -0500102#pragma GCC diagnostic pop
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500103
104/**
105 * Parses a JSON element containing an action.
106 *
107 * Returns the corresponding C++ Action object.
108 *
109 * Throws an exception if parsing fails.
110 *
111 * @param element JSON element
112 * @return Action object
113 */
114std::unique_ptr<Action> parseAction(const nlohmann::json& element);
115
116/**
117 * Parses a JSON element containing an array of actions.
118 *
119 * Returns the corresponding C++ Action objects.
120 *
121 * Throws an exception if parsing fails.
122 *
123 * @param element JSON element
124 * @return vector of Action objects
125 */
126std::vector<std::unique_ptr<Action>>
127 parseActionArray(const nlohmann::json& element);
128
129/**
Bob King3a787542020-04-14 13:45:01 +0800130 * Parses a JSON element containing an and action.
131 *
132 * Returns the corresponding C++ AndAction object.
133 *
134 * Throws an exception if parsing fails.
135 *
136 * @param element JSON element
137 * @return AndAction object
138 */
139std::unique_ptr<AndAction> parseAnd(const nlohmann::json& element);
140
141/**
Bob Kingf617f892020-03-30 19:03:35 +0800142 * Parses a JSON element containing a bit position (from 0-7).
143 *
144 * Returns the corresponding C++ uint8_t value.
145 *
146 * Throws an exception if parsing fails.
147 *
148 * @param element JSON element
149 * @return uint8_t value
150 */
151inline uint8_t parseBitPosition(const nlohmann::json& element)
152{
153 // Verify element contains an integer
154 if (!element.is_number_integer())
155 {
156 throw std::invalid_argument{"Element is not an integer"};
157 }
Bob King6afbf1a2020-04-06 17:19:01 +0800158 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800159 if ((value < 0) || (value > 7))
160 {
161 throw std::invalid_argument{"Element is not a bit position"};
162 }
163 return static_cast<uint8_t>(value);
164}
165
166/**
167 * Parses a JSON element containing a bit value (0 or 1).
168 *
169 * Returns the corresponding C++ uint8_t value.
170 *
171 * Throws an exception if parsing fails.
172 *
173 * @param element JSON element
174 * @return uint8_t value
175 */
176inline uint8_t parseBitValue(const nlohmann::json& element)
177{
178 // Verify element contains an integer
179 if (!element.is_number_integer())
180 {
181 throw std::invalid_argument{"Element is not an integer"};
182 }
Bob King6afbf1a2020-04-06 17:19:01 +0800183 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800184 if ((value < 0) || (value > 1))
185 {
186 throw std::invalid_argument{"Element is not a bit value"};
187 }
188 return static_cast<uint8_t>(value);
189}
190
191/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500192 * Parses a JSON element containing a boolean.
193 *
194 * Returns the corresponding C++ boolean value.
195 *
196 * Throws an exception if parsing fails.
197 *
198 * @param element JSON element
199 * @return boolean value
200 */
201inline bool parseBoolean(const nlohmann::json& element)
202{
203 // Verify element contains a boolean
204 if (!element.is_boolean())
205 {
206 throw std::invalid_argument{"Element is not a boolean"};
207 }
208 return element.get<bool>();
209}
210
211/**
Bob King0e701132020-04-03 21:50:31 +0800212 * Parses a JSON element containing a chassis.
213 *
214 * Returns the corresponding C++ Chassis object.
215 *
216 * Throws an exception if parsing fails.
217 *
218 * @param element JSON element
219 * @return Chassis object
220 */
221std::unique_ptr<Chassis> parseChassis(const nlohmann::json& element);
222
223/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500224 * Parses a JSON element containing an array of chassis.
225 *
226 * Returns the corresponding C++ Chassis objects.
227 *
228 * Throws an exception if parsing fails.
229 *
230 * @param element JSON element
231 * @return vector of Chassis objects
232 */
233std::vector<std::unique_ptr<Chassis>>
234 parseChassisArray(const nlohmann::json& element);
235
236/**
Bob Kingb267b7e2020-04-22 14:42:39 +0800237 * Parses a JSON element containing a compare_presence action.
238 *
239 * Returns the corresponding C++ ComparePresenceAction object.
240 *
241 * Throws an exception if parsing fails.
242 *
243 * @param element JSON element
244 * @return ComparePresenceAction object
245 */
246std::unique_ptr<ComparePresenceAction>
247 parseComparePresence(const nlohmann::json& element);
248
249/**
Bob Kingf2134322020-04-27 14:14:56 +0800250 * Parses a JSON element containing a compare_vpd action.
251 *
252 * Returns the corresponding C++ CompareVPDAction object.
253 *
254 * Throws an exception if parsing fails.
255 *
256 * @param element JSON element
257 * @return CompareVPDAction object
258 */
259std::unique_ptr<CompareVPDAction>
260 parseCompareVPD(const nlohmann::json& element);
261
262/**
Shawn McCarney39eb08a2021-09-07 16:34:49 -0500263 * Parses a JSON element containing a configuration object.
Bob King33e7eaa2020-04-01 18:09:34 +0800264 *
265 * Returns the corresponding C++ Configuration object.
266 *
267 * Throws an exception if parsing fails.
268 *
269 * @param element JSON element
270 * @return Configuration object
271 */
272std::unique_ptr<Configuration>
273 parseConfiguration(const nlohmann::json& element);
274
275/**
Bob King9c36c5f2020-04-06 11:34:09 +0800276 * Parses a JSON element containing a device.
277 *
278 * Returns the corresponding C++ Device object.
279 *
280 * Throws an exception if parsing fails.
281 *
282 * @param element JSON element
283 * @return Device object
284 */
285std::unique_ptr<Device> parseDevice(const nlohmann::json& element);
286
287/**
Bob King0e701132020-04-03 21:50:31 +0800288 * Parses a JSON element containing an array of devices.
289 *
290 * Returns the corresponding C++ Device objects.
291 *
292 * Throws an exception if parsing fails.
293 *
294 * @param element JSON element
295 * @return vector of Device objects
296 */
297std::vector<std::unique_ptr<Device>>
298 parseDeviceArray(const nlohmann::json& element);
299
300/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500301 * Parses a JSON element containing a double (floating point number).
302 *
303 * Returns the corresponding C++ double value.
304 *
305 * Throws an exception if parsing fails.
306 *
307 * @param element JSON element
308 * @return double value
309 */
310inline double parseDouble(const nlohmann::json& element)
311{
312 // Verify element contains a number (integer or floating point)
313 if (!element.is_number())
314 {
315 throw std::invalid_argument{"Element is not a number"};
316 }
317 return element.get<double>();
318}
319
320/**
Bob Kingbafcb862020-03-31 16:39:00 +0800321 * Parses a JSON element containing a byte value expressed as a hexadecimal
322 * string.
323 *
324 * The JSON number data type does not support the hexadecimal format. For this
325 * reason, hexadecimal byte values are stored as strings in the configuration
326 * file.
327 *
328 * Returns the corresponding C++ uint8_t value.
329 *
330 * Throws an exception if parsing fails.
331 *
332 * @param element JSON element
333 * @return uint8_t value
334 */
335inline uint8_t parseHexByte(const nlohmann::json& element)
336{
337 if (!element.is_string())
338 {
339 throw std::invalid_argument{"Element is not a string"};
340 }
Bob King6afbf1a2020-04-06 17:19:01 +0800341 std::string value = element.get<std::string>();
Bob Kingbafcb862020-03-31 16:39:00 +0800342
343 bool isHex = (value.compare(0, 2, "0x") == 0) && (value.size() > 2) &&
344 (value.size() < 5) &&
345 (value.find_first_not_of("0123456789abcdefABCDEF", 2) ==
346 std::string::npos);
347 if (!isHex)
348 {
349 throw std::invalid_argument{"Element is not hexadecimal string"};
350 }
351 return static_cast<uint8_t>(std::stoul(value, 0, 0));
352}
353
354/**
355 * Parses a JSON element containing an array of byte values expressed as a
356 * hexadecimal strings.
357 *
358 * Returns the corresponding C++ uint8_t values.
359 *
360 * Throws an exception if parsing fails.
361 *
362 * @param element JSON element
363 * @return vector of uint8_t
364 */
365std::vector<uint8_t> parseHexByteArray(const nlohmann::json& element);
366
367/**
Shawn McCarney91f87a52021-09-07 09:59:57 -0500368 * Parses a JSON element containing an i2c_capture_bytes action.
369 *
370 * Returns the corresponding C++ I2CCaptureBytesAction object.
371 *
372 * Throws an exception if parsing fails.
373 *
374 * @param element JSON element
375 * @return I2CCaptureBytesAction object
376 */
377std::unique_ptr<I2CCaptureBytesAction>
378 parseI2CCaptureBytes(const nlohmann::json& element);
379
380/**
Bob Kingf09bfe02020-04-13 17:21:15 +0800381 * Parses a JSON element containing an i2c_compare_bit action.
382 *
383 * Returns the corresponding C++ I2CCompareBitAction object.
384 *
385 * Throws an exception if parsing fails.
386 *
387 * @param element JSON element
388 * @return I2CCompareBitAction object
389 */
390std::unique_ptr<I2CCompareBitAction>
391 parseI2CCompareBit(const nlohmann::json& element);
392
393/**
394 * Parses a JSON element containing an i2c_compare_byte action.
395 *
396 * Returns the corresponding C++ I2CCompareByteAction object.
397 *
398 * Throws an exception if parsing fails.
399 *
400 * @param element JSON element
401 * @return I2CCompareByteAction object
402 */
403std::unique_ptr<I2CCompareByteAction>
404 parseI2CCompareByte(const nlohmann::json& element);
405
406/**
407 * Parses a JSON element containing an i2c_compare_bytes action.
408 *
409 * Returns the corresponding C++ I2CCompareBytesAction object.
410 *
411 * Throws an exception if parsing fails.
412 *
413 * @param element JSON element
414 * @return I2CCompareBytesAction object
415 */
416std::unique_ptr<I2CCompareBytesAction>
417 parseI2CCompareBytes(const nlohmann::json& element);
418
419/**
Bob King9c36c5f2020-04-06 11:34:09 +0800420 * Parses a JSON element containing an i2c_interface.
421 *
422 * Returns the corresponding C++ i2c::I2CInterface object.
423 *
424 * Throws an exception if parsing fails.
425 *
426 * @param element JSON element
427 * @return i2c::I2CInterface object
428 */
429std::unique_ptr<i2c::I2CInterface>
430 parseI2CInterface(const nlohmann::json& element);
431
432/**
Bob Kingf617f892020-03-30 19:03:35 +0800433 * Parses a JSON element containing an i2c_write_bit action.
434 *
435 * Returns the corresponding C++ I2CWriteBitAction object.
436 *
437 * Throws an exception if parsing fails.
438 *
439 * @param element JSON element
440 * @return I2CWriteBitAction object
441 */
442std::unique_ptr<I2CWriteBitAction>
443 parseI2CWriteBit(const nlohmann::json& element);
444
445/**
Bob King87ff9d72020-03-31 14:02:55 +0800446 * Parses a JSON element containing an i2c_write_byte action.
447 *
448 * Returns the corresponding C++ I2CWriteByteAction object.
449 *
450 * Throws an exception if parsing fails.
451 *
452 * @param element JSON element
453 * @return I2CWriteByteAction object
454 */
455std::unique_ptr<I2CWriteByteAction>
456 parseI2CWriteByte(const nlohmann::json& element);
457
458/**
Bob Kingbafcb862020-03-31 16:39:00 +0800459 * Parses a JSON element containing an i2c_write_bytes action.
460 *
461 * Returns the corresponding C++ I2CWriteBytesAction object.
462 *
463 * Throws an exception if parsing fails.
464 *
465 * @param element JSON element
466 * @return I2CWriteBytesAction object
467 */
468std::unique_ptr<I2CWriteBytesAction>
469 parseI2CWriteBytes(const nlohmann::json& element);
470
471/**
Bob King93a89d72020-04-15 15:11:11 +0800472 * Parses a JSON element containing an if action.
473 *
474 * Returns the corresponding C++ IfAction object.
475 *
476 * Throws an exception if parsing fails.
477 *
478 * @param element JSON element
479 * @return IfAction object
480 */
481std::unique_ptr<IfAction> parseIf(const nlohmann::json& element);
482
483/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500484 * Parses a JSON element containing an 8-bit signed integer.
485 *
486 * Returns the corresponding C++ int8_t value.
487 *
488 * Throws an exception if parsing fails.
489 *
490 * @param element JSON element
491 * @return int8_t value
492 */
493inline int8_t parseInt8(const nlohmann::json& element)
494{
495 // Verify element contains an integer
496 if (!element.is_number_integer())
497 {
498 throw std::invalid_argument{"Element is not an integer"};
499 }
Bob King6afbf1a2020-04-06 17:19:01 +0800500 int value = element.get<int>();
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500501 if ((value < INT8_MIN) || (value > INT8_MAX))
502 {
503 throw std::invalid_argument{"Element is not an 8-bit signed integer"};
504 }
505 return static_cast<int8_t>(value);
506}
507
508/**
Bob Kinga76898f2020-10-13 15:08:33 +0800509 * Parses a JSON element containing a relative inventory path.
510 *
511 * Returns the corresponding C++ string containing the absolute inventory path.
512 *
513 * Inventory paths in the JSON configuration file are relative. Adds the
514 * necessary prefix to make the path absolute.
515 *
516 * Throws an exception if parsing fails.
517 *
518 * @param element JSON element
519 * @return absolute D-Bus inventory path
520 */
521std::string parseInventoryPath(const nlohmann::json& element);
522
523/**
Shawn McCarney11157852021-09-07 14:04:36 -0500524 * Parses a JSON element containing a log_phase_fault action.
525 *
526 * Returns the corresponding C++ LogPhaseFaultAction object.
527 *
528 * Throws an exception if parsing fails.
529 *
530 * @param element JSON element
531 * @return LogPhaseFaultAction object
532 */
533std::unique_ptr<LogPhaseFaultAction>
534 parseLogPhaseFault(const nlohmann::json& element);
535
536/**
Bob Kingf1b58dc2020-04-14 14:53:10 +0800537 * Parses a JSON element containing a not action.
538 *
539 * Returns the corresponding C++ NotAction object.
540 *
541 * Throws an exception if parsing fails.
542 *
543 * @param element JSON element
544 * @return NotAction object
545 */
546std::unique_ptr<NotAction> parseNot(const nlohmann::json& element);
547
548/**
Bob King0b51a9b2020-04-15 13:24:18 +0800549 * Parses a JSON element containing an or action.
550 *
551 * Returns the corresponding C++ OrAction object.
552 *
553 * Throws an exception if parsing fails.
554 *
555 * @param element JSON element
556 * @return OrAction object
557 */
558std::unique_ptr<OrAction> parseOr(const nlohmann::json& element);
559
560/**
Shawn McCarney39eb08a2021-09-07 16:34:49 -0500561 * Parses a JSON element containing a phase_fault_detection object.
562 *
563 * Returns the corresponding C++ PhaseFaultDetection object.
564 *
565 * Throws an exception if parsing fails.
566 *
567 * @param element JSON element
568 * @return PhaseFaultDetection object
569 */
570std::unique_ptr<PhaseFaultDetection>
571 parsePhaseFaultDetection(const nlohmann::json& element);
572
573/**
Shawn McCarneyb70370b2021-09-07 12:07:40 -0500574 * Parses a JSON element containing a PhaseFaultType expressed as a string.
575 *
576 * Returns the corresponding PhaseFaultType enum value.
577 *
578 * Throws an exception if parsing fails.
579 *
580 * @param element JSON element
581 * @return PhaseFaultType enum value
582 */
583PhaseFaultType parsePhaseFaultType(const nlohmann::json& element);
584
585/**
Bob King84614882020-04-30 13:13:48 +0800586 * Parses a JSON element containing a pmbus_read_sensor action.
587 *
588 * Returns the corresponding C++ PMBusReadSensorAction object.
589 *
590 * Throws an exception if parsing fails.
591 *
592 * @param element JSON element
593 * @return PMBusReadSensorAction object
594 */
595std::unique_ptr<PMBusReadSensorAction>
596 parsePMBusReadSensor(const nlohmann::json& element);
597
598/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500599 * Parses a JSON element containing a pmbus_write_vout_command action.
600 *
601 * Returns the corresponding C++ PMBusWriteVoutCommandAction object.
602 *
603 * Throws an exception if parsing fails.
604 *
605 * @param element JSON element
606 * @return PMBusWriteVoutCommandAction object
607 */
608std::unique_ptr<PMBusWriteVoutCommandAction>
609 parsePMBusWriteVoutCommand(const nlohmann::json& element);
610
611/**
Shawn McCarney39eb08a2021-09-07 16:34:49 -0500612 * Parses a JSON element containing a presence_detection object.
Bob King2aafb1c2020-04-16 15:24:32 +0800613 *
614 * Returns the corresponding C++ PresenceDetection object.
615 *
616 * Throws an exception if parsing fails.
617 *
618 * @param element JSON element
619 * @return PresenceDetection object
620 */
621std::unique_ptr<PresenceDetection>
622 parsePresenceDetection(const nlohmann::json& element);
623
624/**
Bob Kinga2f2a0d2020-04-09 13:32:14 +0800625 * Parses a JSON element containing a rail.
626 *
627 * Returns the corresponding C++ Rail object.
628 *
629 * Throws an exception if parsing fails.
630 *
631 * @param element JSON element
632 * @return Rail object
633 */
634std::unique_ptr<Rail> parseRail(const nlohmann::json& element);
635
636/**
Bob King9c36c5f2020-04-06 11:34:09 +0800637 * Parses a JSON element containing an array of rails.
638 *
639 * Returns the corresponding C++ Rail objects.
640 *
641 * Throws an exception if parsing fails.
642 *
643 * @param element JSON element
644 * @return vector of Rail objects
645 */
646std::vector<std::unique_ptr<Rail>>
647 parseRailArray(const nlohmann::json& element);
648
649/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500650 * Parses the JSON root element of the entire configuration file.
651 *
652 * Returns the corresponding C++ Rule and Chassis objects.
653 *
654 * Throws an exception if parsing fails.
655 *
656 * @param element JSON element
657 * @return tuple containing vectors of Rule and Chassis objects
658 */
659std::tuple<std::vector<std::unique_ptr<Rule>>,
660 std::vector<std::unique_ptr<Chassis>>>
661 parseRoot(const nlohmann::json& element);
662
663/**
664 * Parses a JSON element containing a rule.
665 *
666 * Returns the corresponding C++ Rule object.
667 *
668 * Throws an exception if parsing fails.
669 *
670 * @param element JSON element
671 * @return Rule object
672 */
673std::unique_ptr<Rule> parseRule(const nlohmann::json& element);
674
675/**
676 * Parses a JSON element containing an array of rules.
677 *
678 * Returns the corresponding C++ Rule objects.
679 *
680 * Throws an exception if parsing fails.
681 *
682 * @param element JSON element
683 * @return vector of Rule objects
684 */
685std::vector<std::unique_ptr<Rule>>
686 parseRuleArray(const nlohmann::json& element);
687
688/**
Bob King33e7eaa2020-04-01 18:09:34 +0800689 * Parses the "rule_id" or "actions" property in a JSON element.
690 *
691 * The element must contain one property or the other but not both.
692 *
693 * If the element contains a "rule_id" property, the corresponding C++
694 * RunRuleAction object is returned.
695 *
696 * If the element contains an "actions" property, the corresponding C++ Action
697 * objects are returned.
698 *
699 * Throws an exception if parsing fails.
700 *
701 * @param element JSON element
702 * @return vector of Action objects
703 */
704std::vector<std::unique_ptr<Action>>
705 parseRuleIDOrActionsProperty(const nlohmann::json& element);
706
707/**
Bob King315b0b62020-04-03 21:47:58 +0800708 * Parses a JSON element containing a run_rule action.
709 *
710 * Returns the corresponding C++ RunRuleAction object.
711 *
712 * Throws an exception if parsing fails.
713 *
714 * @param element JSON element
715 * @return RunRuleAction object
716 */
717std::unique_ptr<RunRuleAction> parseRunRule(const nlohmann::json& element);
718
719/**
Bob King84614882020-04-30 13:13:48 +0800720 * Parses a JSON element containing a SensorDataFormat expressed as a string.
721 *
722 * Returns the corresponding SensorDataFormat enum value.
723 *
724 * Throws an exception if parsing fails.
725 *
726 * @param element JSON element
727 * @return SensorDataFormat enum value
728 */
729pmbus_utils::SensorDataFormat
730 parseSensorDataFormat(const nlohmann::json& element);
731
732/**
Shawn McCarney39eb08a2021-09-07 16:34:49 -0500733 * Parses a JSON element containing a sensor_monitoring object.
Bob Kinga2f2a0d2020-04-09 13:32:14 +0800734 *
735 * Returns the corresponding C++ SensorMonitoring object.
736 *
737 * Throws an exception if parsing fails.
738 *
739 * @param element JSON element
740 * @return SensorMonitoring object
741 */
742std::unique_ptr<SensorMonitoring>
743 parseSensorMonitoring(const nlohmann::json& element);
744
745/**
Shawn McCarney2f9e14f2021-04-29 02:45:18 -0500746 * Parses a JSON element containing a SensorType expressed as a string.
Bob King84614882020-04-30 13:13:48 +0800747 *
Shawn McCarney2f9e14f2021-04-29 02:45:18 -0500748 * Returns the corresponding SensorType enum value.
Bob King84614882020-04-30 13:13:48 +0800749 *
750 * Throws an exception if parsing fails.
751 *
752 * @param element JSON element
Shawn McCarney2f9e14f2021-04-29 02:45:18 -0500753 * @return SensorType enum value
Bob King84614882020-04-30 13:13:48 +0800754 */
Shawn McCarney2f9e14f2021-04-29 02:45:18 -0500755SensorType parseSensorType(const nlohmann::json& element);
Bob King84614882020-04-30 13:13:48 +0800756
757/**
Bob King18a68502020-04-17 14:19:56 +0800758 * Parses a JSON element containing a set_device action.
759 *
760 * Returns the corresponding C++ SetDeviceAction object.
761 *
762 * Throws an exception if parsing fails.
763 *
764 * @param element JSON element
765 * @return SetDeviceAction object
766 */
767std::unique_ptr<SetDeviceAction> parseSetDevice(const nlohmann::json& element);
768
769/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500770 * Parses a JSON element containing a string.
771 *
772 * Returns the corresponding C++ string.
773 *
774 * Throws an exception if parsing fails.
775 *
776 * @param element JSON element
777 * @param isEmptyValid indicates whether an empty string value is valid
778 * @return string value
779 */
780inline std::string parseString(const nlohmann::json& element,
781 bool isEmptyValid = false)
782{
783 if (!element.is_string())
784 {
785 throw std::invalid_argument{"Element is not a string"};
786 }
Bob King6afbf1a2020-04-06 17:19:01 +0800787 std::string value = element.get<std::string>();
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500788 if (value.empty() && !isEmptyValid)
789 {
790 throw std::invalid_argument{"Element contains an empty string"};
791 }
792 return value;
793}
794
795/**
Bob Kingf617f892020-03-30 19:03:35 +0800796 * Parses a JSON element containing an 8-bit unsigned integer.
797 *
798 * Returns the corresponding C++ uint8_t value.
799 *
800 * Throws an exception if parsing fails.
801 *
802 * @param element JSON element
803 * @return uint8_t value
804 */
805inline uint8_t parseUint8(const nlohmann::json& element)
806{
807 // Verify element contains an integer
808 if (!element.is_number_integer())
809 {
810 throw std::invalid_argument{"Element is not an integer"};
811 }
Bob King6afbf1a2020-04-06 17:19:01 +0800812 int value = element.get<int>();
Bob Kingf617f892020-03-30 19:03:35 +0800813 if ((value < 0) || (value > UINT8_MAX))
814 {
815 throw std::invalid_argument{"Element is not an 8-bit unsigned integer"};
816 }
817 return static_cast<uint8_t>(value);
818}
819
820/**
Bob King0e701132020-04-03 21:50:31 +0800821 * Parses a JSON element containing an unsigned integer.
822 *
823 * Returns the corresponding C++ unsigned int value.
824 *
825 * Throws an exception if parsing fails.
826 *
827 * @param element JSON element
828 * @return unsigned int value
829 */
830inline unsigned int parseUnsignedInteger(const nlohmann::json& element)
831{
832 // Verify element contains an unsigned integer
833 if (!element.is_number_unsigned())
834 {
835 throw std::invalid_argument{"Element is not an unsigned integer"};
836 }
837 return element.get<unsigned int>();
838}
839
840/**
Bob King84614882020-04-30 13:13:48 +0800841 * Parses a JSON element containing a VoutDataFormat expressed as a string.
842 *
843 * Returns the corresponding VoutDataFormat enum value.
844 *
845 * Throws an exception if parsing fails.
846 *
847 * @param element JSON element
848 * @return VoutDataFormat enum value
849 */
850pmbus_utils::VoutDataFormat parseVoutDataFormat(const nlohmann::json& element);
851
852/**
Shawn McCarney0e8c68a2020-03-27 01:44:48 -0500853 * Verifies that the specified JSON element is a JSON array.
854 *
855 * Throws an invalid_argument exception if the element is not an array.
856 *
857 * @param element JSON element
858 */
859inline void verifyIsArray(const nlohmann::json& element)
860{
861 if (!element.is_array())
862 {
863 throw std::invalid_argument{"Element is not an array"};
864 }
865}
866
867/**
868 * Verifies that the specified JSON element is a JSON object.
869 *
870 * Throws an invalid_argument exception if the element is not an object.
871 *
872 * @param element JSON element
873 */
874inline void verifyIsObject(const nlohmann::json& element)
875{
876 if (!element.is_object())
877 {
878 throw std::invalid_argument{"Element is not an object"};
879 }
880}
881
882/**
883 * Verifies that the specified JSON element contains the expected number of
884 * properties.
885 *
886 * Throws an invalid_argument exception if the element contains a different
887 * number of properties. This indicates the element contains an invalid
888 * property.
889 *
890 * @param element JSON element
891 * @param expectedCount expected number of properties in element
892 */
893inline void verifyPropertyCount(const nlohmann::json& element,
894 unsigned int expectedCount)
895{
896 if (element.size() != expectedCount)
897 {
898 throw std::invalid_argument{"Element contains an invalid property"};
899 }
900}
901
902} // namespace internal
903
904} // namespace phosphor::power::regulators::config_file_parser