1 #include "platform_config.hpp" 2 3 namespace pldm 4 { 5 namespace responder 6 { 7 8 namespace platform_config 9 { 10 /** @brief callback function invoked when interfaces get added from 11 * Entity manager 12 * 13 * @param[in] msg - Data associated with subscribed signal 14 */ 15 void Handler::systemCompatibleCallback(sdbusplus::message_t& msg) 16 { 17 sdbusplus::message::object_path path; 18 19 pldm::utils::InterfaceMap interfaceMap; 20 21 msg.read(path, interfaceMap); 22 23 if (!interfaceMap.contains(compatibleInterface)) 24 { 25 return; 26 } 27 // Get the "Name" property value of the 28 // "xyz.openbmc_project.Inventory.Decorator.Compatible" interface 29 const auto& properties = interfaceMap.at(compatibleInterface); 30 31 if (!properties.contains(namesProperty)) 32 { 33 return; 34 } 35 auto names = 36 std::get<pldm::utils::Interfaces>(properties.at(namesProperty)); 37 38 std::string systemType; 39 if (!names.empty()) 40 { 41 // get only the first system type 42 systemType = names.front(); 43 } 44 45 if (!systemType.empty()) 46 { 47 systemCompatibleMatchCallBack.reset(); 48 } 49 } 50 51 /** @brief Method to get the system type information 52 * 53 * @return - the system type information 54 */ 55 std::optional<std::filesystem::path> Handler::getPlatformName() 56 { 57 if (!systemType.empty()) 58 { 59 return fs::path{systemType}; 60 } 61 62 namespace fs = std::filesystem; 63 static const std::string entityMangerService = 64 "xyz.openbmc_project.EntityManager"; 65 66 static constexpr auto searchpath = "/xyz/openbmc_project/"; 67 int depth = 0; 68 std::vector<std::string> systemCompatible = {compatibleInterface}; 69 70 try 71 { 72 pldm::utils::GetSubTreeResponse response = 73 pldm::utils::DBusHandler().getSubtree(searchpath, depth, 74 systemCompatible); 75 auto& bus = pldm::utils::DBusHandler::getBus(); 76 77 for (const auto& [objectPath, serviceMap] : response) 78 { 79 try 80 { 81 auto record = std::find_if( 82 serviceMap.begin(), serviceMap.end(), 83 [](auto map) { return map.first == entityMangerService; }); 84 85 if (record != serviceMap.end()) 86 { 87 auto method = bus.new_method_call( 88 entityMangerService.c_str(), objectPath.c_str(), 89 "org.freedesktop.DBus.Properties", "Get"); 90 method.append(compatibleInterface, namesProperty); 91 auto propSystemList = 92 bus.call(method, dbusTimeout).unpack<PropertyValue>(); 93 auto systemList = 94 std::get<std::vector<std::string>>(propSystemList); 95 96 if (!systemList.empty()) 97 { 98 systemType = systemList.at(0); 99 // once systemtype received,then resetting a callback 100 systemCompatibleMatchCallBack.reset(); 101 return fs::path{systemType}; 102 } 103 } 104 } 105 catch (const std::exception& e) 106 { 107 error( 108 "Error getting Names property at '{PATH}' on '{INTERFACE}': {ERROR}", 109 "PATH", objectPath, "INTERFACE", compatibleInterface, 110 "ERROR", e); 111 } 112 } 113 } 114 catch (const std::exception& e) 115 { 116 error("Failed to make a d-bus call to get platform name {ERROR}", 117 "ERROR", e); 118 } 119 return std::nullopt; 120 } 121 122 } // namespace platform_config 123 124 } // namespace responder 125 126 } // namespace pldm 127