xref: /openbmc/pldm/libpldmresponder/platform_config.cpp (revision 16c2a0a03e5daac77e204eb99e00711490fb6e26)
13c50c82aSKamalkumar Patel #include "platform_config.hpp"
23c50c82aSKamalkumar Patel 
389644441SRiya Dixit #include <phosphor-logging/lg2.hpp>
489644441SRiya Dixit 
589644441SRiya Dixit PHOSPHOR_LOG2_USING;
689644441SRiya Dixit 
73c50c82aSKamalkumar Patel namespace pldm
83c50c82aSKamalkumar Patel {
93c50c82aSKamalkumar Patel namespace responder
103c50c82aSKamalkumar Patel {
113c50c82aSKamalkumar Patel 
123c50c82aSKamalkumar Patel namespace platform_config
133c50c82aSKamalkumar Patel {
143c50c82aSKamalkumar Patel /** @brief callback function invoked when interfaces get added from
153c50c82aSKamalkumar Patel  *      Entity manager
163c50c82aSKamalkumar Patel  *
173c50c82aSKamalkumar Patel  *  @param[in] msg - Data associated with subscribed signal
183c50c82aSKamalkumar Patel  */
systemCompatibleCallback(sdbusplus::message_t & msg)193c50c82aSKamalkumar Patel void Handler::systemCompatibleCallback(sdbusplus::message_t& msg)
203c50c82aSKamalkumar Patel {
213c50c82aSKamalkumar Patel     sdbusplus::message::object_path path;
223c50c82aSKamalkumar Patel 
233c50c82aSKamalkumar Patel     pldm::utils::InterfaceMap interfaceMap;
243c50c82aSKamalkumar Patel 
253c50c82aSKamalkumar Patel     msg.read(path, interfaceMap);
263c50c82aSKamalkumar Patel 
273c50c82aSKamalkumar Patel     if (!interfaceMap.contains(compatibleInterface))
283c50c82aSKamalkumar Patel     {
293c50c82aSKamalkumar Patel         return;
303c50c82aSKamalkumar Patel     }
313c50c82aSKamalkumar Patel     // Get the "Name" property value of the
323c50c82aSKamalkumar Patel     // "xyz.openbmc_project.Inventory.Decorator.Compatible" interface
333c50c82aSKamalkumar Patel     const auto& properties = interfaceMap.at(compatibleInterface);
343c50c82aSKamalkumar Patel 
353c50c82aSKamalkumar Patel     if (!properties.contains(namesProperty))
363c50c82aSKamalkumar Patel     {
373c50c82aSKamalkumar Patel         return;
383c50c82aSKamalkumar Patel     }
393c50c82aSKamalkumar Patel     auto names =
403c50c82aSKamalkumar Patel         std::get<pldm::utils::Interfaces>(properties.at(namesProperty));
413c50c82aSKamalkumar Patel 
423c50c82aSKamalkumar Patel     if (!names.empty())
433c50c82aSKamalkumar Patel     {
44*16c2a0a0SPatrick Williams         std::optional<std::string> sysType =
45*16c2a0a0SPatrick Williams             getSysSpecificJsonDir(sysDirPath, names);
460a422696SKamalkumar Patel         if (sysType.has_value())
470a422696SKamalkumar Patel         {
480a422696SKamalkumar Patel             systemType = sysType.value();
490a422696SKamalkumar Patel         }
5062dd8ff2SArchana Kakani         if (sysTypeCallback)
5162dd8ff2SArchana Kakani         {
5246f352edSArchana Kakani             sysTypeCallback(systemType, true);
5362dd8ff2SArchana Kakani         }
543c50c82aSKamalkumar Patel     }
553c50c82aSKamalkumar Patel 
563c50c82aSKamalkumar Patel     if (!systemType.empty())
573c50c82aSKamalkumar Patel     {
583c50c82aSKamalkumar Patel         systemCompatibleMatchCallBack.reset();
593c50c82aSKamalkumar Patel     }
603c50c82aSKamalkumar Patel }
613c50c82aSKamalkumar Patel 
623c50c82aSKamalkumar Patel /** @brief Method to get the system type information
633c50c82aSKamalkumar Patel  *
643c50c82aSKamalkumar Patel  *  @return - the system type information
653c50c82aSKamalkumar Patel  */
getPlatformName()663c50c82aSKamalkumar Patel std::optional<std::filesystem::path> Handler::getPlatformName()
673c50c82aSKamalkumar Patel {
683c50c82aSKamalkumar Patel     if (!systemType.empty())
693c50c82aSKamalkumar Patel     {
703c50c82aSKamalkumar Patel         return fs::path{systemType};
713c50c82aSKamalkumar Patel     }
723c50c82aSKamalkumar Patel 
733c50c82aSKamalkumar Patel     namespace fs = std::filesystem;
742edc34bbSKamalkumar Patel     static const std::string entityMangerService =
752edc34bbSKamalkumar Patel         "xyz.openbmc_project.EntityManager";
763c50c82aSKamalkumar Patel 
773c50c82aSKamalkumar Patel     static constexpr auto searchpath = "/xyz/openbmc_project/";
783c50c82aSKamalkumar Patel     int depth = 0;
793c50c82aSKamalkumar Patel     std::vector<std::string> systemCompatible = {compatibleInterface};
802edc34bbSKamalkumar Patel 
812edc34bbSKamalkumar Patel     try
822edc34bbSKamalkumar Patel     {
833c50c82aSKamalkumar Patel         pldm::utils::GetSubTreeResponse response =
843c50c82aSKamalkumar Patel             pldm::utils::DBusHandler().getSubtree(searchpath, depth,
853c50c82aSKamalkumar Patel                                                   systemCompatible);
863c50c82aSKamalkumar Patel         auto& bus = pldm::utils::DBusHandler::getBus();
873c50c82aSKamalkumar Patel 
883c50c82aSKamalkumar Patel         for (const auto& [objectPath, serviceMap] : response)
893c50c82aSKamalkumar Patel         {
903c50c82aSKamalkumar Patel             try
913c50c82aSKamalkumar Patel             {
922edc34bbSKamalkumar Patel                 auto record = std::find_if(
932edc34bbSKamalkumar Patel                     serviceMap.begin(), serviceMap.end(),
942edc34bbSKamalkumar Patel                     [](auto map) { return map.first == entityMangerService; });
952edc34bbSKamalkumar Patel 
962edc34bbSKamalkumar Patel                 if (record != serviceMap.end())
972edc34bbSKamalkumar Patel                 {
983c50c82aSKamalkumar Patel                     auto method = bus.new_method_call(
992edc34bbSKamalkumar Patel                         entityMangerService.c_str(), objectPath.c_str(),
1002edc34bbSKamalkumar Patel                         "org.freedesktop.DBus.Properties", "Get");
1012edc34bbSKamalkumar Patel                     method.append(compatibleInterface, namesProperty);
1022edc34bbSKamalkumar Patel                     auto propSystemList =
1032edc34bbSKamalkumar Patel                         bus.call(method, dbusTimeout).unpack<PropertyValue>();
1042edc34bbSKamalkumar Patel                     auto systemList =
1052edc34bbSKamalkumar Patel                         std::get<std::vector<std::string>>(propSystemList);
1062edc34bbSKamalkumar Patel 
1073c50c82aSKamalkumar Patel                     if (!systemList.empty())
1083c50c82aSKamalkumar Patel                     {
1090a422696SKamalkumar Patel                         std::optional<std::string> sysType =
1100a422696SKamalkumar Patel                             getSysSpecificJsonDir(sysDirPath, systemList);
1112edc34bbSKamalkumar Patel                         // once systemtype received,then resetting a callback
1122edc34bbSKamalkumar Patel                         systemCompatibleMatchCallBack.reset();
1130a422696SKamalkumar Patel                         if (sysType.has_value())
1140a422696SKamalkumar Patel                         {
1150a422696SKamalkumar Patel                             systemType = sysType.value();
1160a422696SKamalkumar Patel                         }
1173c50c82aSKamalkumar Patel                         return fs::path{systemType};
1183c50c82aSKamalkumar Patel                     }
1193c50c82aSKamalkumar Patel                 }
1202edc34bbSKamalkumar Patel             }
1213c50c82aSKamalkumar Patel             catch (const std::exception& e)
1223c50c82aSKamalkumar Patel             {
1233c50c82aSKamalkumar Patel                 error(
12489644441SRiya Dixit                     "Failed to get Names property at '{PATH}' on interface '{INTERFACE}', error - {ERROR}",
1252edc34bbSKamalkumar Patel                     "PATH", objectPath, "INTERFACE", compatibleInterface,
1262edc34bbSKamalkumar Patel                     "ERROR", e);
1273c50c82aSKamalkumar Patel             }
1283c50c82aSKamalkumar Patel         }
1292edc34bbSKamalkumar Patel     }
1302edc34bbSKamalkumar Patel     catch (const std::exception& e)
1312edc34bbSKamalkumar Patel     {
13289644441SRiya Dixit         error(
13389644441SRiya Dixit             "Failed to make a d-bus call to get platform name, error - {ERROR}",
1342edc34bbSKamalkumar Patel             "ERROR", e);
1352edc34bbSKamalkumar Patel     }
1363c50c82aSKamalkumar Patel     return std::nullopt;
1373c50c82aSKamalkumar Patel }
1383c50c82aSKamalkumar Patel 
getSysSpecificJsonDir(const fs::path & dirPath,const std::vector<std::string> & dirNames)139*16c2a0a0SPatrick Williams std::optional<std::string> Handler::getSysSpecificJsonDir(
140*16c2a0a0SPatrick Williams     const fs::path& dirPath, const std::vector<std::string>& dirNames)
1410a422696SKamalkumar Patel {
1420a422696SKamalkumar Patel     // The current setup assumes that the BIOS and PDR configurations always
1430a422696SKamalkumar Patel     // come from the same system type. If, in the future, we need to use BIOS
1440a422696SKamalkumar Patel     // and PDR configurations from different system types, we should create
1450a422696SKamalkumar Patel     // separate system type folders for each and update the logic to support
1460a422696SKamalkumar Patel     // this.
1470a422696SKamalkumar Patel 
1480a422696SKamalkumar Patel     if (dirPath.empty())
1490a422696SKamalkumar Patel     {
1500a422696SKamalkumar Patel         return std::nullopt;
1510a422696SKamalkumar Patel     }
1520a422696SKamalkumar Patel 
1530a422696SKamalkumar Patel     for (const auto& dirEntry : std::filesystem::directory_iterator{dirPath})
1540a422696SKamalkumar Patel     {
1550a422696SKamalkumar Patel         if (dirEntry.is_directory())
1560a422696SKamalkumar Patel         {
1570a422696SKamalkumar Patel             const auto sysDir = dirEntry.path().filename().string();
1580a422696SKamalkumar Patel             if (std::find(dirNames.begin(), dirNames.end(), sysDir) !=
1590a422696SKamalkumar Patel                 dirNames.end())
1600a422696SKamalkumar Patel             {
1610a422696SKamalkumar Patel                 return sysDir;
1620a422696SKamalkumar Patel             }
1630a422696SKamalkumar Patel         }
1640a422696SKamalkumar Patel     }
1650a422696SKamalkumar Patel 
1660a422696SKamalkumar Patel     return std::nullopt;
1670a422696SKamalkumar Patel }
1680a422696SKamalkumar Patel 
registerSystemTypeCallback(SystemTypeCallback callback)16962dd8ff2SArchana Kakani void Handler::registerSystemTypeCallback(SystemTypeCallback callback)
17062dd8ff2SArchana Kakani {
17162dd8ff2SArchana Kakani     sysTypeCallback = callback;
17262dd8ff2SArchana Kakani }
17362dd8ff2SArchana Kakani 
1743c50c82aSKamalkumar Patel } // namespace platform_config
1753c50c82aSKamalkumar Patel 
1763c50c82aSKamalkumar Patel } // namespace responder
1773c50c82aSKamalkumar Patel 
1783c50c82aSKamalkumar Patel } // namespace pldm
179