| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 1 | /** | 
 | 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 | #include <iostream> | 
 | 17 | #include <memory> | 
| Brad Bishop | 9c7b6e0 | 2016-12-19 12:43:36 -0500 | [diff] [blame] | 18 | #include <cstdlib> | 
| Chiabing Lee | c923ce9 | 2017-09-06 15:58:26 +0800 | [diff] [blame^] | 19 | #include <string> | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 20 |  | 
 | 21 | #include <phosphor-logging/elog-errors.hpp> | 
| Matt Spinler | f9c83c4 | 2017-08-10 08:51:45 -0500 | [diff] [blame] | 22 | #include "config.h" | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 23 | #include "sensorset.hpp" | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 24 | #include "hwmon.hpp" | 
 | 25 | #include "sysfs.hpp" | 
| Brad Bishop | d499ca6 | 2016-12-19 09:24:50 -0500 | [diff] [blame] | 26 | #include "mainloop.hpp" | 
| Brad Bishop | f3df6b4 | 2017-01-06 10:14:09 -0500 | [diff] [blame] | 27 | #include "env.hpp" | 
| Brad Bishop | e0b7d05 | 2017-01-06 15:30:23 -0500 | [diff] [blame] | 28 | #include "thresholds.hpp" | 
| Matthew Barth | bf7b7b1 | 2017-03-07 15:46:59 -0600 | [diff] [blame] | 29 | #include "targets.hpp" | 
| Matthew Barth | 048ac87 | 2017-03-09 14:36:08 -0600 | [diff] [blame] | 30 | #include "fan_speed.hpp" | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 31 |  | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 32 | #include <xyz/openbmc_project/Sensor/Device/error.hpp> | 
 | 33 |  | 
 | 34 | using namespace phosphor::logging; | 
 | 35 |  | 
| Saqib Khan | 973886d | 2017-03-15 14:01:16 -0500 | [diff] [blame] | 36 | // Initialization for Warning Objects | 
 | 37 | decltype(Thresholds<WarningObject>::setLo) Thresholds<WarningObject>::setLo = | 
 | 38 |     &WarningObject::warningLow; | 
 | 39 | decltype(Thresholds<WarningObject>::setHi) Thresholds<WarningObject>::setHi = | 
 | 40 |     &WarningObject::warningHigh; | 
 | 41 | decltype(Thresholds<WarningObject>::getLo) Thresholds<WarningObject>::getLo = | 
 | 42 |     &WarningObject::warningLow; | 
 | 43 | decltype(Thresholds<WarningObject>::getHi) Thresholds<WarningObject>::getHi = | 
 | 44 |     &WarningObject::warningHigh; | 
 | 45 | decltype(Thresholds<WarningObject>::alarmLo) Thresholds<WarningObject>::alarmLo = | 
 | 46 |     &WarningObject::warningAlarmLow; | 
 | 47 | decltype(Thresholds<WarningObject>::alarmHi) Thresholds<WarningObject>::alarmHi = | 
 | 48 |     &WarningObject::warningAlarmHigh; | 
 | 49 |  | 
 | 50 | // Initialization for Critical Objects | 
 | 51 | decltype(Thresholds<CriticalObject>::setLo) Thresholds<CriticalObject>::setLo = | 
 | 52 |     &CriticalObject::criticalLow; | 
 | 53 | decltype(Thresholds<CriticalObject>::setHi) Thresholds<CriticalObject>::setHi = | 
 | 54 |     &CriticalObject::criticalHigh; | 
 | 55 | decltype(Thresholds<CriticalObject>::getLo) Thresholds<CriticalObject>::getLo = | 
 | 56 |     &CriticalObject::criticalLow; | 
 | 57 | decltype(Thresholds<CriticalObject>::getHi) Thresholds<CriticalObject>::getHi = | 
 | 58 |     &CriticalObject::criticalHigh; | 
 | 59 | decltype(Thresholds<CriticalObject>::alarmLo) Thresholds<CriticalObject>::alarmLo = | 
 | 60 |     &CriticalObject::criticalAlarmLow; | 
 | 61 | decltype(Thresholds<CriticalObject>::alarmHi) Thresholds<CriticalObject>::alarmHi = | 
 | 62 |     &CriticalObject::criticalAlarmHigh; | 
 | 63 |  | 
| Chiabing Lee | c923ce9 | 2017-09-06 15:58:26 +0800 | [diff] [blame^] | 64 | // The gain and offset to adjust a value | 
 | 65 | struct valueAdjust | 
 | 66 | { | 
 | 67 |     double gain = 1.0; | 
 | 68 |     int offset = 0; | 
 | 69 | }; | 
 | 70 |  | 
 | 71 | // Store the valueAdjust for sensors | 
 | 72 | std::map<SensorSet::key_type, valueAdjust> sensorAdjusts; | 
 | 73 |  | 
| Brad Bishop | 74aa4dd | 2017-01-06 09:50:31 -0500 | [diff] [blame] | 74 | static constexpr auto typeAttrMap = | 
 | 75 | { | 
 | 76 |     // 1 - hwmon class | 
 | 77 |     // 2 - unit | 
 | 78 |     // 3 - sysfs scaling factor | 
 | 79 |     std::make_tuple( | 
 | 80 |         hwmon::type::ctemp, | 
 | 81 |         ValueInterface::Unit::DegreesC, | 
| Brad Bishop | add9851 | 2017-01-06 22:01:19 -0500 | [diff] [blame] | 82 |         -3, | 
 | 83 |         "temperature"), | 
| Brad Bishop | 74aa4dd | 2017-01-06 09:50:31 -0500 | [diff] [blame] | 84 |     std::make_tuple( | 
 | 85 |         hwmon::type::cfan, | 
 | 86 |         ValueInterface::Unit::RPMS, | 
| Brad Bishop | add9851 | 2017-01-06 22:01:19 -0500 | [diff] [blame] | 87 |         0, | 
 | 88 |         "fan_tach"), | 
| Brad Bishop | 74aa4dd | 2017-01-06 09:50:31 -0500 | [diff] [blame] | 89 |     std::make_tuple( | 
 | 90 |         hwmon::type::cvolt, | 
 | 91 |         ValueInterface::Unit::Volts, | 
| Brad Bishop | add9851 | 2017-01-06 22:01:19 -0500 | [diff] [blame] | 92 |         -3, | 
 | 93 |         "voltage"), | 
| Brad Bishop | 5afe21a | 2017-01-06 20:44:05 -0500 | [diff] [blame] | 94 |     std::make_tuple( | 
 | 95 |         hwmon::type::ccurr, | 
 | 96 |         ValueInterface::Unit::Amperes, | 
| Brad Bishop | add9851 | 2017-01-06 22:01:19 -0500 | [diff] [blame] | 97 |         -3, | 
 | 98 |         "current"), | 
| Brad Bishop | 5afe21a | 2017-01-06 20:44:05 -0500 | [diff] [blame] | 99 |     std::make_tuple( | 
 | 100 |         hwmon::type::cenergy, | 
 | 101 |         ValueInterface::Unit::Joules, | 
| Brad Bishop | add9851 | 2017-01-06 22:01:19 -0500 | [diff] [blame] | 102 |         -6, | 
 | 103 |         "energy"), | 
| Brad Bishop | 5afe21a | 2017-01-06 20:44:05 -0500 | [diff] [blame] | 104 |     std::make_tuple( | 
 | 105 |         hwmon::type::cpower, | 
 | 106 |         ValueInterface::Unit::Watts, | 
| Brad Bishop | add9851 | 2017-01-06 22:01:19 -0500 | [diff] [blame] | 107 |         -6, | 
 | 108 |         "power"), | 
| Brad Bishop | 74aa4dd | 2017-01-06 09:50:31 -0500 | [diff] [blame] | 109 | }; | 
 | 110 |  | 
 | 111 | auto getHwmonType(decltype(typeAttrMap)::const_reference attrs) | 
 | 112 | { | 
 | 113 |     return std::get<0>(attrs); | 
 | 114 | } | 
 | 115 |  | 
 | 116 | auto getUnit(decltype(typeAttrMap)::const_reference attrs) | 
 | 117 | { | 
 | 118 |     return std::get<1>(attrs); | 
 | 119 | } | 
 | 120 |  | 
 | 121 | auto getScale(decltype(typeAttrMap)::const_reference attrs) | 
 | 122 | { | 
 | 123 |     return std::get<2>(attrs); | 
 | 124 | } | 
 | 125 |  | 
| Brad Bishop | add9851 | 2017-01-06 22:01:19 -0500 | [diff] [blame] | 126 | auto getNamespace(decltype(typeAttrMap)::const_reference attrs) | 
 | 127 | { | 
 | 128 |     return std::get<3>(attrs); | 
 | 129 | } | 
 | 130 |  | 
| Brad Bishop | 951a79e | 2017-01-06 21:55:11 -0500 | [diff] [blame] | 131 | using AttributeIterator = decltype(*typeAttrMap.begin()); | 
 | 132 | using Attributes | 
 | 133 |     = std::remove_cv<std::remove_reference<AttributeIterator>::type>::type; | 
 | 134 |  | 
 | 135 | auto getAttributes(const std::string& type, Attributes& attributes) | 
 | 136 | { | 
 | 137 |     // *INDENT-OFF* | 
 | 138 |     auto a = std::find_if( | 
 | 139 |                 typeAttrMap.begin(), | 
 | 140 |                 typeAttrMap.end(), | 
 | 141 |                 [&](const auto & e) | 
 | 142 |                 { | 
 | 143 |                    return type == getHwmonType(e); | 
 | 144 |                 }); | 
 | 145 |     // *INDENT-ON* | 
 | 146 |  | 
 | 147 |     if (a == typeAttrMap.end()) | 
 | 148 |     { | 
 | 149 |         return false; | 
 | 150 |     } | 
 | 151 |  | 
 | 152 |     attributes = *a; | 
 | 153 |     return true; | 
 | 154 | } | 
 | 155 |  | 
| Chiabing Lee | c923ce9 | 2017-09-06 15:58:26 +0800 | [diff] [blame^] | 156 | int adjustValue(const SensorSet::key_type& sensor, int value) | 
 | 157 | { | 
 | 158 |     const auto& it = sensorAdjusts.find(sensor); | 
 | 159 |     if (it != sensorAdjusts.end()) | 
 | 160 |     { | 
 | 161 |         // Adjust based on gain and offset | 
 | 162 |         value = static_cast<decltype(value)>( | 
 | 163 |                     static_cast<double>(value) * it->second.gain | 
 | 164 |                         + it->second.offset); | 
 | 165 |     } | 
 | 166 |     return value; | 
 | 167 | } | 
 | 168 |  | 
| Brad Bishop | e9fdee0 | 2017-01-06 10:43:29 -0500 | [diff] [blame] | 169 | auto addValue(const SensorSet::key_type& sensor, | 
| Brad Bishop | 751043e | 2017-08-29 11:13:46 -0400 | [diff] [blame] | 170 |               const std::string& devPath, | 
 | 171 |               sysfs::hwmonio::HwmonIO& ioAccess, | 
| Brad Bishop | 4db6442 | 2017-02-16 11:33:32 -0500 | [diff] [blame] | 172 |               ObjectInfo& info) | 
| Brad Bishop | e9fdee0 | 2017-01-06 10:43:29 -0500 | [diff] [blame] | 173 | { | 
| Brad Bishop | 30dbcee | 2017-01-18 07:55:42 -0500 | [diff] [blame] | 174 |     static constexpr bool deferSignals = true; | 
 | 175 |  | 
| Brad Bishop | e9fdee0 | 2017-01-06 10:43:29 -0500 | [diff] [blame] | 176 |     // Get the initial value for the value interface. | 
 | 177 |     auto& bus = *std::get<sdbusplus::bus::bus*>(info); | 
 | 178 |     auto& obj = std::get<Object>(info); | 
 | 179 |     auto& objPath = std::get<std::string>(info); | 
 | 180 |  | 
| Brad Bishop | 751043e | 2017-08-29 11:13:46 -0400 | [diff] [blame] | 181 |     auto val = 0; | 
 | 182 |     try | 
 | 183 |     { | 
 | 184 |         // Retry for up to a second if device is busy | 
| Brad Bishop | 754d38c | 2017-09-08 00:46:58 -0400 | [diff] [blame] | 185 |         // or has a transient error. | 
 | 186 |         val = ioAccess.read( | 
| Brad Bishop | 751043e | 2017-08-29 11:13:46 -0400 | [diff] [blame] | 187 |                 sensor.first, | 
 | 188 |                 sensor.second, | 
| Brad Bishop | 754d38c | 2017-09-08 00:46:58 -0400 | [diff] [blame] | 189 |                 hwmon::entry::cinput, | 
 | 190 |                 sysfs::hwmonio::retries, | 
 | 191 |                 sysfs::hwmonio::delay); | 
| Brad Bishop | 751043e | 2017-08-29 11:13:46 -0400 | [diff] [blame] | 192 |     } | 
 | 193 |     catch (const std::system_error& e) | 
 | 194 |     { | 
 | 195 |         using namespace sdbusplus::xyz::openbmc_project::Sensor::Device::Error; | 
 | 196 |         report<ReadFailure>( | 
 | 197 |             xyz::openbmc_project::Sensor::Device:: | 
 | 198 |                 ReadFailure::CALLOUT_ERRNO(e.code().value()), | 
 | 199 |             xyz::openbmc_project::Sensor::Device:: | 
 | 200 |                 ReadFailure::CALLOUT_DEVICE_PATH(devPath.c_str())); | 
 | 201 |  | 
 | 202 |         return static_cast<std::shared_ptr<ValueObject>>(nullptr); | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 203 |     } | 
 | 204 |  | 
| Chiabing Lee | c923ce9 | 2017-09-06 15:58:26 +0800 | [diff] [blame^] | 205 |     auto gain = getEnv("GAIN", sensor); | 
 | 206 |     if (!gain.empty()) | 
 | 207 |     { | 
 | 208 |         sensorAdjusts[sensor].gain = std::stod(gain); | 
 | 209 |     } | 
 | 210 |  | 
 | 211 |     auto offset = getEnv("OFFSET", sensor); | 
 | 212 |     if (!offset.empty()) | 
 | 213 |     { | 
 | 214 |         sensorAdjusts[sensor].offset = std::stoi(offset); | 
 | 215 |     } | 
 | 216 |  | 
 | 217 |     val = adjustValue(sensor, val); | 
 | 218 |  | 
| Brad Bishop | 30dbcee | 2017-01-18 07:55:42 -0500 | [diff] [blame] | 219 |     auto iface = std::make_shared<ValueObject>(bus, objPath.c_str(), deferSignals); | 
| Brad Bishop | e9fdee0 | 2017-01-06 10:43:29 -0500 | [diff] [blame] | 220 |     iface->value(val); | 
 | 221 |  | 
| Brad Bishop | 951a79e | 2017-01-06 21:55:11 -0500 | [diff] [blame] | 222 |     Attributes attrs; | 
 | 223 |     if (getAttributes(sensor.first, attrs)) | 
| Brad Bishop | e9fdee0 | 2017-01-06 10:43:29 -0500 | [diff] [blame] | 224 |     { | 
| Brad Bishop | 951a79e | 2017-01-06 21:55:11 -0500 | [diff] [blame] | 225 |         iface->unit(getUnit(attrs)); | 
 | 226 |         iface->scale(getScale(attrs)); | 
| Brad Bishop | e9fdee0 | 2017-01-06 10:43:29 -0500 | [diff] [blame] | 227 |     } | 
 | 228 |  | 
 | 229 |     obj[InterfaceType::VALUE] = iface; | 
 | 230 |     return iface; | 
 | 231 | } | 
 | 232 |  | 
| Brad Bishop | b9e2b07 | 2016-12-19 13:47:10 -0500 | [diff] [blame] | 233 | MainLoop::MainLoop( | 
| Brad Bishop | 9c7b6e0 | 2016-12-19 12:43:36 -0500 | [diff] [blame] | 234 |     sdbusplus::bus::bus&& bus, | 
| Brad Bishop | b9e2b07 | 2016-12-19 13:47:10 -0500 | [diff] [blame] | 235 |     const std::string& path, | 
| Brad Bishop | f3aa9ae | 2017-08-25 09:56:02 -0400 | [diff] [blame] | 236 |     const std::string& devPath, | 
| Brad Bishop | b9e2b07 | 2016-12-19 13:47:10 -0500 | [diff] [blame] | 237 |     const char* prefix, | 
 | 238 |     const char* root) | 
| Brad Bishop | 9c7b6e0 | 2016-12-19 12:43:36 -0500 | [diff] [blame] | 239 |     : _bus(std::move(bus)), | 
| Brad Bishop | 03e8735 | 2017-03-07 00:12:22 -0500 | [diff] [blame] | 240 |       _manager(_bus, root), | 
| Brad Bishop | 9c7b6e0 | 2016-12-19 12:43:36 -0500 | [diff] [blame] | 241 |       _shutdown(false), | 
| Brad Bishop | b8740fc | 2017-02-24 23:38:37 -0500 | [diff] [blame] | 242 |       _hwmonRoot(), | 
 | 243 |       _instance(), | 
| Brad Bishop | f3aa9ae | 2017-08-25 09:56:02 -0400 | [diff] [blame] | 244 |       _devPath(devPath), | 
| Brad Bishop | b9e2b07 | 2016-12-19 13:47:10 -0500 | [diff] [blame] | 245 |       _prefix(prefix), | 
| Brad Bishop | 3c344d3 | 2017-01-05 11:48:39 -0500 | [diff] [blame] | 246 |       _root(root), | 
| Brad Bishop | 751043e | 2017-08-29 11:13:46 -0400 | [diff] [blame] | 247 |       state(), | 
 | 248 |       ioAccess(path) | 
| Brad Bishop | d499ca6 | 2016-12-19 09:24:50 -0500 | [diff] [blame] | 249 | { | 
| Brad Bishop | b8740fc | 2017-02-24 23:38:37 -0500 | [diff] [blame] | 250 |     std::string p = path; | 
 | 251 |     while (!p.empty() && p.back() == '/') | 
| Brad Bishop | 9c7b6e0 | 2016-12-19 12:43:36 -0500 | [diff] [blame] | 252 |     { | 
| Brad Bishop | b8740fc | 2017-02-24 23:38:37 -0500 | [diff] [blame] | 253 |         p.pop_back(); | 
| Brad Bishop | 9c7b6e0 | 2016-12-19 12:43:36 -0500 | [diff] [blame] | 254 |     } | 
| Brad Bishop | b8740fc | 2017-02-24 23:38:37 -0500 | [diff] [blame] | 255 |  | 
 | 256 |     auto n = p.rfind('/'); | 
 | 257 |     if (n != std::string::npos) | 
 | 258 |     { | 
 | 259 |         _instance.assign(p.substr(n + 1)); | 
 | 260 |         _hwmonRoot.assign(p.substr(0, n)); | 
 | 261 |     } | 
 | 262 |  | 
 | 263 |     assert(!_instance.empty()); | 
 | 264 |     assert(!_hwmonRoot.empty()); | 
| Brad Bishop | d499ca6 | 2016-12-19 09:24:50 -0500 | [diff] [blame] | 265 | } | 
 | 266 |  | 
 | 267 | void MainLoop::shutdown() noexcept | 
 | 268 | { | 
 | 269 |     _shutdown = true; | 
 | 270 | } | 
 | 271 |  | 
 | 272 | void MainLoop::run() | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 273 | { | 
 | 274 |     // Check sysfs for available sensors. | 
| Brad Bishop | 4db6442 | 2017-02-16 11:33:32 -0500 | [diff] [blame] | 275 |     auto sensors = std::make_unique<SensorSet>(_hwmonRoot + '/' + _instance); | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 276 |  | 
| Brad Bishop | 75b4ab8 | 2017-01-06 09:33:50 -0500 | [diff] [blame] | 277 |     for (auto& i : *sensors) | 
 | 278 |     { | 
| Tom Joseph | 1f8a958 | 2017-06-12 20:10:59 +0530 | [diff] [blame] | 279 |         std::string label; | 
| Brad Bishop | f3df6b4 | 2017-01-06 10:14:09 -0500 | [diff] [blame] | 280 |  | 
| Tom Joseph | 1f8a958 | 2017-06-12 20:10:59 +0530 | [diff] [blame] | 281 |         /* | 
 | 282 |          * Check if the value of the MODE_<item><X> env variable for the sensor | 
 | 283 |          * is "label", then read the sensor number from the <item><X>_label | 
 | 284 |          * file. The name of the DBUS object would be the value of the env | 
 | 285 |          * variable LABEL_<item><sensorNum>. If the MODE_<item><X> env variable | 
 | 286 |          * does'nt exist, then the name of DBUS object is the value of the env | 
 | 287 |          * variable LABEL_<item><X>. | 
 | 288 |          */ | 
 | 289 |         auto mode = getEnv("MODE", i.first); | 
 | 290 |         if (!mode.compare(hwmon::entry::label)) | 
