| #include "config-validator.hpp" |
| |
| #include "grouplayout.hpp" |
| #include "ledlayout.hpp" |
| |
| #include <phosphor-logging/lg2.hpp> |
| #include <sdbusplus/bus.hpp> |
| |
| using namespace phosphor::led; |
| |
| namespace phosphor |
| { |
| namespace led |
| { |
| |
| // Priority for a particular LED needs to stay SAME across all groups |
| using PriorityMap = |
| std::unordered_map<std::string, |
| std::optional<phosphor::led::Layout::Action>>; |
| |
| static bool isUsingGroupPriority(const phosphor::led::GroupMap& ledMap) |
| { |
| for (const auto& [_, group] : ledMap) |
| { |
| if (group.priority != 0) |
| { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| static std::string priorityToString( |
| const std::optional<phosphor::led::Layout::Action>& priority) |
| { |
| if (!priority.has_value()) |
| { |
| return "none"; |
| } |
| switch (priority.value()) |
| { |
| case phosphor::led::Layout::Action::Off: |
| return "Off"; |
| case phosphor::led::Layout::Action::On: |
| return "On"; |
| case phosphor::led::Layout::Action::Blink: |
| return "Blink"; |
| } |
| return "?"; |
| } |
| |
| /** @brief Validate the Priority of an LED is same across ALL groups |
| * |
| * @param[in] name - led name member of each group |
| * @param[in] priority - member priority of each group |
| * @param[out] priorityMap - std::unordered_map, key:name, value:priority |
| * |
| * @return |
| */ |
| void validatePriority( |
| const std::string& name, |
| const std::optional<phosphor::led::Layout::Action>& priority, |
| PriorityMap& priorityMap) |
| { |
| auto iter = priorityMap.find(name); |
| if (iter == priorityMap.end()) |
| { |
| priorityMap.emplace(name, priority); |
| return; |
| } |
| |
| if (iter->second != priority) |
| { |
| throw ConfigValidationException( |
| error::LedPriorityMismatch, "?", name, |
| "Priority of the LED is not same across groups. Old Priority = " + |
| priorityToString(iter->second) + |
| ", New Priority = " + priorityToString(priority)); |
| } |
| } |
| |
| static void validateConfigV1GroupForLedPriority( |
| const std::string groupName, |
| const phosphor::led::Layout::GroupLayout& group, PriorityMap& priorityMap) |
| { |
| if (group.priority != 0) |
| { |
| throw ConfigValidationException( |
| error::MixedLedAndGroupPriority, groupName, |
| "Cannot mix group priority and led priority"); |
| } |
| |
| for (const auto& ledAction : group.actionSet) |
| { |
| if (ledAction.priority == std::nullopt) |
| { |
| throw ConfigValidationException(error::MissingLedPriority, |
| groupName, ledAction.name, |
| "Need valid led priority"); |
| } |
| |
| // Same LEDs can be part of multiple groups. However, their |
| // priorities across groups need to match. |
| validatePriority(ledAction.name, ledAction.priority, priorityMap); |
| } |
| } |
| |
| static void |
| validateConfigV1ForLedPriority(const phosphor::led::GroupMap& ledMap) |
| { |
| PriorityMap priorityMap{}; |
| for (const auto& [groupName, group] : ledMap) |
| { |
| validateConfigV1GroupForLedPriority(groupName, group, priorityMap); |
| } |
| } |
| |
| static void validateConfigV1GroupForGroupPriority( |
| const std::string groupName, |
| const phosphor::led::Layout::GroupLayout& group) |
| { |
| for (const auto& led : group.actionSet) |
| { |
| if (led.priority != std::nullopt) |
| { |
| throw ConfigValidationException( |
| error::MixedLedAndGroupPriority, groupName, led.name, |
| "Cannot mix group priority and led priority for LED"); |
| } |
| } |
| |
| if (group.priority == 0) |
| { |
| // group priority 0 is for internal use |
| throw ConfigValidationException(error::InvalidGroupPriority, groupName, |
| "Group Priority cannot be 0"); |
| } |
| } |
| |
| static void |
| validateConfigV1ForGroupPriority(const phosphor::led::GroupMap& ledMap) |
| { |
| std::set<int> groupPriorities; |
| for (const auto& [_, group] : ledMap) |
| { |
| groupPriorities.insert(group.priority); |
| } |
| |
| if (groupPriorities.size() != ledMap.size()) |
| { |
| throw ConfigValidationException( |
| error::DuplicateGroupPriority, |
| "When using Group Priority, no 2 Groups may have the same priority"); |
| } |
| |
| for (const auto& [groupName, group] : ledMap) |
| { |
| validateConfigV1GroupForGroupPriority(groupName, group); |
| } |
| } |
| |
| void validateConfigV1(const GroupMap& ledMap) |
| { |
| const bool useGroupPriority = isUsingGroupPriority(ledMap); |
| |
| if (useGroupPriority) |
| { |
| validateConfigV1ForGroupPriority(ledMap); |
| } |
| else |
| { |
| validateConfigV1ForLedPriority(ledMap); |
| } |
| } |
| |
| } // namespace led |
| } // namespace phosphor |