#pragma once #include "occ_status.hpp" #include #include namespace pldm { namespace MatchRules = sdbusplus::bus::match::rules; using CompositeEffecterCount = uint8_t; using EffecterID = uint16_t; using EntityType = uint16_t; using EntityInstance = uint16_t; using EventState = uint8_t; using OccInstanceToEffecter = std::map; using PdrList = std::vector>; using SensorID = uint16_t; using SensorOffset = uint8_t; using SensorToOCCInstance = std::map; using TerminusID = uint8_t; /** @brief Hardcoded TID */ constexpr TerminusID tid = 0; /** @brief OCC instance starts with 0 for example "occ0" */ constexpr open_power::occ::instanceID start = 0; /** @brief Hardcoded mctpEid for HBRT */ constexpr mctp_eid_t mctpEid = 10; /** @class Interface * * @brief Abstracts the PLDM details related to the OCC */ class Interface { public: Interface() = delete; ~Interface() = default; Interface(const Interface&) = delete; Interface& operator=(const Interface&) = delete; Interface(Interface&&) = delete; Interface& operator=(Interface&&) = delete; /** @brief Constructs the PLDM Interface object for OCC functions * * @param[in] bus - reference to systemd bus * @param[in] callBack - callBack handler to invoke when the OCC state * changes. */ explicit Interface( sdbusplus::bus::bus& bus, std::function callBack) : bus(bus), callBack(callBack), pldmEventSignal( bus, MatchRules::type::signal() + MatchRules::member("StateSensorEvent") + MatchRules::path("/xyz/openbmc_project/pldm") + MatchRules::interface("xyz.openbmc_project.PLDM.Event"), std::bind(std::mem_fn(&Interface::sensorEvent), this, std::placeholders::_1)), hostStateSignal( bus, MatchRules::propertiesChanged("/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host"), std::bind(std::mem_fn(&Interface::hostStateEvent), this, std::placeholders::_1)) { } /** @brief Fetch the OCC state sensor PDRs and populate the cache with * sensorId to OCC instance mapping information and the sensor * offset for Operational Running Status. * * @param[in] pdrs - OCC state sensor PDRs * @param[out] sensorInstanceMap - map of sensorID to OCC instance * @param[out] sensorOffset - sensor offset of interested state set ID */ void fetchOCCSensorInfo(const PdrList& pdrs, SensorToOCCInstance& sensorInstanceMap, SensorOffset& sensorOffset); /** @brief Fetch the OCC state effecter PDRs and populate the cache with * OCC instance to EffecterID information. * * @param[in] pdrs - OCC state effecter PDRs * @param[out] instanceToEffecterMap - map of OCC instance to effecterID * @param[out] count - sensor offset of interested state set ID * @param[out] bootRestartPos - position of Boot/Restart Cause stateSetID */ void fetchOCCEffecterInfo(const PdrList& pdrs, OccInstanceToEffecter& instanceToEffecterMap, CompositeEffecterCount& count, uint8_t& bootRestartPos); /** @brief Prepare the request for SetStateEffecterStates command * * @param[in] instanceId - PLDM instanceID * @param[in] instanceToEffecterMap - map of OCC instance to effecterID * @param[in] count - compositeEffecterCount for OCC reset effecter PDR * @param[in] bootRestartPos - position of Boot/Restart Cause stateSetID * * @return PLDM request message to be sent to host for OCC reset, empty * response in the case of failure. */ std::vector prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId, CompositeEffecterCount effecterCount, uint8_t bootRestartPos); /** @brief Send the PLDM message to reset the OCC * * @param[in] instanceId - OCC instance to reset * */ void resetOCC(open_power::occ::instanceID occInstanceId); private: /** @brief reference to the systemd bus*/ sdbusplus::bus::bus& bus; /** @brief Callback handler to be invoked when the state of the OCC * changes */ std::function callBack = nullptr; /** @brief Used to subscribe to D-Bus PLDM StateSensorEvent signal and * processes if the event corresponds to OCC state change. */ sdbusplus::bus::match_t pldmEventSignal; /** @brief Used to subscribe for host state change signal */ sdbusplus::bus::match_t hostStateSignal; /** @brief PLDM Sensor ID to OCC Instance mapping */ SensorToOCCInstance sensorToOCCInstance; /** @brief Sensor offset of state set ID * PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS in state sensor PDR. */ SensorOffset sensorOffset; /** @brief OCC Instance mapping to PLDM Effecter ID */ OccInstanceToEffecter occInstanceToEffecter; /** @brief compositeEffecterCount for OCC reset state effecter PDR */ CompositeEffecterCount effecterCount = 0; /** @brief Position of Boot/Restart Cause stateSetID in OCC state * effecter PDR */ uint8_t bootRestartPosition = 0; /** @brief When the OCC state changes host sends PlatformEventMessage * StateSensorEvent, this function processes the D-Bus signal * with the sensor event information and invokes the callback * to change the OCC state. * * @param[in] msg - data associated with the subscribed signal */ void sensorEvent(sdbusplus::message::message& msg); /** @brief When the host state changes and if the CurrentHostState is * xyz.openbmc_project.State.Host.HostState.Off then * the cache of OCC sensors and effecters mapping is cleared. * * @param[in] msg - data associated with the subscribed signal */ void hostStateEvent(sdbusplus::message::message& msg); /** @brief Check if the PDR cache for PLDM OCC sensors is valid * * @return true if cache is populated and false if the cache is not * populated. */ auto isOCCSensorCacheValid() { return (sensorToOCCInstance.empty() ? false : true); } /** @brief Check if the PDR cache for PLDM OCC effecters is valid * * @return true if cache is populated and false if the cache is not * populated. */ auto isPDREffecterCacheValid() { return (occInstanceToEffecter.empty() ? false : true); } }; } // namespace pldm