blob: 8c7cb0459f3f3469c4f07ad9c49cdda30795623a [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 Venture1d66fe62019-06-03 14:57:27 -07007#include "status.hpp"
Patrick Venture7dad86f2019-05-17 08:52:20 -07008#include "util.hpp"
Patrick Venturea78e39f2018-11-06 18:37:06 -08009
Patrick Ventureefba42d2019-05-24 10:48:16 -070010#include <algorithm>
Patrick Venturec7ca2912018-11-02 11:38:33 -070011#include <blobs-ipmid/blobs.hpp>
Patrick Venture192d60f2018-11-06 11:11:59 -080012#include <cstdint>
Patrick Ventured9fb6132018-11-08 09:56:10 -080013#include <map>
Patrick Venture68cf64f2018-11-06 10:46:51 -080014#include <memory>
Patrick Venture148cd652018-11-06 10:59:47 -080015#include <string>
16#include <vector>
Patrick Venturec7ca2912018-11-02 11:38:33 -070017
Patrick Venture1d5a31c2019-05-20 11:38:22 -070018namespace ipmi_flash
Patrick Venturec7ca2912018-11-02 11:38:33 -070019{
20
Patrick Venturec7ca2912018-11-02 11:38:33 -070021/**
Patrick Venture2d3a2542018-11-08 09:23:24 -080022 * Representation of a session, includes how to read/write data.
23 */
24struct Session
25{
Patrick Ventured6461d62018-11-09 17:30:25 -080026 /**
Patrick Ventureedd55b52018-11-15 11:05:13 -080027 * Built a session object.
28 *
29 * @param[in] the active path to which this corresponds.
30 */
31 explicit Session(const std::string& path) :
Patrick Ventured816b232019-06-05 13:30:32 -070032 dataHandler(nullptr), imageHandler(nullptr), flags(0), activePath(path)
Patrick Ventureedd55b52018-11-15 11:05:13 -080033 {
34 }
35
36 /**
Patrick Ventured6461d62018-11-09 17:30:25 -080037 * Pointer to the correct Data handler interface. (nullptr on BT (or KCS))
Patrick Venture2d3a2542018-11-08 09:23:24 -080038 */
39 DataInterface* dataHandler;
40
Patrick Ventured6461d62018-11-09 17:30:25 -080041 /**
42 * Pointer to the correct image handler interface. (nullptr on hash
43 * blob_id)
44 */
Patrick Venture2d3a2542018-11-08 09:23:24 -080045 ImageHandlerInterface* imageHandler;
Patrick Venture18235e62018-11-08 10:21:09 -080046
47 /** The flags used to open the session. */
48 std::uint16_t flags;
Patrick Venture32ba9dd2018-11-09 16:22:53 -080049
Patrick Ventureedd55b52018-11-15 11:05:13 -080050 /** The active path. */
51 std::string activePath;
Patrick Venture2d3a2542018-11-08 09:23:24 -080052};
53
Patrick Venture18235e62018-11-08 10:21:09 -080054struct ExtChunkHdr
55{
56 std::uint32_t length; /* Length of the data queued (little endian). */
57} __attribute__((packed));
58
Patrick Venture2d3a2542018-11-08 09:23:24 -080059/**
Patrick Venturec7ca2912018-11-02 11:38:33 -070060 * Register only one firmware blob handler that will manage all sessions.
61 */
Patrick Venture1d5a31c2019-05-20 11:38:22 -070062class FirmwareBlobHandler : public blobs::GenericBlobInterface
Patrick Venturec7ca2912018-11-02 11:38:33 -070063{
64 public:
Patrick Venture05abf7e2018-11-09 11:02:56 -080065 enum UpdateFlags : std::uint16_t
Patrick Venturefc3857b2018-11-07 08:14:55 -080066 {
Patrick Venture3ca43622018-12-13 09:15:11 -080067 openRead = (1 << 0), /* Flag for reading. */
68 openWrite = (1 << 1), /* Flag for writing. */
Patrick Venture9158dcf2018-11-08 09:44:28 -080069 ipmi = (1 << 8), /* Expect to send contents over IPMI BlockTransfer. */
Patrick Venturefc3857b2018-11-07 08:14:55 -080070 p2a = (1 << 9), /* Expect to send contents over P2A bridge. */
71 lpc = (1 << 10), /* Expect to send contents over LPC bridge. */
72 };
73
Patrick Venture92106df2018-11-09 09:26:30 -080074 /** The state of the firmware update process. */
Patrick Venture88bc26e2019-05-15 12:02:05 -070075 enum class UpdateState
Patrick Venture92106df2018-11-09 09:26:30 -080076 {
77 /** The initial state. */
78 notYetStarted = 0,
Patrick Venture12233c52019-05-16 09:26:59 -070079 /** The BMC is expecting to receive bytes. */
80 uploadInProgress,
81 /** The BMC is ready for verification or more bytes. */
82 verificationPending,
Patrick Venture92106df2018-11-09 09:26:30 -080083 /** The verification process has started, no more writes allowed. */
Patrick Venture12233c52019-05-16 09:26:59 -070084 verificationStarted,
Patrick Venture92106df2018-11-09 09:26:30 -080085 /** The verification process has completed. */
Patrick Venture12233c52019-05-16 09:26:59 -070086 verificationCompleted,
Patrick Venture02922e42019-05-22 09:49:31 -070087 /** The update process is pending. */
88 updatePending,
89 /** The update process has started. */
90 updateStarted,
91 /** The update has completed (optional state to reach) */
Patrick Venturef1f0f652019-06-03 09:10:19 -070092 updateCompleted,
Patrick Venture92106df2018-11-09 09:26:30 -080093 };
94
Patrick Venture137ad2c2018-11-06 11:30:43 -080095 /**
96 * Create a FirmwareBlobHandler.
97 *
Patrick Venture4cceb8e2018-11-06 11:56:48 -080098 * @param[in] firmwares - list of firmware blob_ids to support.
Patrick Venture1cde5f92018-11-07 08:26:47 -080099 * @param[in] transports - list of transports to support.
Patrick Venture3ecb3502019-05-17 11:03:51 -0700100 * @param[in] verification - pointer to object for triggering verification
Patrick Venture27ac5822019-05-20 17:39:31 -0700101 * @param[in] update - point to object for triggering the update
Patrick Venture137ad2c2018-11-06 11:30:43 -0800102 */
Patrick Venture9efef5d2019-06-19 08:45:44 -0700103 static std::unique_ptr<blobs::GenericBlobInterface>
104 CreateFirmwareBlobHandler(
105 const std::vector<HandlerPack>& firmwares,
106 const std::vector<DataHandlerPack>& transports,
Patrick Venture6d7735d2019-06-21 10:03:19 -0700107 std::unique_ptr<TriggerableActionInterface> preparation,
Patrick Venture9efef5d2019-06-19 08:45:44 -0700108 std::unique_ptr<TriggerableActionInterface> verification,
109 std::unique_ptr<TriggerableActionInterface> update);
Patrick Venture68cf64f2018-11-06 10:46:51 -0800110
Patrick Venture137ad2c2018-11-06 11:30:43 -0800111 /**
112 * Create a FirmwareBlobHandler.
113 *
Patrick Venture1cde5f92018-11-07 08:26:47 -0800114 * @param[in] firmwares - list of firmware types and their handlers
115 * @param[in] blobs - list of blobs_ids to support
116 * @param[in] transports - list of transport types and their handlers
117 * @param[in] bitmask - bitmask of transports to support
Patrick Venture3ecb3502019-05-17 11:03:51 -0700118 * @param[in] verification - pointer to object for triggering verification
Patrick Venture27ac5822019-05-20 17:39:31 -0700119 * @param[in] update - point to object for triggering the update
Patrick Venture137ad2c2018-11-06 11:30:43 -0800120 */
Patrick Venture1d66fe62019-06-03 14:57:27 -0700121 FirmwareBlobHandler(
122 const std::vector<HandlerPack>& firmwares,
123 const std::vector<std::string>& blobs,
124 const std::vector<DataHandlerPack>& transports, std::uint16_t bitmask,
Patrick Venture6d7735d2019-06-21 10:03:19 -0700125 std::unique_ptr<TriggerableActionInterface> preparation,
Patrick Venture1d66fe62019-06-03 14:57:27 -0700126 std::unique_ptr<TriggerableActionInterface> verification,
127 std::unique_ptr<TriggerableActionInterface> update) :
Patrick Venture3ecb3502019-05-17 11:03:51 -0700128 handlers(firmwares),
129 blobIDs(blobs), transports(transports), bitmask(bitmask),
130 activeImage(activeImageBlobId), activeHash(activeHashBlobId),
Patrick Venture26e241d2019-05-20 18:39:01 -0700131 verifyImage(verifyBlobId), updateImage(updateBlobId), lookup(),
Patrick Venture6d7735d2019-06-21 10:03:19 -0700132 state(UpdateState::notYetStarted), preparation(std::move(preparation)),
Patrick Venture27ac5822019-05-20 17:39:31 -0700133 verification(std::move(verification)), update(std::move(update))
Patrick Venture148cd652018-11-06 10:59:47 -0800134 {
135 }
Patrick Venturec7ca2912018-11-02 11:38:33 -0700136 ~FirmwareBlobHandler() = default;
Patrick Venture4eb55952018-11-16 15:36:24 -0800137 FirmwareBlobHandler(const FirmwareBlobHandler&) = delete;
138 FirmwareBlobHandler& operator=(const FirmwareBlobHandler&) = delete;
Patrick Venturec7ca2912018-11-02 11:38:33 -0700139 FirmwareBlobHandler(FirmwareBlobHandler&&) = default;
140 FirmwareBlobHandler& operator=(FirmwareBlobHandler&&) = default;
141
142 bool canHandleBlob(const std::string& path) override;
143 std::vector<std::string> getBlobIds() override;
144 bool deleteBlob(const std::string& path) override;
Patrick Venturee312f392019-06-04 07:44:37 -0700145 bool stat(const std::string& path, blobs::BlobMeta* meta) override;
Patrick Venturec7ca2912018-11-02 11:38:33 -0700146 bool open(uint16_t session, uint16_t flags,
147 const std::string& path) override;
148 std::vector<uint8_t> read(uint16_t session, uint32_t offset,
149 uint32_t requestedSize) override;
150 bool write(uint16_t session, uint32_t offset,
151 const std::vector<uint8_t>& data) override;
152 bool writeMeta(uint16_t session, uint32_t offset,
153 const std::vector<uint8_t>& data) override;
154 bool commit(uint16_t session, const std::vector<uint8_t>& data) override;
155 bool close(uint16_t session) override;
Patrick Venturee312f392019-06-04 07:44:37 -0700156 bool stat(uint16_t session, blobs::BlobMeta* meta) override;
Patrick Venturec7ca2912018-11-02 11:38:33 -0700157 bool expire(uint16_t session) override;
Patrick Venture148cd652018-11-06 10:59:47 -0800158
Patrick Ventured5741022019-06-17 09:08:35 -0700159 void abortProcess();
160
161 void abortVerification();
Patrick Ventureffcc5502018-11-16 12:32:38 -0800162 bool triggerVerification();
Patrick Venture49731712019-06-17 10:04:02 -0700163 void abortUpdate();
Patrick Venture1a406fe2019-05-31 07:29:56 -0700164 bool triggerUpdate();
Patrick Ventureffcc5502018-11-16 12:32:38 -0800165
Patrick Venture92106df2018-11-09 09:26:30 -0800166 /** Allow grabbing the current state. */
167 UpdateState getCurrentState() const
168 {
169 return state;
170 };
171
Patrick Venture75c0c272019-06-21 09:15:08 -0700172 /** Provide for any state change triggers in convenience handler. */
173 void changeState(UpdateState next);
174
Patrick Venture148cd652018-11-06 10:59:47 -0800175 private:
Patrick Ventureefba42d2019-05-24 10:48:16 -0700176 void addBlobId(const std::string& blob)
177 {
Patrick Venturef8119952019-06-06 13:47:34 -0700178 auto blobIdMatch = std::find_if(
179 blobIDs.begin(), blobIDs.end(),
180 [&blob](const std::string& iter) { return (iter == blob); });
Patrick Ventureefba42d2019-05-24 10:48:16 -0700181 if (blobIdMatch == blobIDs.end())
182 {
183 blobIDs.push_back(blob);
184 }
185 }
186
Patrick Venture930c7b72019-05-24 11:11:08 -0700187 void removeBlobId(const std::string& blob)
188 {
189 blobIDs.erase(std::remove(blobIDs.begin(), blobIDs.end(), blob),
190 blobIDs.end());
191 }
192
Patrick Ventureda66fd82019-06-03 11:11:24 -0700193 ActionStatus getVerifyStatus();
194 ActionStatus getActionStatus();
Patrick Venturea2d82392019-06-03 10:55:17 -0700195
Patrick Venturea78e39f2018-11-06 18:37:06 -0800196 /** List of handlers by type. */
197 std::vector<HandlerPack> handlers;
198
Patrick Venturec02849b2018-11-06 17:31:15 -0800199 /** Active list of blobIDs. */
Patrick Venture4cceb8e2018-11-06 11:56:48 -0800200 std::vector<std::string> blobIDs;
Patrick Venturec02849b2018-11-06 17:31:15 -0800201
Patrick Venture1cde5f92018-11-07 08:26:47 -0800202 /** List of handlers by transport type. */
203 std::vector<DataHandlerPack> transports;
204
Patrick Venturec02849b2018-11-06 17:31:15 -0800205 /** The bits set indicate what transport mechanisms are supported. */
Patrick Venture1cde5f92018-11-07 08:26:47 -0800206 std::uint16_t bitmask;
Patrick Venturec02849b2018-11-06 17:31:15 -0800207
Patrick Ventured9fb6132018-11-08 09:56:10 -0800208 /** Active image session. */
209 Session activeImage;
210
211 /** Active hash session. */
212 Session activeHash;
213
Patrick Ventureffcc5502018-11-16 12:32:38 -0800214 /** Session for verification. */
215 Session verifyImage;
216
Patrick Venture26e241d2019-05-20 18:39:01 -0700217 /** Session for update. */
218 Session updateImage;
219
Patrick Ventured9fb6132018-11-08 09:56:10 -0800220 /** A quick method for looking up a session's mechanisms and details. */
221 std::map<std::uint16_t, Session*> lookup;
222
Patrick Venture92106df2018-11-09 09:26:30 -0800223 /** The firmware update state. */
224 UpdateState state;
225
Patrick Venture6d7735d2019-06-21 10:03:19 -0700226 /* preparation is triggered once we go into uploadInProgress(), but only
227 * once per full cycle, going back to notYetStarted resets this.
228 */
229 bool preparationTriggered = false;
230 std::unique_ptr<TriggerableActionInterface> preparation;
231
Patrick Venture1d66fe62019-06-03 14:57:27 -0700232 std::unique_ptr<TriggerableActionInterface> verification;
Patrick Venture74059d62019-05-17 10:40:26 -0700233
Patrick Venture1d66fe62019-06-03 14:57:27 -0700234 std::unique_ptr<TriggerableActionInterface> update;
Patrick Venture27ac5822019-05-20 17:39:31 -0700235
Patrick Venturec02849b2018-11-06 17:31:15 -0800236 /** Temporary variable to track whether a blob is open. */
237 bool fileOpen = false;
Patrick Venture615c69e2019-05-29 10:49:54 -0700238
Patrick Ventureda66fd82019-06-03 11:11:24 -0700239 ActionStatus lastVerificationStatus = ActionStatus::unknown;
Patrick Venturea2d82392019-06-03 10:55:17 -0700240
Patrick Ventureda66fd82019-06-03 11:11:24 -0700241 ActionStatus lastUpdateStatus = ActionStatus::unknown;
Patrick Venturec7ca2912018-11-02 11:38:33 -0700242};
243
Patrick Venture1d5a31c2019-05-20 11:38:22 -0700244} // namespace ipmi_flash