blob: 3ae7db4ccfed3ed83888d3c4dfe27851536f659b [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}