Add LED grouping support
This enables creating custom groups and participating LEDs so that it can later
be generated from MRW. For each of the group, a dbus object is created which
will announce LED actions.
Fixes openbmc/openbmc#550
Change-Id: I7a56d08755288dcfce45ee4c6d6b6c5e5aa454f7
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/led-manager.cpp b/led-manager.cpp
new file mode 100644
index 0000000..8bc1751
--- /dev/null
+++ b/led-manager.cpp
@@ -0,0 +1,119 @@
+#include <iostream>
+#include <cstring>
+#include <sdbusplus/vtable.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/bus.hpp>
+#include "led-manager.hpp"
+#include "led-gen.hpp"
+
+namespace phosphor
+{
+
+namespace led
+{
+
+/** @brief Called when the group's property is read
+ * Signature as needed by sd_bus
+ */
+int getGroupState(sd_bus *bus, const char *path, const char *interface,
+ const char *property, sd_bus_message *reply,
+ void *data, sd_bus_error* error)
+{
+ auto group = strrchr(path, '/');
+ if (group)
+ {
+ // Removing the starting '/' in /group
+ group++;
+ }
+
+ //TODO : Need to see how to represent group specific asserted state
+ // May be a new tuple / map ?
+ sd_bus_message_append(reply, "b", 0);
+ return 0;
+}
+
+/** @brief Called when the group's asserted state is updated
+ * Signature as needed by sd_bus
+ */
+int setGroupState(sd_bus *bus, const char *path, const char *interface,
+ const char *property, sd_bus_message *value,
+ void *data, sd_bus_error* error)
+{
+ bool state {};
+ auto group = strrchr(path, '/');
+ if (group)
+ {
+ // Removing the starting '/' in /group
+ group++;
+ }
+
+ auto msg = sdbusplus::message::message(value);
+ sd_bus_message_ref(value);
+ msg.read(state);
+
+ //TODO : Need to see how to represent group specific asserted state
+ // May be a new tuple / map ?
+ return 1;
+}
+
+/** @brief Users having to assert a group will just turn this property to 1
+ * similarly, setting this property to 0 will deassert the group
+ */
+constexpr sdbusplus::vtable::vtable_t led_vtable[] =
+{
+ sdbusplus::vtable::start(),
+ sdbusplus::vtable::property("Assert", "b",
+ getGroupState, setGroupState, sdbusplus::vtable::property_::emits_change),
+ sdbusplus::vtable::end()
+};
+
+/** @brief Initialize the bus and announce services */
+Manager::Manager(const char* busName,
+ const char* objPath,
+ const char* intfName) :
+ iv_bus(sdbusplus::bus::new_system()),
+ objManager(iv_bus, objPath)
+{
+ // Like /org/openbmc/ledmanager/groups/
+ auto path = std::string(objPath) + "/";
+
+ /** Now create so many dbus objects as there are groups */
+ for (auto &grp: Manager::cv_LedMap)
+ {
+ auto grpPath = path + grp.first;
+ intfContainer.emplace_back(sdbusplus::server::interface::interface(
+ iv_bus, grpPath.c_str(), intfName, led_vtable, this));
+
+ // These are now set of structs having LED name and the action. Do not
+ // have anything to be done here at the moment but need to create a
+ // mapping between led names to device strigs eventually
+ //for (auto &set: grp.second)
+ //{
+
+ //}
+ }
+ // Once done, claim the bus and systemd will
+ // consider this service started
+ iv_bus.request_name(busName);
+}
+
+/** @brief Wait for client requests */
+void Manager::run()
+{
+ while(true)
+ {
+ try
+ {
+ iv_bus.process_discard();
+ iv_bus.wait();
+ }
+ catch (std::exception &e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+ }
+}
+
+} // namespace led
+
+} // namespace phosphor