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