| // Copyright 2024 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "hoth_state.hpp" |
| |
| #include "google3/host_commands.h" |
| |
| #include "ec_util_interface.hpp" |
| |
| #include <stdplus/print.hpp> |
| #include <stdplus/raw.hpp> |
| #include <xyz/openbmc_project/Control/Hoth/State/error.hpp> |
| |
| #include <chrono> |
| #include <cstdint> |
| #include <cstring> |
| #include <exception> |
| #include <functional> |
| #include <future> |
| |
| namespace google |
| { |
| namespace hoth |
| { |
| namespace |
| { |
| |
| constexpr uint32_t kTimerIntervalSeconds = 20; |
| |
| template <typename T> |
| bool statisticsReponseHasEnoughWords(const ec_response_statistics& stats, |
| const T& field) |
| { |
| uint64_t offset_required = |
| (uint64_t)&field - (uint64_t)&stats + sizeof(field); |
| return stats.valid_words * 4 >= offset_required; |
| } |
| } // namespace |
| |
| HothState::HothState(sdbusplus::bus::bus& bus, boost::asio::io_context& io, |
| const char* objPath, internal::HostCommand* hostCmd, |
| internal::EcUtil* ecutil) : |
| HothStateObject(bus, objPath), bus(bus), io(io), hostCmd(hostCmd), |
| ecUtil(ecutil), timer(io) |
| { |
| // Update metrics immediately while kicking off the timer. |
| timerUpdateMetrics(); |
| } |
| |
| void HothState::updateMetrics() |
| { |
| statistics = ecUtil->getHothStatistics(); |
| |
| // Emit the signal that property has changed. |
| // Fall back to default values if response does not contain enought words. |
| HothStateObject::resetFlags( |
| statisticsReponseHasEnoughWords(statistics, statistics.hoth_reset_flags) |
| ? (uint32_t)statistics.hoth_reset_flags |
| : 0); |
| HothStateObject::upTime(statisticsReponseHasEnoughWords( |
| statistics, statistics.time_since_hoth_boot_us) |
| ? (uint64_t)statistics.time_since_hoth_boot_us |
| : 0); |
| HothStateObject::roInfoStrikes( |
| statisticsReponseHasEnoughWords(statistics, statistics.ro_info_strikes) |
| ? (uint32_t)statistics.ro_info_strikes |
| : 0xffffffff); |
| HothStateObject::rwInfoStrikes( |
| statisticsReponseHasEnoughWords(statistics, statistics.rw_info_strikes) |
| ? (uint32_t)statistics.rw_info_strikes |
| : 0xffffffff); |
| HothStateObject::payloadUpdateFailureCode( |
| statisticsReponseHasEnoughWords( |
| statistics, statistics.payload_update_failure_reason) |
| ? (uint16_t)statistics.payload_update_failure_reason |
| : 0xffff); |
| HothStateObject::payloadConfirmFailureCode( |
| statisticsReponseHasEnoughWords( |
| statistics, |
| statistics.payload_update_confirmation_cookie_failure_reason) |
| ? (uint32_t) |
| statistics.payload_update_confirmation_cookie_failure_reason |
| : 0xffffffff); |
| HothStateObject::firmwareUpdateFailureCode( |
| statisticsReponseHasEnoughWords( |
| statistics, statistics.firmware_update_failure_reason) |
| ? (uint16_t)statistics.firmware_update_failure_reason |
| : 0xffff); |
| HothStateObject::firmwareUpdateFailedMinor( |
| statisticsReponseHasEnoughWords( |
| statistics, statistics.failed_firmware_minor_version) |
| ? (uint32_t)statistics.failed_firmware_minor_version |
| : 0xffffffff); |
| HothStateObject::bootloaderUpdateFailureCode( |
| statisticsReponseHasEnoughWords(statistics, |
| statistics.bootloader_update_error) |
| ? (uint32_t)statistics.bootloader_update_error |
| : 0xffffffff); |
| |
| HothStateObject::hasPersistentPanicInfo( |
| ecUtil->checkHothPersistentPanicInfo()); |
| } |
| |
| void HothState::timerUpdateMetrics() |
| { |
| try |
| { |
| updateMetrics(); |
| } |
| catch (const std::exception& e) |
| { |
| stdplus::print(stderr, "Fetching Hoth metrics had an exception: {}\n", |
| e.what()); |
| } |
| timer.expires_after(std::chrono::seconds(kTimerIntervalSeconds)); |
| // NOLINTNEXTLINE(modernize-avoid-bind) |
| timer.async_wait(std::bind(&HothState::timerUpdateMetrics, this)); |
| } |
| |
| } // namespace hoth |
| |
| } // namespace google |