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