xref: /openbmc/phosphor-led-sysfs/sysfs.cpp (revision b6779846)
1 /**
2  * Copyright © 2019 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 
17 #include "sysfs.hpp"
18 
19 #include <fstream>
20 #include <iostream>
21 #include <string>
22 
23 namespace fs = std::filesystem;
24 
25 namespace phosphor
26 {
27 namespace led
28 {
29 template <typename T>
30 T getSysfsAttr(const fs::path& path);
31 
32 template <>
33 std::string getSysfsAttr(const fs::path& path)
34 {
35     std::string content;
36     std::ifstream file(path);
37     std::getline(file, content);
38     return content;
39 }
40 
41 template <>
42 unsigned long getSysfsAttr(const fs::path& path)
43 {
44     std::string content = getSysfsAttr<std::string>(path);
45     return std::strtoul(content.c_str(), nullptr, 0);
46 }
47 
48 template <typename T>
49 void setSysfsAttr(const fs::path& path, const T& value)
50 {
51     std::ofstream file(path);
52     file << value;
53 }
54 
55 unsigned long SysfsLed::getBrightness()
56 {
57     return getSysfsAttr<unsigned long>(root / attrBrightness);
58 }
59 
60 void SysfsLed::setBrightness(unsigned long brightness)
61 {
62     setSysfsAttr<unsigned long>(root / attrBrightness, brightness);
63 }
64 
65 unsigned long SysfsLed::getMaxBrightness()
66 {
67     return getSysfsAttr<unsigned long>(root / attrMaxBrightness);
68 }
69 
70 std::string SysfsLed::getTrigger()
71 {
72     // Example content for `/sys/class/leds/<led_name>/trigger`:
73     //
74     // * `[none] timer heartbeat default-on`
75     // * `none [timer] heartbeat default-on`
76     //
77     // Refer to:
78     //
79     // * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/ABI/testing/sysfs-class-led?h=v6.6#n71
80     // * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/ABI/stable/sysfs-block?h=v6.6#n558
81     std::string triggerLine = getSysfsAttr<std::string>(root / attrTrigger);
82     size_t start = triggerLine.find_first_of('[');
83     size_t end = triggerLine.find_first_of(']');
84     if (start >= end || start == std::string::npos || end == std::string::npos)
85     {
86         return "none";
87     }
88 
89     std::string rc = triggerLine.substr(start + 1, end - start - 1);
90     if (rc.empty())
91     {
92         return "none";
93     }
94 
95     return rc;
96 }
97 
98 void SysfsLed::setTrigger(const std::string& trigger)
99 {
100     setSysfsAttr<std::string>(root / attrTrigger, trigger);
101 }
102 
103 unsigned long SysfsLed::getDelayOn()
104 {
105     return getSysfsAttr<unsigned long>(root / attrDelayOn);
106 }
107 
108 void SysfsLed::setDelayOn(unsigned long ms)
109 {
110     setSysfsAttr<unsigned long>(root / attrDelayOn, ms);
111 }
112 
113 unsigned long SysfsLed::getDelayOff()
114 {
115     return getSysfsAttr<unsigned long>(root / attrDelayOff);
116 }
117 
118 void SysfsLed::setDelayOff(unsigned long ms)
119 {
120     setSysfsAttr<unsigned long>(root / attrDelayOff, ms);
121 }
122 } // namespace led
123 } // namespace phosphor
124