1852db67bSMatt Spinler #pragma once 2852db67bSMatt Spinler 3852db67bSMatt Spinler #include "config.h" 4852db67bSMatt Spinler 559521e87SMatt Spinler #include "types.hpp" 659521e87SMatt Spinler 759521e87SMatt Spinler #include <nlohmann/json.hpp> 8c47ca585SMatt Spinler #include <xyz/openbmc_project/Association/Definitions/server.hpp> 9852db67bSMatt Spinler 1059521e87SMatt Spinler #include <any> 1159521e87SMatt Spinler #include <filesystem> 1259521e87SMatt Spinler 13852db67bSMatt Spinler namespace phosphor 14852db67bSMatt Spinler { 15852db67bSMatt Spinler namespace inventory 16852db67bSMatt Spinler { 17852db67bSMatt Spinler namespace manager 18852db67bSMatt Spinler { 19852db67bSMatt Spinler namespace associations 20852db67bSMatt Spinler { 21852db67bSMatt Spinler 2299e66a03SMatt Spinler static constexpr auto forwardTypePos = 0; 2399e66a03SMatt Spinler static constexpr auto reverseTypePos = 1; 2499e66a03SMatt Spinler using Types = std::tuple<std::string, std::string>; 2599e66a03SMatt Spinler using Paths = std::vector<std::string>; 2699e66a03SMatt Spinler 2799e66a03SMatt Spinler static constexpr auto typesPos = 0; 2899e66a03SMatt Spinler static constexpr auto pathsPos = 1; 2999e66a03SMatt Spinler using EndpointsEntry = std::vector<std::tuple<Types, Paths>>; 3099e66a03SMatt Spinler 3199e66a03SMatt Spinler using AssociationMap = std::map<std::string, EndpointsEntry>; 3299e66a03SMatt Spinler 33*563306f6SPatrick Williams using AssociationObject = sdbusplus::server::object_t< 34c47ca585SMatt Spinler sdbusplus::xyz::openbmc_project::Association::server::Definitions>; 35c47ca585SMatt Spinler 36c47ca585SMatt Spinler using AssociationIfaceMap = 37c47ca585SMatt Spinler std::map<std::string, std::unique_ptr<AssociationObject>>; 38c47ca585SMatt Spinler 39852db67bSMatt Spinler /** 40852db67bSMatt Spinler * @class Manager 41852db67bSMatt Spinler * 42852db67bSMatt Spinler * @brief This class provides the ability to add org.openbmc.Associations 43852db67bSMatt Spinler * interfaces on inventory D-Bus objects, based on a definition in a 44852db67bSMatt Spinler * JSON file. 45852db67bSMatt Spinler * 46852db67bSMatt Spinler * The purpose for this is to be able to associate other D-Bus paths 47852db67bSMatt Spinler * with the inventory items they relate to. 48852db67bSMatt Spinler * 49852db67bSMatt Spinler * For example, a card temperature sensor D-Bus object can be associated 50852db67bSMatt Spinler * with the D-Bus object for that card's inventory entry so that some 51852db67bSMatt Spinler * code can tie them together. 52852db67bSMatt Spinler */ 53852db67bSMatt Spinler class Manager 54852db67bSMatt Spinler { 55852db67bSMatt Spinler public: 5659521e87SMatt Spinler struct Condition 5759521e87SMatt Spinler { 5859521e87SMatt Spinler std::string path; 5959521e87SMatt Spinler std::string interface; 6059521e87SMatt Spinler std::string property; 6159521e87SMatt Spinler std::vector<InterfaceVariantType> values; 6259521e87SMatt Spinler std::filesystem::path file; 6359521e87SMatt Spinler InterfaceVariantType actualValue; 6459521e87SMatt Spinler }; 6559521e87SMatt Spinler 66852db67bSMatt Spinler Manager() = delete; 67852db67bSMatt Spinler ~Manager() = default; 68852db67bSMatt Spinler Manager(const Manager&) = delete; 69852db67bSMatt Spinler Manager& operator=(const Manager&) = delete; 70852db67bSMatt Spinler Manager(Manager&&) = delete; 71852db67bSMatt Spinler Manager& operator=(Manager&&) = delete; 72852db67bSMatt Spinler 73852db67bSMatt Spinler /** 74852db67bSMatt Spinler * @brief Constructor 75852db67bSMatt Spinler * 76852db67bSMatt Spinler * @param[in] bus - sdbusplus object 77852db67bSMatt Spinler * @param[in] jsonPath - path to the JSON File that contains associations 78852db67bSMatt Spinler */ 79*563306f6SPatrick Williams Manager(sdbusplus::bus_t& bus, const std::string& jsonPath); 80852db67bSMatt Spinler 81852db67bSMatt Spinler /** 82852db67bSMatt Spinler * @brief Constructor 83852db67bSMatt Spinler * 84852db67bSMatt Spinler * @param[in] bus - sdbusplus object 85852db67bSMatt Spinler */ Manager(sdbusplus::bus_t & bus)86*563306f6SPatrick Williams explicit Manager(sdbusplus::bus_t& bus) : 87852db67bSMatt Spinler Manager(bus, ASSOCIATIONS_FILE_PATH) 88a83db30eSBrad Bishop {} 89852db67bSMatt Spinler 90852db67bSMatt Spinler /** 91852db67bSMatt Spinler * @brief Creates any association D-Bus interfaces required based on 92852db67bSMatt Spinler * the JSON associations definition for the object path passed 93852db67bSMatt Spinler * in. 94852db67bSMatt Spinler * 95852db67bSMatt Spinler * Called after PIM creates a new inventory D-Bus interface on objectPath. 96852db67bSMatt Spinler * 97852db67bSMatt Spinler * @param[in] objectPath - the D-Bus object path to check for associations 98104ccba9SBrad Bishop * @param[in] deferSignal - whether or not to send a Properties or 99104ccba9SBrad Bishop * ObjectManager signal 100852db67bSMatt Spinler */ 101104ccba9SBrad Bishop void createAssociations(const std::string& objectPath, bool deferSignal); 102852db67bSMatt Spinler 10399e66a03SMatt Spinler /** 10499e66a03SMatt Spinler * @brief Returned the association configuration. 10599e66a03SMatt Spinler * Used for testing. 10699e66a03SMatt Spinler * 10799e66a03SMatt Spinler * @return AssociationMap& - the association config 10899e66a03SMatt Spinler */ getAssociationsConfig()10999e66a03SMatt Spinler const AssociationMap& getAssociationsConfig() 11099e66a03SMatt Spinler { 11199e66a03SMatt Spinler return _associations; 11299e66a03SMatt Spinler } 11399e66a03SMatt Spinler 11459521e87SMatt Spinler /** 11559521e87SMatt Spinler * @brief Returns the list of conditions 11659521e87SMatt Spinler * 11759521e87SMatt Spinler * @return vector<Condition>& - The conditions 11859521e87SMatt Spinler */ getConditions()11959521e87SMatt Spinler std::vector<Condition>& getConditions() 12059521e87SMatt Spinler { 12159521e87SMatt Spinler return _conditions; 12259521e87SMatt Spinler } 12359521e87SMatt Spinler 12459521e87SMatt Spinler /** 12559521e87SMatt Spinler * @brief Says if there are conditions that need to be met 12659521e87SMatt Spinler * before an associations file is valid. 12759521e87SMatt Spinler * 12859521e87SMatt Spinler * @return bool - If there are pending conditions 12959521e87SMatt Spinler */ pendingCondition() const13059521e87SMatt Spinler bool pendingCondition() const 13159521e87SMatt Spinler { 13259521e87SMatt Spinler return !_conditions.empty(); 13359521e87SMatt Spinler } 13459521e87SMatt Spinler 13559521e87SMatt Spinler /** 13659521e87SMatt Spinler * @brief Checks if a pending condition is satisfied based on the 13759521e87SMatt Spinler * path, interface, and property value of the object passed 13859521e87SMatt Spinler * in. 13959521e87SMatt Spinler * 14059521e87SMatt Spinler * If it is valid, it will load the associations pointed to 14159521e87SMatt Spinler * by that condition and erase the _conditions vector as 14259521e87SMatt Spinler * there are no longer any pending conditions. 14359521e87SMatt Spinler * 14459521e87SMatt Spinler * @param[in] objectPath - The D-Bus path of the object to check 14559521e87SMatt Spinler * @param[in] in object - The interface and properties of the object 14659521e87SMatt Spinler * 14759521e87SMatt Spinler * @return bool - If the object matched a condition 14859521e87SMatt Spinler */ 14959521e87SMatt Spinler bool conditionMatch(const sdbusplus::message::object_path& objectPath, 15059521e87SMatt Spinler const Object& object); 15159521e87SMatt Spinler 15259521e87SMatt Spinler /** 15359521e87SMatt Spinler * @brief Checks if a pending condition is satisfied based on if the 15459521e87SMatt Spinler * actualValue field in the condition matches one of the values 15559521e87SMatt Spinler * in the values field. 15659521e87SMatt Spinler * 15759521e87SMatt Spinler * The actualValue field was previously set by code based on the 15859521e87SMatt Spinler * real property value of the specified interface on the specified 15959521e87SMatt Spinler * path. 16059521e87SMatt Spinler * 16159521e87SMatt Spinler * If it is valid, it will load the associations pointed to 16259521e87SMatt Spinler * by that condition and erase the _conditions vector as 16359521e87SMatt Spinler * there are no longer any pending conditions. 16459521e87SMatt Spinler * 16559521e87SMatt Spinler * @return bool - If a condition was met 16659521e87SMatt Spinler */ 16759521e87SMatt Spinler bool conditionMatch(); 16859521e87SMatt Spinler 169852db67bSMatt Spinler private: 170852db67bSMatt Spinler /** 17159521e87SMatt Spinler * @brief Loads the association JSON into the _associations data 17259521e87SMatt Spinler * structure. 17359521e87SMatt Spinler * 17459521e87SMatt Spinler * @param[in] json - The associations JSON 17599e66a03SMatt Spinler */ 17659521e87SMatt Spinler void load(const nlohmann::json& json); 17799e66a03SMatt Spinler 17899e66a03SMatt Spinler /** 179c47ca585SMatt Spinler * @brief Creates an instance of an org.openbmc.Associations 180c47ca585SMatt Spinler * interface using the passed in properties. 181c47ca585SMatt Spinler * 182c47ca585SMatt Spinler * @param[in] forwardPath - the path of the forward association 183c47ca585SMatt Spinler * @param[in] forwardType - the type of the forward association 184c47ca585SMatt Spinler * @param[in] reversePath - the path of the reverse association 185c47ca585SMatt Spinler * @param[in] reverseType - the type of the reverse association 186104ccba9SBrad Bishop * @param[in] deferSignal - whether or not to send a Properties or 187104ccba9SBrad Bishop * ObjectManager signal 188c47ca585SMatt Spinler */ 189c47ca585SMatt Spinler void createAssociation(const std::string& forwardPath, 190c47ca585SMatt Spinler const std::string& forwardType, 191c47ca585SMatt Spinler const std::string& reversePath, 192104ccba9SBrad Bishop const std::string& reverseType, bool deferSignal); 193c47ca585SMatt Spinler 194c47ca585SMatt Spinler /** 19559521e87SMatt Spinler * @brief Looks for all JSON files in the associations directory that 19659521e87SMatt Spinler * contain a valid association condition, and loads the 19759521e87SMatt Spinler * conditions into the _conditions vector. 19859521e87SMatt Spinler */ 19959521e87SMatt Spinler bool loadConditions(); 20059521e87SMatt Spinler 20159521e87SMatt Spinler /** 20299e66a03SMatt Spinler * @brief The map of association data that is loaded from its 20399e66a03SMatt Spinler * JSON definition. Association D-Bus objects will be 20499e66a03SMatt Spinler * created from this data. 20599e66a03SMatt Spinler */ 20699e66a03SMatt Spinler AssociationMap _associations; 20799e66a03SMatt Spinler 20899e66a03SMatt Spinler /** 209c47ca585SMatt Spinler * @brief The map of org.openbmc_project.Associations D-Bus 210c47ca585SMatt Spinler * interfaces objects based on their object path. 211c47ca585SMatt Spinler */ 212c47ca585SMatt Spinler AssociationIfaceMap _associationIfaces; 213c47ca585SMatt Spinler 214c47ca585SMatt Spinler /** 215852db67bSMatt Spinler * @brief The sdbusplus bus object. 216852db67bSMatt Spinler */ 217*563306f6SPatrick Williams sdbusplus::bus_t& _bus; 218852db67bSMatt Spinler 219852db67bSMatt Spinler /** 220852db67bSMatt Spinler * @brief The path to the associations JSON File. 221852db67bSMatt Spinler */ 22259521e87SMatt Spinler const std::filesystem::path _jsonFile; 223c47ca585SMatt Spinler 224c47ca585SMatt Spinler /** 225c47ca585SMatt Spinler * A list of the inventory association paths that have already been handled. 226c47ca585SMatt Spinler */ 227c47ca585SMatt Spinler std::vector<std::string> _handled; 22859521e87SMatt Spinler 22959521e87SMatt Spinler /** 23059521e87SMatt Spinler * @brief Conditions that specify when an associations file is valid. 23159521e87SMatt Spinler */ 23259521e87SMatt Spinler std::vector<Condition> _conditions; 233852db67bSMatt Spinler }; 234852db67bSMatt Spinler 235852db67bSMatt Spinler } // namespace associations 236852db67bSMatt Spinler } // namespace manager 237852db67bSMatt Spinler } // namespace inventory 238852db67bSMatt Spinler } // namespace phosphor 239