| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 1 | /* | 
 | 2 | // Copyright (c) 2019 Intel 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 |  | 
| Cheng C Yang | 5665db2 | 2019-07-12 00:57:30 +0800 | [diff] [blame] | 17 | #include <systemd/sd-journal.h> | 
 | 18 |  | 
| Ed Tanous | 8a57ec0 | 2020-10-09 12:46:52 -0700 | [diff] [blame] | 19 | #include <PSUEvent.hpp> | 
| Ed Tanous | 6cb732a | 2021-02-18 15:33:51 -0800 | [diff] [blame] | 20 | #include <SensorPaths.hpp> | 
| James Feist | 8086aba | 2020-08-25 16:00:59 -0700 | [diff] [blame] | 21 | #include <boost/asio/io_service.hpp> | 
 | 22 | #include <boost/asio/read_until.hpp> | 
| Patrick Venture | 96e97db | 2019-10-31 13:44:38 -0700 | [diff] [blame] | 23 | #include <boost/container/flat_map.hpp> | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 24 | #include <sdbusplus/asio/connection.hpp> | 
 | 25 | #include <sdbusplus/asio/object_server.hpp> | 
| James Feist | 38fb598 | 2020-05-28 10:09:54 -0700 | [diff] [blame] | 26 |  | 
 | 27 | #include <iostream> | 
 | 28 | #include <memory> | 
| Patrick Venture | 96e97db | 2019-10-31 13:44:38 -0700 | [diff] [blame] | 29 | #include <stdexcept> | 
 | 30 | #include <string> | 
 | 31 | #include <utility> | 
 | 32 | #include <variant> | 
 | 33 | #include <vector> | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 34 |  | 
 | 35 | PSUCombineEvent::PSUCombineEvent( | 
| Yong Li | 3046a02 | 2020-04-03 13:01:02 +0800 | [diff] [blame] | 36 |     sdbusplus::asio::object_server& objectServer, | 
 | 37 |     std::shared_ptr<sdbusplus::asio::connection>& conn, | 
 | 38 |     boost::asio::io_service& io, const std::string& psuName, | 
| Konstantin Aladyshev | c7a1ae6 | 2021-04-30 08:50:43 +0000 | [diff] [blame] | 39 |     const PowerState& powerState, | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 40 |     boost::container::flat_map<std::string, std::vector<std::string>>& | 
 | 41 |         eventPathList, | 
| Cheng C Yang | 202a1ff | 2020-01-09 09:34:22 +0800 | [diff] [blame] | 42 |     boost::container::flat_map< | 
 | 43 |         std::string, | 
 | 44 |         boost::container::flat_map<std::string, std::vector<std::string>>>& | 
 | 45 |         groupEventPathList, | 
| Lei YU | 7170a23 | 2021-02-04 16:19:27 +0800 | [diff] [blame] | 46 |     const std::string& combineEventName, double pollRate) : | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 47 |     objServer(objectServer) | 
 | 48 | { | 
| Ed Tanous | 6cb732a | 2021-02-18 15:33:51 -0800 | [diff] [blame] | 49 |     std::string psuNameEscaped = sensor_paths::escapePathForDbus(psuName); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 50 |     eventInterface = objServer.add_interface( | 
| Ed Tanous | 6cb732a | 2021-02-18 15:33:51 -0800 | [diff] [blame] | 51 |         "/xyz/openbmc_project/State/Decorator/" + psuNameEscaped + "_" + | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 52 |             combineEventName, | 
 | 53 |         "xyz.openbmc_project.State.Decorator.OperationalStatus"); | 
| James Feist | b6c0b91 | 2019-07-09 12:21:44 -0700 | [diff] [blame] | 54 |     eventInterface->register_property("functional", true); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 55 |  | 
 | 56 |     if (!eventInterface->initialize()) | 
 | 57 |     { | 
 | 58 |         std::cerr << "error initializing event interface\n"; | 
 | 59 |     } | 
 | 60 |  | 
 | 61 |     std::shared_ptr<std::set<std::string>> combineEvent = | 
 | 62 |         std::make_shared<std::set<std::string>>(); | 
 | 63 |     for (const auto& pathList : eventPathList) | 
 | 64 |     { | 
| Yong Li | 591b1e4 | 2019-12-19 17:46:31 +0800 | [diff] [blame] | 65 |         std::shared_ptr<std::set<std::string>> assert = | 
 | 66 |             std::make_shared<std::set<std::string>>(); | 
| Cheng C Yang | 202a1ff | 2020-01-09 09:34:22 +0800 | [diff] [blame] | 67 |         std::shared_ptr<bool> state = std::make_shared<bool>(false); | 
| Yong Li | 591b1e4 | 2019-12-19 17:46:31 +0800 | [diff] [blame] | 68 |  | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 69 |         const std::string& eventName = pathList.first; | 
 | 70 |         std::string eventPSUName = eventName + psuName; | 
 | 71 |         for (const auto& path : pathList.second) | 
 | 72 |         { | 
| Yong Li | bf8b1da | 2020-04-15 16:32:50 +0800 | [diff] [blame] | 73 |             auto p = std::make_shared<PSUSubEvent>( | 
| Konstantin Aladyshev | c7a1ae6 | 2021-04-30 08:50:43 +0000 | [diff] [blame] | 74 |                 eventInterface, path, conn, io, powerState, eventName, | 
 | 75 |                 eventName, assert, combineEvent, state, psuName, pollRate); | 
| Yong Li | bf8b1da | 2020-04-15 16:32:50 +0800 | [diff] [blame] | 76 |             p->setupRead(); | 
 | 77 |  | 
 | 78 |             events[eventPSUName].emplace_back(p); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 79 |             asserts.emplace_back(assert); | 
 | 80 |             states.emplace_back(state); | 
 | 81 |         } | 
 | 82 |     } | 
| Cheng C Yang | 202a1ff | 2020-01-09 09:34:22 +0800 | [diff] [blame] | 83 |  | 
 | 84 |     for (const auto& groupPathList : groupEventPathList) | 
 | 85 |     { | 
 | 86 |         for (const auto& pathList : groupPathList.second) | 
 | 87 |         { | 
 | 88 |             std::shared_ptr<std::set<std::string>> assert = | 
 | 89 |                 std::make_shared<std::set<std::string>>(); | 
 | 90 |             std::shared_ptr<bool> state = std::make_shared<bool>(false); | 
 | 91 |  | 
 | 92 |             const std::string& groupEventName = pathList.first; | 
 | 93 |             std::string eventPSUName = groupEventName + psuName; | 
 | 94 |             for (const auto& path : pathList.second) | 
 | 95 |             { | 
| Yong Li | bf8b1da | 2020-04-15 16:32:50 +0800 | [diff] [blame] | 96 |                 auto p = std::make_shared<PSUSubEvent>( | 
| Konstantin Aladyshev | c7a1ae6 | 2021-04-30 08:50:43 +0000 | [diff] [blame] | 97 |                     eventInterface, path, conn, io, powerState, groupEventName, | 
| Lei YU | 7170a23 | 2021-02-04 16:19:27 +0800 | [diff] [blame] | 98 |                     groupPathList.first, assert, combineEvent, state, psuName, | 
 | 99 |                     pollRate); | 
| Yong Li | bf8b1da | 2020-04-15 16:32:50 +0800 | [diff] [blame] | 100 |                 p->setupRead(); | 
 | 101 |                 events[eventPSUName].emplace_back(p); | 
 | 102 |  | 
| Cheng C Yang | 202a1ff | 2020-01-09 09:34:22 +0800 | [diff] [blame] | 103 |                 asserts.emplace_back(assert); | 
 | 104 |                 states.emplace_back(state); | 
 | 105 |             } | 
 | 106 |         } | 
 | 107 |     } | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 108 | } | 
 | 109 |  | 
 | 110 | PSUCombineEvent::~PSUCombineEvent() | 
 | 111 | { | 
| Cheng C Yang | 202a1ff | 2020-01-09 09:34:22 +0800 | [diff] [blame] | 112 |     // Clear unique_ptr first | 
 | 113 |     for (auto& event : events) | 
 | 114 |     { | 
 | 115 |         for (auto& subEventPtr : event.second) | 
 | 116 |         { | 
 | 117 |             subEventPtr.reset(); | 
 | 118 |         } | 
 | 119 |     } | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 120 |     events.clear(); | 
 | 121 |     objServer.remove_interface(eventInterface); | 
 | 122 | } | 
 | 123 |  | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 124 | static boost::container::flat_map<std::string, | 
 | 125 |                                   std::pair<std::string, std::string>> | 
 | 126 |     logID = { | 
 | 127 |         {"PredictiveFailure", | 
 | 128 |          {"OpenBMC.0.1.PowerSupplyFailurePredicted", | 
 | 129 |           "OpenBMC.0.1.PowerSupplyPredictedFailureRecovered"}}, | 
 | 130 |         {"Failure", | 
 | 131 |          {"OpenBMC.0.1.PowerSupplyFailed", "OpenBMC.0.1.PowerSupplyRecovered"}}, | 
 | 132 |         {"ACLost", | 
| Cheng C Yang | bb732ef | 2019-09-18 16:25:58 +0800 | [diff] [blame] | 133 |          {"OpenBMC.0.1.PowerSupplyPowerLost", | 
 | 134 |           "OpenBMC.0.1.PowerSupplyPowerRestored"}}, | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 135 |         {"FanFault", | 
 | 136 |          {"OpenBMC.0.1.PowerSupplyFanFailed", | 
 | 137 |           "OpenBMC.0.1.PowerSupplyFanRecovered"}}, | 
| jayaprakash Mutyala | d12f23e | 2019-12-03 23:03:52 +0000 | [diff] [blame] | 138 |         {"ConfigureError", | 
 | 139 |          {"OpenBMC.0.1.PowerSupplyConfigurationError", | 
 | 140 |           "OpenBMC.0.1.PowerSupplyConfigurationErrorRecovered"}}}; | 
| Cheng C Yang | 5665db2 | 2019-07-12 00:57:30 +0800 | [diff] [blame] | 141 |  | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 142 | PSUSubEvent::PSUSubEvent( | 
 | 143 |     std::shared_ptr<sdbusplus::asio::dbus_interface> eventInterface, | 
| Yong Li | 3046a02 | 2020-04-03 13:01:02 +0800 | [diff] [blame] | 144 |     const std::string& path, std::shared_ptr<sdbusplus::asio::connection>& conn, | 
| Konstantin Aladyshev | c7a1ae6 | 2021-04-30 08:50:43 +0000 | [diff] [blame] | 145 |     boost::asio::io_service& io, const PowerState& powerState, | 
 | 146 |     const std::string& groupEventName, const std::string& eventName, | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 147 |     std::shared_ptr<std::set<std::string>> asserts, | 
 | 148 |     std::shared_ptr<std::set<std::string>> combineEvent, | 
| Lei YU | 7170a23 | 2021-02-04 16:19:27 +0800 | [diff] [blame] | 149 |     std::shared_ptr<bool> state, const std::string& psuName, double pollRate) : | 
| Yong Li | bf8b1da | 2020-04-15 16:32:50 +0800 | [diff] [blame] | 150 |     std::enable_shared_from_this<PSUSubEvent>(), | 
| Ed Tanous | 8a57ec0 | 2020-10-09 12:46:52 -0700 | [diff] [blame] | 151 |     eventInterface(std::move(eventInterface)), asserts(std::move(asserts)), | 
 | 152 |     combineEvent(std::move(combineEvent)), assertState(std::move(state)), | 
| Konstantin Aladyshev | c7a1ae6 | 2021-04-30 08:50:43 +0000 | [diff] [blame] | 153 |     errCount(0), path(path), eventName(eventName), readState(powerState), | 
 | 154 |     waitTimer(io), inputDev(io), psuName(psuName), | 
 | 155 |     groupEventName(groupEventName), systemBus(conn) | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 156 | { | 
| Lei YU | 7170a23 | 2021-02-04 16:19:27 +0800 | [diff] [blame] | 157 |     if (pollRate > 0.0) | 
 | 158 |     { | 
 | 159 |         eventPollMs = static_cast<unsigned int>(pollRate * 1000); | 
 | 160 |     } | 
| Cheng C Yang | a97f134 | 2020-02-11 15:10:41 +0800 | [diff] [blame] | 161 |     fd = open(path.c_str(), O_RDONLY); | 
 | 162 |     if (fd < 0) | 
 | 163 |     { | 
 | 164 |         std::cerr << "PSU sub event failed to open file\n"; | 
 | 165 |         return; | 
 | 166 |     } | 
 | 167 |     inputDev.assign(fd); | 
 | 168 |  | 
| Cheng C Yang | 5665db2 | 2019-07-12 00:57:30 +0800 | [diff] [blame] | 169 |     auto found = logID.find(eventName); | 
 | 170 |     if (found == logID.end()) | 
 | 171 |     { | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 172 |         assertMessage.clear(); | 
 | 173 |         deassertMessage.clear(); | 
| Cheng C Yang | 5665db2 | 2019-07-12 00:57:30 +0800 | [diff] [blame] | 174 |     } | 
 | 175 |     else | 
 | 176 |     { | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 177 |         assertMessage = found->second.first; | 
 | 178 |         deassertMessage = found->second.second; | 
| Cheng C Yang | 5665db2 | 2019-07-12 00:57:30 +0800 | [diff] [blame] | 179 |     } | 
 | 180 |  | 
 | 181 |     auto fanPos = path.find("fan"); | 
 | 182 |     if (fanPos != std::string::npos) | 
 | 183 |     { | 
 | 184 |         fanName = path.substr(fanPos); | 
| Ed Tanous | 8a57ec0 | 2020-10-09 12:46:52 -0700 | [diff] [blame] | 185 |         auto fanNamePos = fanName.find('_'); | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 186 |         if (fanNamePos != std::string::npos) | 
 | 187 |         { | 
 | 188 |             fanName = fanName.substr(0, fanNamePos); | 
 | 189 |         } | 
| Cheng C Yang | 5665db2 | 2019-07-12 00:57:30 +0800 | [diff] [blame] | 190 |     } | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 191 | } | 
 | 192 |  | 
| Konstantin Aladyshev | c7a1ae6 | 2021-04-30 08:50:43 +0000 | [diff] [blame] | 193 | PSUSubEvent::~PSUSubEvent() | 
 | 194 | { | 
 | 195 |     waitTimer.cancel(); | 
 | 196 |     inputDev.close(); | 
 | 197 | } | 
 | 198 |  | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 199 | void PSUSubEvent::setupRead(void) | 
 | 200 | { | 
| Konstantin Aladyshev | c7a1ae6 | 2021-04-30 08:50:43 +0000 | [diff] [blame] | 201 |     if (!readingStateGood(readState)) | 
 | 202 |     { | 
 | 203 |         // Deassert the event | 
 | 204 |         updateValue(0); | 
 | 205 |         restartRead(); | 
 | 206 |         return; | 
 | 207 |     } | 
 | 208 |  | 
| Yong Li | bf8b1da | 2020-04-15 16:32:50 +0800 | [diff] [blame] | 209 |     std::shared_ptr<boost::asio::streambuf> buffer = | 
 | 210 |         std::make_shared<boost::asio::streambuf>(); | 
 | 211 |     std::weak_ptr<PSUSubEvent> weakRef = weak_from_this(); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 212 |     boost::asio::async_read_until( | 
| Yong Li | bf8b1da | 2020-04-15 16:32:50 +0800 | [diff] [blame] | 213 |         inputDev, *buffer, '\n', | 
 | 214 |         [weakRef, buffer](const boost::system::error_code& ec, | 
 | 215 |                           std::size_t /*bytes_transfered*/) { | 
 | 216 |             std::shared_ptr<PSUSubEvent> self = weakRef.lock(); | 
 | 217 |             if (self) | 
 | 218 |             { | 
 | 219 |                 self->readBuf = buffer; | 
 | 220 |                 self->handleResponse(ec); | 
 | 221 |             } | 
 | 222 |         }); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 223 | } | 
 | 224 |  | 
