10b02be92SPatrick Venture #include "settings.hpp" 20b02be92SPatrick Venture 3*6a98fe7fSVernon Mauery #include <ipmid/utils.hpp> 418aa044eSDeepak Kodihalli #include <phosphor-logging/elog-errors.hpp> 518aa044eSDeepak Kodihalli #include <phosphor-logging/log.hpp> 64c008028SWilliam A. Kennington III #include <sdbusplus/message/types.hpp> 70b02be92SPatrick Venture #include <xyz/openbmc_project/Common/error.hpp> 818aa044eSDeepak Kodihalli 918aa044eSDeepak Kodihalli namespace settings 1018aa044eSDeepak Kodihalli { 1118aa044eSDeepak Kodihalli 1218aa044eSDeepak Kodihalli using namespace phosphor::logging; 1318aa044eSDeepak Kodihalli using namespace sdbusplus::xyz::openbmc_project::Common::Error; 144c008028SWilliam A. Kennington III namespace variant_ns = sdbusplus::message::variant_ns; 1518aa044eSDeepak Kodihalli 1618aa044eSDeepak Kodihalli constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper"; 1718aa044eSDeepak Kodihalli constexpr auto mapperPath = "/xyz/openbmc_project/object_mapper"; 1818aa044eSDeepak Kodihalli constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper"; 1918aa044eSDeepak Kodihalli 2018aa044eSDeepak Kodihalli Objects::Objects(sdbusplus::bus::bus& bus, 2118aa044eSDeepak Kodihalli const std::vector<Interface>& filter) : 2218aa044eSDeepak Kodihalli bus(bus) 2318aa044eSDeepak Kodihalli { 2418aa044eSDeepak Kodihalli auto depth = 0; 2518aa044eSDeepak Kodihalli 260b02be92SPatrick Venture auto mapperCall = bus.new_method_call(mapperService, mapperPath, mapperIntf, 2718aa044eSDeepak Kodihalli "GetSubTree"); 2818aa044eSDeepak Kodihalli mapperCall.append(root); 2918aa044eSDeepak Kodihalli mapperCall.append(depth); 3018aa044eSDeepak Kodihalli mapperCall.append(filter); 3118aa044eSDeepak Kodihalli auto response = bus.call(mapperCall); 3218aa044eSDeepak Kodihalli if (response.is_method_error()) 3318aa044eSDeepak Kodihalli { 3418aa044eSDeepak Kodihalli log<level::ERR>("Error in mapper GetSubTree"); 3518aa044eSDeepak Kodihalli elog<InternalFailure>(); 3618aa044eSDeepak Kodihalli } 3718aa044eSDeepak Kodihalli 3818aa044eSDeepak Kodihalli using Interfaces = std::vector<Interface>; 3918aa044eSDeepak Kodihalli using MapperResponse = std::map<Path, std::map<Service, Interfaces>>; 4018aa044eSDeepak Kodihalli MapperResponse result; 4118aa044eSDeepak Kodihalli response.read(result); 4218aa044eSDeepak Kodihalli if (result.empty()) 4318aa044eSDeepak Kodihalli { 4418aa044eSDeepak Kodihalli log<level::ERR>("Invalid response from mapper"); 4518aa044eSDeepak Kodihalli elog<InternalFailure>(); 4618aa044eSDeepak Kodihalli } 4718aa044eSDeepak Kodihalli 4818aa044eSDeepak Kodihalli for (auto& iter : result) 4918aa044eSDeepak Kodihalli { 5018aa044eSDeepak Kodihalli const auto& path = iter.first; 51e602709dSDeepak Kodihalli for (auto& interface : iter.second.begin()->second) 52e602709dSDeepak Kodihalli { 53e602709dSDeepak Kodihalli auto found = map.find(interface); 54e602709dSDeepak Kodihalli if (map.end() != found) 55e602709dSDeepak Kodihalli { 56e602709dSDeepak Kodihalli auto& paths = found->second; 57e602709dSDeepak Kodihalli paths.push_back(path); 58e602709dSDeepak Kodihalli } 59e602709dSDeepak Kodihalli else 60e602709dSDeepak Kodihalli { 61e602709dSDeepak Kodihalli map.emplace(std::move(interface), std::vector<Path>({path})); 62e602709dSDeepak Kodihalli } 63e602709dSDeepak Kodihalli } 6418aa044eSDeepak Kodihalli } 6518aa044eSDeepak Kodihalli } 6618aa044eSDeepak Kodihalli 6718aa044eSDeepak Kodihalli Service Objects::service(const Path& path, const Interface& interface) const 6818aa044eSDeepak Kodihalli { 6918aa044eSDeepak Kodihalli using Interfaces = std::vector<Interface>; 700b02be92SPatrick Venture auto mapperCall = 710b02be92SPatrick Venture bus.new_method_call(mapperService, mapperPath, mapperIntf, "GetObject"); 7218aa044eSDeepak Kodihalli mapperCall.append(path); 7318aa044eSDeepak Kodihalli mapperCall.append(Interfaces({interface})); 7418aa044eSDeepak Kodihalli 7518aa044eSDeepak Kodihalli auto response = bus.call(mapperCall); 7618aa044eSDeepak Kodihalli if (response.is_method_error()) 7718aa044eSDeepak Kodihalli { 7818aa044eSDeepak Kodihalli log<level::ERR>("Error in mapper GetObject"); 7918aa044eSDeepak Kodihalli elog<InternalFailure>(); 8018aa044eSDeepak Kodihalli } 8118aa044eSDeepak Kodihalli 8218aa044eSDeepak Kodihalli std::map<Service, Interfaces> result; 8318aa044eSDeepak Kodihalli response.read(result); 8418aa044eSDeepak Kodihalli if (result.empty()) 8518aa044eSDeepak Kodihalli { 8618aa044eSDeepak Kodihalli log<level::ERR>("Invalid response from mapper"); 8718aa044eSDeepak Kodihalli elog<InternalFailure>(); 8818aa044eSDeepak Kodihalli } 8918aa044eSDeepak Kodihalli 9018aa044eSDeepak Kodihalli return result.begin()->first; 9118aa044eSDeepak Kodihalli } 9218aa044eSDeepak Kodihalli 9313791bd5SDeepak Kodihalli namespace boot 9413791bd5SDeepak Kodihalli { 9513791bd5SDeepak Kodihalli 9613791bd5SDeepak Kodihalli std::tuple<Path, OneTimeEnabled> setting(const Objects& objects, 9713791bd5SDeepak Kodihalli const Interface& iface) 9813791bd5SDeepak Kodihalli { 9913791bd5SDeepak Kodihalli constexpr auto bootObjCount = 2; 10013791bd5SDeepak Kodihalli constexpr auto oneTime = "one_time"; 10113791bd5SDeepak Kodihalli constexpr auto enabledIntf = "xyz.openbmc_project.Object.Enable"; 10213791bd5SDeepak Kodihalli 10313791bd5SDeepak Kodihalli const std::vector<Path>& paths = objects.map.at(iface); 10413791bd5SDeepak Kodihalli auto count = paths.size(); 10513791bd5SDeepak Kodihalli if (count != bootObjCount) 10613791bd5SDeepak Kodihalli { 10713791bd5SDeepak Kodihalli log<level::ERR>("Exactly two objects expected", 10813791bd5SDeepak Kodihalli entry("INTERFACE=%s", iface.c_str()), 10913791bd5SDeepak Kodihalli entry("COUNT=%d", count)); 11013791bd5SDeepak Kodihalli elog<InternalFailure>(); 11113791bd5SDeepak Kodihalli } 11213791bd5SDeepak Kodihalli size_t index = 0; 11313791bd5SDeepak Kodihalli if (std::string::npos == paths[0].rfind(oneTime)) 11413791bd5SDeepak Kodihalli { 11513791bd5SDeepak Kodihalli index = 1; 11613791bd5SDeepak Kodihalli } 11713791bd5SDeepak Kodihalli const Path& oneTimeSetting = paths[index]; 11813791bd5SDeepak Kodihalli const Path& regularSetting = paths[!index]; 11913791bd5SDeepak Kodihalli 1200b02be92SPatrick Venture auto method = objects.bus.new_method_call( 1210b02be92SPatrick Venture objects.service(oneTimeSetting, iface).c_str(), oneTimeSetting.c_str(), 1220b02be92SPatrick Venture ipmi::PROP_INTF, "Get"); 12313791bd5SDeepak Kodihalli method.append(enabledIntf, "Enabled"); 12413791bd5SDeepak Kodihalli auto reply = objects.bus.call(method); 12513791bd5SDeepak Kodihalli if (reply.is_method_error()) 12613791bd5SDeepak Kodihalli { 12713791bd5SDeepak Kodihalli log<level::ERR>("Error in getting Enabled property", 12813791bd5SDeepak Kodihalli entry("OBJECT=%s", oneTimeSetting.c_str()), 12913791bd5SDeepak Kodihalli entry("INTERFACE=%s", iface.c_str())); 13013791bd5SDeepak Kodihalli elog<InternalFailure>(); 13113791bd5SDeepak Kodihalli } 13213791bd5SDeepak Kodihalli 13313791bd5SDeepak Kodihalli sdbusplus::message::variant<bool> enabled; 13413791bd5SDeepak Kodihalli reply.read(enabled); 1354c008028SWilliam A. Kennington III auto oneTimeEnabled = variant_ns::get<bool>(enabled); 13613791bd5SDeepak Kodihalli const Path& setting = oneTimeEnabled ? oneTimeSetting : regularSetting; 13713791bd5SDeepak Kodihalli return std::make_tuple(setting, oneTimeEnabled); 13813791bd5SDeepak Kodihalli } 13913791bd5SDeepak Kodihalli 14013791bd5SDeepak Kodihalli } // namespace boot 14113791bd5SDeepak Kodihalli 14218aa044eSDeepak Kodihalli } // namespace settings 143