blob: c02541bfe3165e198afac03b8b574eb285516bc6 [file] [log] [blame]
Lei YUd19df252019-10-25 17:31:52 +08001/**
2 * Copyright © 2019 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17
Lei YU7c2fbbb2019-11-06 14:56:02 +080018#include "i2c_interface.hpp"
19
Lei YU9ab6d752019-10-28 17:03:20 +080020#include <sdbusplus/bus.hpp>
Brandon Wymand1bc4ce2019-12-13 14:20:34 -060021
22#include <filesystem>
Faisal Awadaec61bbd2024-11-04 08:46:20 -060023#include <memory>
Lei YUd19df252019-10-25 17:31:52 +080024#include <string>
25
Lei YU7c2fbbb2019-11-06 14:56:02 +080026class TestUpdater;
27
Lei YUd19df252019-10-25 17:31:52 +080028namespace updater
29{
30
Lei YU9ab6d752019-10-28 17:03:20 +080031namespace fs = std::filesystem;
32
Lei YUd19df252019-10-25 17:31:52 +080033/**
34 * Update PSU firmware
35 *
Faisal Awadaec61bbd2024-11-04 08:46:20 -060036 * @param[in] bus - The sdbusplus DBus bus connection
Lei YUd19df252019-10-25 17:31:52 +080037 * @param[in] psuInventoryPath - The inventory path of the PSU
38 * @param[in] imageDir - The directory containing the PSU image
39 *
40 * @return true if successful, otherwise false
41 */
Faisal Awadaec61bbd2024-11-04 08:46:20 -060042bool update(sdbusplus::bus_t& bus, const std::string& psuInventoryPath,
43 const std::string& imageDir);
Lei YUd19df252019-10-25 17:31:52 +080044
Lei YU9ab6d752019-10-28 17:03:20 +080045class Updater
46{
47 public:
Lei YU7c2fbbb2019-11-06 14:56:02 +080048 friend TestUpdater;
Lei YU9ab6d752019-10-28 17:03:20 +080049 Updater() = delete;
50 Updater(const Updater&) = delete;
51 Updater& operator=(const Updater&) = delete;
52 Updater(Updater&&) = default;
53 Updater& operator=(Updater&&) = default;
54
55 /**
56 * @brief Constructor
57 *
58 * @param psuInventoryPath - The PSU inventory path
59 * @param devPath - The PSU device path
60 * @param imageDir - The update image directory
61 */
62 Updater(const std::string& psuInventoryPath, const std::string& devPath,
63 const std::string& imageDir);
64
65 /** @brief Destructor */
Faisal Awadaec61bbd2024-11-04 08:46:20 -060066 virtual ~Updater() = default;
Lei YU9ab6d752019-10-28 17:03:20 +080067
68 /** @brief Bind or unbind the driver
69 *
70 * @param doBind - indicate if it's going to bind or unbind the driver
71 */
72 void bindUnbind(bool doBind);
73
74 /** @brief Set the PSU inventory present property
75 *
76 * @param present - The present state to set
77 */
78 void setPresent(bool present);
79
Lei YU575ed132019-10-29 17:22:16 +080080 /** @brief Check if it's ready to update the PSU
81 *
82 * @return true if it's ready, otherwise false
83 */
84 bool isReadyToUpdate();
85
Lei YU9ab6d752019-10-28 17:03:20 +080086 /** @brief Do the PSU update
87 *
88 * @return 0 if success, otherwise non-zero
89 */
Faisal Awadaec61bbd2024-11-04 08:46:20 -060090 virtual int doUpdate();
Lei YU9ab6d752019-10-28 17:03:20 +080091
Lei YU7c2fbbb2019-11-06 14:56:02 +080092 /** @brief Create I2C device
93 *
94 * Creates the I2C device based on the device name.
95 * e.g. It opens busId 3, address 0x68 for "3-0068"
96 */
97 void createI2CDevice();
98
Faisal Awadaec61bbd2024-11-04 08:46:20 -060099 protected:
100 /** @brief Accessor for PSU inventory path */
101 const std::string& getPsuInventoryPath() const
102 {
103 return psuInventoryPath;
104 }
105
106 /** @brief Accessor for device path */
107 const std::string& getDevPath() const
108 {
109 return devPath;
110 }
111
112 /** @brief Accessor for device name */
113 const std::string& getDevName() const
114 {
115 return devName;
116 }
117
118 /** @brief Accessor for image directory */
119 const std::string& getImageDir() const
120 {
121 return imageDir;
122 }
123
124 /** @brief I2C interface accessor */
125 i2c::I2CInterface* getI2C()
126 {
127 return i2c.get();
128 }
129
Lei YU9ab6d752019-10-28 17:03:20 +0800130 private:
131 /** @brief The sdbusplus DBus bus connection */
Patrick Williams7354ce62022-07-22 19:26:56 -0500132 sdbusplus::bus_t bus;
Lei YU9ab6d752019-10-28 17:03:20 +0800133
134 /** @brief The PSU inventory path */
135 std::string psuInventoryPath;
136
137 /** @brief The PSU device path
138 *
139 * Usually it is a device in i2c subsystem, e.g.
140 * /sys/bus/i2c/devices/3-0068
141 */
142 std::string devPath;
143
144 /** @brief The PSU device name
145 *
146 * Usually it is a i2c device name, e.g.
147 * 3-0068
148 */
149 std::string devName;
150
151 /** @brief The PSU image directory */
152 std::string imageDir;
153
154 /** @brief The PSU device driver's path
155 *
156 * Usually it is the PSU driver, e.g.
157 * /sys/bus/i2c/drivers/ibm-cffps
158 */
159 fs::path driverPath;
Lei YU7c2fbbb2019-11-06 14:56:02 +0800160
161 /** @brief The i2c device interface */
162 std::unique_ptr<i2c::I2CInterface> i2c;
Lei YU9ab6d752019-10-28 17:03:20 +0800163};
164
Faisal Awadaec61bbd2024-11-04 08:46:20 -0600165namespace internal
166{
167
168/**
Faisal Awadaec61bbd2024-11-04 08:46:20 -0600169 * @brief Factory function to create an Updater instance based on PSU model
170 * number
171 *
172 * @param[in] model - PSU model number
173 * @param[in] psuInventoryPath - PSU inventory path
174 * @param[in] devPath - Device path
175 * @param[in] imageDir - Image directory
176 *
177 * return pointer class based on the device PSU model.
178 */
179std::unique_ptr<updater::Updater> getClassInstance(
180 const std::string& model, const std::string& psuInventoryPath,
181 const std::string& devPath, const std::string& imageDir);
182
183/**
184 * @brief Retrieve the firmware filename path in the specified directory
185 *
186 * @param[in] directory - Path to FS directory
187 *
188 * @retun filename or null
189 */
190const std::string getFWFilenamePath(const std::string& directory);
191
192/**
193 * @brief Calculate CRC-8 for a data vector
194 *
195 * @param[in] data - Firmware data block
196 *
197 * @return CRC8
198 */
199uint8_t calculateCRC8(const std::vector<uint8_t>& data);
200
201/**
202 * @brief Delay execution in milliseconds
203 *
204 * @param[in] milliseconds - Time in milliseconds
205 */
206void delay(const int& milliseconds);
207
208/**
209 * @brief Convert a big-endian value to little-endian
210 *
211 * @param[in] bigEndianValue - Uint 32 bit value
212 *
213 * @return vector of little endians.
214 */
215std::vector<uint8_t> bigEndianToLittleEndian(const uint32_t bigEndianValue);
216
217/**
218 * @brief Validate the existence and size of a firmware file.
219 *
220 * @param[in] fileName - Firmware file name
221 *
222 * @return true for success or false
223 */
224bool validateFWFile(const std::string& fileName);
225
226/**
227 * @brief Open a firmware file for reading in binary mode.
228 *
229 * @param[in] fileName - Firmware file name
230 *
231 * @return pointer to firmware file stream
232 */
233std::unique_ptr<std::ifstream> openFirmwareFile(const std::string& fileName);
234
235/**
236 * @brief Read firmware bytes from file.
237 *
238 * @param[in] inputFile - Input file stream
239 * @param[in] numberOfBytesToRead - Number of bytes to read from firmware file.
240 *
241 * @return vector of data read
242 */
243std::vector<uint8_t> readFirmwareBytes(std::ifstream& inputFile,
244 const size_t numberOfBytesToRead);
245
Faisal Awadaec61bbd2024-11-04 08:46:20 -0600246} // namespace internal
Lei YUd19df252019-10-25 17:31:52 +0800247} // namespace updater