| Brad Bishop | 73831cd | 2017-01-06 09:37:22 -0500 | [diff] [blame] | 291 |         { | 
| Tom Joseph | 1f8a958 | 2017-06-12 20:10:59 +0530 | [diff] [blame] | 292 |             label = getIndirectLabelEnv( | 
 | 293 |                 "LABEL", _hwmonRoot + '/' + _instance + '/', i.first); | 
 | 294 |             if (label.empty()) | 
 | 295 |             { | 
 | 296 |                 continue; | 
 | 297 |             } | 
 | 298 |         } | 
 | 299 |         else | 
 | 300 |         { | 
 | 301 |             // Ignore inputs without a label. | 
 | 302 |             label = getEnv("LABEL", i.first); | 
 | 303 |             if (label.empty()) | 
 | 304 |             { | 
 | 305 |                 continue; | 
 | 306 |             } | 
| Brad Bishop | 73831cd | 2017-01-06 09:37:22 -0500 | [diff] [blame] | 307 |         } | 
 | 308 |  | 
| Brad Bishop | add9851 | 2017-01-06 22:01:19 -0500 | [diff] [blame] | 309 |         Attributes attrs; | 
 | 310 |         if (!getAttributes(i.first.first, attrs)) | 
 | 311 |         { | 
 | 312 |             continue; | 
 | 313 |         } | 
 | 314 |  | 
