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