blob: 8b9a22d89fd19c001cda5f4425c84610a3f3ae6a [file] [log] [blame]
Vishwanatha Subbanna835571e2016-11-30 11:29:30 +05301/**
2 * Copyright © 2016 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093017#include "config.h"
18
Vishwanatha Subbanna835571e2016-11-30 11:29:30 +053019#include "argument.hpp"
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053020#include "physical.hpp"
Andrew Jeffery42e02d32018-05-24 13:34:05 +093021#include "sysfs.hpp"
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093022
23#include <algorithm>
Alexander Soldatov97ddb722019-04-16 09:10:00 +030024#include <boost/algorithm/string.hpp>
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +093025#include <iostream>
26#include <string>
Vishwanatha Subbanna835571e2016-11-30 11:29:30 +053027
28static void ExitWithError(const char* err, char** argv)
29{
30 phosphor::led::ArgumentParser::usage(argv);
31 std::cerr << std::endl;
32 std::cerr << "ERROR: " << err << std::endl;
33 exit(-1);
34}
35
Alexander Soldatov97ddb722019-04-16 09:10:00 +030036struct LedDescr
37{
38 std::string devicename;
39 std::string color;
40 std::string function;
41};
42
43/** @brief parse LED name in sysfs
44 * Parse sysfs LED name in format "devicename:colour:function"
45 * or "devicename:colour" or "devicename" and sets corresponding
46 * fields in LedDescr struct.
47 *
48 * @param[in] name - LED name in sysfs
49 * @param[out] ledDescr - LED description
50 */
51void getLedDescr(const std::string& name, LedDescr& ledDescr)
52{
53 std::vector<std::string> words;
54 boost::split(words, name, boost::is_any_of(":"));
55 try
56 {
57 ledDescr.devicename = words.at(0);
58 ledDescr.color = words.at(1);
59 ledDescr.function = words.at(2);
60 }
61 catch (const std::out_of_range&)
62 {
63 return;
64 }
65}
66
67/** @brief generates LED DBus name from LED description
68 *
69 * @param[in] name - LED description
70 * @return - DBus LED name
71 */
72std::string getDbusName(const LedDescr& ledDescr)
73{
74 std::vector<std::string> words;
75 words.emplace_back(ledDescr.devicename);
76 if (!ledDescr.function.empty())
77 words.emplace_back(ledDescr.function);
78 if (!ledDescr.color.empty())
79 words.emplace_back(ledDescr.color);
80 return boost::join(words, "_");
81}
82
Vishwanatha Subbanna835571e2016-11-30 11:29:30 +053083int main(int argc, char** argv)
84{
Andrew Jeffery42e02d32018-05-24 13:34:05 +093085 namespace fs = std::experimental::filesystem;
86
Vishwanatha Subbanna835571e2016-11-30 11:29:30 +053087 // Read arguments.
88 auto options = phosphor::led::ArgumentParser(argc, argv);
89
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +053090 // Parse out Path argument.
Vishwanatha Subbanna835571e2016-11-30 11:29:30 +053091 auto path = std::move((options)["path"]);
92 if (path == phosphor::led::ArgumentParser::empty_string)
93 {
94 ExitWithError("Path not specified.", argv);
95 }
96
Vishwanatha Subbannaf9de54b2017-05-25 21:06:33 +053097 // If the LED has a hyphen in the name like: "one-two", then it gets passed
98 // as /one/two/ as opposed to /one-two to the service file. There is a
99 // change needed in systemd to solve this issue and hence putting in this
100 // work-around.
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530101
Vishwanatha Subbannaf9de54b2017-05-25 21:06:33 +0530102 // Since this application always gets invoked as part of a udev rule,
103 // it is always guaranteed to get /sys/class/leds/one/two
Alexander Soldatov97ddb722019-04-16 09:10:00 +0300104 // and we can go beyond leds/ to get the actual LED name.
Vishwanatha Subbannaf9de54b2017-05-25 21:06:33 +0530105 // Refer: systemd/systemd#5072
106
107 // On an error, this throws an exception and terminates.
108 auto name = path.substr(strlen(DEVPATH));
109
110 // LED names may have a hyphen and that would be an issue for
111 // dbus paths and hence need to convert them to underscores.
112 std::replace(name.begin(), name.end(), '/', '-');
Andrew Jefferycd3b05e2018-05-24 13:05:30 +0930113 path = DEVPATH + name;
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530114
Vishwanatha Subbanna413fd342017-03-30 17:25:18 +0530115 // Convert to lowercase just in case some are not and that
116 // we follow lowercase all over
117 std::transform(name.begin(), name.end(), name.begin(), ::tolower);
118
119 // LED names may have a hyphen and that would be an issue for
120 // dbus paths and hence need to convert them to underscores.
121 std::replace(name.begin(), name.end(), '-', '_');
122
Alexander Soldatov97ddb722019-04-16 09:10:00 +0300123 // Convert LED name in sysfs into DBus name
124 LedDescr ledDescr;
125 getLedDescr(name, ledDescr);
126 name = getDbusName(ledDescr);
127
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530128 // Unique bus name representing a single LED.
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +0930129 auto busName = std::string(BUSNAME) + '.' + name;
130 auto objPath = std::string(OBJPATH) + '/' + name;
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530131
132 // Get a handle to system dbus.
Andrew Jefferycd3b05e2018-05-24 13:05:30 +0930133 auto bus = sdbusplus::bus::new_default();
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530134
135 // Add systemd object manager.
136 sdbusplus::server::manager::manager(bus, objPath.c_str());
137
138 // Create the Physical LED objects for directing actions.
139 // Need to save this else sdbusplus destructor will wipe this off.
Andrew Jeffery42e02d32018-05-24 13:34:05 +0930140 phosphor::led::SysfsLed sled{fs::path(path)};
Alexander Soldatov97ddb722019-04-16 09:10:00 +0300141 phosphor::led::Physical led(bus, objPath, sled, ledDescr.color);
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530142
143 /** @brief Claim the bus */
144 bus.request_name(busName.c_str());
145
146 /** @brief Wait for client requests */
Andrew Jefferyc41bf5b2018-05-25 16:39:22 +0930147 while (true)
Vishwanatha Subbanna75b55102016-11-30 14:20:53 +0530148 {
149 // Handle dbus message / signals discarding unhandled
150 bus.process_discard();
151 bus.wait();
152 }
Vishwanatha Subbanna835571e2016-11-30 11:29:30 +0530153 return 0;
154}