13cc348ceSShawn McCarney /**
23cc348ceSShawn McCarney * Copyright © 2024 IBM Corporation
33cc348ceSShawn McCarney *
43cc348ceSShawn McCarney * Licensed under the Apache License, Version 2.0 (the "License");
53cc348ceSShawn McCarney * you may not use this file except in compliance with the License.
63cc348ceSShawn McCarney * You may obtain a copy of the License at
73cc348ceSShawn McCarney *
83cc348ceSShawn McCarney * http://www.apache.org/licenses/LICENSE-2.0
93cc348ceSShawn McCarney *
103cc348ceSShawn McCarney * Unless required by applicable law or agreed to in writing, software
113cc348ceSShawn McCarney * distributed under the License is distributed on an "AS IS" BASIS,
123cc348ceSShawn McCarney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133cc348ceSShawn McCarney * See the License for the specific language governing permissions and
143cc348ceSShawn McCarney * limitations under the License.
153cc348ceSShawn McCarney */
163cc348ceSShawn McCarney
173cc348ceSShawn McCarney #include "compatible_system_types_finder.hpp"
183cc348ceSShawn McCarney
193cc348ceSShawn McCarney #include <phosphor-logging/lg2.hpp>
203cc348ceSShawn McCarney
213cc348ceSShawn McCarney #include <algorithm>
223cc348ceSShawn McCarney #include <exception>
233cc348ceSShawn McCarney #include <format>
243cc348ceSShawn McCarney #include <ranges>
253cc348ceSShawn McCarney #include <regex>
263cc348ceSShawn McCarney #include <stdexcept>
273cc348ceSShawn McCarney #include <utility>
283cc348ceSShawn McCarney #include <variant>
293cc348ceSShawn McCarney
303cc348ceSShawn McCarney namespace phosphor::power::util
313cc348ceSShawn McCarney {
323cc348ceSShawn McCarney
333cc348ceSShawn McCarney const std::string compatibleInterfaceService =
343cc348ceSShawn McCarney "xyz.openbmc_project.EntityManager";
353cc348ceSShawn McCarney
363cc348ceSShawn McCarney const std::string compatibleInterface =
373cc348ceSShawn McCarney "xyz.openbmc_project.Inventory.Decorator.Compatible";
383cc348ceSShawn McCarney
393cc348ceSShawn McCarney const std::string namesProperty = "Names";
403cc348ceSShawn McCarney
CompatibleSystemTypesFinder(sdbusplus::bus_t & bus,Callback callback)413cc348ceSShawn McCarney CompatibleSystemTypesFinder::CompatibleSystemTypesFinder(sdbusplus::bus_t& bus,
423cc348ceSShawn McCarney Callback callback) :
43*1838dbf9SShawn McCarney callback{std::move(callback)}
44*1838dbf9SShawn McCarney {
45*1838dbf9SShawn McCarney interfaceFinder = std::make_unique<DBusInterfacesFinder>(
463cc348ceSShawn McCarney bus, compatibleInterfaceService,
473cc348ceSShawn McCarney std::vector<std::string>{compatibleInterface},
483cc348ceSShawn McCarney std::bind_front(&CompatibleSystemTypesFinder::interfaceFoundCallback,
49*1838dbf9SShawn McCarney this));
50*1838dbf9SShawn McCarney }
513cc348ceSShawn McCarney
interfaceFoundCallback(const std::string & path,const std::string & interface,const DbusPropertyMap & properties)523cc348ceSShawn McCarney void CompatibleSystemTypesFinder::interfaceFoundCallback(
533cc348ceSShawn McCarney [[maybe_unused]] const std::string& path,
543cc348ceSShawn McCarney [[maybe_unused]] const std::string& interface,
553cc348ceSShawn McCarney const DbusPropertyMap& properties)
563cc348ceSShawn McCarney {
573cc348ceSShawn McCarney try
583cc348ceSShawn McCarney {
593cc348ceSShawn McCarney // Get the property containing the list of compatible names
603cc348ceSShawn McCarney auto it = properties.find(namesProperty);
613cc348ceSShawn McCarney if (it == properties.end())
623cc348ceSShawn McCarney {
633cc348ceSShawn McCarney throw std::runtime_error{
643cc348ceSShawn McCarney std::format("{} property not found", namesProperty)};
653cc348ceSShawn McCarney }
663cc348ceSShawn McCarney auto names = std::get<std::vector<std::string>>(it->second);
673cc348ceSShawn McCarney if (!names.empty())
683cc348ceSShawn McCarney {
693cc348ceSShawn McCarney // If all the compatible names are system or chassis types
703cc348ceSShawn McCarney std::regex pattern{"\\.(system|chassis)\\.", std::regex::icase};
713cc348ceSShawn McCarney if (std::ranges::all_of(names, [&pattern](auto&& name) {
723cc348ceSShawn McCarney return std::regex_search(name, pattern);
733cc348ceSShawn McCarney }))
743cc348ceSShawn McCarney {
753cc348ceSShawn McCarney // Call callback with compatible system type names
763cc348ceSShawn McCarney callback(names);
773cc348ceSShawn McCarney }
783cc348ceSShawn McCarney }
793cc348ceSShawn McCarney }
803cc348ceSShawn McCarney catch (const std::exception& e)
813cc348ceSShawn McCarney {
823cc348ceSShawn McCarney lg2::error(
833cc348ceSShawn McCarney "Unable to obtain properties of Compatible interface: {ERROR}",
843cc348ceSShawn McCarney "ERROR", e);
853cc348ceSShawn McCarney }
863cc348ceSShawn McCarney }
873cc348ceSShawn McCarney
883cc348ceSShawn McCarney } // namespace phosphor::power::util
89