blob: c6c7fa5bb8c3c33aea4931281a49103a301ea8f9 [file] [log] [blame]
Patrick Venture22e38752018-11-21 08:52:49 -08001/*
2 * Copyright 2018 Google Inc.
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
Patrick Venturec7ca2912018-11-02 11:38:33 -070017#include "firmware_handler.hpp"
18
Patrick Venturea78e39f2018-11-06 18:37:06 -080019#include "image_handler.hpp"
20
Patrick Venture137ad2c2018-11-06 11:30:43 -080021#include <algorithm>
Patrick Venture192d60f2018-11-06 11:11:59 -080022#include <cstdint>
Patrick Venture18235e62018-11-08 10:21:09 -080023#include <cstring>
Patrick Venture68cf64f2018-11-06 10:46:51 -080024#include <memory>
Patrick Venturefa6c4d92018-11-02 18:34:53 -070025#include <string>
26#include <vector>
27
Patrick Venturec7ca2912018-11-02 11:38:33 -070028namespace blobs
29{
30
Patrick Ventureffcc5502018-11-16 12:32:38 -080031const std::string FirmwareBlobHandler::verifyBlobID = "/flash/verify";
Patrick Venture21be45a2018-11-06 12:08:52 -080032const std::string FirmwareBlobHandler::hashBlobID = "/flash/hash";
Patrick Venture7b9256f2018-11-06 15:06:04 -080033const std::string FirmwareBlobHandler::activeImageBlobID =
34 "/flash/active/image";
35const std::string FirmwareBlobHandler::activeHashBlobID = "/flash/active/hash";
Patrick Venture4cceb8e2018-11-06 11:56:48 -080036
Patrick Venture68cf64f2018-11-06 10:46:51 -080037std::unique_ptr<GenericBlobInterface>
Patrick Venture148cd652018-11-06 10:59:47 -080038 FirmwareBlobHandler::CreateFirmwareBlobHandler(
Patrick Venture4eb55952018-11-16 15:36:24 -080039 sdbusplus::bus::bus&& bus, const std::vector<HandlerPack>& firmwares,
Patrick Venture1cde5f92018-11-07 08:26:47 -080040 const std::vector<DataHandlerPack>& transports)
Patrick Venture68cf64f2018-11-06 10:46:51 -080041{
Patrick Venture52854622018-11-06 12:30:00 -080042 /* There must be at least one. */
43 if (!firmwares.size())
44 {
45 return nullptr;
46 }
Patrick Venture1cde5f92018-11-07 08:26:47 -080047 if (!transports.size())
48 {
49 return nullptr;
50 }
Patrick Venture52854622018-11-06 12:30:00 -080051
Patrick Venturea78e39f2018-11-06 18:37:06 -080052 std::vector<std::string> blobs;
53 for (const auto& item : firmwares)
54 {
55 blobs.push_back(item.blobName);
56 }
Patrick Ventureffcc5502018-11-16 12:32:38 -080057 blobs.push_back(verifyBlobID); /* Add blob_id to always exist. */
Patrick Venture18235e62018-11-08 10:21:09 -080058
59 if (0 == std::count(blobs.begin(), blobs.end(), hashBlobID))
60 {
61 return nullptr;
62 }
Patrick Venture4cceb8e2018-11-06 11:56:48 -080063
Patrick Venture1cde5f92018-11-07 08:26:47 -080064 std::uint16_t bitmask = 0;
65 for (const auto& item : transports)
66 {
67 /* TODO: can use std::accumulate() unless I'm mistaken. :D */
68 bitmask |= item.bitmask;
69 }
70
Patrick Venture4eb55952018-11-16 15:36:24 -080071 return std::make_unique<FirmwareBlobHandler>(std::move(bus), firmwares,
72 blobs, transports, bitmask);
Patrick Venture68cf64f2018-11-06 10:46:51 -080073}
74
Patrick Ventured6461d62018-11-09 17:30:25 -080075/* Check if the path is in our supported list (or active list). */
Patrick Venturec7ca2912018-11-02 11:38:33 -070076bool FirmwareBlobHandler::canHandleBlob(const std::string& path)
77{
Patrick Venture4cceb8e2018-11-06 11:56:48 -080078 if (std::count(blobIDs.begin(), blobIDs.end(), path))
Patrick Venture137ad2c2018-11-06 11:30:43 -080079 {
80 return true;
81 }
82
Patrick Venturec7ca2912018-11-02 11:38:33 -070083 return false;
84}
Patrick Venture53977962018-11-02 18:59:35 -070085
Patrick Ventured6461d62018-11-09 17:30:25 -080086/*
87 * Grab the list of supported firmware.
88 *
89 * If there's an open firmware session, it'll already be present in the
90 * list as "/flash/active/image", and if the hash has started,
91 * "/flash/active/hash" regardless of mechanism. This is done in the open
92 * comamnd, no extra work is required here.
93 */
Patrick Venturec7ca2912018-11-02 11:38:33 -070094std::vector<std::string> FirmwareBlobHandler::getBlobIds()
95{
Patrick Venture4cceb8e2018-11-06 11:56:48 -080096 return blobIDs;
Patrick Venturec7ca2912018-11-02 11:38:33 -070097}
Patrick Venture53977962018-11-02 18:59:35 -070098
Patrick Ventured6461d62018-11-09 17:30:25 -080099/*
100 * Per the design, this mean abort, and this will trigger whatever
101 * appropriate actions are required to abort the process.
Patrick Venture9e5aab22018-11-09 20:49:28 -0800102 *
103 * You cannot delete a blob that has an open handle in the system, therefore
104 * this is never called if there's an open session. Guaranteed by the blob
105 * manager.
Patrick Ventured6461d62018-11-09 17:30:25 -0800106 */
Patrick Venturec7ca2912018-11-02 11:38:33 -0700107bool FirmwareBlobHandler::deleteBlob(const std::string& path)
108{
Patrick Venture9e5aab22018-11-09 20:49:28 -0800109 const std::string* toDelete;
110
Patrick Ventureffcc5502018-11-16 12:32:38 -0800111 /* You cannot delete the verify blob -- trying to delete it, currently has
112 * no impact.
113 * TODO: Should trying to delete this cause an abort?
114 */
115 if (path == verifyBlobID)
116 {
117 return false;
118 }
119
Patrick Venture9e5aab22018-11-09 20:49:28 -0800120 if (path == hashBlobID || path == activeHashBlobID)
121 {
122 /* They're deleting the hash. */
123 toDelete = &activeHashBlobID;
124 }
125 else
126 {
127 /* They're deleting the image. */
128 toDelete = &activeImageBlobID;
129 }
130
131 auto it = std::find_if(
132 blobIDs.begin(), blobIDs.end(),
133 [toDelete](const auto& iter) { return (iter == *toDelete); });
134 if (it == blobIDs.end())
135 {
136 /* Somehow they've asked to delete something we didn't say we could
137 * handle.
138 */
139 return false;
140 }
141
142 blobIDs.erase(it);
143
144 /* TODO: Handle aborting the process and fixing up the state. */
145
146 return true;
Patrick Venturec7ca2912018-11-02 11:38:33 -0700147}
Patrick Venture53977962018-11-02 18:59:35 -0700148
Patrick Ventured6461d62018-11-09 17:30:25 -0800149/*
150 * Stat on the files will return information such as what supported
151 * transport mechanisms are available.
152 *
153 * Stat on an active file or hash will return information such as the size
154 * of the data cached, and any additional pertinent information. The
155 * blob_state on the active files will return the state of the update.
156 */
Patrick Venturec7ca2912018-11-02 11:38:33 -0700157bool FirmwareBlobHandler::stat(const std::string& path, struct BlobMeta* meta)
158{
Patrick Venture46637c82018-11-06 15:20:24 -0800159 /* We know we support this path because canHandle is called ahead */
Patrick Ventureffcc5502018-11-16 12:32:38 -0800160 if (path == verifyBlobID)
161 {
162 /* We need to return information for the verify state -- did they call
163 * commit() did things start?
164 */
165 }
166 else if (path == activeImageBlobID)
Patrick Venture46637c82018-11-06 15:20:24 -0800167 {
168 /* We need to return information for the image that's staged. */
169 }
Patrick Ventureffcc5502018-11-16 12:32:38 -0800170 else if (path == activeHashBlobID)
Patrick Venture46637c82018-11-06 15:20:24 -0800171 {
172 /* We need to return information for the hash that's staged. */
173 }
174 else
175 {
176 /* They are requesting information about the generic blob_id. */
Patrick Venture1cde5f92018-11-07 08:26:47 -0800177 meta->blobState = bitmask;
Patrick Venture46637c82018-11-06 15:20:24 -0800178 meta->size = 0;
179
180 /* The generic blob_ids state is only the bits related to the transport
Patrick Ventured6461d62018-11-09 17:30:25 -0800181 * mechanisms.
182 */
Patrick Venture46637c82018-11-06 15:20:24 -0800183 return true;
184 }
185
Patrick Venturec7ca2912018-11-02 11:38:33 -0700186 return false;
187}
Patrick Venture53977962018-11-02 18:59:35 -0700188
Patrick Venturec02849b2018-11-06 17:31:15 -0800189/*
Patrick Ventured6461d62018-11-09 17:30:25 -0800190 * Return stat information on an open session. It therefore must be an active
191 * handle to either the active image or active hash.
192 *
193 * The stat() and sessionstat() commands will return the same information in
194 * many cases, therefore the logic will be combined.
195 *
196 * TODO: combine the logic for stat and sessionstat().
197 */
198bool FirmwareBlobHandler::stat(uint16_t session, struct BlobMeta* meta)
199{
Patrick Venturecc7d1602018-11-15 13:58:33 -0800200 auto item = lookup.find(session);
201 if (item == lookup.end())
202 {
203 return false;
204 }
205
206 /* The blobState here relates to an active sesion, so we should return the
207 * flags used to open this session.
Patrick Ventured6461d62018-11-09 17:30:25 -0800208 */
Patrick Venturecc7d1602018-11-15 13:58:33 -0800209 meta->blobState = item->second->flags;
210 /* The size here refers to the size of the file -- of something analagous.
211 */
212 meta->size = item->second->imageHandler->getSize();
213
214 /* The metadata blob returned comes from the data handler... it's used for
215 * instance, in P2A bridging to get required information about the mapping,
216 * and is the "opposite" of the lpc writemeta requirement.
217 */
218 meta->metadata.clear();
219 if (item->second->dataHandler)
220 {
221 auto bytes = item->second->dataHandler->read();
222 meta->metadata.insert(meta->metadata.begin(), bytes.begin(),
223 bytes.end());
224 }
225
226 /* TODO: During things like verification, etc, we can report the state as
227 * committed, etc, so we'll need to do that.
228 */
229
230 return true;
Patrick Ventured6461d62018-11-09 17:30:25 -0800231}
232
233/*
Patrick Venturec02849b2018-11-06 17:31:15 -0800234 * If you open /flash/image or /flash/tarball, or /flash/hash it will
235 * interpret the open flags and perform whatever actions are required for
236 * that update process. The session returned can be used immediately for
237 * sending data down, without requiring one to open the new active file.
238 *
239 * If you open the active flash image or active hash it will let you
240 * overwrite pieces, depending on the state.
241 *
242 * Once the verification process has started the active files cannot be
243 * opened.
244 *
245 * You can only have one open session at a time. Which means, you can only
246 * have one file open at a time. Trying to open the hash blob_id while you
247 * still have the flash image blob_id open will fail. Opening the flash
248 * blob_id when it is already open will fail.
249 */
Patrick Venturec7ca2912018-11-02 11:38:33 -0700250bool FirmwareBlobHandler::open(uint16_t session, uint16_t flags,
251 const std::string& path)
252{
Patrick Venture6e307a72018-11-09 18:21:17 -0800253 /* Check that they've opened for writing - read back not currently
254 * supported.
255 */
Patrick Venturec02849b2018-11-06 17:31:15 -0800256 if ((flags & OpenFlags::write) == 0)
257 {
258 return false;
259 }
260
Patrick Ventureb1b68fc2018-11-09 09:37:04 -0800261 /* Is the verification process underway? */
262 if (state == UpdateState::verificationStarted)
263 {
264 return false;
265 }
Patrick Venturec02849b2018-11-06 17:31:15 -0800266
267 /* Is there an open session already? We only allow one at a time.
Patrick Venture6e307a72018-11-09 18:21:17 -0800268 *
Patrick Venturec02849b2018-11-06 17:31:15 -0800269 * TODO: Temporarily using a simple boolean flag until there's a full
270 * session object to check.
Patrick Venture7c8b97e2018-11-08 09:14:30 -0800271 *
272 * Further on this, if there's an active session to the hash we don't allow
273 * re-opening the image, and if we have the image open, we don't allow
274 * opening the hash. This design decision may be re-evaluated, and changed
275 * to only allow one session per object type (of the two types). But,
276 * consider if the hash is open, do we want to allow writing to the image?
277 * And why would we? But, really, the point of no-return is once the
278 * verification process has begun -- which is done via commit() on the hash
279 * blob_id, we no longer want to allow updating the contents.
Patrick Venture53977962018-11-02 18:59:35 -0700280 */
Patrick Venturec02849b2018-11-06 17:31:15 -0800281 if (fileOpen)
282 {
283 return false;
284 }
285
Patrick Ventureffcc5502018-11-16 12:32:38 -0800286 /* Handle opening the verifyBlobId --> we know the image and hash aren't
287 * open because of the fileOpen check.
288 *
289 * The file must be opened for writing, but no transport mechanism specified
290 * since it's irrelevant.
291 */
292 if (path == verifyBlobID)
293 {
294 /* In this case, there's no image handler to use, or data handler,
295 * simply set up a session.
296 */
297 verifyImage.flags = flags;
298 verifyImage.state = Session::State::open;
299
300 lookup[session] = &verifyImage;
301
302 fileOpen = true;
303
304 return true;
305 }
306
Patrick Venturec02849b2018-11-06 17:31:15 -0800307 /* There are two abstractions at play, how you get the data and how you
308 * handle that data. such that, whether the data comes from the PCI bridge
309 * or LPC bridge is not connected to whether the data goes into a static
310 * layout flash update or a UBI tarball.
311 */
312
313 /* Check the flags for the transport mechanism: if none match we don't
Patrick Venture18235e62018-11-08 10:21:09 -0800314 * support what they request.
315 */
Patrick Venture1cde5f92018-11-07 08:26:47 -0800316 if ((flags & bitmask) == 0)
Patrick Venturec02849b2018-11-06 17:31:15 -0800317 {
318 return false;
319 }
320
321 /* 2) there isn't, so what are they opening? */
322 if (path == activeImageBlobID)
323 {
324 /* 2a) are they opening the active image? this can only happen if they
Patrick Venture18235e62018-11-08 10:21:09 -0800325 * already started one (due to canHandleBlob's behavior).
326 */
Patrick Venture21c62c12018-11-09 17:46:58 -0800327 return false;
Patrick Venturec02849b2018-11-06 17:31:15 -0800328 }
329 else if (path == activeHashBlobID)
330 {
331 /* 2b) are they opening the active hash? this can only happen if they
Patrick Venture18235e62018-11-08 10:21:09 -0800332 * already started one (due to canHandleBlob's behavior).
333 */
Patrick Venture21c62c12018-11-09 17:46:58 -0800334 return false;
Patrick Venturec02849b2018-11-06 17:31:15 -0800335 }
Patrick Venture18235e62018-11-08 10:21:09 -0800336
337 /* How are they expecting to copy this data? */
338 auto d = std::find_if(
339 transports.begin(), transports.end(),
340 [&flags](const auto& iter) { return (iter.bitmask & flags); });
341 if (d == transports.end())
Patrick Venturec02849b2018-11-06 17:31:15 -0800342 {
Patrick Venture18235e62018-11-08 10:21:09 -0800343 return false;
344 }
345
346 /* We found the transport handler they requested, no surprise since
347 * above we verify they selected at least one we wanted.
348 */
349 Session* curr;
Patrick Venturedb253bf2018-11-09 19:36:03 -0800350 const std::string* active;
Patrick Venture18235e62018-11-08 10:21:09 -0800351
352 if (path == hashBlobID)
353 {
Patrick Venturec02849b2018-11-06 17:31:15 -0800354 /* 2c) are they opening the /flash/hash ? (to start the process) */
Patrick Venture21c62c12018-11-09 17:46:58 -0800355 curr = &activeHash;
Patrick Venturedb253bf2018-11-09 19:36:03 -0800356 active = &activeHashBlobID;
Patrick Venturec02849b2018-11-06 17:31:15 -0800357 }
358 else
359 {
Patrick Venture18235e62018-11-08 10:21:09 -0800360 curr = &activeImage;
Patrick Venturedb253bf2018-11-09 19:36:03 -0800361 active = &activeImageBlobID;
Patrick Venturec02849b2018-11-06 17:31:15 -0800362 }
363
Patrick Venture6e307a72018-11-09 18:21:17 -0800364 /* Elsewhere I do this check by checking "if ::ipmi" because that's the
365 * only non-external data pathway -- but this is just a more generic
366 * approach to that.
367 */
368 if (d->handler)
369 {
370 /* If the data handler open call fails, open fails. */
371 if (!d->handler->open())
372 {
373 return false;
374 }
375 }
376
Patrick Venture18235e62018-11-08 10:21:09 -0800377 /* 2d) are they opening the /flash/tarball ? (to start the UBI process)
Patrick Ventured6461d62018-11-09 17:30:25 -0800378 * 2e) are they opening the /flash/image ? (to start the process)
379 * 2...) are they opening the /flash/... ? (to start the process)
Patrick Venture18235e62018-11-08 10:21:09 -0800380 */
Patrick Venture18235e62018-11-08 10:21:09 -0800381 auto h = std::find_if(
382 handlers.begin(), handlers.end(),
383 [&path](const auto& iter) { return (iter.blobName == path); });
384 if (h == handlers.end())
385 {
386 return false;
387 }
388
389 /* Ok, so we found a handler that matched, so call open() */
390 if (!h->handler->open(path))
391 {
392 return false;
393 }
394
395 curr->flags = flags;
396 curr->dataHandler = d->handler;
397 curr->imageHandler = h->handler;
Patrick Venturecd310222018-11-09 18:47:13 -0800398 curr->state = Session::State::open;
Patrick Venture18235e62018-11-08 10:21:09 -0800399
400 lookup[session] = curr;
401
Patrick Venturedb253bf2018-11-09 19:36:03 -0800402 blobIDs.push_back(*active);
403
Patrick Venture991910a2018-11-09 19:43:48 -0800404 fileOpen = true;
405
Patrick Venture18235e62018-11-08 10:21:09 -0800406 return true;
Patrick Venturec7ca2912018-11-02 11:38:33 -0700407}
Patrick Venture53977962018-11-02 18:59:35 -0700408
Patrick Venture18235e62018-11-08 10:21:09 -0800409/**
410 * The write command really just grabs the data from wherever it is and sends it
411 * to the image handler. It's the image handler's responsibility to deal with
412 * the data provided.
Patrick Ventured6461d62018-11-09 17:30:25 -0800413 *
414 * This receives a session from the blob manager, therefore it is always called
415 * between open() and close().
Patrick Venture18235e62018-11-08 10:21:09 -0800416 */
Patrick Venturec7ca2912018-11-02 11:38:33 -0700417bool FirmwareBlobHandler::write(uint16_t session, uint32_t offset,
418 const std::vector<uint8_t>& data)
419{
Patrick Venture18235e62018-11-08 10:21:09 -0800420 auto item = lookup.find(session);
421 if (item == lookup.end())
422 {
423 return false;
424 }
425
Patrick Ventureb1b68fc2018-11-09 09:37:04 -0800426 /* Prevent writing during verification. */
427 if (state == UpdateState::verificationStarted)
428 {
429 return false;
430 }
431
Patrick Venture18235e62018-11-08 10:21:09 -0800432 std::vector<std::uint8_t> bytes;
433
Patrick Venture05abf7e2018-11-09 11:02:56 -0800434 if (item->second->flags & UpdateFlags::ipmi)
Patrick Venture18235e62018-11-08 10:21:09 -0800435 {
436 bytes = data;
437 }
438 else
439 {
440 /* little endian required per design, and so on, but TODO: do endianness
441 * with boost.
442 */
443 struct ExtChunkHdr header;
444
445 if (data.size() != sizeof(header))
446 {
447 return false;
448 }
449
450 std::memcpy(&header, data.data(), data.size());
451 bytes = item->second->dataHandler->copyFrom(header.length);
452 }
453
454 return item->second->imageHandler->write(offset, bytes);
Patrick Venturec7ca2912018-11-02 11:38:33 -0700455}
Patrick Venture18235e62018-11-08 10:21:09 -0800456
Patrick Venture8c535332018-11-08 15:58:00 -0800457/*
458 * If the active session (image or hash) is over LPC, this allows
459 * configuring it. This option is only available before you start
460 * writing data for the given item (image or hash). This will return
461 * false at any other part. -- the lpc handler portion will know to return
462 * false.
463 */
Patrick Venturec7ca2912018-11-02 11:38:33 -0700464bool FirmwareBlobHandler::writeMeta(uint16_t session, uint32_t offset,
465 const std::vector<uint8_t>& data)
466{
Patrick Venture8c535332018-11-08 15:58:00 -0800467 auto item = lookup.find(session);
468 if (item == lookup.end())
469 {
470 return false;
471 }
472
Patrick Venture05abf7e2018-11-09 11:02:56 -0800473 if (item->second->flags & UpdateFlags::ipmi)
Patrick Venture8c535332018-11-08 15:58:00 -0800474 {
475 return false;
476 }
477
478 return item->second->dataHandler->write(data);
Patrick Venturec7ca2912018-11-02 11:38:33 -0700479}
Patrick Venture8c535332018-11-08 15:58:00 -0800480
Patrick Ventured6461d62018-11-09 17:30:25 -0800481/*
Patrick Ventureffcc5502018-11-16 12:32:38 -0800482 * If this command is called on the session for the verifyBlobID, it'll
Patrick Ventured6461d62018-11-09 17:30:25 -0800483 * trigger a systemd service `verify_image.service` to attempt to verify
Patrick Ventureffcc5502018-11-16 12:32:38 -0800484 * the image.
485 *
486 * For this file to have opened, the other two must be closed, which means any
487 * out-of-band transport mechanism involved is closed.
Patrick Ventured6461d62018-11-09 17:30:25 -0800488 */
Patrick Venturec7ca2912018-11-02 11:38:33 -0700489bool FirmwareBlobHandler::commit(uint16_t session,
490 const std::vector<uint8_t>& data)
491{
Patrick Ventureffcc5502018-11-16 12:32:38 -0800492 auto item = lookup.find(session);
493 if (item == lookup.end())
494 {
495 return false;
496 }
497
498 /* You can only commit on the verifyBlodId */
499 if (item->second->activePath != verifyBlobID)
500 {
501 return false;
502 }
503
504 /* Can only be called once per verification. */
505 if (state == UpdateState::verificationStarted)
506 {
507 return false;
508 }
509
510 /* Set state to committing. */
511 item->second->flags |= StateFlags::committing;
512
513 return triggerVerification();
Patrick Venturec7ca2912018-11-02 11:38:33 -0700514}
Patrick Ventured6461d62018-11-09 17:30:25 -0800515
516/*
517 * Close must be called on the firmware image before triggering
518 * verification via commit. Once the verification is complete, you can
519 * then close the hash file.
520 *
521 * If the `verify_image.service` returned success, closing the hash file
522 * will have a specific behavior depending on the update. If it's UBI,
523 * it'll perform the install. If it's static layout, it'll do nothing. The
524 * verify_image service in the static layout case is responsible for placing
525 * the file in the correct staging position.
526 */
Patrick Venturec7ca2912018-11-02 11:38:33 -0700527bool FirmwareBlobHandler::close(uint16_t session)
528{
Patrick Venture68bb1432018-11-09 20:08:48 -0800529 auto item = lookup.find(session);
530 if (item == lookup.end())
531 {
532 return false;
533 }
534
Patrick Ventureffcc5502018-11-16 12:32:38 -0800535 /* Are you closing the verify blob? */
536 if (item->second->activePath == verifyBlobID)
537 {
538 /* If they close this blob before verification finishes, that's an
539 * abort.
540 * TODO: implement this, for now just let them close the file.
541 */
542 if (state == UpdateState::verificationStarted)
543 {
544 return false;
545 }
546 }
547
Patrick Venture68bb1432018-11-09 20:08:48 -0800548 if (item->second->dataHandler)
549 {
550 item->second->dataHandler->close();
551 }
Patrick Ventureffcc5502018-11-16 12:32:38 -0800552 if (item->second->imageHandler)
553 {
554 item->second->imageHandler->close();
555 }
556
Patrick Venture68bb1432018-11-09 20:08:48 -0800557 item->second->state = Session::State::closed;
558 /* Do not delete the active blob_id from the list of blob_ids, because that
559 * blob_id indicates there is data stored. Delete will destroy it.
560 */
561
562 lookup.erase(item);
563
Patrick Venture991910a2018-11-09 19:43:48 -0800564 fileOpen = false;
565
Patrick Venture68bb1432018-11-09 20:08:48 -0800566 /* TODO: implement other aspects of closing out a session, such as changing
567 * global firmware state.
568 */
569 return true;
Patrick Venturec7ca2912018-11-02 11:38:33 -0700570}
Patrick Ventured6461d62018-11-09 17:30:25 -0800571
Patrick Venturec7ca2912018-11-02 11:38:33 -0700572bool FirmwareBlobHandler::expire(uint16_t session)
573{
574 return false;
575}
Patrick Ventured6461d62018-11-09 17:30:25 -0800576
577/*
578 * Currently, the design does not provide this with a function, however,
579 * it will likely change to support reading data back.
580 */
581std::vector<uint8_t> FirmwareBlobHandler::read(uint16_t session,
582 uint32_t offset,
583 uint32_t requestedSize)
584{
585 return {};
586}
587
Patrick Ventureffcc5502018-11-16 12:32:38 -0800588bool FirmwareBlobHandler::triggerVerification()
589{
590 state = UpdateState::verificationStarted;
591
592 /* TODO: implement this. */
593 return true;
594}
595
Patrick Venturec7ca2912018-11-02 11:38:33 -0700596} // namespace blobs