1 #pragma once 2 3 #include "common/utils.hpp" 4 #include "libpldmresponder/pdr_utils.hpp" 5 #include "libpldmresponder/platform.hpp" 6 7 #include <string> 8 9 namespace pldm 10 { 11 namespace responder 12 { 13 14 static constexpr uint8_t pSideNum = 1; 15 static constexpr uint8_t tSideNum = 2; 16 static constexpr auto Pside = "P"; 17 static constexpr auto Tside = "T"; 18 19 static constexpr auto redundancyIntf = 20 "xyz.openbmc_project.Software.RedundancyPriority"; 21 22 /** 23 * @struct pldm_boot_side_data 24 * @brief Holds PLDM current/next boot side and the boot side which has the 25 * active image. 26 * 27 * This structure stores the current and next boot side identifiers, 28 * as well as the running version information. 29 * The running version value is an alias to the currently active boot side. 30 * It contains either 'a' or 'b', mapping to the two available boot sides 31 * based on which side is active. 32 */ 33 struct pldm_boot_side_data 34 { 35 std::string current_boot_side; 36 std::string next_boot_side; 37 std::string running_version_object; 38 }; 39 40 /** @class CodeUpdate 41 * 42 * @brief This class performs the necessary operation in pldm for 43 * inband code update. That includes taking actions on the 44 * setStateEffecterStates calls from Host and also sending 45 * notification to phosphor-software-manager app 46 */ 47 class CodeUpdate 48 { 49 public: 50 /** @brief Constructor to create an inband codeupdate object 51 * @param[in] dBusIntf - D-Bus handler pointer 52 */ CodeUpdate(const pldm::utils::DBusHandler * dBusIntf)53 CodeUpdate(const pldm::utils::DBusHandler* dBusIntf) : dBusIntf(dBusIntf) 54 { 55 currBootSide = Tside; 56 nextBootSide = Tside; 57 markerLidSensorId = PLDM_INVALID_EFFECTER_ID; 58 firmwareUpdateSensorId = PLDM_INVALID_EFFECTER_ID; 59 imageActivationMatch = nullptr; 60 } 61 62 /* @brief Method to return the current boot side 63 */ 64 std::string fetchCurrentBootSide(); 65 66 /* @brief Method to return the next boot side 67 */ 68 std::string fetchNextBootSide(); 69 70 /* @brief Method to set the current boot side or 71 * perform a rename operation on current boot side 72 * @param[in] currSide - current side to be set to 73 * @return PLDM_SUCCESS codes 74 */ 75 int setCurrentBootSide(const std::string& currSide); 76 77 /* @brief Method to set the next boot side 78 * @param[in] nextSide - next boot side to be set to 79 * @return PLDM_SUCCESS codes 80 */ 81 int setNextBootSide(const std::string& nextSide); 82 83 /* @brief Method to set the running and non-running 84 * images 85 */ 86 virtual void setVersions(); 87 88 /* @brief Method to return the newly upoaded image id in 89 * /tmp 90 */ fetchnewImageId()91 std::string fetchnewImageId() 92 { 93 return newImageId; 94 } 95 96 /* @brief Method to set the oem platform handler in CodeUpdate class */ 97 void setOemPlatformHandler(pldm::responder::oem_platform::Handler* handler); 98 99 /* @brief Method to check whether code update is 100 * going on 101 * @return - bool 102 */ isCodeUpdateInProgress()103 bool isCodeUpdateInProgress() 104 { 105 return codeUpdateInProgress; 106 } 107 108 /* @brief Method to indicate whether code update 109 * is going on 110 * @param[in] progress - yes/no 111 */ setCodeUpdateProgress(bool progress)112 void setCodeUpdateProgress(bool progress) 113 { 114 codeUpdateInProgress = progress; 115 } 116 117 /** @brief Method to clear contents the LID staging directory that contains 118 * images such as host firmware and BMC. 119 * @param[in] dirPath - directory system path that has to be cleared 120 * @return none 121 */ 122 void clearDirPath(const std::string& dirPath); 123 124 /* @brief Method to set the RequestApplyTime D-Bus property 125 * on start update to OnReset 126 * @return - Completion codes 127 */ 128 int setRequestedApplyTime(); 129 130 /* @brief Method to set the RequestedActivation D-Bus property 131 * on end update to Active by fetching the newImageID and 132 * clearning it once RequestedActivation is set or on error 133 * @param[in] codeUpdate - codeUpdate pointer 134 * @return - Completion codes 135 */ 136 int setRequestedActivation(); 137 138 /* @brief Method to fetch the sensor id for marker lid 139 * validation PDR 140 * @return - sensor id 141 */ getMarkerLidSensor()142 uint16_t getMarkerLidSensor() 143 { 144 return markerLidSensorId; 145 } 146 147 /* @brief Method to set the sensor id for marker lid 148 * validation 149 * @param[in] sensorId - sensor id for marker lid validation 150 */ setMarkerLidSensor(uint16_t sensorId)151 void setMarkerLidSensor(uint16_t sensorId) 152 { 153 markerLidSensorId = sensorId; 154 } 155 156 /* @brief Method to set the sensor id for firmware update state 157 * @param[in] sensorId - sensor id for firmware update state 158 */ setFirmwareUpdateSensor(uint16_t sensorId)159 void setFirmwareUpdateSensor(uint16_t sensorId) 160 { 161 firmwareUpdateSensorId = sensorId; 162 } 163 164 /* @brief Method to fetch the sensor id for firmware update state 165 * @return - sensor id 166 */ getFirmwareUpdateSensor()167 uint16_t getFirmwareUpdateSensor() 168 { 169 return firmwareUpdateSensorId; 170 } 171 172 /* @brief Method to set the sensor id for boot side rename state 173 * @param[in] sensorId - sensor id for boot side rename update 174 * state 175 */ setBootSideRenameStateSensor(uint16_t sensorId)176 void setBootSideRenameStateSensor(uint16_t sensorId) 177 { 178 bootSideRenameStateSensorId = sensorId; 179 } 180 181 /* @brief Method to fetch the sensor id for boot side rename state 182 * @return - sensor id 183 */ getBootSideRenameStateSensor()184 uint16_t getBootSideRenameStateSensor() 185 { 186 return bootSideRenameStateSensorId; 187 } 188 189 /* @brief Method to send a state sensor event to Host from CodeUpdate class 190 * @param[in] sensorId - sensor id for the event 191 * @param[in] sensorEventClass - sensor event class wrt DSP0248 192 * @param[in] sensorOffset - sensor offset 193 * @param[in] eventState - new event state 194 * @param[in] prevEventState - previous state 195 */ 196 void sendStateSensorEvent(uint16_t sensorId, 197 enum sensor_event_class_states sensorEventClass, 198 uint8_t sensorOffset, uint8_t eventState, 199 uint8_t prevEventState); 200 201 /* @brief Method to delete the image from non running side prior to 202 * an inband code update 203 */ 204 void deleteImage(); 205 206 /** @brief Method to assemble the code update tarball and trigger the 207 * phosphor software manager to create a version interface 208 * @return - PLDM_SUCCESS codes 209 */ 210 int assembleCodeUpdateImage(); 211 212 /* @brief Method to process the bootside rename event, sends a boot side 213 * rename event notification to host when code update is initiated*/ 214 void processRenameEvent(); 215 216 /* @brief Method to write the bootside information into mapping 217 * file which would be stored on bmc 218 * @param[in] pldmBootSideData - bootside information such as 219 * current boot side and running version 220 */ 221 void writeBootSideFile(const pldm_boot_side_data& pldmBootSideData); 222 223 /* @brief Method to read the mapping file containing bootside 224 * which is stored on bmc and stores that information 225 * in a structure 226 * @return pldm_boot_side_data - the structure which holds information 227 * regarding bootside information */ 228 pldm_boot_side_data readBootSideFile(); 229 ~CodeUpdate()230 virtual ~CodeUpdate() {} 231 232 private: 233 std::string currBootSide; //!< current boot side 234 std::string nextBootSide; //!< next boot side 235 std::string runningVersion; //!< currently running image 236 std::string nonRunningVersion; //!< alternate image 237 std::string newImageId; //!< new image id 238 bool codeUpdateInProgress = 239 false; //!< indicates whether codeupdate is going on 240 const pldm::utils::DBusHandler* dBusIntf; //!< D-Bus handler 241 std::vector<std::unique_ptr<sdbusplus::bus::match_t>> 242 captureNextBootSideChange; //!< vector to catch the D-Bus property 243 //!< change for next boot side 244 std::vector<std::unique_ptr<sdbusplus::bus::match_t>> 245 fwUpdateMatcher; //!< pointer to capture the interface added signal for 246 //!< new image 247 pldm::responder::oem_platform::Handler* 248 oemPlatformHandler; //!< oem platform handler 249 uint16_t markerLidSensorId; 250 uint16_t firmwareUpdateSensorId; 251 uint16_t bootSideRenameStateSensorId; 252 /** @brief D-Bus property changed signal match for image activation */ 253 std::unique_ptr<sdbusplus::bus::match_t> imageActivationMatch; 254 255 /* @brief Method to take action when the subscribed D-Bus property is 256 * changed 257 * @param[in] chProperties - list of properties which have changed 258 * @return - none 259 */ 260 void processPriorityChangeNotification( 261 const pldm::utils::DbusChangedProps& chProperties); 262 }; 263 264 /* @brief Method to fetch current or next boot side 265 * @param[in] entityInstance - entity instance for the sensor 266 * @param[in] codeUpdate - pointer to the CodeUpdate object 267 * 268 * @return - boot side 269 */ 270 uint8_t fetchBootSide(uint16_t entityInstance, CodeUpdate* codeUpdate); 271 272 /* @brief Method to set current or next boot side 273 * @param[in] entityInstance - entity instance for the effecter 274 * @param[in] currState - state to be set 275 * @param[in] stateField - state field set as sent by Host 276 * @return - PLDM_SUCCESS codes 277 */ 278 int setBootSide(uint16_t entityInstance, uint8_t currState, 279 const std::vector<set_effecter_state_field>& stateField, 280 CodeUpdate* codeUpdate); 281 282 /* @brief Method to process LIDs during inband update, such as verifying and 283 * removing the header to get them ready to be written to flash 284 * @param[in] filePath - Path to the LID file 285 * @return - PLDM_SUCCESS codes 286 */ 287 int processCodeUpdateLid(const std::string& filePath); 288 289 } // namespace responder 290 } // namespace pldm 291