blob: 9bb7a34ccb4baea6224ffcdc8971e4f9d10a11de [file] [log] [blame]
Andrew Geisslera80a3af2019-02-04 14:01:49 -06001#include "associations.hpp"
2
3void removeAssociation(const std::string& sourcePath, const std::string& owner,
4 sdbusplus::asio::object_server& server,
5 AssociationOwnersType& assocOwners,
6 AssociationInterfaces& assocInterfaces)
7{
8 // Use associationOwners to find the association paths and endpoints
9 // that the passed in object path and service own. Remove all of
10 // these endpoints from the actual association D-Bus objects, and if
11 // the endpoints property is then empty, the whole association object
12 // can be removed. Note there can be multiple services that own an
13 // association, and also that sourcePath is the path of the object
14 // that contains the org.openbmc.Associations interface and not the
15 // association path itself.
16
17 // Find the services that have associations for this object path
18 auto owners = assocOwners.find(sourcePath);
19 if (owners == assocOwners.end())
20 {
21 return;
22 }
23
24 // Find the association paths and endpoints owned by this object
25 // path for this service.
26 auto assocs = owners->second.find(owner);
27 if (assocs == owners->second.end())
28 {
29 return;
30 }
31
32 for (const auto& [assocPath, endpointsToRemove] : assocs->second)
33 {
34 // Get the association D-Bus object for this assocPath
35 auto target = assocInterfaces.find(assocPath);
36 if (target == assocInterfaces.end())
37 {
38 continue;
39 }
40
41 // Remove the entries in the endpoints D-Bus property for this
42 // path/owner/association-path.
43 auto& existingEndpoints = std::get<endpointsPos>(target->second);
44 for (const auto& endpointToRemove : endpointsToRemove)
45 {
46 auto e = std::find(existingEndpoints.begin(),
47 existingEndpoints.end(), endpointToRemove);
48
49 if (e != existingEndpoints.end())
50 {
51 existingEndpoints.erase(e);
52 }
53 }
54
55 // Remove the association from D-Bus if there are no more endpoints,
56 // otherwise just update the endpoints property.
57 if (existingEndpoints.empty())
58 {
59 server.remove_interface(std::get<ifacePos>(target->second));
60 std::get<ifacePos>(target->second) = nullptr;
61 std::get<endpointsPos>(target->second).clear();
62 }
63 else
64 {
65 std::get<ifacePos>(target->second)
66 ->set_property("endpoints", existingEndpoints);
67 }
68 }
69
70 // Remove the associationOwners entries for this owning path/service.
71 owners->second.erase(assocs);
72 if (owners->second.empty())
73 {
74 assocOwners.erase(owners);
75 }
76}
Andrew Geisslerff5ce922019-02-21 12:43:09 -060077
78void removeAssociationEndpoints(
79 sdbusplus::asio::object_server& objectServer, const std::string& assocPath,
80 const boost::container::flat_set<std::string>& endpointsToRemove,
81 AssociationInterfaces& assocInterfaces)
82{
83 auto assoc = assocInterfaces.find(assocPath);
84 if (assoc == assocInterfaces.end())
85 {
86 return;
87 }
88
89 auto& endpointsInDBus = std::get<endpointsPos>(assoc->second);
90
91 for (const auto& endpointToRemove : endpointsToRemove)
92 {
93 auto e = std::find(endpointsInDBus.begin(), endpointsInDBus.end(),
94 endpointToRemove);
95
96 if (e != endpointsInDBus.end())
97 {
98 endpointsInDBus.erase(e);
99 }
100 }
101
102 if (endpointsInDBus.empty())
103 {
104 objectServer.remove_interface(std::get<ifacePos>(assoc->second));
105 std::get<ifacePos>(assoc->second) = nullptr;
106 std::get<endpointsPos>(assoc->second).clear();
107 }
108 else
109 {
110 std::get<ifacePos>(assoc->second)
111 ->set_property("endpoints", endpointsInDBus);
112 }
113}