| Brad Bishop | 075f7a2 | 2017-01-06 09:45:08 -0500 | [diff] [blame] | 315 |         std::string objectPath{_root}; | 
| Brad Bishop | b8740fc | 2017-02-24 23:38:37 -0500 | [diff] [blame] | 316 |         objectPath.append(1, '/'); | 
| Brad Bishop | add9851 | 2017-01-06 22:01:19 -0500 | [diff] [blame] | 317 |         objectPath.append(getNamespace(attrs)); | 
| Brad Bishop | b8740fc | 2017-02-24 23:38:37 -0500 | [diff] [blame] | 318 |         objectPath.append(1, '/'); | 
| Brad Bishop | 075f7a2 | 2017-01-06 09:45:08 -0500 | [diff] [blame] | 319 |         objectPath.append(label); | 
 | 320 |  | 
| Brad Bishop | f7426cf | 2017-01-06 15:36:43 -0500 | [diff] [blame] | 321 |         ObjectInfo info(&_bus, std::move(objectPath), Object()); | 
| Brad Bishop | 751043e | 2017-08-29 11:13:46 -0400 | [diff] [blame] | 322 |         auto valueInterface = addValue(i.first, _devPath, ioAccess, info); | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 323 |         if (!valueInterface) | 
 | 324 |         { | 
| Matt Spinler | f9c83c4 | 2017-08-10 08:51:45 -0500 | [diff] [blame] | 325 | #ifdef REMOVE_ON_FAIL | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 326 |             continue; /* skip adding this sensor for now. */ | 
| Matt Spinler | f9c83c4 | 2017-08-10 08:51:45 -0500 | [diff] [blame] | 327 | #else | 
 | 328 |             exit(EXIT_FAILURE); | 
 | 329 | #endif | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 330 |         } | 
| Brad Bishop | e0b7d05 | 2017-01-06 15:30:23 -0500 | [diff] [blame] | 331 |         auto sensorValue = valueInterface->value(); | 
 | 332 |         addThreshold<WarningObject>(i.first, sensorValue, info); | 
 | 333 |         addThreshold<CriticalObject>(i.first, sensorValue, info); | 
| Matthew Barth | bf7b7b1 | 2017-03-07 15:46:59 -0600 | [diff] [blame] | 334 |         //TODO openbmc/openbmc#1347 | 
 | 335 |         //     Handle application restarts to set/refresh fan speed values | 
| Matt Spinler | 0a8de64 | 2017-05-11 10:59:39 -0500 | [diff] [blame] | 336 |         auto target = addTarget<hwmon::FanSpeed>( | 
| Brad Bishop | 751043e | 2017-08-29 11:13:46 -0400 | [diff] [blame] | 337 |                 i.first, ioAccess.path(), _devPath, info); | 
| Matt Spinler | 0a8de64 | 2017-05-11 10:59:39 -0500 | [diff] [blame] | 338 |  | 
 | 339 |         if (target) | 
 | 340 |         { | 
 | 341 |             target->enable(); | 
 | 342 |         } | 
| Brad Bishop | 075f7a2 | 2017-01-06 09:45:08 -0500 | [diff] [blame] | 343 |  | 
| Brad Bishop | 30dbcee | 2017-01-18 07:55:42 -0500 | [diff] [blame] | 344 |         // All the interfaces have been created.  Go ahead | 
 | 345 |         // and emit InterfacesAdded. | 
 | 346 |         valueInterface->emit_object_added(); | 
 | 347 |  | 
| Brad Bishop | 075f7a2 | 2017-01-06 09:45:08 -0500 | [diff] [blame] | 348 |         auto value = std::make_tuple( | 
 | 349 |                          std::move(i.second), | 
 | 350 |                          std::move(label), | 
| Brad Bishop | f7426cf | 2017-01-06 15:36:43 -0500 | [diff] [blame] | 351 |                          std::move(info)); | 
| Brad Bishop | 73831cd | 2017-01-06 09:37:22 -0500 | [diff] [blame] | 352 |  | 
| Brad Bishop | 75b4ab8 | 2017-01-06 09:33:50 -0500 | [diff] [blame] | 353 |         state[std::move(i.first)] = std::move(value); | 
 | 354 |     } | 
 | 355 |  | 
