| // Copyright 2024 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #pragma once |
| |
| #include "google3/cr51_image_descriptor.h" |
| #include "google3/host_commands.h" |
| |
| #include "host_command.hpp" |
| #include "message_util.hpp" |
| #include "payload_update_interface.hpp" |
| #include "sys.hpp" |
| |
| #include <stdplus/handle/managed.hpp> |
| |
| #include <optional> |
| #include <span> |
| #include <string> |
| #include <vector> |
| |
| namespace google |
| { |
| namespace hoth |
| { |
| namespace internal |
| { |
| |
| // Struct used to send activate request: |
| struct ActivateRequest |
| { |
| payload_update_packet header; |
| payload_update_activate activate; |
| }; |
| |
| // Struct used to send confirm request: |
| struct ConfirmRequest |
| { |
| payload_update_packet header; |
| payload_update_confirm confirm; |
| }; |
| |
| // Maximum allowed payload size |
| constexpr size_t max_packet_size = |
| mailbox_size - sizeof(payload_update_packet) - sizeof(ReqHeader); |
| |
| constexpr size_t kImageDescriptorAlignment = 64 * 1024; |
| |
| constexpr uint64_t kDescriptorMagic = 0x5f435344474d495f; // "_IMGDSC_" |
| |
| constexpr uint32_t kSectorSizeBytes = 4096; |
| constexpr uint32_t kEraseChunkSizeBytes = kSectorSizeBytes * 32; |
| |
| /** @class PayloadUpdateImpl |
| * @brief PayloadUpdate method implementation |
| * @details Methods to interface with Hoth to perform payload update |
| */ |
| class PayloadUpdateImpl : public PayloadUpdate |
| { |
| public: |
| explicit PayloadUpdateImpl(HostCommand* hostCmd, |
| const Sys* sys = &sys_impl) : |
| hostCmd(hostCmd), sys(sys) |
| {} |
| |
| void initiate() const override; |
| void erase(uint32_t offset, uint32_t size) const override; |
| void eraseAndSendStaticWP(const std::string& path) const override; |
| void read(uint32_t offset, std::span<uint8_t> data) const override; |
| void verify() const override; |
| payload_update_status getStatus() const override; |
| void activate(Side side, Persistence persistence) const override; |
| void send(const std::string& imagePath) const override; |
| std::optional<payload_update_confirm_response> |
| confirm(enum payload_update_confirm_option option, uint32_t timeout, |
| uint64_t confirmation_cookie) const override; |
| bool findDescriptor(const std::string& path, uint32_t* desc_offset) const override; |
| void eraseAndSendStaticWPRegions(const std::string& path, |
| uint32_t desc_offset) const override; |
| // Arbitrarily picked due to the performance of the calls taking ~0.4s |
| static constexpr size_t verify_size = 512 * 1024; |
| |
| private: |
| void sendCommand(uint8_t command, uint32_t offset = 0, |
| uint32_t len = 0) const; |
| void sendCommand(std::span<const uint8_t> request) const; |
| [[nodiscard]] std::span<const uint8_t> |
| sendCommand(std::vector<uint8_t>& buf, uint8_t command, |
| uint32_t offset = 0, uint32_t len = 0) const; |
| [[nodiscard]] std::span<const uint8_t> |
| sendCommand(std::vector<uint8_t>& buf, |
| std::span<const uint8_t> request) const; |
| void trimAndSend(std::span<const uint8_t> data, |
| uint32_t globalOffset) const; |
| /** @brief RAII wrapper and its destructor for opening a file descriptor */ |
| static void closeFd(int&& fd, const Sys*& sys) |
| { |
| if (sys) |
| { |
| sys->close(fd); |
| } |
| } |
| using Fd = stdplus::Managed<int, const Sys*>::Handle<closeFd>; |
| |
| /** @brief Connection to Hoth for sending and receiving host commands */ |
| HostCommand* hostCmd = nullptr; |
| const Sys* sys = nullptr; |
| }; |
| |
| } // namespace internal |
| |
| } // namespace hoth |
| |
| } // namespace google |