blob: 908963c0a03c5a2f9955d965f1ecc86f10211ccc [file] [log] [blame]
Patrick Venture3d1786b2018-08-01 11:19:24 -07001#pragma once
2
Patrick Venture3c086f22018-08-07 11:59:20 -07003#include <cstdio>
Patrick Venture605f75f2018-08-07 16:27:05 -07004#include <sdbusplus/bus.hpp>
Patrick Venture8ec019f2018-08-07 11:22:33 -07005#include <string>
Patrick Venture79e131f2018-08-01 13:34:35 -07006#include <vector>
7
Patrick Venture54c3b532018-08-01 11:45:49 -07008#include "host-ipmid/ipmid-api.h"
9
10/* Clearer way to represent the subcommand size. */
11#define SUBCMD_SZ sizeof(uint8_t)
12
Patrick Venture3d1786b2018-08-01 11:19:24 -070013/*
Patrick Venturefdc65b22018-08-07 14:37:58 -070014 * These are the codes we return over IPMI when the host checks for the status
15 * of the asynchronous verification call.
16 */
17enum VerifyCheckResponse
18{
19 running = 0x00,
20 success = 0x01,
21 failed = 0x02,
22 other = 0x03,
23};
24
25/*
Patrick Venture3d1786b2018-08-01 11:19:24 -070026 * flashStartTransfer -- starts file upload.
27 * flashDataBlock -- adds data to image file.
28 * flashDataFinish -- closes the file.
29 *
30 * flashStartHash -- starts uploading hash.
31 * flashDataHash -- adds data to the hash.
32 * flashDataVerify -- triggers verification.
33 *
34 * flashAbort -- abort everything.
35 *
36 * flashVerifyCheck -- Check if the verification has completed.
37 *
38 * flashVersion -- Get the version of this OEM Handler.
39 *
40 * flashRequestRegion -- Request the physical address for decode (bridge)
41 * flashDataExtBlock -- Provide image data via a bridge
42 * flashHashExtData -- Provide hash data via a bridge
43 */
44enum FlashSubCmds
45{
46 /* Start a transfer. */
47 flashStartTransfer = 0,
48 /* Data block. */
49 flashDataBlock = 1,
50 /* Close file. */
51 flashDataFinish = 2,
52
53 /* Start a hash transfer. */
54 flashStartHash = 3,
55 /* Add data to the hash. */
56 flashHashData = 4,
57 /* Close out the hash file. */
58 flashHashFinish = 5,
59
60 /* Verify the flash image against the hast sent. */
61 flashDataVerify = 6,
62
63 /* Abort. */
64 flashAbort = 7,
65
66 /*
67 * Check if the verification is ready and was successful.
68 * If the response from the IPMI command is OK, check the
69 * response bytes to know if it's ready or still computing,
70 * or failed.
71 */
72 flashVerifyCheck = 8,
73
74 flashVersion = 9,
75 flashRequestRegion = 10,
76 flashDataExtBlock = 11,
77 flashHashExtData = 12,
78 flashMapRegionLpc = 13,
79};
Patrick Venture54c3b532018-08-01 11:45:49 -070080
81/*
82 * StartTransfer expects a basic structure providing some information.
83 */
84struct StartTx
85{
86 uint8_t cmd;
87 uint32_t length; /* Maximum image length is 4GiB (little-endian) */
88} __attribute__((packed));
89
Patrick Venture79e131f2018-08-01 13:34:35 -070090struct ChunkHdr
91{
92 uint8_t cmd;
93 uint32_t offset; /* 0-based write offset */
94 uint8_t data[];
95} __attribute__((packed));
96
Patrick Venture54c3b532018-08-01 11:45:49 -070097class UpdateInterface
98{
99 public:
100 virtual ~UpdateInterface() = default;
101
Patrick Venture2c1205d2018-08-03 10:23:14 -0700102 /**
103 * Prepare to receive a BMC image and then a signature.
104 *
105 * @param[in] length - the size of the flash image.
106 * @return true on success, false otherwise.
107 */
Patrick Venture54c3b532018-08-01 11:45:49 -0700108 virtual bool start(uint32_t length) = 0;
Patrick Venture2c1205d2018-08-03 10:23:14 -0700109
110 /**
111 * Attempt to write the bytes at the offset.
112 *
113 * @param[in] offset - the 0-based byte offset into the flash image.
114 * @param[in] bytes - the bytes to write.
115 * @return true on success, false otherwise.
116 */
Patrick Venture79e131f2018-08-01 13:34:35 -0700117 virtual bool flashData(uint32_t offset,
118 const std::vector<uint8_t>& bytes) = 0;
Patrick Venture2c1205d2018-08-03 10:23:14 -0700119
120 /**
121 * Called to indicate the host is done sending the flash bytes.
122 */
123 virtual bool flashFinish() = 0;
Patrick Venture8d9f7322018-08-03 10:39:13 -0700124
125 /**
126 * Prepare to receive a BMC image signature.
127 *
128 * @param[in] length - length of signature in bytes.
129 * @return true on success, false otherwise.
130 */
131 virtual bool startHash(uint32_t length) = 0;
Patrick Venturecfe66872018-08-03 13:32:33 -0700132
133 /**
134 * Attempt to write the bytes at the offset.
135 *
136 * @param[in] offset - the 0-based byte offset into the flash image.
137 * @param[in] bytes - the bytes to write.
138 * @return true on success, false otherwise.
139 */
140 virtual bool hashData(uint32_t offset,
141 const std::vector<uint8_t>& bytes) = 0;
Patrick Venturefbc7d192018-08-03 13:54:21 -0700142
143 /**
144 * Called to indicate the host is done sending the hash bytes.
145 */
146 virtual bool hashFinish() = 0;
Patrick Venture1cb87d22018-08-03 18:22:09 -0700147
148 /**
149 * Kick off the flash image verification process.
150 *
151 * @return true if it was started succesfully.
152 */
153 virtual bool startDataVerification() = 0;
Patrick Venture5c251ca2018-08-03 18:31:01 -0700154
155 /**
156 * Attempt to abort everything.
157 *
158 * @return true if aborted, false if unable or failed.
159 */
160 virtual bool abortUpdate() = 0;
Patrick Venturefdc65b22018-08-07 14:37:58 -0700161
162 /**
163 * Check if the verification result is available and return.
164 *
165 * @return the verification response.
166 */
167 virtual VerifyCheckResponse checkVerify() = 0;
Patrick Venture54c3b532018-08-01 11:45:49 -0700168};
169
170class FlashUpdate : public UpdateInterface
171{
172 public:
Patrick Venture605f75f2018-08-07 16:27:05 -0700173 FlashUpdate(sdbusplus::bus::bus&& bus, const std::string& stagingPath,
174 const std::string& verifyPath, const std::string& hash = "") :
175 bus(std::move(bus)),
176 flashLength(0), flashFd(nullptr), tmpPath(stagingPath), hashLength(0),
177 hashFd(nullptr), hashPath(hash), verifyPath(verifyPath){};
Patrick Venture8ec019f2018-08-07 11:22:33 -0700178 ~FlashUpdate();
179
Patrick Venture605f75f2018-08-07 16:27:05 -0700180 FlashUpdate(const FlashUpdate&) = delete;
181 FlashUpdate& operator=(const FlashUpdate&) = delete;
Patrick Venture54c3b532018-08-01 11:45:49 -0700182 FlashUpdate(FlashUpdate&&) = default;
183 FlashUpdate& operator=(FlashUpdate&&) = default;
184
Patrick Venture54c3b532018-08-01 11:45:49 -0700185 bool start(uint32_t length) override;
Patrick Venture79e131f2018-08-01 13:34:35 -0700186 bool flashData(uint32_t offset, const std::vector<uint8_t>& bytes) override;
Patrick Venture2c1205d2018-08-03 10:23:14 -0700187 bool flashFinish() override;
188
Patrick Venture8d9f7322018-08-03 10:39:13 -0700189 bool startHash(uint32_t length) override;
Patrick Venturecfe66872018-08-03 13:32:33 -0700190 bool hashData(uint32_t offset, const std::vector<uint8_t>& bytes) override;
Patrick Venturefbc7d192018-08-03 13:54:21 -0700191 bool hashFinish() override;
Patrick Venture8d9f7322018-08-03 10:39:13 -0700192
Patrick Venture1cb87d22018-08-03 18:22:09 -0700193 bool startDataVerification() override;
Patrick Venture5c251ca2018-08-03 18:31:01 -0700194 bool abortUpdate() override;
Patrick Venturefdc65b22018-08-07 14:37:58 -0700195 VerifyCheckResponse checkVerify() override;
Patrick Venture1cb87d22018-08-03 18:22:09 -0700196
Patrick Venture54c3b532018-08-01 11:45:49 -0700197 private:
198 /**
Patrick Venture3c086f22018-08-07 11:59:20 -0700199 * Attempt to write the bytes at the offset.
200 *
201 * @param[in] fd - the file stream pointer.
202 * @param[in] offset - the 0-based byte offset into the flash image.
203 * @param[in] bytes - the bytes to write.
204 * @return true on success, false otherwise.
205 */
206 bool writeBlock(std::FILE* fd, uint32_t offset,
207 const std::vector<uint8_t>& bytes);
208
209 /**
Patrick Venture605f75f2018-08-07 16:27:05 -0700210 * Tries to delete everything.
211 */
212 void deleteEverything();
213
214 /**
Patrick Venture8ec019f2018-08-07 11:22:33 -0700215 * Tries to close out everything.
216 */
217 void closeEverything();
218
219 /**
Patrick Venture54c3b532018-08-01 11:45:49 -0700220 * Tries to close out and delete anything staged.
221 */
222 void abortEverything();
223
224 /**
225 * Open all staged file handles you expect to use.
226 *
227 * @return false on failure.
228 */
229 bool openEverything();
Patrick Venture8ec019f2018-08-07 11:22:33 -0700230
Patrick Venture605f75f2018-08-07 16:27:05 -0700231 /* A bus. */
232 sdbusplus::bus::bus bus;
233
Patrick Venture8ec019f2018-08-07 11:22:33 -0700234 /* The length of the flash image in bytes. */
235 uint32_t flashLength;
236
237 /* The file handle to the flash staging file. */
238 std::FILE* flashFd;
239
240 /* Where the bytes are written before verification. */
241 const std::string tmpPath;
Patrick Venture6f17bd22018-08-07 13:24:17 -0700242
243 /* The length of the hash in bytes. */
244 uint32_t hashLength;
245
246 /* The file handle to the hash file. */
247 std::FILE* hashFd;
248
249 /* Where we write the hash bytes. Only required if your verification
250 * process uses a separate signature.
251 */
252 const std::string hashPath;
Patrick Venturefdc65b22018-08-07 14:37:58 -0700253
254 /* The path to read the status of the signature verification. */
255 const std::string verifyPath;
Patrick Venture54c3b532018-08-01 11:45:49 -0700256};