xref: /openbmc/openpower-occ-control/occ_device.cpp (revision 37abe9be91df2bb173c9642a2740a425904d7921)
1 #include "occ_device.hpp"
2 
3 #include "occ_manager.hpp"
4 #include "occ_status.hpp"
5 
6 #include <phosphor-logging/lg2.hpp>
7 
8 #include <filesystem>
9 #include <iostream>
10 
11 namespace open_power
12 {
13 namespace occ
14 {
15 
setActive(bool active)16 void Device::setActive(bool active)
17 {
18     std::string data = active ? "1" : "0";
19     auto activeFile = devPath / "occ_active";
20     try
21     {
22         write(activeFile, data);
23     }
24     catch (const std::exception& e)
25     {
26         lg2::error("Failed to set {DEVICE} active: {ERROR}", "DEVICE", devPath,
27                    "ERROR", e.what());
28     }
29 }
30 
getPathBack(const fs::path & path)31 std::string Device::getPathBack(const fs::path& path)
32 {
33     if (path.empty())
34     {
35         return std::string();
36     }
37 
38     // Points to the last element in the path
39     auto conf = --path.end();
40 
41     if (conf->empty() && conf != path.begin())
42     {
43         return *(--conf);
44     }
45     else
46     {
47         return *conf;
48     }
49 }
50 
active() const51 bool Device::active() const
52 {
53     return readBinary("occ_active");
54 }
55 
master() const56 bool Device::master() const
57 {
58     return readBinary("occ_master");
59 }
60 
readBinary(const std::string & fileName) const61 bool Device::readBinary(const std::string& fileName) const
62 {
63     int v = 0;
64     if (statusObject.occActive())
65     {
66         auto filePath = devPath / fileName;
67         std::ifstream file(filePath, std::ios::in);
68         if (!file)
69         {
70             return false;
71         }
72 
73         file >> v;
74         file.close();
75     }
76     return v == 1;
77 }
78 
errorCallback(int error)79 void Device::errorCallback(int error)
80 {
81     if (error)
82     {
83         if (error != -EHOSTDOWN)
84         {
85             fs::path p = devPath;
86             if (fs::is_symlink(p))
87             {
88                 p = fs::read_symlink(p);
89             }
90             statusObject.deviceError(
91                 Error::Descriptor("org.open_power.OCC.Device.Error.ReadFailure",
92                                   error, p.c_str()));
93         }
94         else
95         {
96             statusObject.deviceError(Error::Descriptor(SAFE_ERROR_PATH));
97         }
98     }
99 }
100 
presenceCallback(int)101 void Device::presenceCallback(int)
102 {
103     statusObject.deviceError(Error::Descriptor(PRESENCE_ERROR_PATH));
104 }
105 
106 #ifdef PLDM
timeoutCallback(int error)107 void Device::timeoutCallback(int error)
108 {
109     if (error)
110     {
111         managerObject.sbeTimeout(instance);
112     }
113 }
114 #endif
115 
throttleProcTempCallback(int error)116 void Device::throttleProcTempCallback(int error)
117 {
118     statusObject.throttleProcTemp(error);
119     // Update the processor throttle on dbus
120     statusObject.updateThrottle(error, THROTTLED_THERMAL);
121 }
122 
throttleProcPowerCallback(int error)123 void Device::throttleProcPowerCallback(int error)
124 {
125     statusObject.throttleProcPower(error);
126     // Update the processor throttle on dbus
127     statusObject.updateThrottle(error, THROTTLED_POWER);
128 }
129 
throttleMemTempCallback(int error)130 void Device::throttleMemTempCallback(int error)
131 {
132     statusObject.throttleMemTemp(error);
133 }
134 
getFilenameByRegex(fs::path basePath,const std::regex & expr) const135 fs::path Device::getFilenameByRegex(fs::path basePath,
136                                     const std::regex& expr) const
137 {
138     try
139     {
140         for (auto& file : fs::directory_iterator(basePath))
141         {
142             if (std::regex_search(file.path().string(), expr))
143             {
144                 // Found match
145                 return file;
146             }
147         }
148     }
149     catch (const fs::filesystem_error& e)
150     {
151         lg2::error("getFilenameByRegex: Failed to get filename: {ERROR}",
152                    "ERROR", e.what());
153     }
154 
155     // Return empty path
156     return fs::path{};
157 }
158 
159 } // namespace occ
160 } // namespace open_power
161