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), package(package), fwDeviceIDRecord(fwDeviceIDRecord), 57 compImageInfos(compImageInfos), compInfo(compInfo), 58 maxTransferSize(maxTransferSize), updateManager(updateManager) 59 {} 60 61 /** @brief Start the firmware update flow for the FD 62 * 63 * To start the update flow RequestUpdate command is sent to the FD. 64 * 65 */ 66 void startFwUpdateFlow(); 67 68 /** @brief Handler for RequestUpdate command response 69 * 70 * The response of the RequestUpdate is processed and if the response 71 * is success, send PassComponentTable request to FD. 72 * 73 * @param[in] eid - Remote MCTP endpoint 74 * @param[in] response - PLDM response message 75 * @param[in] respMsgLen - Response message length 76 */ 77 void requestUpdate(mctp_eid_t eid, const pldm_msg* response, 78 size_t respMsgLen); 79 80 /** @brief Handler for PassComponentTable command response 81 * 82 * The response of the PassComponentTable is processed. If the response 83 * indicates component can be updated, continue with either a) or b). 84 * 85 * a. Send PassComponentTable request for the next component if 86 * applicable 87 * b. UpdateComponent command to request updating a specific 88 * firmware component 89 * 90 * If the response indicates component may be updateable, continue 91 * based on the policy in DeviceUpdateOptionFlags. 92 * 93 * @param[in] eid - Remote MCTP endpoint 94 * @param[in] response - PLDM response message 95 * @param[in] respMsgLen - Response message length 96 */ 97 void passCompTable(mctp_eid_t eid, const pldm_msg* response, 98 size_t respMsgLen); 99 100 /** @brief Handler for UpdateComponent command response 101 * 102 * The response of the UpdateComponent is processed and will wait for 103 * FD to request the firmware data. 104 * 105 * @param[in] eid - Remote MCTP endpoint 106 * @param[in] response - PLDM response message 107 * @param[in] respMsgLen - Response message length 108 */ 109 void updateComponent(mctp_eid_t eid, const pldm_msg* response, 110 size_t respMsgLen); 111 112 /** @brief Handler for RequestFirmwareData request 113 * 114 * @param[in] request - Request message 115 * @param[in] payload_length - Request message payload length 116 * @return Response - PLDM Response message 117 */ 118 Response requestFwData(const pldm_msg* request, size_t payloadLength); 119 120 /** @brief Handler for TransferComplete request 121 * 122 * @param[in] request - Request message 123 * @param[in] payload_length - Request message payload length 124 * @return Response - PLDM Response message 125 */ 126 Response transferComplete(const pldm_msg* request, size_t payloadLength); 127 128 /** @brief Handler for VerifyComplete request 129 * 130 * @param[in] request - Request message 131 * @param[in] payload_length - Request message payload length 132 * @return Response - PLDM Response message 133 */ 134 Response verifyComplete(const pldm_msg* request, size_t payloadLength); 135 136 /** @brief Handler for ApplyComplete request 137 * 138 * @param[in] request - Request message 139 * @param[in] payload_length - Request message payload length 140 * @return Response - PLDM Response message 141 */ 142 Response applyComplete(const pldm_msg* request, size_t payloadLength); 143 144 /** @brief Handler for ActivateFirmware command response 145 * 146 * The response of the ActivateFirmware is processed and will update the 147 * UpdateManager with the completion of the firmware update. 148 * 149 * @param[in] eid - Remote MCTP endpoint 150 * @param[in] response - PLDM response message 151 * @param[in] respMsgLen - Response message length 152 */ 153 void activateFirmware(mctp_eid_t eid, const pldm_msg* response, 154 size_t respMsgLen); 155 156 private: 157 /** @brief Send PassComponentTable command request 158 * 159 * @param[in] compOffset - component offset in compImageInfos 160 */ 161 void sendPassCompTableRequest(size_t offset); 162 163 /** @brief Send UpdateComponent command request 164 * 165 * @param[in] compOffset - component offset in compImageInfos 166 */ 167 void sendUpdateComponentRequest(size_t offset); 168 169 /** @brief Send ActivateFirmware command request */ 170 void sendActivateFirmwareRequest(); 171 172 /** @brief Endpoint ID of the firmware device */ 173 mctp_eid_t eid; 174 175 /** @brief File stream for firmware update package */ 176 std::ifstream& package; 177 178 /** @brief FirmwareDeviceIDRecord in the fw update package that matches this 179 * firmware device 180 */ 181 const FirmwareDeviceIDRecord& fwDeviceIDRecord; 182 183 /** @brief Component image information for all the components in the fw 184 * update package 185 */ 186 const ComponentImageInfos& compImageInfos; 187 188 /** @brief Component info for the components in this FD derived from 189 * GetFirmwareParameters response 190 */ 191 const ComponentInfo& compInfo; 192 193 /** @brief Maximum size in bytes of the variable payload to be requested by 194 * the FD via RequestFirmwareData command 195 */ 196 uint32_t maxTransferSize; 197 198 /** @brief To update the status of fw update of the FD */ 199 UpdateManager* updateManager; 200 201 /** @brief Component index is used to track the current component being 202 * updated if multiple components are applicable for the FD. 203 * It is also used to keep track of the next component in 204 * PassComponentTable 205 */ 206 size_t componentIndex = 0; 207 208 /** @brief To send a PLDM request after the current command handling */ 209 std::unique_ptr<sdeventplus::source::Defer> pldmRequest; 210 }; 211 212 } // namespace fw_update 213 214 } // namespace pldm 215