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