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