blob: b2f5a64f3d6ddf7ae40427abdc312d606d9dffb3 [file] [log] [blame]
Patrick Venturec7ca2912018-11-02 11:38:33 -07001#pragma once
2
Patrick Ventureac11ae92019-01-16 12:43:00 -08003#include "config.h"
4
Patrick Venture1cde5f92018-11-07 08:26:47 -08005#include "data_handler.hpp"
Patrick Venturea78e39f2018-11-06 18:37:06 -08006#include "image_handler.hpp"
Patrick Venture27ac5822019-05-20 17:39:31 -07007#include "update.hpp"
Patrick Venture7dad86f2019-05-17 08:52:20 -07008#include "util.hpp"
Patrick Venture3ecb3502019-05-17 11:03:51 -07009#include "verify.hpp"
Patrick Venturea78e39f2018-11-06 18:37:06 -080010
Patrick Ventureefba42d2019-05-24 10:48:16 -070011#include <algorithm>
Patrick Venturec7ca2912018-11-02 11:38:33 -070012#include <blobs-ipmid/blobs.hpp>
Patrick Venture192d60f2018-11-06 11:11:59 -080013#include <cstdint>
Patrick Ventured9fb6132018-11-08 09:56:10 -080014#include <map>
Patrick Venture68cf64f2018-11-06 10:46:51 -080015#include <memory>
Patrick Venture148cd652018-11-06 10:59:47 -080016#include <string>
17#include <vector>
Patrick Venturec7ca2912018-11-02 11:38:33 -070018
Patrick Venture1d5a31c2019-05-20 11:38:22 -070019namespace ipmi_flash
Patrick Venturec7ca2912018-11-02 11:38:33 -070020{
21
Patrick Venturec7ca2912018-11-02 11:38:33 -070022/**
Patrick Venture2d3a2542018-11-08 09:23:24 -080023 * Representation of a session, includes how to read/write data.
24 */
25struct Session
26{
Patrick Ventured6461d62018-11-09 17:30:25 -080027 /**
Patrick Ventureedd55b52018-11-15 11:05:13 -080028 * Built a session object.
29 *
30 * @param[in] the active path to which this corresponds.
31 */
32 explicit Session(const std::string& path) :
33 dataHandler(nullptr), imageHandler(nullptr), flags(0),
34 state(State::closed), activePath(path)
35 {
36 }
37
38 /**
Patrick Ventured6461d62018-11-09 17:30:25 -080039 * Pointer to the correct Data handler interface. (nullptr on BT (or KCS))
Patrick Venture2d3a2542018-11-08 09:23:24 -080040 */
41 DataInterface* dataHandler;
42
Patrick Ventured6461d62018-11-09 17:30:25 -080043 /**
44 * Pointer to the correct image handler interface. (nullptr on hash
45 * blob_id)
46 */
Patrick Venture2d3a2542018-11-08 09:23:24 -080047 ImageHandlerInterface* imageHandler;
Patrick Venture18235e62018-11-08 10:21:09 -080048
49 /** The flags used to open the session. */
50 std::uint16_t flags;
Patrick Venture32ba9dd2018-11-09 16:22:53 -080051
52 /** A sesion can be for an image (or tarball) or the hash. */
Patrick Venture9420ad22019-05-15 14:34:12 -070053 enum class State
Patrick Venture32ba9dd2018-11-09 16:22:53 -080054 {
55 open = 0,
56 closed = 1,
57 };
58
59 /** The current state of this session. */
60 State state;
Patrick Ventureedd55b52018-11-15 11:05:13 -080061
62 /** The active path. */
63 std::string activePath;
Patrick Venture2d3a2542018-11-08 09:23:24 -080064};
65
Patrick Venture18235e62018-11-08 10:21:09 -080066struct ExtChunkHdr
67{
68 std::uint32_t length; /* Length of the data queued (little endian). */
69} __attribute__((packed));
70
Patrick Venture2d3a2542018-11-08 09:23:24 -080071/**
Patrick Venturec7ca2912018-11-02 11:38:33 -070072 * Register only one firmware blob handler that will manage all sessions.
73 */
Patrick Venture1d5a31c2019-05-20 11:38:22 -070074class FirmwareBlobHandler : public blobs::GenericBlobInterface
Patrick Venturec7ca2912018-11-02 11:38:33 -070075{
76 public:
Patrick Venture05abf7e2018-11-09 11:02:56 -080077 enum UpdateFlags : std::uint16_t
Patrick Venturefc3857b2018-11-07 08:14:55 -080078 {
Patrick Venture3ca43622018-12-13 09:15:11 -080079 openRead = (1 << 0), /* Flag for reading. */
80 openWrite = (1 << 1), /* Flag for writing. */
Patrick Venture9158dcf2018-11-08 09:44:28 -080081 ipmi = (1 << 8), /* Expect to send contents over IPMI BlockTransfer. */
Patrick Venturefc3857b2018-11-07 08:14:55 -080082 p2a = (1 << 9), /* Expect to send contents over P2A bridge. */
83 lpc = (1 << 10), /* Expect to send contents over LPC bridge. */
84 };
85
Patrick Ventureffcc5502018-11-16 12:32:38 -080086 /* TODO: All of the states may not be required - if we add abort() commands
87 * appropriately.
88 */
Patrick Venture92106df2018-11-09 09:26:30 -080089 /** The state of the firmware update process. */
Patrick Venture88bc26e2019-05-15 12:02:05 -070090 enum class UpdateState
Patrick Venture92106df2018-11-09 09:26:30 -080091 {
92 /** The initial state. */
93 notYetStarted = 0,
Patrick Venture12233c52019-05-16 09:26:59 -070094 /** The BMC is expecting to receive bytes. */
95 uploadInProgress,
96 /** The BMC is ready for verification or more bytes. */
97 verificationPending,
Patrick Venture92106df2018-11-09 09:26:30 -080098 /** The verification process has started, no more writes allowed. */
Patrick Venture12233c52019-05-16 09:26:59 -070099 verificationStarted,
Patrick Venture92106df2018-11-09 09:26:30 -0800100 /** The verification process has completed. */
Patrick Venture12233c52019-05-16 09:26:59 -0700101 verificationCompleted,
Patrick Venture02922e42019-05-22 09:49:31 -0700102 /** The update process is pending. */
103 updatePending,
104 /** The update process has started. */
105 updateStarted,
106 /** The update has completed (optional state to reach) */
107 updatedCompleted,
Patrick Venture92106df2018-11-09 09:26:30 -0800108 };
109
Patrick Venture137ad2c2018-11-06 11:30:43 -0800110 /**
111 * Create a FirmwareBlobHandler.
112 *
Patrick Venture4cceb8e2018-11-06 11:56:48 -0800113 * @param[in] firmwares - list of firmware blob_ids to support.
Patrick Venture1cde5f92018-11-07 08:26:47 -0800114 * @param[in] transports - list of transports to support.
Patrick Venture3ecb3502019-05-17 11:03:51 -0700115 * @param[in] verification - pointer to object for triggering verification
Patrick Venture27ac5822019-05-20 17:39:31 -0700116 * @param[in] update - point to object for triggering the update
Patrick Venture137ad2c2018-11-06 11:30:43 -0800117 */
Patrick Venture1cde5f92018-11-07 08:26:47 -0800118 static std::unique_ptr<GenericBlobInterface> CreateFirmwareBlobHandler(
Patrick Venture3ecb3502019-05-17 11:03:51 -0700119 const std::vector<HandlerPack>& firmwares,
Patrick Venture74059d62019-05-17 10:40:26 -0700120 const std::vector<DataHandlerPack>& transports,
Patrick Venture27ac5822019-05-20 17:39:31 -0700121 std::unique_ptr<VerificationInterface> verification,
122 std::unique_ptr<UpdateInterface> update);
Patrick Venture68cf64f2018-11-06 10:46:51 -0800123
Patrick Venture137ad2c2018-11-06 11:30:43 -0800124 /**
125 * Create a FirmwareBlobHandler.
126 *
Patrick Venture1cde5f92018-11-07 08:26:47 -0800127 * @param[in] firmwares - list of firmware types and their handlers
128 * @param[in] blobs - list of blobs_ids to support
129 * @param[in] transports - list of transport types and their handlers
130 * @param[in] bitmask - bitmask of transports to support
Patrick Venture3ecb3502019-05-17 11:03:51 -0700131 * @param[in] verification - pointer to object for triggering verification
Patrick Venture27ac5822019-05-20 17:39:31 -0700132 * @param[in] update - point to object for triggering the update
Patrick Venture137ad2c2018-11-06 11:30:43 -0800133 */
Patrick Venture3ecb3502019-05-17 11:03:51 -0700134 FirmwareBlobHandler(const std::vector<HandlerPack>& firmwares,
Patrick Venturea78e39f2018-11-06 18:37:06 -0800135 const std::vector<std::string>& blobs,
Patrick Venture1cde5f92018-11-07 08:26:47 -0800136 const std::vector<DataHandlerPack>& transports,
Patrick Venture74059d62019-05-17 10:40:26 -0700137 std::uint16_t bitmask,
Patrick Venture27ac5822019-05-20 17:39:31 -0700138 std::unique_ptr<VerificationInterface> verification,
139 std::unique_ptr<UpdateInterface> update) :
Patrick Venture3ecb3502019-05-17 11:03:51 -0700140 handlers(firmwares),
141 blobIDs(blobs), transports(transports), bitmask(bitmask),
142 activeImage(activeImageBlobId), activeHash(activeHashBlobId),
Patrick Venture26e241d2019-05-20 18:39:01 -0700143 verifyImage(verifyBlobId), updateImage(updateBlobId), lookup(),
144 state(UpdateState::notYetStarted),
Patrick Venture27ac5822019-05-20 17:39:31 -0700145 verification(std::move(verification)), update(std::move(update))
Patrick Venture148cd652018-11-06 10:59:47 -0800146 {
147 }
Patrick Venturec7ca2912018-11-02 11:38:33 -0700148 ~FirmwareBlobHandler() = default;
Patrick Venture4eb55952018-11-16 15:36:24 -0800149 FirmwareBlobHandler(const FirmwareBlobHandler&) = delete;
150 FirmwareBlobHandler& operator=(const FirmwareBlobHandler&) = delete;
Patrick Venturec7ca2912018-11-02 11:38:33 -0700151 FirmwareBlobHandler(FirmwareBlobHandler&&) = default;
152 FirmwareBlobHandler& operator=(FirmwareBlobHandler&&) = default;
153
154 bool canHandleBlob(const std::string& path) override;
155 std::vector<std::string> getBlobIds() override;
156 bool deleteBlob(const std::string& path) override;
Patrick Venture1d5a31c2019-05-20 11:38:22 -0700157 bool stat(const std::string& path, struct blobs::BlobMeta* meta) override;
Patrick Venturec7ca2912018-11-02 11:38:33 -0700158 bool open(uint16_t session, uint16_t flags,
159 const std::string& path) override;
160 std::vector<uint8_t> read(uint16_t session, uint32_t offset,
161 uint32_t requestedSize) override;
162 bool write(uint16_t session, uint32_t offset,
163 const std::vector<uint8_t>& data) override;
164 bool writeMeta(uint16_t session, uint32_t offset,
165 const std::vector<uint8_t>& data) override;
166 bool commit(uint16_t session, const std::vector<uint8_t>& data) override;
167 bool close(uint16_t session) override;
Patrick Venture1d5a31c2019-05-20 11:38:22 -0700168 bool stat(uint16_t session, struct blobs::BlobMeta* meta) override;
Patrick Venturec7ca2912018-11-02 11:38:33 -0700169 bool expire(uint16_t session) override;
Patrick Venture148cd652018-11-06 10:59:47 -0800170
Patrick Ventureffcc5502018-11-16 12:32:38 -0800171 bool triggerVerification();
Patrick Venture1a406fe2019-05-31 07:29:56 -0700172 bool triggerUpdate();
Patrick Ventureffcc5502018-11-16 12:32:38 -0800173
Patrick Venture92106df2018-11-09 09:26:30 -0800174 /** Allow grabbing the current state. */
175 UpdateState getCurrentState() const
176 {
177 return state;
178 };
179
Patrick Venture148cd652018-11-06 10:59:47 -0800180 private:
Patrick Ventureefba42d2019-05-24 10:48:16 -0700181 void addBlobId(const std::string& blob)
182 {
183 auto blobIdMatch =
184 std::find_if(blobIDs.begin(), blobIDs.end(),
185 [&blob](const auto& iter) { return (iter == blob); });
186 if (blobIdMatch == blobIDs.end())
187 {
188 blobIDs.push_back(blob);
189 }
190 }
191
Patrick Venture930c7b72019-05-24 11:11:08 -0700192 void removeBlobId(const std::string& blob)
193 {
194 blobIDs.erase(std::remove(blobIDs.begin(), blobIDs.end(), blob),
195 blobIDs.end());
196 }
197
Patrick Venturea78e39f2018-11-06 18:37:06 -0800198 /** List of handlers by type. */
199 std::vector<HandlerPack> handlers;
200
Patrick Venturec02849b2018-11-06 17:31:15 -0800201 /** Active list of blobIDs. */
Patrick Venture4cceb8e2018-11-06 11:56:48 -0800202 std::vector<std::string> blobIDs;
Patrick Venturec02849b2018-11-06 17:31:15 -0800203
Patrick Venture1cde5f92018-11-07 08:26:47 -0800204 /** List of handlers by transport type. */
205 std::vector<DataHandlerPack> transports;
206
Patrick Venturec02849b2018-11-06 17:31:15 -0800207 /** The bits set indicate what transport mechanisms are supported. */
Patrick Venture1cde5f92018-11-07 08:26:47 -0800208 std::uint16_t bitmask;
Patrick Venturec02849b2018-11-06 17:31:15 -0800209
Patrick Ventured9fb6132018-11-08 09:56:10 -0800210 /** Active image session. */
211 Session activeImage;
212
213 /** Active hash session. */
214 Session activeHash;
215
Patrick Ventureffcc5502018-11-16 12:32:38 -0800216 /** Session for verification. */
217 Session verifyImage;
218
Patrick Venture26e241d2019-05-20 18:39:01 -0700219 /** Session for update. */
220 Session updateImage;
221
Patrick Ventured9fb6132018-11-08 09:56:10 -0800222 /** A quick method for looking up a session's mechanisms and details. */
223 std::map<std::uint16_t, Session*> lookup;
224
Patrick Venture92106df2018-11-09 09:26:30 -0800225 /** The firmware update state. */
226 UpdateState state;
227
Patrick Venture3ecb3502019-05-17 11:03:51 -0700228 std::unique_ptr<VerificationInterface> verification;
Patrick Venture74059d62019-05-17 10:40:26 -0700229
Patrick Venture27ac5822019-05-20 17:39:31 -0700230 std::unique_ptr<UpdateInterface> update;
231
Patrick Venturec02849b2018-11-06 17:31:15 -0800232 /** Temporary variable to track whether a blob is open. */
233 bool fileOpen = false;
Patrick Venture615c69e2019-05-29 10:49:54 -0700234
235 VerifyCheckResponses lastVerificationResponse = VerifyCheckResponses::other;
Patrick Venturec7ca2912018-11-02 11:38:33 -0700236};
237
Patrick Venture1d5a31c2019-05-20 11:38:22 -0700238} // namespace ipmi_flash