1 #pragma once
2 
3 #include <boost/container/flat_map.hpp>
4 #include <boost/container/flat_set.hpp>
5 #include <memory>
6 #include <sdbusplus/asio/object_server.hpp>
7 #include <string>
8 #include <tuple>
9 #include <vector>
10 
11 constexpr const char* XYZ_ASSOCIATION_INTERFACE =
12     "xyz.openbmc_project.Association";
13 
14 //  Associations and some metadata are stored in associationInterfaces.
15 //  The fields are:
16 //   * ifacePos - holds the D-Bus interface object
17 //   * endpointsPos - holds the endpoints array that shadows the property
18 static constexpr auto ifacePos = 0;
19 static constexpr auto endpointsPos = 1;
20 using Endpoints = std::vector<std::string>;
21 
22 // map[interface path: tuple[dbus_interface,vector[endpoint paths]]]
23 using AssociationInterfaces = boost::container::flat_map<
24     std::string,
25     std::tuple<std::shared_ptr<sdbusplus::asio::dbus_interface>, Endpoints>>;
26 
27 // The associationOwners map contains information about creators of
28 // associations, so that when a org.openbmc.Association interface is
29 // removed or its 'associations' property is changed, the mapper owned
30 // association objects can be correctly handled.  It is a map of the
31 // object path of the org.openbmc.Association owner to a map of the
32 // service the path is owned by, to a map of the association objects to
33 // their endpoint paths:
34 // map[ownerPath : map[service : map[assocPath : [endpoint paths]]]
35 // For example:
36 // [/logging/entry/1 :
37 //   [xyz.openbmc_project.Logging :
38 //     [/logging/entry/1/callout : [/system/cpu0],
39 //      /system/cpu0/fault : [/logging/entry/1]]]]
40 
41 using AssociationPaths =
42     boost::container::flat_map<std::string,
43                                boost::container::flat_set<std::string>>;
44 
45 using AssociationOwnersType = boost::container::flat_map<
46     std::string, boost::container::flat_map<std::string, AssociationPaths>>;
47 
48 // Store the contents of the associations property on the interface
49 // For example:
50 // ["inventory", "activation", "/xyz/openbmc_project/inventory/system/chassis"]
51 using Association = std::tuple<std::string, std::string, std::string>;
52 
53 /** @brief Remove input association
54  *
55  * @param[in] sourcePath          - Path of the object that contains the
56  *                                  org.openbmc.Associations
57  * @param[in] owner               - The Dbus service having its associations
58  *                                  removed
59  * @param[in,out] server          - sdbus system object
60  * @param[in,out] assocOwners     - Owners of associations
61  * @param[in,out] assocInterfaces - Associations endpoints
62  *
63  * @return Void, server, assocOwners, and assocInterfaces updated if needed
64  */
65 void removeAssociation(const std::string& sourcePath, const std::string& owner,
66                        sdbusplus::asio::object_server& server,
67                        AssociationOwnersType& assocOwners,
68                        AssociationInterfaces& assocInterfaces);
69 
70 /** @brief Remove input paths from endpoints of an association
71  *
72  * If the last endpoint was removed, then remove the whole
73  * association object, otherwise just set the property
74  *
75  * @param[in] objectServer        - sdbus system object
76  * @param[in] assocPath           - Path of the object that contains the
77  *                                  org.openbmc.Associations
78  * @param[in] endpointsToRemove   - Endpoints to remove
79  * @param[in,out] assocInterfaces - Associations endpoints
80  *
81  * @return Void, objectServer and assocInterfaces updated if needed
82  */
83 void removeAssociationEndpoints(
84     sdbusplus::asio::object_server& objectServer, const std::string& assocPath,
85     const boost::container::flat_set<std::string>& endpointsToRemove,
86     AssociationInterfaces& assocInterfaces);
87 
88 /** @brief Check and remove any changed associations
89  *
90  * Based on the latest values of the org.openbmc.Associations.associations
91  * property, passed in via the newAssociations param, check if any of the
92  * paths in the xyz.openbmc_project.Association.endpoints D-Bus property
93  * for that association need to be removed.  If the last path is removed
94  * from the endpoints property, remove that whole association object from
95  * D-Bus.
96  *
97  * @param[in] sourcePath         - Path of the object that contains the
98  *                                 org.openbmc.Associations
99  * @param[in] owner              - The Dbus service having it's associatons
100  *                                 changed
101  * @param[in] newAssociations    - New associations to look at for change
102  * @param[in,out] objectServer   - sdbus system object
103  * @param[in,out] assocOwners    - Owners of associations
104  * @param[in,out] assocInterfaces - Associations endpoints
105  *
106  * @return Void, objectServer and assocOwners updated if needed
107  */
108 void checkAssociationEndpointRemoves(
109     const std::string& sourcePath, const std::string& owner,
110     const AssociationPaths& newAssociations,
111     sdbusplus::asio::object_server& objectServer,
112     AssociationOwnersType& assocOwners, AssociationInterfaces& assocInterfaces);
113 
114 /** @brief Handle new or changed association interfaces
115  *
116  * Called when either a new org.openbmc.Associations interface was
117  * created, or the associations property on that interface changed
118  *
119  * @param[in,out] objectServer    - sdbus system object
120  * @param[in] associations        - New associations to look at for change
121  * @param[in] path                - Path of the object that contains the
122  *                                  org.openbmc.Associations
123  * @param[in] owner               - The Dbus service having it's associatons
124  *                                  changed
125  * @param[in,out] assocOwners     - Owners of associations
126  * @param[in,out] assocInterfaces - Associations endpoints
127  *
128  * @return Void, objectServer and assocOwners updated if needed
129  */
130 void associationChanged(sdbusplus::asio::object_server& objectServer,
131                         const std::vector<Association>& associations,
132                         const std::string& path, const std::string& owner,
133                         AssociationOwnersType& assocOwners,
134                         AssociationInterfaces& assocInterfaces);
135