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