1aba14d3dSWilly Tu #include "handler.hpp"
2aba14d3dSWilly Tu
3aba14d3dSWilly Tu #include "types.hpp"
4aba14d3dSWilly Tu
5aba14d3dSWilly Tu #include <xyz/openbmc_project/Common/error.hpp>
6aba14d3dSWilly Tu
7aba14d3dSWilly Tu #include <algorithm>
8aba14d3dSWilly Tu #include <string>
958881d0bSWilly Tu #include <unordered_set>
10aba14d3dSWilly Tu #include <utility>
11aba14d3dSWilly Tu #include <vector>
12aba14d3dSWilly Tu
addObjectMapResult(std::vector<InterfaceMapType::value_type> & objectMap,const std::string & objectPath,const ConnectionNames::value_type & interfaceMap)13aba14d3dSWilly Tu void addObjectMapResult(std::vector<InterfaceMapType::value_type>& objectMap,
14aba14d3dSWilly Tu const std::string& objectPath,
15aba14d3dSWilly Tu const ConnectionNames::value_type& interfaceMap)
16aba14d3dSWilly Tu {
17aba14d3dSWilly Tu // Adds an object path/service name/interface list entry to
18aba14d3dSWilly Tu // the results of GetSubTree and GetAncestors.
19aba14d3dSWilly Tu // If an entry for the object path already exists, just add the
20aba14d3dSWilly Tu // service name and interfaces to that entry, otherwise create
21aba14d3dSWilly Tu // a new entry.
2247b68cbcSPatrick Williams auto entry = std::find_if(
2347b68cbcSPatrick Williams objectMap.begin(), objectMap.end(),
2447b68cbcSPatrick Williams [&objectPath](const auto& i) { return objectPath == i.first; });
25aba14d3dSWilly Tu
26aba14d3dSWilly Tu if (entry != objectMap.end())
27aba14d3dSWilly Tu {
28aba14d3dSWilly Tu entry->second.emplace(interfaceMap);
29aba14d3dSWilly Tu }
30aba14d3dSWilly Tu else
31aba14d3dSWilly Tu {
32aba14d3dSWilly Tu InterfaceMapType::value_type object;
33aba14d3dSWilly Tu object.first = objectPath;
34aba14d3dSWilly Tu object.second.emplace(interfaceMap);
35aba14d3dSWilly Tu objectMap.push_back(object);
36aba14d3dSWilly Tu }
37aba14d3dSWilly Tu }
38aba14d3dSWilly Tu
getAncestors(const InterfaceMapType & interfaceMap,std::string reqPath,std::vector<std::string> & interfaces)39*d884cdf7SPatrick Williams std::vector<InterfaceMapType::value_type> getAncestors(
40*d884cdf7SPatrick Williams const InterfaceMapType& interfaceMap, std::string reqPath,
41aba14d3dSWilly Tu std::vector<std::string>& interfaces)
42aba14d3dSWilly Tu {
43aba14d3dSWilly Tu // Interfaces need to be sorted for intersect to function
44aba14d3dSWilly Tu std::sort(interfaces.begin(), interfaces.end());
45aba14d3dSWilly Tu
46aba14d3dSWilly Tu if (reqPath.ends_with("/"))
47aba14d3dSWilly Tu {
48aba14d3dSWilly Tu reqPath.pop_back();
49aba14d3dSWilly Tu }
50aba14d3dSWilly Tu if (!reqPath.empty() && interfaceMap.find(reqPath) == interfaceMap.end())
51aba14d3dSWilly Tu {
52aba14d3dSWilly Tu throw sdbusplus::xyz::openbmc_project::Common::Error::
53aba14d3dSWilly Tu ResourceNotFound();
54aba14d3dSWilly Tu }
55aba14d3dSWilly Tu
56aba14d3dSWilly Tu std::vector<InterfaceMapType::value_type> ret;
57aba14d3dSWilly Tu for (const auto& objectPath : interfaceMap)
58aba14d3dSWilly Tu {
59aba14d3dSWilly Tu const auto& thisPath = objectPath.first;
60aba14d3dSWilly Tu
61aba14d3dSWilly Tu if (reqPath == thisPath)
62aba14d3dSWilly Tu {
63aba14d3dSWilly Tu continue;
64aba14d3dSWilly Tu }
65aba14d3dSWilly Tu
66aba14d3dSWilly Tu if (reqPath.starts_with(thisPath))
67aba14d3dSWilly Tu {
68aba14d3dSWilly Tu if (interfaces.empty())
69aba14d3dSWilly Tu {
70aba14d3dSWilly Tu ret.emplace_back(objectPath);
71aba14d3dSWilly Tu }
72aba14d3dSWilly Tu else
73aba14d3dSWilly Tu {
74aba14d3dSWilly Tu for (const auto& interfaceMap : objectPath.second)
75aba14d3dSWilly Tu {
76aba14d3dSWilly Tu std::vector<std::string> output(std::min(
77aba14d3dSWilly Tu interfaces.size(), interfaceMap.second.size()));
78aba14d3dSWilly Tu // Return iterator points at the first output elemtn,
79aba14d3dSWilly Tu // meaning that there are no intersections.
809052ebd3SPatrick Williams if (std::set_intersection(
819052ebd3SPatrick Williams interfaces.begin(), interfaces.end(),
82aba14d3dSWilly Tu interfaceMap.second.begin(),
839052ebd3SPatrick Williams interfaceMap.second.end(), output.begin()) !=
849052ebd3SPatrick Williams output.begin())
85aba14d3dSWilly Tu {
86aba14d3dSWilly Tu addObjectMapResult(ret, thisPath, interfaceMap);
87aba14d3dSWilly Tu }
88aba14d3dSWilly Tu }
89aba14d3dSWilly Tu }
90aba14d3dSWilly Tu }
91aba14d3dSWilly Tu }
92aba14d3dSWilly Tu
93aba14d3dSWilly Tu return ret;
94aba14d3dSWilly Tu }
95aba14d3dSWilly Tu
getObject(const InterfaceMapType & interfaceMap,const std::string & path,std::vector<std::string> & interfaces)96aba14d3dSWilly Tu ConnectionNames getObject(const InterfaceMapType& interfaceMap,
97aba14d3dSWilly Tu const std::string& path,
98aba14d3dSWilly Tu std::vector<std::string>& interfaces)
99aba14d3dSWilly Tu {
100aba14d3dSWilly Tu ConnectionNames results;
101aba14d3dSWilly Tu
102aba14d3dSWilly Tu // Interfaces need to be sorted for intersect to function
103aba14d3dSWilly Tu std::sort(interfaces.begin(), interfaces.end());
104aba14d3dSWilly Tu auto pathRef = interfaceMap.find(path);
105aba14d3dSWilly Tu if (pathRef == interfaceMap.end())
106aba14d3dSWilly Tu {
107aba14d3dSWilly Tu throw sdbusplus::xyz::openbmc_project::Common::Error::
108aba14d3dSWilly Tu ResourceNotFound();
109aba14d3dSWilly Tu }
110aba14d3dSWilly Tu if (interfaces.empty())
111aba14d3dSWilly Tu {
112aba14d3dSWilly Tu return pathRef->second;
113aba14d3dSWilly Tu }
114aba14d3dSWilly Tu for (const auto& interfaceMap : pathRef->second)
115aba14d3dSWilly Tu {
116aba14d3dSWilly Tu std::vector<std::string> output(
117aba14d3dSWilly Tu std::min(interfaces.size(), interfaceMap.second.size()));
118aba14d3dSWilly Tu // Return iterator points at the first output elemtn,
119aba14d3dSWilly Tu // meaning that there are no intersections.
120aba14d3dSWilly Tu if (std::set_intersection(interfaces.begin(), interfaces.end(),
121aba14d3dSWilly Tu interfaceMap.second.begin(),
1229052ebd3SPatrick Williams interfaceMap.second.end(), output.begin()) !=
1239052ebd3SPatrick Williams output.begin())
124aba14d3dSWilly Tu {
125aba14d3dSWilly Tu results.emplace(interfaceMap.first, interfaceMap.second);
126aba14d3dSWilly Tu }
127aba14d3dSWilly Tu }
128aba14d3dSWilly Tu
129aba14d3dSWilly Tu if (results.empty())
130aba14d3dSWilly Tu {
131aba14d3dSWilly Tu throw sdbusplus::xyz::openbmc_project::Common::Error::
132aba14d3dSWilly Tu ResourceNotFound();
133aba14d3dSWilly Tu }
134aba14d3dSWilly Tu
135aba14d3dSWilly Tu return results;
136aba14d3dSWilly Tu }
137aba14d3dSWilly Tu
getSubTree(const InterfaceMapType & interfaceMap,std::string reqPath,int32_t depth,std::vector<std::string> & interfaces)138*d884cdf7SPatrick Williams std::vector<InterfaceMapType::value_type> getSubTree(
139*d884cdf7SPatrick Williams const InterfaceMapType& interfaceMap, std::string reqPath, int32_t depth,
140*d884cdf7SPatrick Williams std::vector<std::string>& interfaces)
141aba14d3dSWilly Tu {
142aba14d3dSWilly Tu if (depth <= 0)
143aba14d3dSWilly Tu {
144aba14d3dSWilly Tu depth = std::numeric_limits<int32_t>::max();
145aba14d3dSWilly Tu }
146aba14d3dSWilly Tu // Interfaces need to be sorted for intersect to function
147aba14d3dSWilly Tu std::sort(interfaces.begin(), interfaces.end());
148aba14d3dSWilly Tu
149aba14d3dSWilly Tu // reqPath is now guaranteed to have a trailing "/" while reqPathStripped
150aba14d3dSWilly Tu // will be guaranteed not to have a trailing "/"
151aba14d3dSWilly Tu if (!reqPath.ends_with("/"))
152aba14d3dSWilly Tu {
153aba14d3dSWilly Tu reqPath += "/";
154aba14d3dSWilly Tu }
155aba14d3dSWilly Tu std::string_view reqPathStripped =
156aba14d3dSWilly Tu std::string_view(reqPath).substr(0, reqPath.size() - 1);
157aba14d3dSWilly Tu
158aba14d3dSWilly Tu if (!reqPathStripped.empty() &&
159aba14d3dSWilly Tu interfaceMap.find(reqPathStripped) == interfaceMap.end())
160aba14d3dSWilly Tu {
161aba14d3dSWilly Tu throw sdbusplus::xyz::openbmc_project::Common::Error::
162aba14d3dSWilly Tu ResourceNotFound();
163aba14d3dSWilly Tu }
164aba14d3dSWilly Tu
165aba14d3dSWilly Tu std::vector<InterfaceMapType::value_type> ret;
166aba14d3dSWilly Tu for (const auto& objectPath : interfaceMap)
167aba14d3dSWilly Tu {
168aba14d3dSWilly Tu const auto& thisPath = objectPath.first;
169aba14d3dSWilly Tu
170aba14d3dSWilly Tu // Skip exact match on stripped search term
171aba14d3dSWilly Tu if (thisPath == reqPathStripped)
172aba14d3dSWilly Tu {
173aba14d3dSWilly Tu continue;
174aba14d3dSWilly Tu }
175aba14d3dSWilly Tu
176aba14d3dSWilly Tu if (thisPath.starts_with(reqPath))
177aba14d3dSWilly Tu {
178aba14d3dSWilly Tu // count the number of slashes past the stripped search term
179aba14d3dSWilly Tu int32_t thisDepth = std::count(
180aba14d3dSWilly Tu thisPath.begin() + reqPathStripped.size(), thisPath.end(), '/');
181aba14d3dSWilly Tu if (thisDepth <= depth)
182aba14d3dSWilly Tu {
183aba14d3dSWilly Tu for (const auto& interfaceMap : objectPath.second)
184aba14d3dSWilly Tu {
185aba14d3dSWilly Tu std::vector<std::string> output(std::min(
186aba14d3dSWilly Tu interfaces.size(), interfaceMap.second.size()));
187aba14d3dSWilly Tu // Return iterator points at the first output elemtn,
188aba14d3dSWilly Tu // meaning that there are no intersections.
189aba14d3dSWilly Tu if (std::set_intersection(
190aba14d3dSWilly Tu interfaces.begin(), interfaces.end(),
191aba14d3dSWilly Tu interfaceMap.second.begin(),
192aba14d3dSWilly Tu interfaceMap.second.end(),
193aba14d3dSWilly Tu output.begin()) != output.begin() ||
194aba14d3dSWilly Tu interfaces.empty())
195aba14d3dSWilly Tu {
196aba14d3dSWilly Tu addObjectMapResult(ret, thisPath, interfaceMap);
197aba14d3dSWilly Tu }
198aba14d3dSWilly Tu }
199aba14d3dSWilly Tu }
200aba14d3dSWilly Tu }
201aba14d3dSWilly Tu }
202aba14d3dSWilly Tu
203aba14d3dSWilly Tu return ret;
204aba14d3dSWilly Tu }
205aba14d3dSWilly Tu
getSubTreePaths(const InterfaceMapType & interfaceMap,std::string reqPath,int32_t depth,std::vector<std::string> & interfaces)206*d884cdf7SPatrick Williams std::vector<std::string> getSubTreePaths(const InterfaceMapType& interfaceMap,
207*d884cdf7SPatrick Williams std::string reqPath, int32_t depth,
208*d884cdf7SPatrick Williams std::vector<std::string>& interfaces)
209aba14d3dSWilly Tu {
210aba14d3dSWilly Tu if (depth <= 0)
211aba14d3dSWilly Tu {
212aba14d3dSWilly Tu depth = std::numeric_limits<int32_t>::max();
213aba14d3dSWilly Tu }
214aba14d3dSWilly Tu // Interfaces need to be sorted for intersect to function
215aba14d3dSWilly Tu std::sort(interfaces.begin(), interfaces.end());
216aba14d3dSWilly Tu
217aba14d3dSWilly Tu // reqPath is now guaranteed to have a trailing "/" while reqPathStripped
218aba14d3dSWilly Tu // will be guaranteed not to have a trailing "/"
219aba14d3dSWilly Tu if (!reqPath.ends_with("/"))
220aba14d3dSWilly Tu {
221aba14d3dSWilly Tu reqPath += "/";
222aba14d3dSWilly Tu }
223aba14d3dSWilly Tu std::string_view reqPathStripped =
224aba14d3dSWilly Tu std::string_view(reqPath).substr(0, reqPath.size() - 1);
225aba14d3dSWilly Tu
226aba14d3dSWilly Tu if (!reqPathStripped.empty() &&
227aba14d3dSWilly Tu interfaceMap.find(reqPathStripped) == interfaceMap.end())
228aba14d3dSWilly Tu {
229aba14d3dSWilly Tu throw sdbusplus::xyz::openbmc_project::Common::Error::
230aba14d3dSWilly Tu ResourceNotFound();
231aba14d3dSWilly Tu }
232aba14d3dSWilly Tu
233aba14d3dSWilly Tu std::vector<std::string> ret;
234aba14d3dSWilly Tu for (const auto& objectPath : interfaceMap)
235aba14d3dSWilly Tu {
236aba14d3dSWilly Tu const auto& thisPath = objectPath.first;
237aba14d3dSWilly Tu
238aba14d3dSWilly Tu // Skip exact match on stripped search term
239aba14d3dSWilly Tu if (thisPath == reqPathStripped)
240aba14d3dSWilly Tu {
241aba14d3dSWilly Tu continue;
242aba14d3dSWilly Tu }
243aba14d3dSWilly Tu
244aba14d3dSWilly Tu if (thisPath.starts_with(reqPath))
245aba14d3dSWilly Tu {
246aba14d3dSWilly Tu // count the number of slashes past the stripped search term
247aba14d3dSWilly Tu int thisDepth = std::count(
248aba14d3dSWilly Tu thisPath.begin() + reqPathStripped.size(), thisPath.end(), '/');
249aba14d3dSWilly Tu if (thisDepth <= depth)
250aba14d3dSWilly Tu {
251aba14d3dSWilly Tu bool add = interfaces.empty();
252aba14d3dSWilly Tu for (const auto& interfaceMap : objectPath.second)
253aba14d3dSWilly Tu {
254aba14d3dSWilly Tu std::vector<std::string> output(std::min(
255aba14d3dSWilly Tu interfaces.size(), interfaceMap.second.size()));
256aba14d3dSWilly Tu // Return iterator points at the first output elemtn,
257aba14d3dSWilly Tu // meaning that there are no intersections.
2589052ebd3SPatrick Williams if (std::set_intersection(
2599052ebd3SPatrick Williams interfaces.begin(), interfaces.end(),
260aba14d3dSWilly Tu interfaceMap.second.begin(),
2619052ebd3SPatrick Williams interfaceMap.second.end(), output.begin()) !=
2629052ebd3SPatrick Williams output.begin())
263aba14d3dSWilly Tu {
264aba14d3dSWilly Tu add = true;
265aba14d3dSWilly Tu break;
266aba14d3dSWilly Tu }
267aba14d3dSWilly Tu }
268aba14d3dSWilly Tu if (add)
269aba14d3dSWilly Tu {
270aba14d3dSWilly Tu // TODO(ed) this is a copy
271aba14d3dSWilly Tu ret.emplace_back(thisPath);
272aba14d3dSWilly Tu }
273aba14d3dSWilly Tu }
274aba14d3dSWilly Tu }
275aba14d3dSWilly Tu }
276aba14d3dSWilly Tu
277aba14d3dSWilly Tu return ret;
278aba14d3dSWilly Tu }
27958881d0bSWilly Tu
getAssociatedSubTree(const InterfaceMapType & interfaceMap,const AssociationMaps & associationMaps,const sdbusplus::message::object_path & associationPath,const sdbusplus::message::object_path & reqPath,int32_t depth,std::vector<std::string> & interfaces)2809052ebd3SPatrick Williams std::vector<InterfaceMapType::value_type> getAssociatedSubTree(
2819052ebd3SPatrick Williams const InterfaceMapType& interfaceMap,
28258881d0bSWilly Tu const AssociationMaps& associationMaps,
28358881d0bSWilly Tu const sdbusplus::message::object_path& associationPath,
2849052ebd3SPatrick Williams const sdbusplus::message::object_path& reqPath, int32_t depth,
2859052ebd3SPatrick Williams std::vector<std::string>& interfaces)
28658881d0bSWilly Tu {
28758881d0bSWilly Tu auto findEndpoint = associationMaps.ifaces.find(associationPath.str);
28858881d0bSWilly Tu if (findEndpoint == associationMaps.ifaces.end())
28958881d0bSWilly Tu {
29058881d0bSWilly Tu return {};
29158881d0bSWilly Tu }
29258881d0bSWilly Tu const std::vector<std::string>& association =
29358881d0bSWilly Tu std::get<endpointsPos>(findEndpoint->second);
29458881d0bSWilly Tu std::unordered_set<std::string> associationSet(association.begin(),
29558881d0bSWilly Tu association.end());
2968c25006cSPatrick Williams const std::vector<InterfaceMapType::value_type> interfacePairs =
29758881d0bSWilly Tu getSubTree(interfaceMap, reqPath, depth, interfaces);
29858881d0bSWilly Tu
29958881d0bSWilly Tu std::vector<InterfaceMapType::value_type> output;
30058881d0bSWilly Tu for (const InterfaceMapType::value_type& interfacePair : interfacePairs)
30158881d0bSWilly Tu {
30258881d0bSWilly Tu if (associationSet.contains(interfacePair.first))
30358881d0bSWilly Tu {
30458881d0bSWilly Tu output.emplace_back(interfacePair);
30558881d0bSWilly Tu }
30658881d0bSWilly Tu }
30758881d0bSWilly Tu return output;
30858881d0bSWilly Tu }
30958881d0bSWilly Tu
getAssociatedSubTreePaths(const InterfaceMapType & interfaceMap,const AssociationMaps & associationMaps,const sdbusplus::message::object_path & associationPath,const sdbusplus::message::object_path & reqPath,int32_t depth,std::vector<std::string> & interfaces)31058881d0bSWilly Tu std::vector<std::string> getAssociatedSubTreePaths(
31158881d0bSWilly Tu const InterfaceMapType& interfaceMap,
31258881d0bSWilly Tu const AssociationMaps& associationMaps,
31358881d0bSWilly Tu const sdbusplus::message::object_path& associationPath,
31458881d0bSWilly Tu const sdbusplus::message::object_path& reqPath, int32_t depth,
31558881d0bSWilly Tu std::vector<std::string>& interfaces)
31658881d0bSWilly Tu {
31758881d0bSWilly Tu auto findEndpoint = associationMaps.ifaces.find(associationPath.str);
31858881d0bSWilly Tu if (findEndpoint == associationMaps.ifaces.end())
31958881d0bSWilly Tu {
32058881d0bSWilly Tu return {};
32158881d0bSWilly Tu }
32258881d0bSWilly Tu const std::vector<std::string>& association =
32358881d0bSWilly Tu std::get<endpointsPos>(findEndpoint->second);
32458881d0bSWilly Tu std::unordered_set<std::string> associationSet(association.begin(),
32558881d0bSWilly Tu association.end());
3268c25006cSPatrick Williams const std::vector<std::string> paths =
32758881d0bSWilly Tu getSubTreePaths(interfaceMap, reqPath, depth, interfaces);
32858881d0bSWilly Tu
32958881d0bSWilly Tu std::vector<std::string> output;
33058881d0bSWilly Tu for (const auto& path : paths)
33158881d0bSWilly Tu {
33258881d0bSWilly Tu if (associationSet.contains(path))
33358881d0bSWilly Tu {
33458881d0bSWilly Tu output.emplace_back(path);
33558881d0bSWilly Tu }
33658881d0bSWilly Tu }
33758881d0bSWilly Tu return output;
33858881d0bSWilly Tu }
339c363323eSLakshmi Yadlapati
340c363323eSLakshmi Yadlapati // This function works like getSubTreePaths() but only matching id with
341c363323eSLakshmi Yadlapati // the leaf-name instead of full path.
getSubTreePathsById(const InterfaceMapType & interfaceMap,const std::string & id,const std::string & objectPath,std::vector<std::string> & interfaces)342c363323eSLakshmi Yadlapati std::vector<std::string> getSubTreePathsById(
343c363323eSLakshmi Yadlapati const InterfaceMapType& interfaceMap, const std::string& id,
344c363323eSLakshmi Yadlapati const std::string& objectPath, std::vector<std::string>& interfaces)
345c363323eSLakshmi Yadlapati {
346c363323eSLakshmi Yadlapati std::sort(interfaces.begin(), interfaces.end());
347c363323eSLakshmi Yadlapati
348c363323eSLakshmi Yadlapati std::string localObjectPath = objectPath;
349c363323eSLakshmi Yadlapati
350c363323eSLakshmi Yadlapati if (!localObjectPath.ends_with("/"))
351c363323eSLakshmi Yadlapati {
352c363323eSLakshmi Yadlapati localObjectPath += "/";
353c363323eSLakshmi Yadlapati }
354c363323eSLakshmi Yadlapati std::string_view objectPathStripped =
355c363323eSLakshmi Yadlapati std::string_view(localObjectPath).substr(0, localObjectPath.size() - 1);
356c363323eSLakshmi Yadlapati
357c363323eSLakshmi Yadlapati if (!objectPathStripped.empty() &&
358c363323eSLakshmi Yadlapati interfaceMap.find(objectPathStripped) == interfaceMap.end())
359c363323eSLakshmi Yadlapati {
360c363323eSLakshmi Yadlapati throw sdbusplus::xyz::openbmc_project::Common::Error::
361c363323eSLakshmi Yadlapati ResourceNotFound();
362c363323eSLakshmi Yadlapati }
363c363323eSLakshmi Yadlapati
364c363323eSLakshmi Yadlapati std::vector<std::string> output;
365c363323eSLakshmi Yadlapati for (const auto& path : interfaceMap)
366c363323eSLakshmi Yadlapati {
367c363323eSLakshmi Yadlapati const auto& thisPath = path.first;
368c363323eSLakshmi Yadlapati
369c363323eSLakshmi Yadlapati // Skip exact match on stripped search term or
370c363323eSLakshmi Yadlapati // the path does not end with the id
371c363323eSLakshmi Yadlapati if (thisPath == objectPathStripped || !thisPath.ends_with("/" + id))
372c363323eSLakshmi Yadlapati {
373c363323eSLakshmi Yadlapati continue;
374c363323eSLakshmi Yadlapati }
375c363323eSLakshmi Yadlapati
376c363323eSLakshmi Yadlapati if (thisPath.starts_with(objectPath))
377c363323eSLakshmi Yadlapati {
378c363323eSLakshmi Yadlapati for (const auto& interfaceMap : path.second)
379c363323eSLakshmi Yadlapati {
380c363323eSLakshmi Yadlapati std::vector<std::string> tempoutput(
381c363323eSLakshmi Yadlapati std::min(interfaces.size(), interfaceMap.second.size()));
382c363323eSLakshmi Yadlapati if (std::set_intersection(
383c363323eSLakshmi Yadlapati interfaces.begin(), interfaces.end(),
384c363323eSLakshmi Yadlapati interfaceMap.second.begin(), interfaceMap.second.end(),
385c363323eSLakshmi Yadlapati tempoutput.begin()) != tempoutput.begin())
386c363323eSLakshmi Yadlapati {
387c363323eSLakshmi Yadlapati output.emplace_back(thisPath);
388c363323eSLakshmi Yadlapati break;
389c363323eSLakshmi Yadlapati }
390c363323eSLakshmi Yadlapati }
391c363323eSLakshmi Yadlapati }
392c363323eSLakshmi Yadlapati }
393c363323eSLakshmi Yadlapati return output;
394c363323eSLakshmi Yadlapati }
395c363323eSLakshmi Yadlapati
getAssociatedSubTreeById(const InterfaceMapType & interfaceMap,const AssociationMaps & associationMaps,const std::string & id,const std::string & objectPath,std::vector<std::string> & subtreeInterfaces,const std::string & association,std::vector<std::string> & endpointInterfaces)396c363323eSLakshmi Yadlapati std::vector<InterfaceMapType::value_type> getAssociatedSubTreeById(
397c363323eSLakshmi Yadlapati const InterfaceMapType& interfaceMap,
398c363323eSLakshmi Yadlapati const AssociationMaps& associationMaps, const std::string& id,
399c363323eSLakshmi Yadlapati const std::string& objectPath, std::vector<std::string>& subtreeInterfaces,
400c363323eSLakshmi Yadlapati const std::string& association,
401c363323eSLakshmi Yadlapati std::vector<std::string>& endpointInterfaces)
402c363323eSLakshmi Yadlapati {
403c363323eSLakshmi Yadlapati std::vector<std::string> subtreePaths =
404c363323eSLakshmi Yadlapati getSubTreePathsById(interfaceMap, id, objectPath, subtreeInterfaces);
405c363323eSLakshmi Yadlapati
406c363323eSLakshmi Yadlapati std::vector<InterfaceMapType::value_type> output;
407c363323eSLakshmi Yadlapati for (const auto& subtreePath : subtreePaths)
408c363323eSLakshmi Yadlapati {
409c363323eSLakshmi Yadlapati // Form the association path
410c363323eSLakshmi Yadlapati std::string associationPathStr = subtreePath + "/" + association;
411c363323eSLakshmi Yadlapati sdbusplus::message::object_path associationPath(associationPathStr);
412c363323eSLakshmi Yadlapati
413c363323eSLakshmi Yadlapati auto associatedSubTree =
414c363323eSLakshmi Yadlapati getAssociatedSubTree(interfaceMap, associationMaps, associationPath,
415c363323eSLakshmi Yadlapati objectPath, 0, endpointInterfaces);
416c363323eSLakshmi Yadlapati
417c363323eSLakshmi Yadlapati output.insert(output.end(), associatedSubTree.begin(),
418c363323eSLakshmi Yadlapati associatedSubTree.end());
419c363323eSLakshmi Yadlapati }
420c363323eSLakshmi Yadlapati return output;
421c363323eSLakshmi Yadlapati }
422c363323eSLakshmi Yadlapati
getAssociatedSubTreePathsById(const InterfaceMapType & interfaceMap,const AssociationMaps & associationMaps,const std::string & id,const std::string & objectPath,std::vector<std::string> & subtreeInterfaces,const std::string & association,std::vector<std::string> & endpointInterfaces)423c363323eSLakshmi Yadlapati std::vector<std::string> getAssociatedSubTreePathsById(
424c363323eSLakshmi Yadlapati const InterfaceMapType& interfaceMap,
425c363323eSLakshmi Yadlapati const AssociationMaps& associationMaps, const std::string& id,
426c363323eSLakshmi Yadlapati const std::string& objectPath, std::vector<std::string>& subtreeInterfaces,
427c363323eSLakshmi Yadlapati const std::string& association,
428c363323eSLakshmi Yadlapati std::vector<std::string>& endpointInterfaces)
429c363323eSLakshmi Yadlapati {
430c363323eSLakshmi Yadlapati std::vector<std::string> subtreePaths =
431c363323eSLakshmi Yadlapati getSubTreePathsById(interfaceMap, id, objectPath, subtreeInterfaces);
432c363323eSLakshmi Yadlapati std::vector<std::string> output;
433c363323eSLakshmi Yadlapati for (const auto& subtreePath : subtreePaths)
434c363323eSLakshmi Yadlapati {
435c363323eSLakshmi Yadlapati // Form the association path
436c363323eSLakshmi Yadlapati std::string associationPathStr = subtreePath + "/" + association;
437c363323eSLakshmi Yadlapati sdbusplus::message::object_path associationPath(associationPathStr);
438c363323eSLakshmi Yadlapati
439c363323eSLakshmi Yadlapati auto associatedSubTree = getAssociatedSubTreePaths(
440c363323eSLakshmi Yadlapati interfaceMap, associationMaps, associationPath, objectPath, 0,
441c363323eSLakshmi Yadlapati endpointInterfaces);
442c363323eSLakshmi Yadlapati
443c363323eSLakshmi Yadlapati output.insert(output.end(), associatedSubTree.begin(),
444c363323eSLakshmi Yadlapati associatedSubTree.end());
445c363323eSLakshmi Yadlapati }
446c363323eSLakshmi Yadlapati
447c363323eSLakshmi Yadlapati return output;
448c363323eSLakshmi Yadlapati }
449