| Patrick Venture | 62503a4 | 2017-05-23 07:30:29 -0700 | [diff] [blame] | 356 |     /* If there are no sensors specified by labels, exit. */ | 
 | 357 |     if (0 == state.size()) | 
 | 358 |     { | 
 | 359 |         return; | 
 | 360 |     } | 
 | 361 |  | 
| Brad Bishop | 9c7b6e0 | 2016-12-19 12:43:36 -0500 | [diff] [blame] | 362 |     { | 
| Brad Bishop | b8740fc | 2017-02-24 23:38:37 -0500 | [diff] [blame] | 363 |         std::string busname{_prefix}; | 
 | 364 |         busname.append(1, '.'); | 
 | 365 |         busname.append(_instance); | 
| Brad Bishop | 9c7b6e0 | 2016-12-19 12:43:36 -0500 | [diff] [blame] | 366 |         _bus.request_name(busname.c_str()); | 
 | 367 |     } | 
 | 368 |  | 
| Patrick Venture | ab10f16 | 2017-05-22 09:44:50 -0700 | [diff] [blame] | 369 |     { | 
 | 370 |         auto interval = getenv("INTERVAL"); | 
 | 371 |         if (interval) | 
 | 372 |         { | 
 | 373 |             _interval = strtoull(interval, NULL, 10); | 
 | 374 |         } | 
 | 375 |     } | 
 | 376 |  | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 377 |     // TODO: Issue#3 - Need to make calls to the dbus sensor cache here to | 
 | 378 |     //       ensure the objects all exist? | 
 | 379 |  | 
 | 380 |     // Polling loop. | 
