15e0dcb39SLei YU #include "config.h" 25e0dcb39SLei YU 35e0dcb39SLei YU #include "utils.hpp" 45e0dcb39SLei YU 5ad90ad51SLei YU #include <openssl/sha.h> 6ad90ad51SLei YU 75e0dcb39SLei YU #include <fstream> 8*f77189f7SLei YU #include <phosphor-logging/log.hpp> 9*f77189f7SLei YU 10*f77189f7SLei YU using namespace phosphor::logging; 115e0dcb39SLei YU 125e0dcb39SLei YU namespace utils 135e0dcb39SLei YU { 145e0dcb39SLei YU 155e0dcb39SLei YU namespace // anonymous 165e0dcb39SLei YU { 175e0dcb39SLei YU constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper"; 185e0dcb39SLei YU constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper"; 195e0dcb39SLei YU constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper"; 205e0dcb39SLei YU } // namespace 215e0dcb39SLei YU 22*f77189f7SLei YU const UtilsInterface& getUtils() 23*f77189f7SLei YU { 24*f77189f7SLei YU static Utils utils; 25*f77189f7SLei YU return utils; 26*f77189f7SLei YU } 27*f77189f7SLei YU 28*f77189f7SLei YU std::vector<std::string> 29*f77189f7SLei YU Utils::getPSUInventoryPath(sdbusplus::bus::bus& bus) const 305e0dcb39SLei YU { 315e0dcb39SLei YU std::vector<std::string> paths; 325e0dcb39SLei YU auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH, 335e0dcb39SLei YU MAPPER_INTERFACE, "GetSubTreePaths"); 345e0dcb39SLei YU method.append(PSU_INVENTORY_PATH_BASE); 355e0dcb39SLei YU method.append(0); // Depth 0 to search all 365e0dcb39SLei YU method.append(std::vector<std::string>({PSU_INVENTORY_IFACE})); 375e0dcb39SLei YU auto reply = bus.call(method); 385e0dcb39SLei YU 395e0dcb39SLei YU reply.read(paths); 405e0dcb39SLei YU return paths; 415e0dcb39SLei YU } 425e0dcb39SLei YU 43*f77189f7SLei YU std::string Utils::getService(sdbusplus::bus::bus& bus, const char* path, 44*f77189f7SLei YU const char* interface) const 45ad90ad51SLei YU { 46ad90ad51SLei YU auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH, 47ad90ad51SLei YU MAPPER_INTERFACE, "GetObject"); 48ad90ad51SLei YU 49ad90ad51SLei YU mapper.append(path, std::vector<std::string>({interface})); 50ad90ad51SLei YU try 51ad90ad51SLei YU { 52ad90ad51SLei YU auto mapperResponseMsg = bus.call(mapper); 53ad90ad51SLei YU 54ad90ad51SLei YU std::vector<std::pair<std::string, std::vector<std::string>>> 55ad90ad51SLei YU mapperResponse; 56ad90ad51SLei YU mapperResponseMsg.read(mapperResponse); 57ad90ad51SLei YU if (mapperResponse.empty()) 58ad90ad51SLei YU { 59ad90ad51SLei YU log<level::ERR>("Error reading mapper response"); 60ad90ad51SLei YU throw std::runtime_error("Error reading mapper response"); 61ad90ad51SLei YU } 62ad90ad51SLei YU if (mapperResponse.size() < 1) 63ad90ad51SLei YU { 64ad90ad51SLei YU return ""; 65ad90ad51SLei YU } 66ad90ad51SLei YU return mapperResponse[0].first; 67ad90ad51SLei YU } 68ad90ad51SLei YU catch (const sdbusplus::exception::SdBusError& ex) 69ad90ad51SLei YU { 70ad90ad51SLei YU log<level::ERR>("Mapper call failed", entry("METHOD=%d", "GetObject"), 71ad90ad51SLei YU entry("PATH=%s", path), 72ad90ad51SLei YU entry("INTERFACE=%s", interface)); 73ad90ad51SLei YU throw std::runtime_error("Mapper call failed"); 74ad90ad51SLei YU } 75ad90ad51SLei YU } 76ad90ad51SLei YU 77*f77189f7SLei YU std::string Utils::getVersionId(const std::string& version) const 78ad90ad51SLei YU { 79ad90ad51SLei YU if (version.empty()) 80ad90ad51SLei YU { 81ad90ad51SLei YU log<level::ERR>("Error version is empty"); 82ad90ad51SLei YU return {}; 83ad90ad51SLei YU } 84ad90ad51SLei YU 85ad90ad51SLei YU unsigned char digest[SHA512_DIGEST_LENGTH]; 86ad90ad51SLei YU SHA512_CTX ctx; 87ad90ad51SLei YU SHA512_Init(&ctx); 88ad90ad51SLei YU SHA512_Update(&ctx, version.c_str(), strlen(version.c_str())); 89ad90ad51SLei YU SHA512_Final(digest, &ctx); 90ad90ad51SLei YU char mdString[SHA512_DIGEST_LENGTH * 2 + 1]; 91ad90ad51SLei YU for (int i = 0; i < SHA512_DIGEST_LENGTH; i++) 92ad90ad51SLei YU { 93ad90ad51SLei YU snprintf(&mdString[i * 2], 3, "%02x", (unsigned int)digest[i]); 94ad90ad51SLei YU } 95ad90ad51SLei YU 96ad90ad51SLei YU // Only need 8 hex digits. 97ad90ad51SLei YU std::string hexId = std::string(mdString); 98ad90ad51SLei YU return (hexId.substr(0, 8)); 99ad90ad51SLei YU } 100ad90ad51SLei YU 101*f77189f7SLei YU any Utils::getPropertyImpl(sdbusplus::bus::bus& bus, const char* service, 102*f77189f7SLei YU const char* path, const char* interface, 103*f77189f7SLei YU const char* propertyName) const 104*f77189f7SLei YU { 105*f77189f7SLei YU auto method = bus.new_method_call(service, path, 106*f77189f7SLei YU "org.freedesktop.DBus.Properties", "Get"); 107*f77189f7SLei YU method.append(interface, propertyName); 108*f77189f7SLei YU try 109*f77189f7SLei YU { 110*f77189f7SLei YU PropertyType value{}; 111*f77189f7SLei YU auto reply = bus.call(method); 112*f77189f7SLei YU reply.read(value); 113*f77189f7SLei YU return any(value); 114*f77189f7SLei YU } 115*f77189f7SLei YU catch (const sdbusplus::exception::SdBusError& ex) 116*f77189f7SLei YU { 117*f77189f7SLei YU log<level::ERR>("GetProperty call failed", entry("PATH=%s", path), 118*f77189f7SLei YU entry("INTERFACE=%s", interface), 119*f77189f7SLei YU entry("PROPERTY=%s", propertyName)); 120*f77189f7SLei YU throw std::runtime_error("GetProperty call failed"); 121*f77189f7SLei YU } 122*f77189f7SLei YU } 123*f77189f7SLei YU 1245e0dcb39SLei YU } // namespace utils 125