control: Add interfacesRemoved signal support
Subscribe to and handle interfacesRemoved signals to trigger event
actions.
Change-Id: I270dc02bfa78c1801c545712710b27a3d2ba2180
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/json/triggers/handlers.hpp b/control/json/triggers/handlers.hpp
index 102a214..d33d00d 100644
--- a/control/json/triggers/handlers.hpp
+++ b/control/json/triggers/handlers.hpp
@@ -91,6 +91,39 @@
std::get<Prop>(obj), itProp->second);
return true;
}
+
+ /**
+ * @brief Processes an interfaces removed signal and removes the interface
+ * (including its properties) from the object cache on the manager
+ *
+ * @param[in] msg - The sdbusplus signal message
+ * @param[in] obj - Object data associated with the signal
+ * @param[in] mgr - Manager that stores the object cache
+ */
+ static bool interfacesRemoved(message& msg, const SignalObject& obj,
+ Manager& mgr)
+ {
+ sdbusplus::message::object_path op;
+ msg.read(op);
+ if (static_cast<const std::string&>(op) != std::get<Path>(obj))
+ {
+ // Path name does not match object's path
+ return false;
+ }
+
+ std::vector<std::string> intfs;
+ msg.read(intfs);
+ auto itIntf =
+ std::find(intfs.begin(), intfs.end(), std::get<Intf>(obj));
+ if (itIntf == intfs.cend())
+ {
+ // Object's interface not in list of interfaces removed
+ return false;
+ }
+
+ mgr.removeInterface(std::get<Path>(obj), std::get<Intf>(obj));
+ return true;
+ }
};
} // namespace phosphor::fan::control::json::trigger::signal
diff --git a/control/json/triggers/signal.cpp b/control/json/triggers/signal.cpp
index 375ec0f..683acc3 100644
--- a/control/json/triggers/signal.cpp
+++ b/control/json/triggers/signal.cpp
@@ -143,6 +143,32 @@
}
}
+void interfacesRemoved(Manager* mgr, const std::string& eventName,
+ std::unique_ptr<ActionBase>& action)
+{
+ // Groups are optional, but a signal triggered event with no groups
+ // will do nothing since signals require a group
+ for (const auto& group : action->getGroups())
+ {
+ for (const auto& member : group.getMembers())
+ {
+ // Setup interfaces added signal handler on the group member
+ const auto match = rules::interfacesRemoved(member);
+ SignalPkg signalPkg = {Handlers::interfacesRemoved,
+ SignalObject(std::cref(member),
+ std::cref(group.getInterface()),
+ std::cref(group.getProperty())),
+ SignalActions({action})};
+ auto isSameSig = [&intf = group.getInterface()](SignalPkg& pkg) {
+ auto& obj = std::get<SignalObject>(pkg);
+ return intf == std::get<Intf>(obj);
+ };
+
+ subscribe(match, std::move(signalPkg), isSameSig, mgr);
+ }
+ }
+}
+
void triggerSignal(const json& jsonObj, const std::string& eventName,
Manager* mgr,
std::vector<std::unique_ptr<ActionBase>>& actions)
diff --git a/control/json/triggers/signal.hpp b/control/json/triggers/signal.hpp
index 32a9021..f382828 100644
--- a/control/json/triggers/signal.hpp
+++ b/control/json/triggers/signal.hpp
@@ -61,6 +61,16 @@
void interfacesAdded(Manager* mgr, const std::string& eventName,
std::unique_ptr<ActionBase>& action);
+/**
+ * @brief Subscribes to an interfacesRemoved signal
+ *
+ * @param[in] mgr - Pointer to manager of the trigger
+ * @param[in] eventName - Name of event associated to the signal
+ * @param[in] action - Action to be run when signal is received
+ */
+void interfacesRemoved(Manager* mgr, const std::string& eventName,
+ std::unique_ptr<ActionBase>& action);
+
// Match setup function for signals
using SignalMatch = std::function<void(Manager*, const std::string&,
std::unique_ptr<ActionBase>& action)>;
@@ -68,7 +78,8 @@
/* Supported signals to their corresponding match setup functions */
static const std::unordered_map<std::string, SignalMatch> signals = {
{"properties_changed", propertiesChanged},
- {"interfaces_added", interfacesAdded}};
+ {"interfaces_added", interfacesAdded},
+ {"interfaces_removed", interfacesRemoved}};
/**
* @brief Trigger to process an event after a signal is received