1 #pragma once 2 3 #include "common/types.hpp" 4 #include "requester/handler.hpp" 5 #include "requester/request.hpp" 6 7 #include <sdeventplus/event.hpp> 8 #include <sdeventplus/source/event.hpp> 9 10 #include <fstream> 11 12 namespace pldm 13 { 14 15 namespace fw_update 16 { 17 18 class UpdateManager; 19 20 /** @class DeviceUpdater 21 * 22 * DeviceUpdater orchestrates the firmware update of the firmware device and 23 * updates the UpdateManager about the status once it is complete. 24 */ 25 class DeviceUpdater 26 { 27 public: 28 DeviceUpdater() = delete; 29 DeviceUpdater(const DeviceUpdater&) = delete; 30 DeviceUpdater(DeviceUpdater&&) = default; 31 DeviceUpdater& operator=(const DeviceUpdater&) = delete; 32 DeviceUpdater& operator=(DeviceUpdater&&) = delete; 33 ~DeviceUpdater() = default; 34 35 /** @brief Constructor 36 * 37 * @param[in] eid - Endpoint ID of the firmware device 38 * @param[in] package - File stream for firmware update package 39 * @param[in] fwDeviceIDRecord - FirmwareDeviceIDRecord in the fw update 40 * package that matches this firmware device 41 * @param[in] compImageInfos - Component image information for all the 42 * components in the fw update package 43 * @param[in] compInfo - Component info for the components in this FD 44 * derived from GetFirmwareParameters response 45 * @param[in] maxTransferSize - Maximum size in bytes of the variable 46 * payload allowed to be requested by the FD 47 * @param[in] updateManager - To update the status of fw update of the 48 * device 49 */ 50 explicit DeviceUpdater(mctp_eid_t eid, std::ifstream& package, 51 const FirmwareDeviceIDRecord& fwDeviceIDRecord, 52 const ComponentImageInfos& compImageInfos, 53 const ComponentInfo& compInfo, 54 uint32_t maxTransferSize, 55 UpdateManager* updateManager) : 56 eid(eid), 57 package(package), fwDeviceIDRecord(fwDeviceIDRecord), 58 compImageInfos(compImageInfos), compInfo(compInfo), 59 maxTransferSize(maxTransferSize), updateManager(updateManager) 60 {} 61 62 /** @brief Start the firmware update flow for the FD 63 * 64 * To start the update flow RequestUpdate command is sent to the FD. 65 * 66 */ 67 void startFwUpdateFlow(); 68 69 /** @brief Handler for RequestUpdate command response 70 * 71 * The response of the RequestUpdate is processed and if the response 72 * is success, send PassComponentTable request to FD. 73 * 74 * @param[in] eid - Remote MCTP endpoint 75 * @param[in] response - PLDM response message 76 * @param[in] respMsgLen - Response message length 77 */ 78 void requestUpdate(mctp_eid_t eid, const pldm_msg* response, 79 size_t respMsgLen); 80 81 /** @brief Handler for PassComponentTable command response 82 * 83 * The response of the PassComponentTable is processed. If the response 84 * indicates component can be updated, continue with either a) or b). 85 * 86 * a. Send PassComponentTable request for the next component if 87 * applicable 88 * b. UpdateComponent command to request updating a specific 89 * firmware component 90 * 91 * If the response indicates component may be updateable, continue 92 * based on the policy in DeviceUpdateOptionFlags. 93 * 94 * @param[in] eid - Remote MCTP endpoint 95 * @param[in] response - PLDM response message 96 * @param[in] respMsgLen - Response message length 97 */ 98 void passCompTable(mctp_eid_t eid, const pldm_msg* response, 99 size_t respMsgLen); 100 101 /** @brief Handler for UpdateComponent command response 102 * 103 * The response of the UpdateComponent is processed and will wait for 104 * FD to request the firmware data. 105 * 106 * @param[in] eid - Remote MCTP endpoint 107 * @param[in] response - PLDM response message 108 * @param[in] respMsgLen - Response message length 109 */ 110 void updateComponent(mctp_eid_t eid, const pldm_msg* response, 111 size_t respMsgLen); 112 113 /** @brief Handler for RequestFirmwareData request 114 * 115 * @param[in] request - Request message 116 * @param[in] payload_length - Request message payload length 117 * @return Response - PLDM Response message 118 */ 119 Response requestFwData(const pldm_msg* request, size_t payloadLength); 120 121 /** @brief Handler for TransferComplete request 122 * 123 * @param[in] request - Request message 124 * @param[in] payload_length - Request message payload length 125 * @return Response - PLDM Response message 126 */ 127 Response transferComplete(const pldm_msg* request, size_t payloadLength); 128 129 /** @brief Handler for VerifyComplete request 130 * 131 * @param[in] request - Request message 132 * @param[in] payload_length - Request message payload length 133 * @return Response - PLDM Response message 134 */ 135 Response verifyComplete(const pldm_msg* request, size_t payloadLength); 136 137 /** @brief Handler for ApplyComplete request 138 * 139 * @param[in] request - Request message 140 * @param[in] payload_length - Request message payload length 141 * @return Response - PLDM Response message 142 */ 143 Response applyComplete(const pldm_msg* request, size_t payloadLength); 144 145 /** @brief Handler for ActivateFirmware command response 146 * 147 * The response of the ActivateFirmware is processed and will update the 148 * UpdateManager with the completion of the firmware update. 149 * 150 * @param[in] eid - Remote MCTP endpoint 151 * @param[in] response - PLDM response message 152 * @param[in] respMsgLen - Response message length 153 */ 154 void activateFirmware(mctp_eid_t eid, const pldm_msg* response, 155 size_t respMsgLen); 156 157 private: 158 /** @brief Send PassComponentTable command request 159 * 160 * @param[in] compOffset - component offset in compImageInfos 161 */ 162 void sendPassCompTableRequest(size_t offset); 163 164 /** @brief Send UpdateComponent command request 165 * 166 * @param[in] compOffset - component offset in compImageInfos 167 */ 168 void sendUpdateComponentRequest(size_t offset); 169 170 /** @brief Send ActivateFirmware command request */ 171 void sendActivateFirmwareRequest(); 172 173 /** @brief Endpoint ID of the firmware device */ 174 mctp_eid_t eid; 175 176 /** @brief File stream for firmware update package */ 177 std::ifstream& package; 178 179 /** @brief FirmwareDeviceIDRecord in the fw update package that matches this 180 * firmware device 181 */ 182 const FirmwareDeviceIDRecord& fwDeviceIDRecord; 183 184 /** @brief Component image information for all the components in the fw 185 * update package 186 */ 187 const ComponentImageInfos& compImageInfos; 188 189 /** @brief Component info for the components in this FD derived from 190 * GetFirmwareParameters response 191 */ 192 const ComponentInfo& compInfo; 193 194 /** @brief Maximum size in bytes of the variable payload to be requested by 195 * the FD via RequestFirmwareData command 196 */ 197 uint32_t maxTransferSize; 198 199 /** @brief To update the status of fw update of the FD */ 200 UpdateManager* updateManager; 201 202 /** @brief Component index is used to track the current component being 203 * updated if multiple components are applicable for the FD. 204 * It is also used to keep track of the next component in 205 * PassComponentTable 206 */ 207 size_t componentIndex = 0; 208 209 /** @brief To send a PLDM request after the current command handling */ 210 std::unique_ptr<sdeventplus::source::Defer> pldmRequest; 211 }; 212 213 } // namespace fw_update 214 215 } // namespace pldm 216