| Konstantin Aladyshev | c7a1ae6 | 2021-04-30 08:50:43 +0000 | [diff] [blame] | 225 | void PSUSubEvent::restartRead() | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 226 | { | 
| Konstantin Aladyshev | c7a1ae6 | 2021-04-30 08:50:43 +0000 | [diff] [blame] | 227 |     std::weak_ptr<PSUSubEvent> weakRef = weak_from_this(); | 
 | 228 |     waitTimer.expires_from_now(boost::posix_time::milliseconds(eventPollMs)); | 
 | 229 |     waitTimer.async_wait([weakRef](const boost::system::error_code& ec) { | 
 | 230 |         if (ec == boost::asio::error::operation_aborted) | 
 | 231 |         { | 
 | 232 |             return; | 
 | 233 |         } | 
 | 234 |         std::shared_ptr<PSUSubEvent> self = weakRef.lock(); | 
 | 235 |         if (self) | 
 | 236 |         { | 
 | 237 |             self->setupRead(); | 
 | 238 |         } | 
 | 239 |     }); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 240 | } | 
 | 241 |  | 
 | 242 | void PSUSubEvent::handleResponse(const boost::system::error_code& err) | 
 | 243 | { | 
| Yong Li | bf8b1da | 2020-04-15 16:32:50 +0800 | [diff] [blame] | 244 |     if ((err == boost::system::errc::bad_file_descriptor) || | 
 | 245 |         (err == boost::asio::error::misc_errors::not_found)) | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 246 |     { | 
 | 247 |         return; | 
 | 248 |     } | 
| Yong Li | bf8b1da | 2020-04-15 16:32:50 +0800 | [diff] [blame] | 249 |     std::istream responseStream(readBuf.get()); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 250 |     if (!err) | 
 | 251 |     { | 
 | 252 |         std::string response; | 
 | 253 |         try | 
 | 254 |         { | 
 | 255 |             std::getline(responseStream, response); | 
| Josh Lehan | 833661a | 2020-03-04 17:35:41 -0800 | [diff] [blame] | 256 |             int nvalue = std::stoi(response); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 257 |             responseStream.clear(); | 
| Josh Lehan | 833661a | 2020-03-04 17:35:41 -0800 | [diff] [blame] | 258 |  | 
 | 259 |             updateValue(nvalue); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 260 |             errCount = 0; | 
 | 261 |         } | 
 | 262 |         catch (const std::invalid_argument&) | 
 | 263 |         { | 
 | 264 |             errCount++; | 
 | 265 |         } | 
 | 266 |     } | 
 | 267 |     else | 
 | 268 |     { | 
 | 269 |         errCount++; | 
 | 270 |     } | 
 | 271 |     if (errCount >= warnAfterErrorCount) | 
 | 272 |     { | 
 | 273 |         if (errCount == warnAfterErrorCount) | 
 | 274 |         { | 
 | 275 |             std::cerr << "Failure to read event at " << path << "\n"; | 
 | 276 |         } | 
 | 277 |         updateValue(0); | 
 | 278 |         errCount++; | 
 | 279 |     } | 
| Cheng C Yang | a97f134 | 2020-02-11 15:10:41 +0800 | [diff] [blame] | 280 |     lseek(fd, 0, SEEK_SET); | 
| Konstantin Aladyshev | c7a1ae6 | 2021-04-30 08:50:43 +0000 | [diff] [blame] | 281 |     restartRead(); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 282 | } | 
 | 283 |  | 
 | 284 | // Any of the sub events of one event is asserted, then the event will be | 
 | 285 | // asserted. Only if none of the sub events are asserted, the event will be | 
 | 286 | // deasserted. | 
 | 287 | void PSUSubEvent::updateValue(const int& newValue) | 
 | 288 | { | 
| Josh Lehan | 833661a | 2020-03-04 17:35:41 -0800 | [diff] [blame] | 289 |     // Take no action if value already equal | 
 | 290 |     // Same semantics as Sensor::updateValue(const double&) | 
 | 291 |     if (newValue == value) | 
 | 292 |     { | 
 | 293 |         return; | 
 | 294 |     } | 
 | 295 |  | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 296 |     if (newValue == 0) | 
 | 297 |     { | 
| Yong Li | 591b1e4 | 2019-12-19 17:46:31 +0800 | [diff] [blame] | 298 |         // log deassert only after all asserts are gone | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 299 |         if (!(*asserts).empty()) | 
 | 300 |         { | 
| Yong Li | 591b1e4 | 2019-12-19 17:46:31 +0800 | [diff] [blame] | 301 |             auto found = (*asserts).find(path); | 
 | 302 |             if (found == (*asserts).end()) | 
 | 303 |             { | 
 | 304 |                 return; | 
 | 305 |             } | 
 | 306 |             (*asserts).erase(path); | 
 | 307 |  | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 308 |             return; | 
 | 309 |         } | 
 | 310 |         if (*assertState == true) | 
 | 311 |         { | 
 | 312 |             *assertState = false; | 
| Cheng C Yang | 202a1ff | 2020-01-09 09:34:22 +0800 | [diff] [blame] | 313 |             auto foundCombine = (*combineEvent).find(groupEventName); | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 314 |             if (foundCombine == (*combineEvent).end()) | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 315 |             { | 
 | 316 |                 return; | 
 | 317 |             } | 
| Cheng C Yang | 202a1ff | 2020-01-09 09:34:22 +0800 | [diff] [blame] | 318 |             (*combineEvent).erase(groupEventName); | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 319 |             if (!deassertMessage.empty()) | 
 | 320 |             { | 
 | 321 |                 // Fan Failed has two args | 
 | 322 |                 std::string sendMessage = eventName + " deassert"; | 
 | 323 |                 if (deassertMessage == "OpenBMC.0.1.PowerSupplyFanRecovered") | 
 | 324 |                 { | 
 | 325 |                     sd_journal_send( | 
 | 326 |                         "MESSAGE=%s", sendMessage.c_str(), "PRIORITY=%i", | 
| Yong Li | 591b1e4 | 2019-12-19 17:46:31 +0800 | [diff] [blame] | 327 |                         LOG_INFO, "REDFISH_MESSAGE_ID=%s", | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 328 |                         deassertMessage.c_str(), "REDFISH_MESSAGE_ARGS=%s,%s", | 
 | 329 |                         psuName.c_str(), fanName.c_str(), NULL); | 
 | 330 |                 } | 
 | 331 |                 else | 
 | 332 |                 { | 
 | 333 |                     sd_journal_send( | 
 | 334 |                         "MESSAGE=%s", sendMessage.c_str(), "PRIORITY=%i", | 
| Yong Li | 591b1e4 | 2019-12-19 17:46:31 +0800 | [diff] [blame] | 335 |                         LOG_INFO, "REDFISH_MESSAGE_ID=%s", | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 336 |                         deassertMessage.c_str(), "REDFISH_MESSAGE_ARGS=%s", | 
 | 337 |                         psuName.c_str(), NULL); | 
 | 338 |                 } | 
 | 339 |             } | 
 | 340 |  | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 341 |             if ((*combineEvent).empty()) | 
 | 342 |             { | 
 | 343 |                 eventInterface->set_property("functional", true); | 
 | 344 |             } | 
 | 345 |         } | 
 | 346 |     } | 
 | 347 |     else | 
 | 348 |     { | 
| Paul Fertser | 3453354 | 2021-07-20 08:29:09 +0000 | [diff] [blame] | 349 |         std::cerr << "PSUSubEvent asserted by " << path << "\n"; | 
 | 350 |  | 
| Yong Li | 591b1e4 | 2019-12-19 17:46:31 +0800 | [diff] [blame] | 351 |         if ((*assertState == false) && ((*asserts).empty())) | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 352 |         { | 
 | 353 |             *assertState = true; | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 354 |             if (!assertMessage.empty()) | 
| Cheng C Yang | 5665db2 | 2019-07-12 00:57:30 +0800 | [diff] [blame] | 355 |             { | 
| Yong Li | 3046a02 | 2020-04-03 13:01:02 +0800 | [diff] [blame] | 356 |                 // For failure and configure error, spec requires a beep | 
 | 357 |                 if ((assertMessage == "OpenBMC.0.1.PowerSupplyFailed") || | 
 | 358 |                     (assertMessage == | 
 | 359 |                      "OpenBMC.0.1.PowerSupplyConfigurationError")) | 
 | 360 |                 { | 
 | 361 |                     std::cout << " beep for " << assertMessage << "\n"; | 
 | 362 |                     beep(beepPSUFailure); | 
 | 363 |                 } | 
 | 364 |  | 
| Cheng C Yang | 5665db2 | 2019-07-12 00:57:30 +0800 | [diff] [blame] | 365 |                 // Fan Failed has two args | 
 | 366 |                 std::string sendMessage = eventName + " assert"; | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 367 |                 if (assertMessage == "OpenBMC.0.1.PowerSupplyFanFailed") | 
| Cheng C Yang | 5665db2 | 2019-07-12 00:57:30 +0800 | [diff] [blame] | 368 |                 { | 
| Cheng C Yang | 9b53a62 | 2019-08-27 22:13:58 +0800 | [diff] [blame] | 369 |                     sd_journal_send( | 
 | 370 |                         "MESSAGE=%s", sendMessage.c_str(), "PRIORITY=%i", | 
| Yong Li | 591b1e4 | 2019-12-19 17:46:31 +0800 | [diff] [blame] | 371 |                         LOG_WARNING, "REDFISH_MESSAGE_ID=%s", | 
 | 372 |                         assertMessage.c_str(), "REDFISH_MESSAGE_ARGS=%s,%s", | 
 | 373 |                         psuName.c_str(), fanName.c_str(), NULL); | 
| Cheng C Yang | 5665db2 | 2019-07-12 00:57:30 +0800 | [diff] [blame] | 374 |                 } | 
 | 375 |                 else | 
 | 376 |                 { | 
 | 377 |                     sd_journal_send( | 
 | 378 |                         "MESSAGE=%s", sendMessage.c_str(), "PRIORITY=%i", | 
| Yong Li | 591b1e4 | 2019-12-19 17:46:31 +0800 | [diff] [blame] | 379 |                         LOG_WARNING, "REDFISH_MESSAGE_ID=%s", | 
 | 380 |                         assertMessage.c_str(), "REDFISH_MESSAGE_ARGS=%s", | 
 | 381 |                         psuName.c_str(), NULL); | 
| Cheng C Yang | 5665db2 | 2019-07-12 00:57:30 +0800 | [diff] [blame] | 382 |                 } | 
 | 383 |             } | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 384 |             if ((*combineEvent).empty()) | 
 | 385 |             { | 
 | 386 |                 eventInterface->set_property("functional", false); | 
 | 387 |             } | 
| Cheng C Yang | 202a1ff | 2020-01-09 09:34:22 +0800 | [diff] [blame] | 388 |             (*combineEvent).emplace(groupEventName); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 389 |         } | 
| Yong Li | 591b1e4 | 2019-12-19 17:46:31 +0800 | [diff] [blame] | 390 |         (*asserts).emplace(path); | 
| Cheng C Yang | 58b2b53 | 2019-05-31 00:19:45 +0800 | [diff] [blame] | 391 |     } | 
 | 392 |     value = newValue; | 
 | 393 | } | 
| Yong Li | 3046a02 | 2020-04-03 13:01:02 +0800 | [diff] [blame] | 394 |  | 
 | 395 | void PSUSubEvent::beep(const uint8_t& beepPriority) | 
 | 396 | { | 
 | 397 |     systemBus->async_method_call( | 
 | 398 |         [](boost::system::error_code ec) { | 
 | 399 |             if (ec) | 
 | 400 |             { | 
 | 401 |                 std::cerr << "beep error (ec = " << ec << ")\n"; | 
 | 402 |                 return; | 
 | 403 |             } | 
 | 404 |         }, | 
 | 405 |         "xyz.openbmc_project.BeepCode", "/xyz/openbmc_project/BeepCode", | 
 | 406 |         "xyz.openbmc_project.BeepCode", "Beep", uint8_t(beepPriority)); | 
 | 407 | } |