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 /** @class CodeUpdate
23  *
24  *  @brief This class performs the necessary operation in pldm for
25  *         inband code update. That includes taking actions on the
26  *         setStateEffecterStates calls from Host and also sending
27  *         notification to phosphor-software-manager app
28  */
29 class CodeUpdate
30 {
31   public:
32     /** @brief Constructor to create an inband codeupdate object
33      *  @param[in] dBusIntf - D-Bus handler pointer
34      */
35     CodeUpdate(const pldm::utils::DBusHandler* dBusIntf) : dBusIntf(dBusIntf)
36     {
37         currBootSide = Tside;
38         nextBootSide = Tside;
39         markerLidSensorId = PLDM_INVALID_EFFECTER_ID;
40         firmwareUpdateSensorId = PLDM_INVALID_EFFECTER_ID;
41         imageActivationMatch = nullptr;
42     }
43 
44     /* @brief Method to return the current boot side
45      */
46     std::string fetchCurrentBootSide();
47 
48     /* @brief Method to return the next boot side
49      */
50     std::string fetchNextBootSide();
51 
52     /* @brief Method to set the current boot side or
53      *        perform a rename operation on current boot side
54      * @param[in] currSide - current side to be set to
55      * @return PLDM_SUCCESS codes
56      */
57     int setCurrentBootSide(const std::string& currSide);
58 
59     /* @brief Method to set the next boot side
60      * @param[in] nextSide - next boot side to be set to
61      * @return PLDM_SUCCESS codes
62      */
63     int setNextBootSide(const std::string& nextSide);
64 
65     /* @brief Method to set the running and non-running
66      *        images
67      */
68     virtual void setVersions();
69 
70     /* @brief Method to return the newly upoaded image id in
71      *        /tmp
72      */
73     std::string fetchnewImageId()
74     {
75         return newImageId;
76     }
77 
78     /* @brief Method to set the oem platform handler in CodeUpdate class */
79     void setOemPlatformHandler(pldm::responder::oem_platform::Handler* handler);
80 
81     /* @brief Method to check whether code update is
82      *        going on
83      *  @return - bool
84      */
85     bool isCodeUpdateInProgress()
86     {
87         return codeUpdateInProgress;
88     }
89 
90     /* @brief Method to indicate whether code update
91      *        is going on
92      * @param[in] progress - yes/no
93      */
94     void setCodeUpdateProgress(bool progress)
95     {
96         codeUpdateInProgress = progress;
97     }
98 
99     /** @brief Method to clear contents the LID staging directory that contains
100      *  images such as host firmware and BMC.
101      *  @param[in] dirPath - directory system path that has to be cleared
102      *  @return none
103      */
104     void clearDirPath(const std::string& dirPath);
105 
106     /* @brief Method to set the RequestApplyTime D-Bus property
107      *        on start update to OnReset
108      * @return - Completion codes
109      */
110     int setRequestedApplyTime();
111 
112     /* @brief Method to set the RequestedActivation D-Bus property
113      *        on end update to Active by fetching the newImageID and
114      *        clearning it once RequestedActivation is set or on error
115      * @param[in] codeUpdate - codeUpdate pointer
116      * @return - Completion codes
117      */
118     int setRequestedActivation();
119 
120     /* @brief Method to fetch the sensor id for marker lid
121      * validation PDR
122      * @return - sensor id
123      */
124     uint16_t getMarkerLidSensor()
125     {
126         return markerLidSensorId;
127     }
128 
129     /* @brief Method to set the sensor id for marker lid
130      * validation
131      * @param[in] sensorId - sensor id for marker lid validation
132      */
133     void setMarkerLidSensor(uint16_t sensorId)
134     {
135         markerLidSensorId = sensorId;
136     }
137 
138     /* @brief Method to set the sensor id for firmware update state
139      * @param[in] sensorId - sensor id for firmware update state
140      */
141     void setFirmwareUpdateSensor(uint16_t sensorId)
142     {
143         firmwareUpdateSensorId = sensorId;
144     }
145 
146     /* @brief Method to fetch the sensor id for firmware update state
147      * @return - sensor id
148      */
149     uint16_t getFirmwareUpdateSensor()
150     {
151         return firmwareUpdateSensorId;
152     }
153 
154     /* @brief Method to send a state sensor event to Host from CodeUpdate class
155      * @param[in] sensorId - sensor id for the event
156      * @param[in] sensorEventClass - sensor event class wrt DSP0248
157      * @param[in] sensorOffset - sensor offset
158      * @param[in] eventState - new event state
159      * @param[in] prevEventState - previous state
160      */
161     void sendStateSensorEvent(uint16_t sensorId,
162                               enum sensor_event_class_states sensorEventClass,
163                               uint8_t sensorOffset, uint8_t eventState,
164                               uint8_t prevEventState);
165 
166     /* @brief Method to delete the image from non running side prior to
167      * an inband code update
168      */
169     void deleteImage();
170 
171     /** @brief Method to assemble the code update tarball and trigger the
172      *         phosphor software manager to create a version interface
173      *  @return - PLDM_SUCCESS codes
174      */
175     int assembleCodeUpdateImage();
176 
177     virtual ~CodeUpdate() {}
178 
179   private:
180     std::string currBootSide;      //!< current boot side
181     std::string nextBootSide;      //!< next boot side
182     std::string runningVersion;    //!< currently running image
183     std::string nonRunningVersion; //!< alternate image
184     std::string newImageId;        //!< new image id
185     bool codeUpdateInProgress =
186         false;                     //!< indicates whether codeupdate is going on
187     const pldm::utils::DBusHandler* dBusIntf; //!< D-Bus handler
188     std::vector<std::unique_ptr<sdbusplus::bus::match_t>>
189         captureNextBootSideChange; //!< vector to catch the D-Bus property
190                                    //!< change for next boot side
191     std::vector<std::unique_ptr<sdbusplus::bus::match_t>>
192         fwUpdateMatcher; //!< pointer to capture the interface added signal for
193                          //!< new image
194     pldm::responder::oem_platform::Handler*
195         oemPlatformHandler; //!< oem platform handler
196     uint16_t markerLidSensorId;
197     uint16_t firmwareUpdateSensorId;
198 
199     /** @brief D-Bus property changed signal match for image activation */
200     std::unique_ptr<sdbusplus::bus::match_t> imageActivationMatch;
201 
202     /* @brief Method to take action when the subscribed D-Bus property is
203      *        changed
204      * @param[in] chProperties - list of properties which have changed
205      * @return - none
206      */
207     void processPriorityChangeNotification(
208         const pldm::utils::DbusChangedProps& chProperties);
209 };
210 
211 /* @brief Method to fetch current or next boot side
212  * @param[in] entityInstance - entity instance for the sensor
213  * @param[in] codeUpdate - pointer to the CodeUpdate object
214  *
215  * @return - boot side
216  */
217 uint8_t fetchBootSide(uint16_t entityInstance, CodeUpdate* codeUpdate);
218 
219 /* @brief Method to set current or next  boot side
220  * @param[in] entityInstance - entity instance for the effecter
221  * @param[in] currState - state to be set
222  * @param[in] stateField - state field set as sent by Host
223  * @return - PLDM_SUCCESS codes
224  */
225 int setBootSide(uint16_t entityInstance, uint8_t currState,
226                 const std::vector<set_effecter_state_field>& stateField,
227                 CodeUpdate* codeUpdate);
228 
229 /* @brief Method to process LIDs during inband update, such as verifying and
230  *        removing the header to get them ready to be written to flash
231  * @param[in] filePath - Path to the LID file
232  * @return - PLDM_SUCCESS codes
233  */
234 int processCodeUpdateLid(const std::string& filePath);
235 
236 } // namespace responder
237 } // namespace pldm
238