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 if (sysTypeCallback) 44 { 45 sysTypeCallback(systemType, true); 46 } 47 } 48 49 if (!systemType.empty()) 50 { 51 systemCompatibleMatchCallBack.reset(); 52 } 53 } 54 55 /** @brief Method to get the system type information 56 * 57 * @return - the system type information 58 */ 59 std::optional<std::filesystem::path> Handler::getPlatformName() 60 { 61 if (!systemType.empty()) 62 { 63 return fs::path{systemType}; 64 } 65 66 namespace fs = std::filesystem; 67 static const std::string entityMangerService = 68 "xyz.openbmc_project.EntityManager"; 69 70 static constexpr auto searchpath = "/xyz/openbmc_project/"; 71 int depth = 0; 72 std::vector<std::string> systemCompatible = {compatibleInterface}; 73 74 try 75 { 76 pldm::utils::GetSubTreeResponse response = 77 pldm::utils::DBusHandler().getSubtree(searchpath, depth, 78 systemCompatible); 79 auto& bus = pldm::utils::DBusHandler::getBus(); 80 81 for (const auto& [objectPath, serviceMap] : response) 82 { 83 try 84 { 85 auto record = std::find_if( 86 serviceMap.begin(), serviceMap.end(), 87 [](auto map) { return map.first == entityMangerService; }); 88 89 if (record != serviceMap.end()) 90 { 91 auto method = bus.new_method_call( 92 entityMangerService.c_str(), objectPath.c_str(), 93 "org.freedesktop.DBus.Properties", "Get"); 94 method.append(compatibleInterface, namesProperty); 95 auto propSystemList = 96 bus.call(method, dbusTimeout).unpack<PropertyValue>(); 97 auto systemList = 98 std::get<std::vector<std::string>>(propSystemList); 99 100 if (!systemList.empty()) 101 { 102 systemType = systemList.at(0); 103 // once systemtype received,then resetting a callback 104 systemCompatibleMatchCallBack.reset(); 105 return fs::path{systemType}; 106 } 107 } 108 } 109 catch (const std::exception& e) 110 { 111 error( 112 "Error getting Names property at '{PATH}' on '{INTERFACE}': {ERROR}", 113 "PATH", objectPath, "INTERFACE", compatibleInterface, 114 "ERROR", e); 115 } 116 } 117 } 118 catch (const std::exception& e) 119 { 120 error("Failed to make a d-bus call to get platform name {ERROR}", 121 "ERROR", e); 122 } 123 return std::nullopt; 124 } 125 126 void Handler::registerSystemTypeCallback(SystemTypeCallback callback) 127 { 128 sysTypeCallback = callback; 129 } 130 131 } // namespace platform_config 132 133 } // namespace responder 134 135 } // namespace pldm 136