149aefb31SBrad Bishop /**
249aefb31SBrad Bishop * Copyright © 2016 IBM Corporation
349aefb31SBrad Bishop *
449aefb31SBrad Bishop * Licensed under the Apache License, Version 2.0 (the "License");
549aefb31SBrad Bishop * you may not use this file except in compliance with the License.
649aefb31SBrad Bishop * You may obtain a copy of the License at
749aefb31SBrad Bishop *
849aefb31SBrad Bishop * http://www.apache.org/licenses/LICENSE-2.0
949aefb31SBrad Bishop *
1049aefb31SBrad Bishop * Unless required by applicable law or agreed to in writing, software
1149aefb31SBrad Bishop * distributed under the License is distributed on an "AS IS" BASIS,
1249aefb31SBrad Bishop * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1349aefb31SBrad Bishop * See the License for the specific language governing permissions and
1449aefb31SBrad Bishop * limitations under the License.
1549aefb31SBrad Bishop */
1649aefb31SBrad Bishop #include "manager.hpp"
17a680d1efSPatrick Venture
1879ccaf77SBrad Bishop #include "errors.hpp"
1949aefb31SBrad Bishop
20a680d1efSPatrick Venture #include <algorithm>
21a680d1efSPatrick Venture #include <chrono>
22a680d1efSPatrick Venture #include <exception>
23e6b21c74SKun Yi #include <filesystem>
24a680d1efSPatrick Venture #include <iostream>
25a680d1efSPatrick Venture
2624424983SBrad Bishop using namespace std::literals::chrono_literals;
2724424983SBrad Bishop
2849aefb31SBrad Bishop namespace phosphor
2949aefb31SBrad Bishop {
3049aefb31SBrad Bishop namespace inventory
3149aefb31SBrad Bishop {
3249aefb31SBrad Bishop namespace manager
3349aefb31SBrad Bishop {
3449aefb31SBrad Bishop /** @brief Fowrarding signal callback.
3549aefb31SBrad Bishop *
3649aefb31SBrad Bishop * Extracts per-signal specific context and forwards the call to the manager
3749aefb31SBrad Bishop * instance.
3849aefb31SBrad Bishop */
_signal(sd_bus_message * m,void * data,sd_bus_error *)3923314a5cSGeorge Liu auto _signal(sd_bus_message* m, void* data, sd_bus_error* /* e */) noexcept
4049aefb31SBrad Bishop {
417b33777bSBrad Bishop try
427b33777bSBrad Bishop {
43563306f6SPatrick Williams auto msg = sdbusplus::message_t(m);
4449aefb31SBrad Bishop auto& args = *static_cast<Manager::SigArg*>(data);
4549aefb31SBrad Bishop sd_bus_message_ref(m);
4649aefb31SBrad Bishop auto& mgr = *std::get<0>(args);
47615b2a8fSBrad Bishop mgr.handleEvent(msg, static_cast<const DbusSignal&>(*std::get<1>(args)),
4868c80839SBrad Bishop *std::get<2>(args));
4949aefb31SBrad Bishop }
507b33777bSBrad Bishop catch (const std::exception& e)
517b33777bSBrad Bishop {
5249aefb31SBrad Bishop std::cerr << e.what() << std::endl;
5349aefb31SBrad Bishop }
5449aefb31SBrad Bishop
5549aefb31SBrad Bishop return 0;
5649aefb31SBrad Bishop }
5749aefb31SBrad Bishop
Manager(sdbusplus::bus_t && bus,const char * root)58563306f6SPatrick Williams Manager::Manager(sdbusplus::bus_t&& bus, const char* root) :
594627a9ccSBrad Bishop ServerObject<ManagerIface>(bus, root), _root(root), _bus(std::move(bus)),
604627a9ccSBrad Bishop _manager(_bus, root),
61852db67bSMatt Spinler #ifdef CREATE_ASSOCIATIONS
624627a9ccSBrad Bishop _associations(_bus),
63852db67bSMatt Spinler #endif
644627a9ccSBrad Bishop _status(ManagerStatus::STARTING)
6549aefb31SBrad Bishop {
6668c80839SBrad Bishop for (auto& group : _events)
6768c80839SBrad Bishop {
68615b2a8fSBrad Bishop for (auto pEvent : std::get<std::vector<EventBasePtr>>(group))
6968c80839SBrad Bishop {
70615b2a8fSBrad Bishop if (pEvent->type != Event::Type::DBUS_SIGNAL)
717b33777bSBrad Bishop {
724f20a3e3SBrad Bishop continue;
737b33777bSBrad Bishop }
744f20a3e3SBrad Bishop
7568c80839SBrad Bishop // Create a callback context for this event group.
76615b2a8fSBrad Bishop auto dbusEvent = static_cast<DbusSignal*>(pEvent.get());
7768c80839SBrad Bishop
7868c80839SBrad Bishop // Go ahead and store an iterator pointing at
7968c80839SBrad Bishop // the event data to avoid lookups later since
8068c80839SBrad Bishop // additional signal callbacks aren't added
8168c80839SBrad Bishop // after the manager is constructed.
8249aefb31SBrad Bishop _sigargs.emplace_back(
83615b2a8fSBrad Bishop std::make_unique<SigArg>(this, dbusEvent, &group));
8468c80839SBrad Bishop
8549aefb31SBrad Bishop // Register our callback and the context for
8668c80839SBrad Bishop // each signal event.
87615b2a8fSBrad Bishop _matches.emplace_back(_bus, dbusEvent->signature, _signal,
881ab880a1SBrad Bishop _sigargs.back().get());
8949aefb31SBrad Bishop }
9068c80839SBrad Bishop }
9149aefb31SBrad Bishop
92b28990f3SDeepak Kodihalli // Restore any persistent inventory
93b28990f3SDeepak Kodihalli restore();
9449aefb31SBrad Bishop }
9549aefb31SBrad Bishop
shutdown()9649aefb31SBrad Bishop void Manager::shutdown() noexcept
9749aefb31SBrad Bishop {
984627a9ccSBrad Bishop _status = ManagerStatus::STOPPING;
9949aefb31SBrad Bishop }
10049aefb31SBrad Bishop
run(const char * busname)10120c9435cSBrad Bishop void Manager::run(const char* busname)
10249aefb31SBrad Bishop {
103563306f6SPatrick Williams sdbusplus::message_t unusedMsg{nullptr};
1043e4a19a3SBrad Bishop
1053e4a19a3SBrad Bishop // Run startup events.
1063e4a19a3SBrad Bishop for (auto& group : _events)
1073e4a19a3SBrad Bishop {
108615b2a8fSBrad Bishop for (auto pEvent : std::get<std::vector<EventBasePtr>>(group))
1093e4a19a3SBrad Bishop {
110615b2a8fSBrad Bishop if (pEvent->type == Event::Type::STARTUP)
1113e4a19a3SBrad Bishop {
1123e4a19a3SBrad Bishop handleEvent(unusedMsg, *pEvent, group);
1133e4a19a3SBrad Bishop }
1143e4a19a3SBrad Bishop }
1153e4a19a3SBrad Bishop }
1163e4a19a3SBrad Bishop
1174627a9ccSBrad Bishop _status = ManagerStatus::RUNNING;
11820c9435cSBrad Bishop _bus.request_name(busname);
1194627a9ccSBrad Bishop
1204627a9ccSBrad Bishop while (_status != ManagerStatus::STOPPING)
1217b33777bSBrad Bishop {
1227b33777bSBrad Bishop try
1237b33777bSBrad Bishop {
12449aefb31SBrad Bishop _bus.process_discard();
12524424983SBrad Bishop _bus.wait((5000000us).count());
12649aefb31SBrad Bishop }
1277b33777bSBrad Bishop catch (const std::exception& e)
1287b33777bSBrad Bishop {
12949aefb31SBrad Bishop std::cerr << e.what() << std::endl;
13049aefb31SBrad Bishop }
13149aefb31SBrad Bishop }
13249aefb31SBrad Bishop }
13349aefb31SBrad Bishop
updateInterfaces(const sdbusplus::message::object_path & path,const Object & interfaces,ObjectReferences::iterator pos,bool newObject,bool restoreFromCache)134615b2a8fSBrad Bishop void Manager::updateInterfaces(const sdbusplus::message::object_path& path,
13579ccaf77SBrad Bishop const Object& interfaces,
136615b2a8fSBrad Bishop ObjectReferences::iterator pos, bool newObject,
137b28990f3SDeepak Kodihalli bool restoreFromCache)
13879ccaf77SBrad Bishop {
13979ccaf77SBrad Bishop auto& refaces = pos->second;
14079ccaf77SBrad Bishop auto ifaceit = interfaces.cbegin();
14179ccaf77SBrad Bishop auto opsit = _makers.cbegin();
14279ccaf77SBrad Bishop auto refaceit = refaces.begin();
14379ccaf77SBrad Bishop std::vector<std::string> signals;
14479ccaf77SBrad Bishop
14579ccaf77SBrad Bishop while (ifaceit != interfaces.cend())
14679ccaf77SBrad Bishop {
14779ccaf77SBrad Bishop try
14879ccaf77SBrad Bishop {
14979ccaf77SBrad Bishop // Find the binding ops for this interface.
150615b2a8fSBrad Bishop opsit = std::lower_bound(opsit, _makers.cend(), ifaceit->first,
15179ccaf77SBrad Bishop compareFirst(_makers.key_comp()));
15279ccaf77SBrad Bishop
15379ccaf77SBrad Bishop if (opsit == _makers.cend() || opsit->first != ifaceit->first)
15479ccaf77SBrad Bishop {
15579ccaf77SBrad Bishop // This interface is not supported.
156615b2a8fSBrad Bishop throw InterfaceError("Encountered unsupported interface.",
15779ccaf77SBrad Bishop ifaceit->first);
15879ccaf77SBrad Bishop }
15979ccaf77SBrad Bishop
16079ccaf77SBrad Bishop // Find the binding insertion point or the binding to update.
161615b2a8fSBrad Bishop refaceit = std::lower_bound(refaceit, refaces.end(), ifaceit->first,
16279ccaf77SBrad Bishop compareFirst(refaces.key_comp()));
16379ccaf77SBrad Bishop
16479ccaf77SBrad Bishop if (refaceit == refaces.end() || refaceit->first != ifaceit->first)
16579ccaf77SBrad Bishop {
16679ccaf77SBrad Bishop // Add the new interface.
16702763c68SBrad Bishop auto& ctor = std::get<MakeInterfaceType>(opsit->second);
16823a8d935SBrad Bishop // skipSignal = true here to avoid getting PropertiesChanged
16923a8d935SBrad Bishop // signals while the interface is constructed. We'll emit an
17023a8d935SBrad Bishop // ObjectManager signal for this interface below.
17179ccaf77SBrad Bishop refaceit = refaces.insert(
172e96f2aa7SBrad Bishop refaceit, std::make_pair(ifaceit->first,
173e96f2aa7SBrad Bishop ctor(_bus, path.str.c_str(),
17423a8d935SBrad Bishop ifaceit->second, true)));
17579ccaf77SBrad Bishop signals.push_back(ifaceit->first);
17679ccaf77SBrad Bishop }
17779ccaf77SBrad Bishop else
17879ccaf77SBrad Bishop {
17979ccaf77SBrad Bishop // Set the new property values.
18002763c68SBrad Bishop auto& assign = std::get<AssignInterfaceType>(opsit->second);
18123a8d935SBrad Bishop assign(ifaceit->second, refaceit->second,
18223a8d935SBrad Bishop _status != ManagerStatus::RUNNING);
18379ccaf77SBrad Bishop }
184b28990f3SDeepak Kodihalli if (!restoreFromCache)
185b28990f3SDeepak Kodihalli {
18602763c68SBrad Bishop auto& serialize =
18702763c68SBrad Bishop std::get<SerializeInterfaceType<SerialOps>>(opsit->second);
1886620e98dSDeepak Kodihalli serialize(path, ifaceit->first, refaceit->second);
18979ccaf77SBrad Bishop }
190b28990f3SDeepak Kodihalli else
191b28990f3SDeepak Kodihalli {
19202763c68SBrad Bishop auto& deserialize =
19302763c68SBrad Bishop std::get<DeserializeInterfaceType<SerialOps>>(
19402763c68SBrad Bishop opsit->second);
195b28990f3SDeepak Kodihalli deserialize(path, ifaceit->first, refaceit->second);
196b28990f3SDeepak Kodihalli }
197b28990f3SDeepak Kodihalli }
19879ccaf77SBrad Bishop catch (const InterfaceError& e)
19979ccaf77SBrad Bishop {
20079ccaf77SBrad Bishop // Reset the binding ops iterator since we are
20179ccaf77SBrad Bishop // at the end.
20279ccaf77SBrad Bishop opsit = _makers.cbegin();
20379ccaf77SBrad Bishop e.log();
20479ccaf77SBrad Bishop }
20579ccaf77SBrad Bishop
20679ccaf77SBrad Bishop ++ifaceit;
20779ccaf77SBrad Bishop }
20879ccaf77SBrad Bishop
20923a8d935SBrad Bishop if (_status == ManagerStatus::RUNNING)
21023a8d935SBrad Bishop {
21179ccaf77SBrad Bishop if (newObject)
21279ccaf77SBrad Bishop {
21379ccaf77SBrad Bishop _bus.emit_object_added(path.str.c_str());
21479ccaf77SBrad Bishop }
21579ccaf77SBrad Bishop else if (!signals.empty())
21679ccaf77SBrad Bishop {
217a8ff8154SGunnar Mills _bus.emit_interfaces_added(path.str.c_str(), signals);
21879ccaf77SBrad Bishop }
21979ccaf77SBrad Bishop }
22023a8d935SBrad Bishop }
22179ccaf77SBrad Bishop
updateObjects(const std::map<sdbusplus::message::object_path,Object> & objs,bool restoreFromCache)22279ccaf77SBrad Bishop void Manager::updateObjects(
223b28990f3SDeepak Kodihalli const std::map<sdbusplus::message::object_path, Object>& objs,
224b28990f3SDeepak Kodihalli bool restoreFromCache)
22579ccaf77SBrad Bishop {
22679ccaf77SBrad Bishop auto objit = objs.cbegin();
22779ccaf77SBrad Bishop auto refit = _refs.begin();
22879ccaf77SBrad Bishop std::string absPath;
22979ccaf77SBrad Bishop bool newObj;
23079ccaf77SBrad Bishop
23179ccaf77SBrad Bishop while (objit != objs.cend())
23279ccaf77SBrad Bishop {
23379ccaf77SBrad Bishop // Find the insertion point or the object to update.
234615b2a8fSBrad Bishop refit = std::lower_bound(refit, _refs.end(), objit->first,
23579ccaf77SBrad Bishop compareFirst(RelPathCompare(_root)));
23679ccaf77SBrad Bishop
23779ccaf77SBrad Bishop absPath.assign(_root);
23879ccaf77SBrad Bishop absPath.append(objit->first);
23979ccaf77SBrad Bishop
24079ccaf77SBrad Bishop newObj = false;
24179ccaf77SBrad Bishop if (refit == _refs.end() || refit->first != absPath)
24279ccaf77SBrad Bishop {
24379ccaf77SBrad Bishop refit = _refs.insert(
244615b2a8fSBrad Bishop refit, std::make_pair(absPath, decltype(_refs)::mapped_type()));
24579ccaf77SBrad Bishop newObj = true;
24679ccaf77SBrad Bishop }
24779ccaf77SBrad Bishop
248b28990f3SDeepak Kodihalli updateInterfaces(absPath, objit->second, refit, newObj,
249b28990f3SDeepak Kodihalli restoreFromCache);
250852db67bSMatt Spinler #ifdef CREATE_ASSOCIATIONS
25159521e87SMatt Spinler if (!_associations.pendingCondition() && newObj)
252852db67bSMatt Spinler {
25323a8d935SBrad Bishop _associations.createAssociations(absPath,
254ee294d68SBrad Bishop _status != ManagerStatus::RUNNING);
255852db67bSMatt Spinler }
25659521e87SMatt Spinler else if (!restoreFromCache &&
25759521e87SMatt Spinler _associations.conditionMatch(objit->first, objit->second))
25859521e87SMatt Spinler {
25959521e87SMatt Spinler // The objit path/interface/property matched a pending condition.
26059521e87SMatt Spinler // Now the associations are valid so attempt to create them against
26159521e87SMatt Spinler // all existing objects. If this was the restoreFromCache path,
26259521e87SMatt Spinler // objit doesn't contain property values so don't bother checking.
26359521e87SMatt Spinler std::for_each(_refs.begin(), _refs.end(), [this](const auto& ref) {
26459521e87SMatt Spinler _associations.createAssociations(
26559521e87SMatt Spinler ref.first, _status != ManagerStatus::RUNNING);
26659521e87SMatt Spinler });
26759521e87SMatt Spinler }
268852db67bSMatt Spinler #endif
26979ccaf77SBrad Bishop ++objit;
27079ccaf77SBrad Bishop }
27179ccaf77SBrad Bishop }
27279ccaf77SBrad Bishop
notify(std::map<sdbusplus::message::object_path,Object> objs)27303f4cd95SBrad Bishop void Manager::notify(std::map<sdbusplus::message::object_path, Object> objs)
27449aefb31SBrad Bishop {
275cda036f7SBrad Bishop updateObjects(objs);
27649aefb31SBrad Bishop }
27749aefb31SBrad Bishop
handleEvent(sdbusplus::message_t & msg,const Event & event,const EventInfo & info)278563306f6SPatrick Williams void Manager::handleEvent(sdbusplus::message_t& msg, const Event& event,
27968c80839SBrad Bishop const EventInfo& info)
28049aefb31SBrad Bishop {
28168c80839SBrad Bishop auto& actions = std::get<1>(info);
2823d57f507SBrad Bishop
28348547a85SBrad Bishop for (auto& f : event)
2847b33777bSBrad Bishop {
28507934a64SBrad Bishop if (!f(_bus, msg, *this))
286064c94a6SBrad Bishop {
287064c94a6SBrad Bishop return;
288064c94a6SBrad Bishop }
289064c94a6SBrad Bishop }
2909007432aSBrad Bishop for (auto& action : actions)
2917b33777bSBrad Bishop {
29207934a64SBrad Bishop action(_bus, *this);
2933d57f507SBrad Bishop }
29449aefb31SBrad Bishop }
29549aefb31SBrad Bishop
destroyObjects(const std::vector<const char * > & paths)296615b2a8fSBrad Bishop void Manager::destroyObjects(const std::vector<const char*>& paths)
2977b7e712cSBrad Bishop {
298a5cc34c2SBrad Bishop std::string p;
299a5cc34c2SBrad Bishop
3007b7e712cSBrad Bishop for (const auto& path : paths)
301656a7d00SBrad Bishop {
302a5cc34c2SBrad Bishop p.assign(_root);
303a5cc34c2SBrad Bishop p.append(path);
304a5cc34c2SBrad Bishop _bus.emit_object_removed(p.c_str());
305a5cc34c2SBrad Bishop _refs.erase(p);
306656a7d00SBrad Bishop }
3077b7e712cSBrad Bishop }
308656a7d00SBrad Bishop
createObjects(const std::map<sdbusplus::message::object_path,Object> & objs)309eb68a687SBrad Bishop void Manager::createObjects(
310eb68a687SBrad Bishop const std::map<sdbusplus::message::object_path, Object>& objs)
311eb68a687SBrad Bishop {
312cda036f7SBrad Bishop updateObjects(objs);
313eb68a687SBrad Bishop }
314eb68a687SBrad Bishop
getInterfaceHolder(const char * path,const char * interface)31525d54b51SBrad Bishop std::any& Manager::getInterfaceHolder(const char* path, const char* interface)
316b83a21eaSBrad Bishop {
31725d54b51SBrad Bishop return const_cast<std::any&>(
318615b2a8fSBrad Bishop const_cast<const Manager*>(this)->getInterfaceHolder(path, interface));
319b83a21eaSBrad Bishop }
320b83a21eaSBrad Bishop
getInterfaceHolder(const char * path,const char * interface) const32125d54b51SBrad Bishop const std::any& Manager::getInterfaceHolder(const char* path,
322615b2a8fSBrad Bishop const char* interface) const
323b83a21eaSBrad Bishop {
324b83a21eaSBrad Bishop std::string p{path};
325b83a21eaSBrad Bishop auto oit = _refs.find(_root + p);
326b83a21eaSBrad Bishop if (oit == _refs.end())
327615b2a8fSBrad Bishop throw std::runtime_error(_root + p + " was not found");
328b83a21eaSBrad Bishop
329b83a21eaSBrad Bishop auto& obj = oit->second;
330b83a21eaSBrad Bishop auto iit = obj.find(interface);
331b83a21eaSBrad Bishop if (iit == obj.end())
332615b2a8fSBrad Bishop throw std::runtime_error("interface was not found");
333b83a21eaSBrad Bishop
334150147aeSBrad Bishop return iit->second;
335b83a21eaSBrad Bishop }
336b83a21eaSBrad Bishop
restore()337b28990f3SDeepak Kodihalli void Manager::restore()
338b28990f3SDeepak Kodihalli {
339e6b21c74SKun Yi namespace fs = std::filesystem;
340b28990f3SDeepak Kodihalli
341b28990f3SDeepak Kodihalli if (!fs::exists(fs::path(PIM_PERSIST_PATH)))
342b28990f3SDeepak Kodihalli {
343b28990f3SDeepak Kodihalli return;
344b28990f3SDeepak Kodihalli }
345b28990f3SDeepak Kodihalli
346*7edafe06SPatrick Williams static const std::string remove = std::string(PIM_PERSIST_PATH) +
347*7edafe06SPatrick Williams INVENTORY_ROOT;
348b28990f3SDeepak Kodihalli
349b28990f3SDeepak Kodihalli std::map<sdbusplus::message::object_path, Object> objects;
350b28990f3SDeepak Kodihalli for (const auto& dirent :
351b28990f3SDeepak Kodihalli fs::recursive_directory_iterator(PIM_PERSIST_PATH))
352b28990f3SDeepak Kodihalli {
353b28990f3SDeepak Kodihalli const auto& path = dirent.path();
354b28990f3SDeepak Kodihalli if (fs::is_regular_file(path))
355b28990f3SDeepak Kodihalli {
356b28990f3SDeepak Kodihalli auto ifaceName = path.filename().string();
357b28990f3SDeepak Kodihalli auto objPath = path.parent_path().string();
358b28990f3SDeepak Kodihalli objPath.erase(0, remove.length());
359b28990f3SDeepak Kodihalli auto objit = objects.find(objPath);
360b28990f3SDeepak Kodihalli Interface propertyMap{};
361b28990f3SDeepak Kodihalli if (objects.end() != objit)
362b28990f3SDeepak Kodihalli {
363b28990f3SDeepak Kodihalli auto& object = objit->second;
364b28990f3SDeepak Kodihalli object.emplace(std::move(ifaceName), std::move(propertyMap));
365b28990f3SDeepak Kodihalli }
366b28990f3SDeepak Kodihalli else
367b28990f3SDeepak Kodihalli {
368b28990f3SDeepak Kodihalli Object object;
369b28990f3SDeepak Kodihalli object.emplace(std::move(ifaceName), std::move(propertyMap));
370b28990f3SDeepak Kodihalli objects.emplace(std::move(objPath), std::move(object));
371b28990f3SDeepak Kodihalli }
372b28990f3SDeepak Kodihalli }
373b28990f3SDeepak Kodihalli }
374b28990f3SDeepak Kodihalli if (!objects.empty())
375b28990f3SDeepak Kodihalli {
376b28990f3SDeepak Kodihalli auto restoreFromCache = true;
377b28990f3SDeepak Kodihalli updateObjects(objects, restoreFromCache);
37859521e87SMatt Spinler
37959521e87SMatt Spinler #ifdef CREATE_ASSOCIATIONS
38059521e87SMatt Spinler // There may be conditional associations waiting to be loaded
38159521e87SMatt Spinler // based on certain path/interface/property values. Now that
38259521e87SMatt Spinler // _refs contains all objects with their property values, check
38359521e87SMatt Spinler // which property values the conditions need and set them in the
38459521e87SMatt Spinler // condition structure entries, using the actualValue field. Then
38559521e87SMatt Spinler // the associations manager can check if the conditions are met.
38659521e87SMatt Spinler if (_associations.pendingCondition())
38759521e87SMatt Spinler {
38859521e87SMatt Spinler ObjectReferences::iterator refIt;
38959521e87SMatt Spinler InterfaceComposite::iterator ifaceIt;
39059521e87SMatt Spinler
39159521e87SMatt Spinler auto& conditions = _associations.getConditions();
39259521e87SMatt Spinler for (auto& condition : conditions)
39359521e87SMatt Spinler {
39459521e87SMatt Spinler refIt = _refs.find(_root + condition.path);
39559521e87SMatt Spinler if (refIt != _refs.end())
39659521e87SMatt Spinler {
39759521e87SMatt Spinler ifaceIt = refIt->second.find(condition.interface);
39859521e87SMatt Spinler }
39959521e87SMatt Spinler
40059521e87SMatt Spinler if ((refIt != _refs.end()) && (ifaceIt != refIt->second.end()))
40159521e87SMatt Spinler {
40259521e87SMatt Spinler const auto& maker = _makers.find(condition.interface);
40359521e87SMatt Spinler if (maker != _makers.end())
40459521e87SMatt Spinler {
40559521e87SMatt Spinler auto& getProperty =
40659521e87SMatt Spinler std::get<GetPropertyValueType>(maker->second);
40759521e87SMatt Spinler
408*7edafe06SPatrick Williams condition.actualValue = getProperty(condition.property,
409*7edafe06SPatrick Williams ifaceIt->second);
41059521e87SMatt Spinler }
41159521e87SMatt Spinler }
41259521e87SMatt Spinler }
41359521e87SMatt Spinler
41459521e87SMatt Spinler // Check if a property value in a condition matches an
41559521e87SMatt Spinler // actual property value just saved. If one did, now the
41659521e87SMatt Spinler // associations file is valid so create its associations.
41759521e87SMatt Spinler if (_associations.conditionMatch())
41859521e87SMatt Spinler {
419*7edafe06SPatrick Williams std::for_each(_refs.begin(), _refs.end(),
420*7edafe06SPatrick Williams [this](const auto& ref) {
42159521e87SMatt Spinler _associations.createAssociations(
42259521e87SMatt Spinler ref.first, _status != ManagerStatus::RUNNING);
42359521e87SMatt Spinler });
42459521e87SMatt Spinler }
42559521e87SMatt Spinler }
42659521e87SMatt Spinler #endif
427b28990f3SDeepak Kodihalli }
428b28990f3SDeepak Kodihalli }
429b28990f3SDeepak Kodihalli
43049aefb31SBrad Bishop } // namespace manager
43149aefb31SBrad Bishop } // namespace inventory
43249aefb31SBrad Bishop } // namespace phosphor
43349aefb31SBrad Bishop
43449aefb31SBrad Bishop // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
435