xref: /openbmc/pldm/oem/ibm/libpldmresponder/inband_code_update.hpp (revision e26d13fc2589e480aea0d648500bdc15e5a177fd)
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