Create a new Dbus interface for LED
A new Dbus API method is created in the phosphor-led-sysfs repository
under xyz.openbmc_project.Led.Sysfs.Internal interface name to add or
remove the LED, which will be coming from each udev LED event to
create the LED dbus path.
xyz.openbmc_project.Led.Sysfs.Internal interface
.AddLED method
.RemoveLED method
This Dbus API method is added to support the multihost physical
LEDs design.
https://gerrit.openbmc.org/c/openbmc/docs/+/55230
Also support a executable for LED DBUS API method
Added a new executable for LED DBUS API method to communicate
between udev and application.
Executable will call Dbus API method to pass LED name as argument from
udev, after the primary service started.
Tested : Tested the dbus method is invoked for each LED udev event
in Facebook YosemiteV2 platform.
Signed-off-by: Jayashree Dhanapal <jayashree-d@hcl.com>
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: I3fa6c3caa130b2b71ebc9fe8d69541c029f516ab
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/add_led_action.cpp b/add_led_action.cpp
new file mode 100644
index 0000000..01b14da
--- /dev/null
+++ b/add_led_action.cpp
@@ -0,0 +1,89 @@
+#include "argument.hpp"
+#include "interfaces/internal_interface.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus.hpp>
+
+#include <filesystem>
+
+static constexpr auto devPath = "/sys/class/leds/";
+
+std::string rootPathVerify(std::string path)
+{
+ if (!path.starts_with(devPath))
+ {
+ lg2::error("Invalid sys path - {PATH}", "PATH", path);
+ throw std::invalid_argument("Invalid argument");
+ }
+
+ if (!std::filesystem::exists(path))
+ {
+ lg2::error("Path does not exist - {PATH}", "PATH", path);
+ throw std::invalid_argument("Invalid argument");
+ }
+
+ std::string led = path.substr(strlen(devPath));
+
+ // path can contain multiple path separators, e.g.
+ // /sys/class/leds//identify
+
+ while (led.starts_with("/"))
+ {
+ led = led.substr(1);
+ }
+
+ return led;
+}
+
+void addLed(std::string ledName)
+{
+ lg2::debug("Adding LED name - {LEDNAME}", "LEDNAME", ledName);
+ try
+ {
+ auto bus = sdbusplus::bus::new_default();
+ auto method = bus.new_method_call(busName, ledPath, internalInterface,
+ ledAddMethod);
+
+ method.append(ledName);
+ bus.call(method);
+ }
+ catch (const std::exception& e)
+ {
+ lg2::error("Unable to add LED name - {LEDNAME}", "LEDNAME", ledName);
+ throw e;
+ }
+}
+
+/* Each LED udev event will trigger systemd service (sysfs-led@.service)
+ * Systemd service will invoke the binary (add-led-action) by passing LED
+ * name as argument.
+ *
+ * Usage: /usr/libexec/phosphor-led-sysfs/add-led-action [options]
+ * Options:
+ * --help Print this menu
+ * --path=<path> absolute path of LED in sysfs; like /sys/class/leds/<name>
+ *
+ */
+
+int main(int argc, char* argv[])
+{
+ // Read arguments.
+ auto options = phosphor::led::ArgumentParser(argc, argv);
+
+ // Parse out Path argument.
+ const auto& path = options["path"];
+
+ if (path.empty())
+ {
+ phosphor::led::ArgumentParser::usage(argv);
+
+ lg2::error("Argument parser error : Path not specified");
+ throw std::invalid_argument("Invalid argument");
+ }
+
+ std::string name = rootPathVerify(path);
+
+ addLed(name);
+
+ return 0;
+}