blob: 8756f7ef351f5042e8d1a5c0ef85d395a84db7b6 [file] [log] [blame]
Matt Spinler852db672019-03-06 13:46:14 -06001#pragma once
2
3#include "config.h"
4
Matt Spinler59521e82021-02-11 13:41:06 -06005#include "types.hpp"
6
7#include <nlohmann/json.hpp>
Matt Spinlerc47ca582019-03-06 14:37:42 -06008#include <xyz/openbmc_project/Association/Definitions/server.hpp>
Matt Spinler852db672019-03-06 13:46:14 -06009
Matt Spinler59521e82021-02-11 13:41:06 -060010#include <any>
11#include <filesystem>
12
Matt Spinler852db672019-03-06 13:46:14 -060013namespace phosphor
14{
15namespace inventory
16{
17namespace manager
18{
19namespace associations
20{
21
Matt Spinler99e66a02019-03-06 14:11:22 -060022static constexpr auto forwardTypePos = 0;
23static constexpr auto reverseTypePos = 1;
24using Types = std::tuple<std::string, std::string>;
25using Paths = std::vector<std::string>;
26
27static constexpr auto typesPos = 0;
28static constexpr auto pathsPos = 1;
29using EndpointsEntry = std::vector<std::tuple<Types, Paths>>;
30
31using AssociationMap = std::map<std::string, EndpointsEntry>;
32
Patrick Williams563306f2022-07-22 19:26:52 -050033using AssociationObject = sdbusplus::server::object_t<
Matt Spinlerc47ca582019-03-06 14:37:42 -060034 sdbusplus::xyz::openbmc_project::Association::server::Definitions>;
35
36using AssociationIfaceMap =
37 std::map<std::string, std::unique_ptr<AssociationObject>>;
38
Matt Spinler852db672019-03-06 13:46:14 -060039/**
40 * @class Manager
41 *
42 * @brief This class provides the ability to add org.openbmc.Associations
43 * interfaces on inventory D-Bus objects, based on a definition in a
44 * JSON file.
45 *
46 * The purpose for this is to be able to associate other D-Bus paths
47 * with the inventory items they relate to.
48 *
49 * For example, a card temperature sensor D-Bus object can be associated
50 * with the D-Bus object for that card's inventory entry so that some
51 * code can tie them together.
52 */
53class Manager
54{
55 public:
Matt Spinler59521e82021-02-11 13:41:06 -060056 struct Condition
57 {
58 std::string path;
59 std::string interface;
60 std::string property;
61 std::vector<InterfaceVariantType> values;
62 std::filesystem::path file;
63 InterfaceVariantType actualValue;
64 };
65
Matt Spinler852db672019-03-06 13:46:14 -060066 Manager() = delete;
67 ~Manager() = default;
68 Manager(const Manager&) = delete;
69 Manager& operator=(const Manager&) = delete;
70 Manager(Manager&&) = delete;
71 Manager& operator=(Manager&&) = delete;
72
73 /**
74 * @brief Constructor
75 *
76 * @param[in] bus - sdbusplus object
77 * @param[in] jsonPath - path to the JSON File that contains associations
78 */
Patrick Williams563306f2022-07-22 19:26:52 -050079 Manager(sdbusplus::bus_t& bus, const std::string& jsonPath);
Matt Spinler852db672019-03-06 13:46:14 -060080
81 /**
82 * @brief Constructor
83 *
84 * @param[in] bus - sdbusplus object
85 */
Patrick Williams563306f2022-07-22 19:26:52 -050086 explicit Manager(sdbusplus::bus_t& bus) :
Matt Spinler852db672019-03-06 13:46:14 -060087 Manager(bus, ASSOCIATIONS_FILE_PATH)
Brad Bishopa83db302020-12-06 14:51:23 -050088 {}
Matt Spinler852db672019-03-06 13:46:14 -060089
90 /**
91 * @brief Creates any association D-Bus interfaces required based on
92 * the JSON associations definition for the object path passed
93 * in.
94 *
95 * Called after PIM creates a new inventory D-Bus interface on objectPath.
96 *
97 * @param[in] objectPath - the D-Bus object path to check for associations
Brad Bishop104ccba2020-12-06 15:22:10 -050098 * @param[in] deferSignal - whether or not to send a Properties or
99 * ObjectManager signal
Matt Spinler852db672019-03-06 13:46:14 -0600100 */
Brad Bishop104ccba2020-12-06 15:22:10 -0500101 void createAssociations(const std::string& objectPath, bool deferSignal);
Matt Spinler852db672019-03-06 13:46:14 -0600102
Matt Spinler99e66a02019-03-06 14:11:22 -0600103 /**
104 * @brief Returned the association configuration.
105 * Used for testing.
106 *
107 * @return AssociationMap& - the association config
108 */
109 const AssociationMap& getAssociationsConfig()
110 {
111 return _associations;
112 }
113
Matt Spinler59521e82021-02-11 13:41:06 -0600114 /**
115 * @brief Returns the list of conditions
116 *
117 * @return vector<Condition>& - The conditions
118 */
119 std::vector<Condition>& getConditions()
120 {
121 return _conditions;
122 }
123
124 /**
125 * @brief Says if there are conditions that need to be met
126 * before an associations file is valid.
127 *
128 * @return bool - If there are pending conditions
129 */
130 bool pendingCondition() const
131 {
132 return !_conditions.empty();
133 }
134
135 /**
136 * @brief Checks if a pending condition is satisfied based on the
137 * path, interface, and property value of the object passed
138 * in.
139 *
140 * If it is valid, it will load the associations pointed to
141 * by that condition and erase the _conditions vector as
142 * there are no longer any pending conditions.
143 *
144 * @param[in] objectPath - The D-Bus path of the object to check
145 * @param[in] in object - The interface and properties of the object
146 *
147 * @return bool - If the object matched a condition
148 */
149 bool conditionMatch(const sdbusplus::message::object_path& objectPath,
150 const Object& object);
151
152 /**
153 * @brief Checks if a pending condition is satisfied based on if the
154 * actualValue field in the condition matches one of the values
155 * in the values field.
156 *
157 * The actualValue field was previously set by code based on the
158 * real property value of the specified interface on the specified
159 * path.
160 *
161 * If it is valid, it will load the associations pointed to
162 * by that condition and erase the _conditions vector as
163 * there are no longer any pending conditions.
164 *
165 * @return bool - If a condition was met
166 */
167 bool conditionMatch();
168
Matt Spinler852db672019-03-06 13:46:14 -0600169 private:
170 /**
Matt Spinler59521e82021-02-11 13:41:06 -0600171 * @brief Loads the association JSON into the _associations data
172 * structure.
173 *
174 * @param[in] json - The associations JSON
Matt Spinler99e66a02019-03-06 14:11:22 -0600175 */
Matt Spinler59521e82021-02-11 13:41:06 -0600176 void load(const nlohmann::json& json);
Matt Spinler99e66a02019-03-06 14:11:22 -0600177
178 /**
Matt Spinlerc47ca582019-03-06 14:37:42 -0600179 * @brief Creates an instance of an org.openbmc.Associations
180 * interface using the passed in properties.
181 *
182 * @param[in] forwardPath - the path of the forward association
183 * @param[in] forwardType - the type of the forward association
184 * @param[in] reversePath - the path of the reverse association
185 * @param[in] reverseType - the type of the reverse association
Brad Bishop104ccba2020-12-06 15:22:10 -0500186 * @param[in] deferSignal - whether or not to send a Properties or
187 * ObjectManager signal
Matt Spinlerc47ca582019-03-06 14:37:42 -0600188 */
189 void createAssociation(const std::string& forwardPath,
190 const std::string& forwardType,
191 const std::string& reversePath,
Brad Bishop104ccba2020-12-06 15:22:10 -0500192 const std::string& reverseType, bool deferSignal);
Matt Spinlerc47ca582019-03-06 14:37:42 -0600193
194 /**
Matt Spinler59521e82021-02-11 13:41:06 -0600195 * @brief Looks for all JSON files in the associations directory that
196 * contain a valid association condition, and loads the
197 * conditions into the _conditions vector.
198 */
199 bool loadConditions();
200
201 /**
Matt Spinler99e66a02019-03-06 14:11:22 -0600202 * @brief The map of association data that is loaded from its
203 * JSON definition. Association D-Bus objects will be
204 * created from this data.
205 */
206 AssociationMap _associations;
207
208 /**
Matt Spinlerc47ca582019-03-06 14:37:42 -0600209 * @brief The map of org.openbmc_project.Associations D-Bus
210 * interfaces objects based on their object path.
211 */
212 AssociationIfaceMap _associationIfaces;
213
214 /**
Matt Spinler852db672019-03-06 13:46:14 -0600215 * @brief The sdbusplus bus object.
216 */
Patrick Williams563306f2022-07-22 19:26:52 -0500217 sdbusplus::bus_t& _bus;
Matt Spinler852db672019-03-06 13:46:14 -0600218
219 /**
220 * @brief The path to the associations JSON File.
221 */
Matt Spinler59521e82021-02-11 13:41:06 -0600222 const std::filesystem::path _jsonFile;
Matt Spinlerc47ca582019-03-06 14:37:42 -0600223
224 /**
225 * A list of the inventory association paths that have already been handled.
226 */
227 std::vector<std::string> _handled;
Matt Spinler59521e82021-02-11 13:41:06 -0600228
229 /**
230 * @brief Conditions that specify when an associations file is valid.
231 */
232 std::vector<Condition> _conditions;
Matt Spinler852db672019-03-06 13:46:14 -0600233};
234
235} // namespace associations
236} // namespace manager
237} // namespace inventory
238} // namespace phosphor