1 #include <string> 2 #include <sdbusplus/server.hpp> 3 #include <phosphor-logging/log.hpp> 4 #include <ext_interface.hpp> 5 6 // Mapper 7 constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper"; 8 constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper"; 9 constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper"; 10 11 // Reboot count 12 constexpr auto REBOOTCOUNTER_PATH("/xyz/openbmc_project/state/host0"); 13 constexpr auto REBOOTCOUNTER_INTERFACE("xyz.openbmc_project.Control.Boot.RebootAttempts"); 14 15 using namespace phosphor::logging; 16 17 /** 18 * @brief Get DBUS service for input interface via mapper call 19 * 20 * This is an internal function to be used only by functions within this 21 * file. 22 * 23 * @param[in] bus - DBUS Bus Object 24 * @param[in] intf - DBUS Interface 25 * @param[in] path - DBUS Object Path 26 * 27 * @return distinct dbus name for input interface/path 28 **/ 29 std::string getService(sdbusplus::bus::bus& bus, 30 const std::string& intf, 31 const std::string& path) 32 { 33 34 auto mapper = bus.new_method_call(MAPPER_BUSNAME, 35 MAPPER_PATH, 36 MAPPER_INTERFACE, 37 "GetObject"); 38 39 mapper.append(path); 40 mapper.append(std::vector<std::string>({intf})); 41 42 auto mapperResponseMsg = bus.call(mapper); 43 44 if (mapperResponseMsg.is_method_error()) 45 { 46 // TODO openbmc/openbmc#851 - Once available, throw returned error 47 throw std::runtime_error("ERROR in mapper call"); 48 } 49 50 std::map<std::string, std::vector<std::string>> mapperResponse; 51 mapperResponseMsg.read(mapperResponse); 52 53 if (mapperResponse.empty()) 54 { 55 // TODO openbmc/openbmc#1712 - Handle empty mapper resp. consistently 56 throw std::runtime_error("ERROR in reading the mapper response"); 57 } 58 59 return mapperResponse.begin()->first; 60 } 61 62 63 uint32_t getBootCount() 64 { 65 auto bus = sdbusplus::bus::new_default(); 66 67 auto rebootSvc = getService(bus, 68 REBOOTCOUNTER_INTERFACE, 69 REBOOTCOUNTER_PATH); 70 71 auto method = bus.new_method_call(rebootSvc.c_str(), 72 REBOOTCOUNTER_PATH, 73 "org.freedesktop.DBus.Properties", 74 "Get"); 75 76 method.append(REBOOTCOUNTER_INTERFACE, "AttemptsLeft"); 77 auto reply = bus.call(method); 78 if (reply.is_method_error()) 79 { 80 log<level::ERR>("Error in BOOTCOUNT getValue"); 81 // TODO openbmc/openbmc#851 - Once available, throw returned error 82 throw std::runtime_error("ERROR in reading BOOTCOUNT"); 83 } 84 sdbusplus::message::variant<uint32_t> rebootCount; 85 reply.read(rebootCount); 86 87 return (rebootCount.get<uint32_t>()); 88 } 89