10b02be92SPatrick Venture #include "settings.hpp" 20b02be92SPatrick Venture 36a98fe7fSVernon 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; 1418aa044eSDeepak Kodihalli 1518aa044eSDeepak Kodihalli constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper"; 1618aa044eSDeepak Kodihalli constexpr auto mapperPath = "/xyz/openbmc_project/object_mapper"; 1718aa044eSDeepak Kodihalli constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper"; 1818aa044eSDeepak Kodihalli 195d82f474SPatrick Williams Objects::Objects(sdbusplus::bus_t& bus, const std::vector<Interface>& filter) : 2018aa044eSDeepak Kodihalli bus(bus) 2118aa044eSDeepak Kodihalli { 2218aa044eSDeepak Kodihalli auto depth = 0; 2318aa044eSDeepak Kodihalli 240b02be92SPatrick Venture auto mapperCall = bus.new_method_call(mapperService, mapperPath, mapperIntf, 2518aa044eSDeepak Kodihalli "GetSubTree"); 2618aa044eSDeepak Kodihalli mapperCall.append(root); 2718aa044eSDeepak Kodihalli mapperCall.append(depth); 2818aa044eSDeepak Kodihalli mapperCall.append(filter); 2918aa044eSDeepak Kodihalli 3018aa044eSDeepak Kodihalli using Interfaces = std::vector<Interface>; 3118aa044eSDeepak Kodihalli using MapperResponse = std::map<Path, std::map<Service, Interfaces>>; 3218aa044eSDeepak Kodihalli MapperResponse result; 33*3e3cc35bSGeorge Liu try 3418aa044eSDeepak Kodihalli { 35*3e3cc35bSGeorge Liu auto response = bus.call(mapperCall); 36*3e3cc35bSGeorge Liu response.read(result); 37*3e3cc35bSGeorge Liu } 38*3e3cc35bSGeorge Liu catch (const std::exception& e) 39*3e3cc35bSGeorge Liu { 40*3e3cc35bSGeorge Liu log<level::ERR>("Error in mapper GetSubTree", 41*3e3cc35bSGeorge Liu entry("ERROR=%s", e.what())); 4218aa044eSDeepak Kodihalli elog<InternalFailure>(); 4318aa044eSDeepak Kodihalli } 4418aa044eSDeepak Kodihalli 4518aa044eSDeepak Kodihalli for (auto& iter : result) 4618aa044eSDeepak Kodihalli { 4718aa044eSDeepak Kodihalli const auto& path = iter.first; 48e602709dSDeepak Kodihalli for (auto& interface : iter.second.begin()->second) 49e602709dSDeepak Kodihalli { 50e602709dSDeepak Kodihalli auto found = map.find(interface); 51e602709dSDeepak Kodihalli if (map.end() != found) 52e602709dSDeepak Kodihalli { 53e602709dSDeepak Kodihalli auto& paths = found->second; 54e602709dSDeepak Kodihalli paths.push_back(path); 55e602709dSDeepak Kodihalli } 56e602709dSDeepak Kodihalli else 57e602709dSDeepak Kodihalli { 58e602709dSDeepak Kodihalli map.emplace(std::move(interface), std::vector<Path>({path})); 59e602709dSDeepak Kodihalli } 60e602709dSDeepak Kodihalli } 6118aa044eSDeepak Kodihalli } 6218aa044eSDeepak Kodihalli } 6318aa044eSDeepak Kodihalli 6418aa044eSDeepak Kodihalli Service Objects::service(const Path& path, const Interface& interface) const 6518aa044eSDeepak Kodihalli { 6618aa044eSDeepak Kodihalli using Interfaces = std::vector<Interface>; 67fbc6c9d7SPatrick Williams auto mapperCall = bus.new_method_call(mapperService, mapperPath, mapperIntf, 68fbc6c9d7SPatrick Williams "GetObject"); 6918aa044eSDeepak Kodihalli mapperCall.append(path); 7018aa044eSDeepak Kodihalli mapperCall.append(Interfaces({interface})); 7118aa044eSDeepak Kodihalli 7218aa044eSDeepak Kodihalli std::map<Service, Interfaces> result; 73*3e3cc35bSGeorge Liu try 7418aa044eSDeepak Kodihalli { 75*3e3cc35bSGeorge Liu auto response = bus.call(mapperCall); 76*3e3cc35bSGeorge Liu response.read(result); 77*3e3cc35bSGeorge Liu return result.begin()->first; 78*3e3cc35bSGeorge Liu } 79*3e3cc35bSGeorge Liu catch (const std::exception& e) 80*3e3cc35bSGeorge Liu { 81*3e3cc35bSGeorge Liu log<level::ERR>("Invalid response from mapper", 82*3e3cc35bSGeorge Liu entry("ERROR=%s", e.what())); 8318aa044eSDeepak Kodihalli elog<InternalFailure>(); 8418aa044eSDeepak Kodihalli } 8518aa044eSDeepak Kodihalli } 8618aa044eSDeepak Kodihalli 8713791bd5SDeepak Kodihalli namespace boot 8813791bd5SDeepak Kodihalli { 8913791bd5SDeepak Kodihalli 9013791bd5SDeepak Kodihalli std::tuple<Path, OneTimeEnabled> setting(const Objects& objects, 9113791bd5SDeepak Kodihalli const Interface& iface) 9213791bd5SDeepak Kodihalli { 9313791bd5SDeepak Kodihalli constexpr auto bootObjCount = 2; 9413791bd5SDeepak Kodihalli constexpr auto oneTime = "one_time"; 9513791bd5SDeepak Kodihalli constexpr auto enabledIntf = "xyz.openbmc_project.Object.Enable"; 9613791bd5SDeepak Kodihalli 9713791bd5SDeepak Kodihalli const std::vector<Path>& paths = objects.map.at(iface); 9813791bd5SDeepak Kodihalli auto count = paths.size(); 9913791bd5SDeepak Kodihalli if (count != bootObjCount) 10013791bd5SDeepak Kodihalli { 10113791bd5SDeepak Kodihalli log<level::ERR>("Exactly two objects expected", 10213791bd5SDeepak Kodihalli entry("INTERFACE=%s", iface.c_str()), 10313791bd5SDeepak Kodihalli entry("COUNT=%d", count)); 10413791bd5SDeepak Kodihalli elog<InternalFailure>(); 10513791bd5SDeepak Kodihalli } 10613791bd5SDeepak Kodihalli size_t index = 0; 10713791bd5SDeepak Kodihalli if (std::string::npos == paths[0].rfind(oneTime)) 10813791bd5SDeepak Kodihalli { 10913791bd5SDeepak Kodihalli index = 1; 11013791bd5SDeepak Kodihalli } 11113791bd5SDeepak Kodihalli const Path& oneTimeSetting = paths[index]; 11213791bd5SDeepak Kodihalli const Path& regularSetting = paths[!index]; 11313791bd5SDeepak Kodihalli 1140b02be92SPatrick Venture auto method = objects.bus.new_method_call( 1150b02be92SPatrick Venture objects.service(oneTimeSetting, iface).c_str(), oneTimeSetting.c_str(), 1160b02be92SPatrick Venture ipmi::PROP_INTF, "Get"); 11713791bd5SDeepak Kodihalli method.append(enabledIntf, "Enabled"); 118*3e3cc35bSGeorge Liu 119*3e3cc35bSGeorge Liu std::variant<bool> enabled; 120*3e3cc35bSGeorge Liu try 121*3e3cc35bSGeorge Liu { 12213791bd5SDeepak Kodihalli auto reply = objects.bus.call(method); 123*3e3cc35bSGeorge Liu reply.read(enabled); 124*3e3cc35bSGeorge Liu } 125*3e3cc35bSGeorge Liu catch (const std::exception& e) 12613791bd5SDeepak Kodihalli { 12713791bd5SDeepak Kodihalli log<level::ERR>("Error in getting Enabled property", 12813791bd5SDeepak Kodihalli entry("OBJECT=%s", oneTimeSetting.c_str()), 129*3e3cc35bSGeorge Liu entry("INTERFACE=%s", iface.c_str()), 130*3e3cc35bSGeorge Liu entry("ERROR=%s", e.what())); 13113791bd5SDeepak Kodihalli elog<InternalFailure>(); 13213791bd5SDeepak Kodihalli } 13313791bd5SDeepak Kodihalli 134f442e119SVernon Mauery auto oneTimeEnabled = std::get<bool>(enabled); 13513791bd5SDeepak Kodihalli const Path& setting = oneTimeEnabled ? oneTimeSetting : regularSetting; 13613791bd5SDeepak Kodihalli return std::make_tuple(setting, oneTimeEnabled); 13713791bd5SDeepak Kodihalli } 13813791bd5SDeepak Kodihalli 13913791bd5SDeepak Kodihalli } // namespace boot 14013791bd5SDeepak Kodihalli 14118aa044eSDeepak Kodihalli } // namespace settings 142