1 #pragma once 2 #include "libpldm/entity.h" 3 #include "libpldm/platform.h" 4 5 #include "inband_code_update.hpp" 6 #include "libpldmresponder/oem_handler.hpp" 7 #include "libpldmresponder/pdr_utils.hpp" 8 #include "libpldmresponder/platform.hpp" 9 #include "requester/handler.hpp" 10 11 namespace pldm 12 { 13 namespace responder 14 { 15 namespace oem_ibm_platform 16 { 17 18 #define PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE 32768 19 #define PLDM_OEM_IBM_BOOT_STATE 32769 20 #define PLDM_OEM_IBM_SYSTEM_POWER_STATE 32771 21 22 static constexpr auto PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE = 24577; 23 static constexpr auto PLDM_OEM_IBM_VERIFICATION_STATE = 32770; 24 constexpr uint16_t ENTITY_INSTANCE_0 = 0; 25 constexpr uint16_t ENTITY_INSTANCE_1 = 1; 26 27 enum class CodeUpdateState : uint8_t 28 { 29 START = 0x1, 30 END = 0x2, 31 FAIL = 0x3, 32 ABORT = 0x4, 33 ACCEPT = 0x5, 34 REJECT = 0x6 35 }; 36 37 enum VerificationStateValues 38 { 39 VALID = 0x0, 40 ENTITLEMENT_FAIL = 0x1, 41 BANNED_PLATFORM_FAIL = 0x2, 42 MIN_MIF_FAIL = 0x4, 43 }; 44 45 enum SystemPowerStates 46 { 47 POWER_CYCLE_HARD = 0x1, 48 }; 49 50 enum SetEventReceiverCount 51 { 52 SET_EVENT_RECEIVER_SENT = 0x2, 53 }; 54 55 class Handler : public oem_platform::Handler 56 { 57 public: 58 Handler(const pldm::utils::DBusHandler* dBusIntf, 59 pldm::responder::CodeUpdate* codeUpdate, int mctp_fd, 60 uint8_t mctp_eid, pldm::dbus_api::Requester& requester, 61 sdeventplus::Event& event, 62 pldm::requester::Handler<pldm::requester::Request>* handler) : 63 oem_platform::Handler(dBusIntf), 64 codeUpdate(codeUpdate), platformHandler(nullptr), mctp_fd(mctp_fd), 65 mctp_eid(mctp_eid), requester(requester), event(event), handler(handler) 66 { 67 codeUpdate->setVersions(); 68 setEventReceiverCnt = 0; 69 70 using namespace sdbusplus::bus::match::rules; 71 hostOffMatch = std::make_unique<sdbusplus::bus::match::match>( 72 pldm::utils::DBusHandler::getBus(), 73 propertiesChanged("/xyz/openbmc_project/state/host0", 74 "xyz.openbmc_project.State.Host"), 75 [this](sdbusplus::message::message& msg) { 76 pldm::utils::DbusChangedProps props{}; 77 std::string intf; 78 msg.read(intf, props); 79 const auto itr = props.find("CurrentHostState"); 80 if (itr != props.end()) 81 { 82 pldm::utils::PropertyValue value = itr->second; 83 auto propVal = std::get<std::string>(value); 84 if (propVal == 85 "xyz.openbmc_project.State.Host.HostState.Off") 86 { 87 hostOff = true; 88 setEventReceiverCnt = 0; 89 disableWatchDogTimer(); 90 } 91 else if (propVal == 92 "xyz.openbmc_project.State.Host.HostState.Running") 93 { 94 hostOff = false; 95 } 96 } 97 }); 98 } 99 100 int getOemStateSensorReadingsHandler( 101 EntityType entityType, pldm::pdr::EntityInstance entityInstance, 102 pldm::pdr::StateSetId stateSetId, 103 pldm::pdr::CompositeCount compSensorCnt, 104 std::vector<get_sensor_state_field>& stateField); 105 106 int oemSetStateEffecterStatesHandler( 107 uint16_t entityType, uint16_t entityInstance, uint16_t stateSetId, 108 uint8_t compEffecterCnt, 109 std::vector<set_effecter_state_field>& stateField, uint16_t effecterId); 110 111 /** @brief Method to set the platform handler in the 112 * oem_ibm_handler class 113 * @param[in] handler - pointer to PLDM platform handler 114 */ 115 void setPlatformHandler(pldm::responder::platform::Handler* handler); 116 117 /** @brief Method to fetch the effecter ID of the code update PDRs 118 * 119 * @return platformHandler->getNextEffecterId() - returns the 120 * effecter ID from the platform handler 121 */ 122 virtual uint16_t getNextEffecterId() 123 { 124 return platformHandler->getNextEffecterId(); 125 } 126 127 /** @brief Method to fetch the sensor ID of the code update PDRs 128 * 129 * @return platformHandler->getNextSensorId() - returns the 130 * Sensor ID from the platform handler 131 */ 132 virtual uint16_t getNextSensorId() 133 { 134 return platformHandler->getNextSensorId(); 135 } 136 137 /** @brief Method to Generate the OEM PDRs 138 * 139 * @param[in] repo - instance of concrete implementation of Repo 140 */ 141 void buildOEMPDR(pdr_utils::Repo& repo); 142 143 /** @brief Method to send code update event to host 144 * @param[in] sensorId - sendor ID 145 * @param[in] sensorEventClass - event class of sensor 146 * @param[in] sensorOffset - sensor offset 147 * @param[in] eventState - new code update event state 148 * @param[in] prevEventState - previous code update event state 149 * @return none 150 */ 151 void sendStateSensorEvent(uint16_t sensorId, 152 enum sensor_event_class_states sensorEventClass, 153 uint8_t sensorOffset, uint8_t eventState, 154 uint8_t prevEventState); 155 156 /** @brief Method to send encoded request msg of code update event to host 157 * @param[in] requestMsg - encoded request msg 158 * @param[in] instanceId - instance id of the message 159 * @return PLDM status code 160 */ 161 int sendEventToHost(std::vector<uint8_t>& requestMsg, uint8_t instanceId); 162 163 /** @brief _processEndUpdate processes the actual work that needs 164 * to be carried out after EndUpdate effecter is set. This is done async 165 * after sending response for EndUpdate set effecter 166 * @param[in] source - sdeventplus event source 167 */ 168 void _processEndUpdate(sdeventplus::source::EventBase& source); 169 170 /** @brief _processStartUpdate processes the actual work that needs 171 * to be carried out after StartUpdate effecter is set. This is done async 172 * after sending response for StartUpdate set effecter 173 * @param[in] source - sdeventplus event source 174 */ 175 void _processStartUpdate(sdeventplus::source::EventBase& source); 176 177 /** @brief _processSystemReboot processes the actual work that needs to be 178 * carried out after the System Power State effecter is set to reboot 179 * the system 180 * @param[in] source - sdeventplus event source 181 */ 182 void _processSystemReboot(sdeventplus::source::EventBase& source); 183 184 /*keeps track how many times setEventReceiver is sent */ 185 void countSetEventReceiver() 186 { 187 setEventReceiverCnt++; 188 } 189 190 /* disables watchdog if running and Host is up */ 191 void checkAndDisableWatchDog(); 192 193 /** @brief To check if the watchdog app is running 194 * 195 * @return the running status of watchdog app 196 */ 197 bool watchDogRunning(); 198 199 /** @brief Method to reset the Watchdog timer on receiving platform Event 200 * Message for heartbeat elapsed time from Hostboot 201 */ 202 void resetWatchDogTimer(); 203 204 /** @brief To disable to the watchdog timer on host poweron completion*/ 205 void disableWatchDogTimer(); 206 207 ~Handler() = default; 208 209 pldm::responder::CodeUpdate* codeUpdate; //!< pointer to CodeUpdate object 210 pldm::responder::platform::Handler* 211 platformHandler; //!< pointer to PLDM platform handler 212 213 /** @brief fd of MCTP communications socket */ 214 int mctp_fd; 215 216 /** @brief MCTP EID of host firmware */ 217 uint8_t mctp_eid; 218 219 /** @brief reference to Requester object, primarily used to access API to 220 * obtain PLDM instance id. 221 */ 222 pldm::dbus_api::Requester& requester; 223 /** @brief sdeventplus event source */ 224 std::unique_ptr<sdeventplus::source::Defer> assembleImageEvent; 225 std::unique_ptr<sdeventplus::source::Defer> startUpdateEvent; 226 std::unique_ptr<sdeventplus::source::Defer> systemRebootEvent; 227 228 /** @brief reference of main event loop of pldmd, primarily used to schedule 229 * work 230 */ 231 sdeventplus::Event& event; 232 233 private: 234 /** @brief D-Bus property changed signal match for CurrentPowerState*/ 235 std::unique_ptr<sdbusplus::bus::match::match> chassisOffMatch; 236 237 /** @brief PLDM request handler */ 238 pldm::requester::Handler<pldm::requester::Request>* handler; 239 240 /** @brief D-Bus property changed signal match */ 241 std::unique_ptr<sdbusplus::bus::match::match> hostOffMatch; 242 243 bool hostOff = true; 244 245 int setEventReceiverCnt = 0; 246 }; 247 248 /** @brief Method to encode code update event msg 249 * @param[in] eventType - type of event 250 * @param[in] eventDataVec - vector of event data to be sent to host 251 * @param[in/out] requestMsg - request msg to be encoded 252 * @param[in] instanceId - instance ID 253 * @return PLDM status code 254 */ 255 int encodeEventMsg(uint8_t eventType, const std::vector<uint8_t>& eventDataVec, 256 std::vector<uint8_t>& requestMsg, uint8_t instanceId); 257 258 } // namespace oem_ibm_platform 259 260 } // namespace responder 261 262 } // namespace pldm 263