| Brad Bishop | d499ca6 | 2016-12-19 09:24:50 -0500 | [diff] [blame] | 381 |     while (!_shutdown) | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 382 |     { | 
| Matt Spinler | f9c83c4 | 2017-08-10 08:51:45 -0500 | [diff] [blame] | 383 | #ifdef REMOVE_ON_FAIL | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 384 |         std::vector<SensorSet::key_type> destroy; | 
| Matt Spinler | f9c83c4 | 2017-08-10 08:51:45 -0500 | [diff] [blame] | 385 | #endif | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 386 |         // Iterate through all the sensors. | 
| Brad Bishop | 75b4ab8 | 2017-01-06 09:33:50 -0500 | [diff] [blame] | 387 |         for (auto& i : state) | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 388 |         { | 
| Brad Bishop | 75b4ab8 | 2017-01-06 09:33:50 -0500 | [diff] [blame] | 389 |             auto& attrs = std::get<0>(i.second); | 
 | 390 |             if (attrs.find(hwmon::entry::input) != attrs.end()) | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 391 |             { | 
 | 392 |                 // Read value from sensor. | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 393 |                 int value; | 
 | 394 |                 try | 
| Brad Bishop | dddb715 | 2017-01-06 09:54:23 -0500 | [diff] [blame] | 395 |                 { | 
| Brad Bishop | 754d38c | 2017-09-08 00:46:58 -0400 | [diff] [blame] | 396 |                     // Retry for up to a second if device is busy | 
 | 397 |                     // or has a transient error. | 
 | 398 |  | 
| Brad Bishop | 751043e | 2017-08-29 11:13:46 -0400 | [diff] [blame] | 399 |                     value = ioAccess.read( | 
 | 400 |                             i.first.first, | 
 | 401 |                             i.first.second, | 
| Brad Bishop | 754d38c | 2017-09-08 00:46:58 -0400 | [diff] [blame] | 402 |                             hwmon::entry::cinput, | 
 | 403 |                             sysfs::hwmonio::retries, | 
 | 404 |                             sysfs::hwmonio::delay); | 
| Brad Bishop | e0b7d05 | 2017-01-06 15:30:23 -0500 | [diff] [blame] | 405 |  | 
| Chiabing Lee | c923ce9 | 2017-09-06 15:58:26 +0800 | [diff] [blame^] | 406 |                     value = adjustValue(i.first, value); | 
 | 407 |  | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 408 |                     auto& objInfo = std::get<ObjectInfo>(i.second); | 
 | 409 |                     auto& obj = std::get<Object>(objInfo); | 
 | 410 |  | 
 | 411 |                     for (auto& iface : obj) | 
| Brad Bishop | e0b7d05 | 2017-01-06 15:30:23 -0500 | [diff] [blame] | 412 |                     { | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 413 |                         auto valueIface = std::shared_ptr<ValueObject>(); | 
 | 414 |                         auto warnIface = std::shared_ptr<WarningObject>(); | 
 | 415 |                         auto critIface = std::shared_ptr<CriticalObject>(); | 
 | 416 |  | 
 | 417 |                         switch (iface.first) | 
 | 418 |                         { | 
 | 419 |                             case InterfaceType::VALUE: | 
 | 420 |                                 valueIface = std::experimental::any_cast<std::shared_ptr<ValueObject>> | 
 | 421 |                                             (iface.second); | 
 | 422 |                                 valueIface->value(value); | 
 | 423 |                                 break; | 
 | 424 |                             case InterfaceType::WARN: | 
 | 425 |                                 checkThresholds<WarningObject>(iface.second, value); | 
 | 426 |                                 break; | 
 | 427 |                             case InterfaceType::CRIT: | 
 | 428 |                                 checkThresholds<CriticalObject>(iface.second, value); | 
 | 429 |                                 break; | 
 | 430 |                             default: | 
 | 431 |                                 break; | 
 | 432 |                         } | 
| Brad Bishop | e0b7d05 | 2017-01-06 15:30:23 -0500 | [diff] [blame] | 433 |                     } | 
| Brad Bishop | dddb715 | 2017-01-06 09:54:23 -0500 | [diff] [blame] | 434 |                 } | 
| Brad Bishop | 751043e | 2017-08-29 11:13:46 -0400 | [diff] [blame] | 435 |                 catch (const std::system_error& e) | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 436 |                 { | 
| Brad Bishop | 751043e | 2017-08-29 11:13:46 -0400 | [diff] [blame] | 437 |                     using namespace sdbusplus::xyz::openbmc_project:: | 
 | 438 |                         Sensor::Device::Error; | 
 | 439 |                     report<ReadFailure>( | 
 | 440 |                             xyz::openbmc_project::Sensor::Device:: | 
 | 441 |                                 ReadFailure::CALLOUT_ERRNO(e.code().value()), | 
 | 442 |                             xyz::openbmc_project::Sensor::Device:: | 
 | 443 |                                 ReadFailure::CALLOUT_DEVICE_PATH( | 
 | 444 |                                     _devPath.c_str())); | 
| Matt Spinler | f9c83c4 | 2017-08-10 08:51:45 -0500 | [diff] [blame] | 445 | #ifdef REMOVE_ON_FAIL | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 446 |                     destroy.push_back(i.first); | 
| Matt Spinler | f9c83c4 | 2017-08-10 08:51:45 -0500 | [diff] [blame] | 447 | #else | 
 | 448 |                     exit(EXIT_FAILURE); | 
 | 449 | #endif | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 450 |                 } | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 451 |             } | 
 | 452 |         } | 
 | 453 |  | 
| Matt Spinler | f9c83c4 | 2017-08-10 08:51:45 -0500 | [diff] [blame] | 454 | #ifdef REMOVE_ON_FAIL | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 455 |         for (auto& i : destroy) | 
 | 456 |         { | 
 | 457 |             state.erase(i); | 
 | 458 |         } | 
| Matt Spinler | f9c83c4 | 2017-08-10 08:51:45 -0500 | [diff] [blame] | 459 | #endif | 
| Patrick Venture | 1e6324f | 2017-06-01 14:07:05 -0700 | [diff] [blame] | 460 |  | 
| Brad Bishop | 9c7b6e0 | 2016-12-19 12:43:36 -0500 | [diff] [blame] | 461 |         // Respond to DBus | 
 | 462 |         _bus.process_discard(); | 
 | 463 |  | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 464 |         // Sleep until next interval. | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 465 |         // TODO: Issue#6 - Optionally look at polling interval sysfs entry. | 
| Patrick Venture | ab10f16 | 2017-05-22 09:44:50 -0700 | [diff] [blame] | 466 |         _bus.wait(_interval); | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 467 |  | 
 | 468 |         // TODO: Issue#7 - Should probably periodically check the SensorSet | 
 | 469 |         //       for new entries. | 
 | 470 |     } | 
| Brad Bishop | e55ef3d | 2016-12-19 09:12:40 -0500 | [diff] [blame] | 471 | } | 
 | 472 |  | 
 | 473 | // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 |