control: Add nameOwnerChanged signal support
Subscribe to and handle nameOwnerChanged signals to trigger event
actions.
Change-Id: I7d5a472d31a2af5297581c18d84ef4ac897ff3ea
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/json/triggers/handlers.hpp b/control/json/triggers/handlers.hpp
index d33d00d..f3b1a23 100644
--- a/control/json/triggers/handlers.hpp
+++ b/control/json/triggers/handlers.hpp
@@ -124,6 +124,36 @@
mgr.removeInterface(std::get<Path>(obj), std::get<Intf>(obj));
return true;
}
+
+ /**
+ * @brief Processes a name owner changed signal and updates the service's
+ * owner state
+ *
+ * @param[in] msg - The sdbusplus signal message
+ * @param[in] obj - Object data associated with the signal
+ * @param[in] mgr - Manager that stores the service's owner state
+ */
+ static bool nameOwnerChanged(message& msg, const SignalObject& obj,
+ Manager& mgr)
+ {
+ bool hasOwner = false;
+
+ std::string serv;
+ msg.read(serv);
+
+ std::string oldOwner;
+ msg.read(oldOwner);
+
+ std::string newOwner;
+ msg.read(newOwner);
+ if (!newOwner.empty())
+ {
+ hasOwner = true;
+ }
+
+ mgr.setOwner(std::get<Path>(obj), std::get<Intf>(obj), serv, hasOwner);
+ return true;
+ }
};
} // namespace phosphor::fan::control::json::trigger::signal
diff --git a/control/json/triggers/signal.cpp b/control/json/triggers/signal.cpp
index 683acc3..cd05756 100644
--- a/control/json/triggers/signal.cpp
+++ b/control/json/triggers/signal.cpp
@@ -169,6 +169,50 @@
}
}
+void nameOwnerChanged(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())
+ {
+ auto serv = Manager::getService(member, group.getInterface());
+ if (!serv.empty())
+ {
+ // Setup name owner changed signal handler on the group
+ // member's service
+ const auto match = rules::nameOwnerChanged(serv);
+ SignalPkg signalPkg = {
+ Handlers::nameOwnerChanged,
+ SignalObject(std::cref(member),
+ std::cref(group.getInterface()),
+ std::cref(group.getProperty())),
+ SignalActions({action})};
+ // If signal match already exists, then the service will be the
+ // same so add action to be run
+ auto isSameSig = [](SignalPkg& pkg) { return true; };
+
+ subscribe(match, std::move(signalPkg), isSameSig, mgr);
+ }
+ else
+ {
+ // Unable to construct nameOwnerChanged match string
+ // Path and/or interface configured does not exist on dbus yet?
+ // TODO How to handle this? Create timer to keep checking for
+ // service to appear? When to stop checking?
+ log<level::ERR>(
+ fmt::format(
+ "Event '{}' will not be triggered by name owner "
+ "changed signals from service of path {}, interface {}",
+ eventName, member, group.getInterface())
+ .c_str());
+ }
+ }
+ }
+}
+
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 f382828..61b03e3 100644
--- a/control/json/triggers/signal.hpp
+++ b/control/json/triggers/signal.hpp
@@ -71,6 +71,16 @@
void interfacesRemoved(Manager* mgr, const std::string& eventName,
std::unique_ptr<ActionBase>& action);
+/**
+ * @brief Subscribes to a nameOwnerChanged 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 nameOwnerChanged(Manager* mgr, const std::string& eventName,
+ std::unique_ptr<ActionBase>& actions);
+
// Match setup function for signals
using SignalMatch = std::function<void(Manager*, const std::string&,
std::unique_ptr<ActionBase>& action)>;
@@ -79,7 +89,8 @@
static const std::unordered_map<std::string, SignalMatch> signals = {
{"properties_changed", propertiesChanged},
{"interfaces_added", interfacesAdded},
- {"interfaces_removed", interfacesRemoved}};
+ {"interfaces_removed", interfacesRemoved},
+ {"name_owner_changed", nameOwnerChanged}};
/**
* @brief Trigger to process an event after a signal is received