diff options
author | Matthew Barth <msbarth@us.ibm.com> | 2017-04-12 13:48:29 -0500 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2017-05-15 16:58:09 -0400 |
commit | 240bf332d20c31be5abe066945012542d94f5333 (patch) | |
tree | 64d28e1df3c88b9e170214674a000807126bb509 | |
parent | e6af23313890b82c4fca4d61ec1d2d9ff4817870 (diff) | |
download | phosphor-dbus-monitor-240bf332d20c31be5abe066945012542d94f5333.tar.gz phosphor-dbus-monitor-240bf332d20c31be5abe066945012542d94f5333.zip |
Add support for processing signal event triggers
Process signal event triggers' list of conditions on a group and perform
the defined actions.
This re-uses the following struct directly from
phosphor-inventory-manager:
--struct PropertyChangedCondition
Change-Id: I98552f3d168cfcd9f0c1c357289b7000374ae60e
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
-rw-r--r-- | src/functor.hpp | 63 | ||||
-rw-r--r-- | src/monitor.cpp | 32 | ||||
-rw-r--r-- | src/monitor.hpp | 14 |
3 files changed, 109 insertions, 0 deletions
diff --git a/src/functor.hpp b/src/functor.hpp index c2c586e..b3ad9a0 100644 --- a/src/functor.hpp +++ b/src/functor.hpp @@ -23,6 +23,59 @@ auto make_action(T&& action) return Action(std::forward<T>(action)); } +template <typename T, typename U> +struct PropertyChangedCondition +{ + PropertyChangedCondition() = delete; + ~PropertyChangedCondition() = default; + PropertyChangedCondition(const PropertyChangedCondition&) = default; + PropertyChangedCondition& operator=(const PropertyChangedCondition&) = + default; + PropertyChangedCondition(PropertyChangedCondition&&) = default; + PropertyChangedCondition& operator=(PropertyChangedCondition&&) = + default; + PropertyChangedCondition(const char* iface, const char* property, + U&& condition) : + _iface(iface), + _property(property), + _condition(std::forward<U>(condition)) { } + + /** @brief Test a property value. + * + * Extract the property from the PropertiesChanged + * message and run the condition test. + */ + bool operator()( + sdbusplus::bus::bus&, + sdbusplus::message::message& msg, + Monitor&) const + { + std::map<std::string, sdbusplus::message::variant<T>> properties; + const char* iface = nullptr; + + msg.read(iface); + if (!iface || strcmp(iface, _iface)) + { + return false; + } + + msg.read(properties); + auto it = properties.find(_property); + if (it == properties.cend()) + { + return false; + } + + return _condition( + std::forward<T>(it->second.template get<T>())); + } + +private: + const char* _iface; + const char* _property; + U _condition; +}; + struct PropertyConditionBase { PropertyConditionBase() = delete; @@ -125,6 +178,16 @@ private: }; template <typename T, typename U> +auto propertySignal(const char* iface, + const char* property, + U&& condition) +{ + return PropertyChangedCondition<T, U>(iface, + property, + std::move(condition)); +} + +template <typename T, typename U> auto propertyStart(const char* path, const char* iface, const char* property, diff --git a/src/monitor.cpp b/src/monitor.cpp index 2864924..aeb1fe5 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -16,7 +16,26 @@ const std::vector<std::tuple<std::vector<std::shared_ptr<Event>>, Monitor::Monitor(sdbusplus::bus::bus& bus) : bus(bus) { + // Process thru given events that are type 'signal' + for (auto& event : events) + { + for (auto& pEvent : std::get<std::vector<std::shared_ptr<Event>>>(event)) + { + if (pEvent->trigger != Event::Trigger::SIGNAL) + { + continue; + } + auto signalEvent = static_cast<SignalEvent*>(pEvent.get()); + eventArgs.emplace_back(std::make_unique<eventArg>(this, + signalEvent, + &event)); + matches.emplace_back(bus, + signalEvent->signature, + handleSignal, + eventArgs.back().get()); + } + } } void Monitor::processStart() noexcept @@ -36,6 +55,19 @@ void Monitor::processStart() noexcept } } +int Monitor::handleSignal(sd_bus_message* msg, + void* data, + sd_bus_error* err) +{ + auto sdbpMsg = sdbusplus::message::message(msg); + auto& eventArg = *static_cast<Monitor::eventArg*>(data); + std::get<0>(eventArg)->handleEvent( + sdbpMsg, + static_cast<const SignalEvent&>(*std::get<1>(eventArg)), + *std::get<2>(eventArg)); + return 0; +} + void Monitor::handleEvent(sdbusplus::message::message& msg, const Event& event, const std::tuple<std::vector<std::shared_ptr<Event>>, diff --git a/src/monitor.hpp b/src/monitor.hpp index aca64d8..5256582 100644 --- a/src/monitor.hpp +++ b/src/monitor.hpp @@ -30,6 +30,12 @@ class Monitor const std::tuple<std::vector<std::shared_ptr<Event>>, std::vector<Action>>& eventDef); + using eventArg = std::tuple<Monitor*, + const SignalEvent*, + const std::tuple< + std::vector<std::shared_ptr<Event>>, + std::vector<Action>>*>; + private: sdbusplus::bus::bus& bus; @@ -37,6 +43,14 @@ class Monitor std::tuple<std::vector<std::shared_ptr<Event>>, std::vector<Action>>> events; + std::vector<std::unique_ptr<eventArg>> eventArgs; + + std::vector<sdbusplus::server::match::match> matches; + + static int handleSignal(sd_bus_message* msg, + void* data, + sd_bus_error* err); + }; } // namespace monitoring |