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