1*b6779846SJayashree Dhanapal #include "argument.hpp"
2*b6779846SJayashree Dhanapal #include "interfaces/internal_interface.hpp"
3*b6779846SJayashree Dhanapal 
4*b6779846SJayashree Dhanapal #include <phosphor-logging/lg2.hpp>
5*b6779846SJayashree Dhanapal #include <sdbusplus/bus.hpp>
6*b6779846SJayashree Dhanapal 
7*b6779846SJayashree Dhanapal #include <filesystem>
8*b6779846SJayashree Dhanapal 
9*b6779846SJayashree Dhanapal static constexpr auto devPath = "/sys/class/leds/";
10*b6779846SJayashree Dhanapal 
rootPathVerify(std::string path)11*b6779846SJayashree Dhanapal std::string rootPathVerify(std::string path)
12*b6779846SJayashree Dhanapal {
13*b6779846SJayashree Dhanapal     if (!path.starts_with(devPath))
14*b6779846SJayashree Dhanapal     {
15*b6779846SJayashree Dhanapal         lg2::error("Invalid sys path - {PATH}", "PATH", path);
16*b6779846SJayashree Dhanapal         throw std::invalid_argument("Invalid argument");
17*b6779846SJayashree Dhanapal     }
18*b6779846SJayashree Dhanapal 
19*b6779846SJayashree Dhanapal     if (!std::filesystem::exists(path))
20*b6779846SJayashree Dhanapal     {
21*b6779846SJayashree Dhanapal         lg2::error("Path does not exist - {PATH}", "PATH", path);
22*b6779846SJayashree Dhanapal         throw std::invalid_argument("Invalid argument");
23*b6779846SJayashree Dhanapal     }
24*b6779846SJayashree Dhanapal 
25*b6779846SJayashree Dhanapal     std::string led = path.substr(strlen(devPath));
26*b6779846SJayashree Dhanapal 
27*b6779846SJayashree Dhanapal     // path can contain multiple path separators, e.g.
28*b6779846SJayashree Dhanapal     // /sys/class/leds//identify
29*b6779846SJayashree Dhanapal 
30*b6779846SJayashree Dhanapal     while (led.starts_with("/"))
31*b6779846SJayashree Dhanapal     {
32*b6779846SJayashree Dhanapal         led = led.substr(1);
33*b6779846SJayashree Dhanapal     }
34*b6779846SJayashree Dhanapal 
35*b6779846SJayashree Dhanapal     return led;
36*b6779846SJayashree Dhanapal }
37*b6779846SJayashree Dhanapal 
addLed(std::string ledName)38*b6779846SJayashree Dhanapal void addLed(std::string ledName)
39*b6779846SJayashree Dhanapal {
40*b6779846SJayashree Dhanapal     lg2::debug("Adding LED name - {LEDNAME}", "LEDNAME", ledName);
41*b6779846SJayashree Dhanapal     try
42*b6779846SJayashree Dhanapal     {
43*b6779846SJayashree Dhanapal         auto bus = sdbusplus::bus::new_default();
44*b6779846SJayashree Dhanapal         auto method = bus.new_method_call(busName, ledPath, internalInterface,
45*b6779846SJayashree Dhanapal                                           ledAddMethod);
46*b6779846SJayashree Dhanapal 
47*b6779846SJayashree Dhanapal         method.append(ledName);
48*b6779846SJayashree Dhanapal         bus.call(method);
49*b6779846SJayashree Dhanapal     }
50*b6779846SJayashree Dhanapal     catch (const std::exception& e)
51*b6779846SJayashree Dhanapal     {
52*b6779846SJayashree Dhanapal         lg2::error("Unable to add LED name - {LEDNAME}", "LEDNAME", ledName);
53*b6779846SJayashree Dhanapal         throw e;
54*b6779846SJayashree Dhanapal     }
55*b6779846SJayashree Dhanapal }
56*b6779846SJayashree Dhanapal 
57*b6779846SJayashree Dhanapal /* Each LED udev event will trigger systemd service (sysfs-led@.service)
58*b6779846SJayashree Dhanapal  * Systemd service will invoke the binary (add-led-action) by passing LED
59*b6779846SJayashree Dhanapal  * name as argument.
60*b6779846SJayashree Dhanapal  *
61*b6779846SJayashree Dhanapal  * Usage: /usr/libexec/phosphor-led-sysfs/add-led-action [options]
62*b6779846SJayashree Dhanapal  * Options:
63*b6779846SJayashree Dhanapal  *  --help           Print this menu
64*b6779846SJayashree Dhanapal  *  --path=<path>    absolute path of LED in sysfs; like /sys/class/leds/<name>
65*b6779846SJayashree Dhanapal  *
66*b6779846SJayashree Dhanapal  */
67*b6779846SJayashree Dhanapal 
main(int argc,char * argv[])68*b6779846SJayashree Dhanapal int main(int argc, char* argv[])
69*b6779846SJayashree Dhanapal {
70*b6779846SJayashree Dhanapal     // Read arguments.
71*b6779846SJayashree Dhanapal     auto options = phosphor::led::ArgumentParser(argc, argv);
72*b6779846SJayashree Dhanapal 
73*b6779846SJayashree Dhanapal     // Parse out Path argument.
74*b6779846SJayashree Dhanapal     const auto& path = options["path"];
75*b6779846SJayashree Dhanapal 
76*b6779846SJayashree Dhanapal     if (path.empty())
77*b6779846SJayashree Dhanapal     {
78*b6779846SJayashree Dhanapal         phosphor::led::ArgumentParser::usage(argv);
79*b6779846SJayashree Dhanapal 
80*b6779846SJayashree Dhanapal         lg2::error("Argument parser error : Path not specified");
81*b6779846SJayashree Dhanapal         throw std::invalid_argument("Invalid argument");
82*b6779846SJayashree Dhanapal     }
83*b6779846SJayashree Dhanapal 
84*b6779846SJayashree Dhanapal     std::string name = rootPathVerify(path);
85*b6779846SJayashree Dhanapal 
86*b6779846SJayashree Dhanapal     addLed(name);
87*b6779846SJayashree Dhanapal 
88*b6779846SJayashree Dhanapal     return 0;
89*b6779846SJayashree Dhanapal }
90