1 #pragma once 2 3 #include <blobs-ipmid/blobs.hpp> 4 #include <ctime> 5 #include <ipmid/oemrouter.hpp> 6 #include <memory> 7 #include <string> 8 #include <unordered_map> 9 #include <vector> 10 11 namespace blobs 12 { 13 14 /* The maximum read size. 15 * NOTE: Once this can be dynamically determined, we'll switch to that method. 16 * Having this in a header allows it to used cleanly for now. 17 */ 18 const int crcSize = sizeof(uint16_t); 19 const int btReplyHdrLen = 5; 20 const int btTransportLength = 64; 21 const uint32_t maximumReadSize = 22 btTransportLength - (btReplyHdrLen + oem::groupMagicSize + crcSize); 23 24 struct SessionInfo 25 { 26 SessionInfo() = default; 27 SessionInfo(const std::string& path, GenericBlobInterface* handler, 28 uint16_t flags) : 29 blobId(path), 30 handler(handler), flags(flags) 31 { 32 } 33 ~SessionInfo() = default; 34 35 std::string blobId; 36 GenericBlobInterface* handler; 37 uint16_t flags; 38 }; 39 40 class ManagerInterface 41 { 42 public: 43 virtual ~ManagerInterface() = default; 44 45 virtual bool 46 registerHandler(std::unique_ptr<GenericBlobInterface> handler) = 0; 47 48 virtual uint32_t buildBlobList() = 0; 49 50 virtual std::string getBlobId(uint32_t index) = 0; 51 52 virtual bool open(uint16_t flags, const std::string& path, 53 uint16_t* session) = 0; 54 55 virtual bool stat(const std::string& path, struct BlobMeta* meta) = 0; 56 57 virtual bool stat(uint16_t session, struct BlobMeta* meta) = 0; 58 59 virtual bool commit(uint16_t session, const std::vector<uint8_t>& data) = 0; 60 61 virtual bool close(uint16_t session) = 0; 62 63 virtual std::vector<uint8_t> read(uint16_t session, uint32_t offset, 64 uint32_t requestedSize) = 0; 65 66 virtual bool write(uint16_t session, uint32_t offset, 67 const std::vector<uint8_t>& data) = 0; 68 69 virtual bool deleteBlob(const std::string& path) = 0; 70 71 virtual bool writeMeta(uint16_t session, uint32_t offset, 72 const std::vector<uint8_t>& data) = 0; 73 }; 74 75 /** 76 * Blob Manager used to store handlers and sessions. 77 */ 78 class BlobManager : public ManagerInterface 79 { 80 public: 81 BlobManager() 82 { 83 next = static_cast<uint16_t>(std::time(nullptr)); 84 }; 85 86 ~BlobManager() = default; 87 /* delete copy constructor & assignment operator, only support move 88 * operations. 89 */ 90 BlobManager(const BlobManager&) = delete; 91 BlobManager& operator=(const BlobManager&) = delete; 92 BlobManager(BlobManager&&) = default; 93 BlobManager& operator=(BlobManager&&) = default; 94 95 /** 96 * Register a handler. We own the pointer. 97 * 98 * @param[in] handler - a pointer to a blob handler. 99 * @return bool - true if registered. 100 */ 101 bool 102 registerHandler(std::unique_ptr<GenericBlobInterface> handler) override; 103 104 /** 105 * Builds the blobId list for enumeration. 106 * 107 * @return lowest value returned is 0, otherwise the number of 108 * blobIds. 109 */ 110 uint32_t buildBlobList() override; 111 112 /** 113 * Grabs the blobId for the indexed blobId. 114 * 115 * @param[in] index - the index into the blobId cache. 116 * @return string - the blobId or empty string on failure. 117 */ 118 std::string getBlobId(uint32_t index) override; 119 120 /** 121 * Attempts to open the file specified and associates with a session. 122 * 123 * @param[in] flags - the flags to pass to open. 124 * @param[in] path - the file path to open. 125 * @param[in,out] session - pointer to store the session on success. 126 * @return bool - true if able to open. 127 */ 128 bool open(uint16_t flags, const std::string& path, 129 uint16_t* session) override; 130 131 /** 132 * Attempts to retrieve a BlobMeta for the specified path. 133 * 134 * @param[in] path - the file path for stat(). 135 * @param[in,out] meta - a pointer to store the metadata. 136 * @return bool - true if able to retrieve the information. 137 */ 138 bool stat(const std::string& path, struct BlobMeta* meta) override; 139 140 /** 141 * Attempts to retrieve a BlobMeta for a given session. 142 * 143 * @param[in] session - the session for this command. 144 * @param[in,out] meta - a pointer to store the metadata. 145 * @return bool - true if able to retrieve the information. 146 */ 147 bool stat(uint16_t session, struct BlobMeta* meta) override; 148 149 /** 150 * Attempt to commit a blob for a given session. 151 * 152 * @param[in] session - the session for this command. 153 * @param[in] data - an optional commit blob. 154 * @return bool - true if the commit succeeds. 155 */ 156 bool commit(uint16_t session, const std::vector<uint8_t>& data) override; 157 158 /** 159 * Attempt to close a session. If the handler returns a failure 160 * in closing, the session is kept open. 161 * 162 * @param[in] session - the session for this command. 163 * @return bool - true if the session was closed. 164 */ 165 bool close(uint16_t session) override; 166 167 /** 168 * Attempt to read bytes from the blob. If there's a failure, such as 169 * an invalid offset it'll just return 0 bytes. 170 * 171 * @param[in] session - the session for this command. 172 * @param[in] offset - the offset from which to read. 173 * @param[in] requestedSize - the number of bytes to try and read. 174 * @return the bytes read. 175 */ 176 std::vector<uint8_t> read(uint16_t session, uint32_t offset, 177 uint32_t requestedSize) override; 178 179 /** 180 * Attempt to write to a blob. The manager does not track whether 181 * the session opened the file for writing. 182 * 183 * @param[in] session - the session for this command. 184 * @param[in] offset - the offset into the blob to write. 185 * @param[in] data - the bytes to write to the blob. 186 * @return bool - true if the write succeeded. 187 */ 188 bool write(uint16_t session, uint32_t offset, 189 const std::vector<uint8_t>& data) override; 190 191 /** 192 * Attempt to delete a blobId. This method will just call the 193 * handler, which will return failure if the blob doesn't support 194 * deletion. This command will also fail if there are any open 195 * sessions against the specific blob. 196 * 197 * In the case where they specify a folder, such as /blob/skm where 198 * the "real" blobIds are /blob/skm/1, or /blob/skm/2, the manager 199 * may see there are on open sessions to that specific path and will 200 * call the handler. In this case, the handler is responsible for 201 * handling any checks or logic. 202 * 203 * @param[in] path - the blobId path. 204 * @return bool - true if delete was successful. 205 */ 206 bool deleteBlob(const std::string& path) override; 207 208 /** 209 * Attempt to write Metadata to a blob. 210 * 211 * @param[in] session - the session for this command. 212 * @param[in] offset - the offset into the blob to write. 213 * @param[in] data - the bytes to write to the blob. 214 * @return bool - true if the write succeeded. 215 */ 216 bool writeMeta(uint16_t session, uint32_t offset, 217 const std::vector<uint8_t>& data) override; 218 219 /** 220 * Attempts to return a valid unique session id. 221 * 222 * @param[in,out] - pointer to the session. 223 * @return bool - true if able to allocate. 224 */ 225 bool getSession(uint16_t* session); 226 227 /** 228 * Given a file path will return first handler to answer that it owns 229 * it. 230 * 231 * @param[in] path - the file path. 232 * @return pointer to the handler or nullptr if not found. 233 */ 234 GenericBlobInterface* getHandler(const std::string& path); 235 236 /** 237 * Given a session id will return associated handler. 238 * 239 * @param[in] session - the session. 240 * @return pointer to the handler or nullptr if not found. 241 */ 242 GenericBlobInterface* getHandler(uint16_t session); 243 244 /** 245 * Given a session id will return associated metadata, including 246 * the handler and the flags passed into open. 247 * 248 * @param[in] session - the session. 249 * @return pointer to the information or nullptr if not found. 250 */ 251 SessionInfo* getSessionInfo(uint16_t session); 252 253 /** 254 * Given a session id will return associated path. 255 * 256 * @param[in] session - the session. 257 * @return the path or "" on failure. 258 */ 259 std::string getPath(uint16_t session) const; 260 261 private: 262 void incrementOpen(const std::string& path); 263 void decrementOpen(const std::string& path); 264 int getOpen(const std::string& path) const; 265 266 /* The next session ID to use */ 267 uint16_t next; 268 /* Temporary list of blobIds used for enumeration. */ 269 std::vector<std::string> ids; 270 /* List of Blob handler. */ 271 std::vector<std::unique_ptr<GenericBlobInterface>> handlers; 272 /* Mapping of session ids to blob handlers and the path used with open. 273 */ 274 std::unordered_map<uint16_t, SessionInfo> sessions; 275 /* Mapping of open blobIds */ 276 std::unordered_map<std::string, int> openFiles; 277 }; 278 279 /** 280 * @brief Gets a handle to the BlobManager. 281 * 282 * @return a pointer to the BlobManager instance. 283 */ 284 ManagerInterface* getBlobManager(); 285 286 } // namespace blobs 287