// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <inttypes.h>

#include <fbl/array.h>
#include <fbl/unique_ptr.h>
#include <fbl/vector.h>
#include <lib/zx/vmo.h>
#include <tee-client-api/tee-client-types.h>
#include <zircon/assert.h>

#include <type_traits>
#include <utility>

#include "optee-smc.h"
#include "shared-memory.h"
#include "util.h"

namespace optee {

// OP-TEE Messages
//
// The majority of data exchange with OP-TEE occurs via OP-TEE messages. These are used in
// conjunction with the OP-TEE SMC Call with Arg function. When that SMC function is invoked,
// OP-TEE will expect a physical pointer to an OP-TEE message to be passed in arguments a1 and a2.
//
// Each message is made up of a header and a variable number of parameters. The relevant fields of
// a message can depend on the command and the context, so these helper classes aim to reduce the
// possibilities of invariant access. For example, in some instances, a field might be an input and
// in others, it might be an output.

struct MessageHeader {
    uint32_t command;
    uint32_t app_function;
    uint32_t session_id;
    uint32_t cancel_id;

    uint32_t unused;
    uint32_t return_code;
    uint32_t return_origin;
    uint32_t num_params;
};

struct MessageParam {
    enum AttributeType : uint64_t {
        kAttributeTypeNone = 0x0,
        kAttributeTypeValueInput = 0x1,
        kAttributeTypeValueOutput = 0x2,
        kAttributeTypeValueInOut = 0x3,
        kAttributeTypeRegMemInput = 0x5,
        kAttributeTypeRegMemOutput = 0x6,
        kAttributeTypeRegMemInOut = 0x7,
        kAttributeTypeTempMemInput = 0x9,
        kAttributeTypeTempMemOutput = 0xa,
        kAttributeTypeTempMemInOut = 0xb,

        kAttributeTypeMeta = 0x100,
        kAttributeTypeFragment = 0x200,
    };

    struct TemporaryMemory {
        uint64_t buffer;
        uint64_t size;
        uint64_t shared_memory_reference;
    };

    struct RegisteredMemory {
        uint64_t offset;
        uint64_t size;
        uint64_t shared_memory_reference;
    };

    union Value {
        struct {
            uint64_t a;
            uint64_t b;
            uint64_t c;
        } generic;
        TEEC_UUID uuid_big_endian;
        struct {
            uint64_t seconds;
            uint64_t nanoseconds;
        } get_time_specs;
        struct {
            uint64_t memory_type;
            uint64_t memory_size;
        } allocate_memory_specs;
        struct {
            uint64_t memory_type;
            uint64_t memory_id;
        } free_memory_specs;
        struct {
            uint64_t command_number;
            uint64_t object_identifier;
            uint64_t object_offset;
        } file_system_command;
        struct {
            uint64_t identifier;
        } file_system_object;
    };

    uint64_t attribute;
    union {
        TemporaryMemory temporary_memory;
        RegisteredMemory registered_memory;
        Value value;
    } payload;
};

// MessageParamList
//
// MessageParamList is a non-owning view of the parameters in a Message. It is only valid within
// the lifetime of the Message.
class MessageParamList {
public:
    constexpr MessageParamList()
        : params_(nullptr), count_(0U) {}

    MessageParamList(MessageParam* params, size_t count)
        : params_(params), count_(count) {}

    size_t size() const { return count_; }
    MessageParam* get() const { return params_; }

    MessageParam& operator[](size_t i) const {
        ZX_DEBUG_ASSERT(i < count_);
        return params_[i];
    }

    MessageParam* begin() const {
        return params_;
    }
    MessageParam* end() const {
        return &params_[count_];
    }

private:
    MessageParam* params_;
    size_t count_;
};

template <typename PtrType>
class MessageBase {
    static_assert(std::is_same<PtrType, SharedMemory*>::value ||
                      std::is_same<PtrType, fbl::unique_ptr<SharedMemory>>::value,
                  "Template type of MessageBase must be a pointer (raw or smart) to SharedMemory!");

public:
    using SharedMemoryPtr = PtrType;

    zx_paddr_t paddr() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing uninitialized OP-TEE message");
        return memory_->paddr();
    }

    // TODO(godtamit): Move this to protected once all usages of it outside are removed
    // TODO(rjascani): Change this to return a reference to make ownership rules clearer
    MessageParamList params() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing uninitialized OP-TEE message");
        return MessageParamList(reinterpret_cast<MessageParam*>(header() + 1),
                                header()->num_params);
    }

    // Returns whether the message is valid. This must be true to access any class-specific field.
    bool is_valid() const { return memory_ != nullptr; }

protected:
    static constexpr size_t CalculateSize(size_t num_params) {
        return sizeof(MessageHeader) + (sizeof(MessageParam) * num_params);
    }

    // MessageBase
    //
    // Move constructor for MessageBase.
    MessageBase(MessageBase&& msg)
        : memory_(std::move(msg.memory_)) {
        msg.memory_ = nullptr;
    }

    // Move-only, so explicitly delete copy constructor and copy assignment operator for clarity
    MessageBase(const MessageBase&) = delete;
    MessageBase& operator=(const MessageBase&) = delete;

    explicit MessageBase()
        : memory_(nullptr) {}

    explicit MessageBase(SharedMemoryPtr memory)
        : memory_(std::move(memory)) {}

    MessageHeader* header() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing uninitialized OP-TEE message");
        return reinterpret_cast<MessageHeader*>(memory_->vaddr());
    }

    SharedMemoryPtr memory_;
};

// Message
//
// A normal message from the rich world (REE).
class Message : public MessageBase<fbl::unique_ptr<SharedMemory>> {
public:
    enum Command : uint32_t {
        kOpenSession = 0,
        kInvokeCommand = 1,
        kCloseSession = 2,
        kCancel = 3,
        kRegisterSharedMemory = 4,
        kUnregisterSharedMemory = 5,
    };

    // Message
    //
    // Move constructor for Message. Uses the default implicit implementation.
    Message(Message&&) = default;

    // Move-only, so explicitly delete copy constructor and copy assignment operator for clarity
    Message(const Message&) = delete;
    Message& operator=(const Message&) = delete;

protected:
    using MessageBase::MessageBase; // inherit constructors

    bool TryInitializeParameters(size_t starting_param_index,
                                 const fuchsia_tee_ParameterSet& parameter_set,
                                 SharedMemoryManager::ClientMemoryPool* temp_memory_pool);
    bool TryInitializeValue(const fuchsia_tee_Value& value, MessageParam* out_param);
    bool TryInitializeBuffer(const fuchsia_tee_Buffer& buffer,
                             SharedMemoryManager::ClientMemoryPool* temp_memory_pool,
                             MessageParam* out_param);

    zx_status_t CreateOutputParameterSet(size_t starting_param_index,
                                         fuchsia_tee_ParameterSet* out_parameter_set);

private:
    // This nested class is just a container for pairing a vmo with a chunk of shared memory. It
    // can be used to synchronize the user provided buffers with the TEE shared memory.
    class TemporarySharedMemory {
    public:
        explicit TemporarySharedMemory(zx::vmo vmo, uint64_t vmo_offset, size_t size,
                                       fbl::unique_ptr<SharedMemory>);

        TemporarySharedMemory(TemporarySharedMemory&&) = default;
        TemporarySharedMemory& operator=(TemporarySharedMemory&&) = default;

        uint64_t vmo_offset() const { return vmo_offset_; }
        bool is_valid() const { return vmo_.is_valid() && shared_memory_ != nullptr; }

        zx_status_t SyncToSharedMemory();
        zx_status_t SyncToVmo(size_t actual_size);

        zx_handle_t ReleaseVmo();

    private:
        zx::vmo vmo_;
        uint64_t vmo_offset_;
        size_t size_;
        fbl::unique_ptr<SharedMemory> shared_memory_;
    };

    fuchsia_tee_Value CreateOutputValueParameter(const MessageParam& optee_param);
    zx_status_t CreateOutputBufferParameter(const MessageParam& optee_param,
                                            fuchsia_tee_Buffer* out_buffer);

    fbl::Vector<TemporarySharedMemory> allocated_temp_memory_;
};

// OpenSessionMessage
//
// This OP-TEE message is used to start a session between a client app and trusted app.
class OpenSessionMessage : public Message {
public:
    explicit OpenSessionMessage(SharedMemoryManager::DriverMemoryPool* message_pool,
                                SharedMemoryManager::ClientMemoryPool* temp_memory_pool,
                                const Uuid& trusted_app,
                                const fuchsia_tee_ParameterSet& parameter_set);

    // Outputs
    uint32_t session_id() const { return header()->session_id; }
    uint32_t return_code() const { return header()->return_code; }
    uint32_t return_origin() const { return header()->return_origin; }

    zx_status_t CreateOutputParameterSet(fuchsia_tee_ParameterSet* out_parameter_set) {
        return Message::CreateOutputParameterSet(kNumFixedOpenSessionParams, out_parameter_set);
    }

protected:
    using Message::header; // make header() protected

    static constexpr size_t kNumFixedOpenSessionParams = 2;
    static constexpr size_t kTrustedAppParamIndex = 0;
    static constexpr size_t kClientAppParamIndex = 1;
};

// CloseSessionMessage
//
// This OP-TEE message is used to close an existing open session.
class CloseSessionMessage : public Message {
public:
    explicit CloseSessionMessage(SharedMemoryManager::DriverMemoryPool* message_pool,
                                 uint32_t session_id);

    // Outputs
    uint32_t return_code() const { return header()->return_code; }
    uint32_t return_origin() const { return header()->return_origin; }

protected:
    using Message::header; // make header() protected

    static constexpr size_t kNumParams = 0;
};

// InvokeCommandMessage
//
// This OP-TEE message is used to invoke a command on a session between client app and trusted app.
class InvokeCommandMessage : public Message {
public:
    explicit InvokeCommandMessage(SharedMemoryManager::DriverMemoryPool* message_pool,
                                  SharedMemoryManager::ClientMemoryPool* temp_memory_pool,
                                  uint32_t session_id, uint32_t command_id,
                                  const fuchsia_tee_ParameterSet& parameter_set);

    // Outputs
    uint32_t return_code() const { return header()->return_code; }
    uint32_t return_origin() const { return header()->return_origin; }

    zx_status_t CreateOutputParameterSet(fuchsia_tee_ParameterSet* out_parameter_set) {
        return Message::CreateOutputParameterSet(0, out_parameter_set);
    }
};

// RpcMessage
//
// A message originating from the trusted world (TEE) specifying the details of a RPC request.
class RpcMessage : public MessageBase<SharedMemory*> {
public:
    enum Command : uint32_t {
        kLoadTa = 0,
        kAccessReplayProtectedMemoryBlock = 1,
        kAccessFileSystem = 2,
        kGetTime = 3,
        kWaitQueue = 4,
        kSuspend = 5,
        kAllocateMemory = 6,
        kFreeMemory = 7,
        kAccessSqlFileSystem = 8,
        kLoadGprof = 9,
        kPerformSocketIo = 10
    };

    // RpcMessage
    //
    // Move constructor for RpcMessage.
    RpcMessage(RpcMessage&& rpc_msg)
        : MessageBase(std::move(rpc_msg)),
          is_valid_(std::move(rpc_msg.is_valid_)) {
        rpc_msg.is_valid_ = false;
    }

    // Move-only, so explicitly delete copy constructor and copy assignment operator for clarity
    RpcMessage(const RpcMessage&) = delete;
    RpcMessage& operator=(const RpcMessage&) = delete;

    // RpcMessage
    //
    // Constructs an instance of an RpcMessage from a backing SharedMemory object.
    //
    // Parameters:
    //  * memory:   A pointer to the SharedMemory object backing the RpcMessage. This pointer must
    //              be non-null and valid.
    explicit RpcMessage(SharedMemory* memory)
        : MessageBase(memory), is_valid_(TryInitializeMembers()) {}

    uint32_t command() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return header()->command;
    }

    void set_return_origin(uint32_t return_origin) {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        header()->return_origin = return_origin;
    }

    void set_return_code(uint32_t return_code) {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        header()->return_code = return_code;
    }

    // Returns whether the message is a valid RpcMessage. This must be true to access any
    // class-specific field.
    bool is_valid() const { return is_valid_; }

protected:
    bool is_valid_;

private:
    bool TryInitializeMembers();
};

// LoadTaRpcMessage
//
// A RpcMessage that should be interpreted with the command of loading a trusted application.
// A RpcMessage can be converted into a LoadTaRpcMessage via a constructor.
class LoadTaRpcMessage : public RpcMessage {
public:
    // LoadTaRpcMessage
    //
    // Move constructor for LoadTaRpcMessage. Uses the default implicit implementation.
    LoadTaRpcMessage(LoadTaRpcMessage&&) = default;

    // LoadTaRpcMessage
    //
    // Constructs a LoadTaRpcMessage from a moved-in RpcMessage.
    explicit LoadTaRpcMessage(RpcMessage&& rpc_message)
        : RpcMessage(std::move(rpc_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The RPC message passed in should've been valid
        ZX_DEBUG_ASSERT(command() == RpcMessage::Command::kLoadTa);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    const TEEC_UUID& ta_uuid() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return ta_uuid_;
    }

    uint64_t memory_reference_id() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return mem_id_;
    }

    size_t memory_reference_size() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return mem_size_;
    }

    zx_paddr_t memory_reference_paddr() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return mem_paddr_;
    }

    void set_output_ta_size(size_t ta_size) {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        ZX_DEBUG_ASSERT(out_ta_size_ != nullptr);
        *out_ta_size_ = static_cast<uint64_t>(ta_size);
    }

protected:
    static constexpr size_t kNumParams = 2;
    static constexpr size_t kUuidParamIndex = 0;
    static constexpr size_t kMemoryReferenceParamIndex = 1;

    TEEC_UUID ta_uuid_;
    uint64_t mem_id_;
    size_t mem_size_;
    zx_paddr_t mem_paddr_;
    uint64_t* out_ta_size_;

private:
    bool TryInitializeMembers();
};

// GetTimeRpcMessage
//
// A RpcMessage that should be interpreted with the command of getting the current time.
// A RpcMessage can be converted into a GetTimeRpcMessage via a constructor.
class GetTimeRpcMessage : public RpcMessage {
public:
    // GetTimeRpcMessage
    //
    // Move constructor for GetTimeRpcMessage. Uses the default implicit implementation.
    GetTimeRpcMessage(GetTimeRpcMessage&&) = default;

    // GetTimeRpcMessage
    //
    // Constructs a GetTimeRpcMessage from a moved-in RpcMessage.
    explicit GetTimeRpcMessage(RpcMessage&& rpc_message)
        : RpcMessage(std::move(rpc_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The RPC message passed in should've been valid
        ZX_DEBUG_ASSERT(command() == RpcMessage::Command::kGetTime);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    void set_output_seconds(uint64_t secs) {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        *out_secs_ = secs;
    }

    void set_output_nanoseconds(uint64_t nanosecs) {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        *out_nanosecs_ = nanosecs;
    }

protected:
    static constexpr size_t kNumParams = 1;
    static constexpr size_t kTimeParamIndex = 0;

    uint64_t* out_secs_;
    uint64_t* out_nanosecs_;

private:
    bool TryInitializeMembers();
};

// AllocateMemoryRpcMessage
//
// A RpcMessage that should be interpreted with the command of allocating shared memory.
// A RpcMessage can be converted into a AllocateMemoryRpcMessage via a constructor.
class AllocateMemoryRpcMessage : public RpcMessage {
public:
    // AllocateMemoryRpcMessage
    //
    // Move constructor for AllocateMemoryRpcMessage. Uses the default implicit implementation.
    AllocateMemoryRpcMessage(AllocateMemoryRpcMessage&&) = default;

    // AllocateMemoryRpcMessage
    //
    // Constructs a AllocateMemoryRpcMessage from a moved-in RpcMessage.
    explicit AllocateMemoryRpcMessage(RpcMessage&& rpc_message)
        : RpcMessage(std::move(rpc_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The RPC message passed in should've been valid
        ZX_DEBUG_ASSERT(command() == RpcMessage::Command::kAllocateMemory);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    SharedMemoryType memory_type() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return memory_type_;
    }

    size_t memory_size() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return static_cast<size_t>(memory_size_);
    }

    void set_output_memory_size(size_t memory_size) {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        ZX_DEBUG_ASSERT(out_memory_size_ != nullptr);
        *out_memory_size_ = static_cast<uint64_t>(memory_size);
    }

    void set_output_buffer(zx_paddr_t buffer_paddr) {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        ZX_DEBUG_ASSERT(out_memory_buffer_ != nullptr);
        *out_memory_buffer_ = static_cast<uint64_t>(buffer_paddr);
    }

    void set_output_memory_identifier(uint64_t id) {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        ZX_DEBUG_ASSERT(out_memory_id_ != nullptr);
        *out_memory_id_ = id;
    }

protected:
    static constexpr size_t kNumParams = 1;
    static constexpr size_t kMemorySpecsParamIndex = 0;
    static constexpr size_t kOutputTemporaryMemoryParamIndex = 0;

    SharedMemoryType memory_type_;
    size_t memory_size_;
    uint64_t* out_memory_size_;
    uint64_t* out_memory_buffer_;
    uint64_t* out_memory_id_;

private:
    bool TryInitializeMembers();
};

// FreeMemoryRpcMessage
//
// A RpcMessage that should be interpreted with the command of freeing shared memory.
// A RpcMessage can be converted into a FreeMemoryRpcMessage via a constructor.
class FreeMemoryRpcMessage : public RpcMessage {
public:
    // FreeMemoryRpcMessage
    //
    // Move constructor for FreeMemoryRpcMessage. Uses the default implicit implementation.
    FreeMemoryRpcMessage(FreeMemoryRpcMessage&&) = default;

    // FreeMemoryRpcMessage
    //
    // Constructs a FreeMemoryRpcMessage from a moved-in RpcMessage.
    explicit FreeMemoryRpcMessage(RpcMessage&& rpc_message)
        : RpcMessage(std::move(rpc_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The RPC message passed in should've been valid
        ZX_DEBUG_ASSERT(command() == RpcMessage::Command::kFreeMemory);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    SharedMemoryType memory_type() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return memory_type_;
    }

    uint64_t memory_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return memory_id_;
    }

protected:
    static constexpr size_t kNumParams = 1;
    static constexpr size_t kMemorySpecsParamIndex = 0;

    SharedMemoryType memory_type_;
    uint64_t memory_id_;

private:
    bool TryInitializeMembers();
};

// FileSystemRpcMessage
//
// A RpcMessage that should be interpreted with the command of accessing the file system.
// A RpcMessage can be converted into a FileSystemRpcMessage via a constructor.
class FileSystemRpcMessage : public RpcMessage {
public:
    enum FileSystemCommand : uint64_t {
        kOpenFile = 0,
        kCreateFile = 1,
        kCloseFile = 2,
        kReadFile = 3,
        kWriteFile = 4,
        kTruncateFile = 5,
        kRemoveFile = 6,
        kRenameFile = 7,
        kOpenDirectory = 8,
        kCloseDirectory = 9,
        kGetNextFileInDirectory = 10
    };

    // FileSystemRpcMessage
    //
    // Move constructor for `FileSystemRpcMessage`. Uses the default implicit implementation.
    FileSystemRpcMessage(FileSystemRpcMessage&&) = default;

    // FileSystemRpcMessage
    //
    // Constructs a FileSystemRpcMessage from a moved-in RpcMessage.
    explicit FileSystemRpcMessage(RpcMessage&& rpc_message)
        : RpcMessage(std::move(rpc_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The RPC message passed in should've been valid
        ZX_DEBUG_ASSERT(command() == RpcMessage::Command::kAccessFileSystem);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    FileSystemCommand file_system_command() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return fs_command_;
    }

protected:
    static constexpr size_t kNumFileSystemCommands = 11;
    static constexpr size_t kMinNumParams = 1;
    static constexpr size_t kFileSystemCommandParamIndex = 0;

    FileSystemCommand fs_command_;

private:
    bool TryInitializeMembers();
};

// OpenFileFileSystemRpcMessage
//
// A `FileSystemRpcMessage` that should be interpreted with the command of opening a file.
// A `FileSystemRpcMessage` can be converted into a `OpenFileFileSystemRpcMessage` via a
// constructor.
class OpenFileFileSystemRpcMessage : public FileSystemRpcMessage {
public:
    // OpenFileFileSystemRpcMessage
    //
    // Move constructor for `OpenFileFileSystemRpcMessage`. Uses the default implicit
    // implementation.
    OpenFileFileSystemRpcMessage(OpenFileFileSystemRpcMessage&&) = default;

    // OpenFileFileSystemRpcMessage
    //
    // Constructs a `OpenFileFileSystemRpcMessage` from a moved-in `FileSystemRpcMessage`.
    explicit OpenFileFileSystemRpcMessage(FileSystemRpcMessage&& fs_message)
        : FileSystemRpcMessage(std::move(fs_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The file system message passed in should've been valid
        ZX_DEBUG_ASSERT(file_system_command() == FileSystemCommand::kOpenFile);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    uint64_t path_memory_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return path_mem_id_;
    }

    size_t path_memory_size() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return path_mem_size_;
    }

    zx_paddr_t path_memory_paddr() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return path_mem_paddr_;
    }

    void set_output_file_system_object_identifier(uint64_t object_id) {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        ZX_DEBUG_ASSERT(out_fs_object_id_ != nullptr);
        *out_fs_object_id_ = object_id;
    }

protected:
    static constexpr size_t kNumParams = 3;
    static constexpr size_t kPathParamIndex = 1;
    static constexpr size_t kOutFileSystemObjectIdParamIndex = 2;

    uint64_t path_mem_id_;
    size_t path_mem_size_;
    zx_paddr_t path_mem_paddr_;
    uint64_t* out_fs_object_id_;

private:
    bool TryInitializeMembers();
};

// CreateFileFileSystemRpcMessage
//
// A `FileSystemRpcMessage` that should be interpreted with the command of creating a file.
// A `FileSystemRpcMessage` can be converted into a `CreateFileFileSystemRpcMessage` via a
// constructor.
class CreateFileFileSystemRpcMessage : public FileSystemRpcMessage {
public:
    // CreateFileFileSystemRpcMessage
    //
    // Move constructor for `CreateFileFileSystemRpcMessage`. Uses the default implicit
    // implementation.
    CreateFileFileSystemRpcMessage(CreateFileFileSystemRpcMessage&&) = default;

    // CreateFileFileSystemRpcMessage
    //
    // Constructs a `CreateFileFileSystemRpcMessage` from a moved-in `FileSystemRpcMessage`.
    explicit CreateFileFileSystemRpcMessage(FileSystemRpcMessage&& fs_message)
        : FileSystemRpcMessage(std::move(fs_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The file system message passed in should've been valid
        ZX_DEBUG_ASSERT(file_system_command() == FileSystemCommand::kCreateFile);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    uint64_t path_memory_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return path_mem_id_;
    }

    size_t path_memory_size() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return path_mem_size_;
    }

    zx_paddr_t path_memory_paddr() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return path_mem_paddr_;
    }

    void set_output_file_system_object_identifier(uint64_t object_id) {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        ZX_DEBUG_ASSERT(out_fs_object_id_ != nullptr);
        *out_fs_object_id_ = object_id;
    }

protected:
    static constexpr size_t kNumParams = 3;
    static constexpr size_t kPathParamIndex = 1;
    static constexpr size_t kOutFileSystemObjectIdParamIndex = 2;

    uint64_t path_mem_id_;
    size_t path_mem_size_;
    zx_paddr_t path_mem_paddr_;
    uint64_t* out_fs_object_id_;

private:
    bool TryInitializeMembers();
};

// CloseFileFileSystemRpcMessage
//
// A `FileSystemRpcMessage` that should be interpreted with the command of closing a file.
// A `FileSystemRpcMessage` can be converted into a `CloseFileFileSystemRpcMessage` via a
// constructor.
class CloseFileFileSystemRpcMessage : public FileSystemRpcMessage {
public:
    // CloseFileFileSystemRpcMessage
    //
    // Move constructor for `CloseFileFileSystemRpcMessage`. Uses the default implicit
    // implementation.
    CloseFileFileSystemRpcMessage(CloseFileFileSystemRpcMessage&&) = default;

    // CloseFileFileSystemRpcMessage
    //
    // Constructs a `CloseFileFileSystemRpcMessage` from a moved-in `FileSystemRpcMessage`.
    explicit CloseFileFileSystemRpcMessage(FileSystemRpcMessage&& fs_message)
        : FileSystemRpcMessage(std::move(fs_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The file system message passed in should've been valid
        ZX_DEBUG_ASSERT(file_system_command() == FileSystemCommand::kCloseFile);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    uint64_t file_system_object_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return fs_object_id_;
    }

protected:
    static constexpr size_t kNumParams = 1;

    uint64_t fs_object_id_;

private:
    bool TryInitializeMembers();
};

// ReadFileFileSystemRpcMessage
//
// A `FileSystemRpcMessage` that should be interpreted with the command of reading an open file.
// A `FileSystemRpcMessage` can be converted into a `ReadFileFileSystemRpcMessage` via a
// constructor.
class ReadFileFileSystemRpcMessage : public FileSystemRpcMessage {
public:
    // ReadFileFileSystemRpcMessage
    //
    // Move constructor for `ReadFileFileSystemRpcMessage`. Uses the default implicit
    // implementation.
    ReadFileFileSystemRpcMessage(ReadFileFileSystemRpcMessage&&) = default;

    // ReadFileFileSystemRpcMessage
    //
    // Constructs a `ReadFileFileSystemRpcMessage` from a moved-in `FileSystemRpcMessage`.
    explicit ReadFileFileSystemRpcMessage(FileSystemRpcMessage&& fs_message)
        : FileSystemRpcMessage(std::move(fs_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The file system message passed in should've been valid
        ZX_DEBUG_ASSERT(file_system_command() == FileSystemCommand::kReadFile);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    uint64_t file_system_object_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return fs_object_id_;
    }

    uint64_t file_offset() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return file_offset_;
    }

    uint64_t file_contents_memory_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return file_contents_memory_identifier_;
    }

    size_t file_contents_memory_size() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return file_contents_memory_size_;
    }

    zx_paddr_t file_contents_memory_paddr() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return file_contents_memory_paddr_;
    }

    void set_output_file_contents_size(size_t size) const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        ZX_DEBUG_ASSERT(out_file_contents_size_ != nullptr);

        *out_file_contents_size_ = static_cast<uint64_t>(size);
    }

protected:
    static constexpr size_t kNumParams = 2;
    static constexpr size_t kOutReadBufferMemoryParamIndex = 1;

    uint64_t fs_object_id_;
    uint64_t file_offset_;
    uint64_t file_contents_memory_identifier_;
    size_t file_contents_memory_size_;
    zx_paddr_t file_contents_memory_paddr_;
    uint64_t* out_file_contents_size_;

private:
    bool TryInitializeMembers();
};

// WriteFileFileSystemRpcMessage
//
// A `FileSystemRpcMessage` that should be interpreted with the command of writing to an open file.
// A `FileSystemRpcMessage` can be converted into a `WriteFileFileSystemRpcMessage` via a
// constructor.
class WriteFileFileSystemRpcMessage : public FileSystemRpcMessage {
public:
    // WriteFileFileSystemRpcMessage
    //
    // Move constructor for `WriteFileFileSystemRpcMessage`. Uses the default implicit
    // implementation.
    WriteFileFileSystemRpcMessage(WriteFileFileSystemRpcMessage&&) = default;

    // WriteFileFileSystemRpcMessage
    //
    // Constructs a `WriteFileFileSystemRpcMessage` from a moved-in `FileSystemRpcMessage`.
    explicit WriteFileFileSystemRpcMessage(FileSystemRpcMessage&& fs_message)
        : FileSystemRpcMessage(std::move(fs_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The file system message passed in should've been valid
        ZX_DEBUG_ASSERT(file_system_command() == FileSystemCommand::kWriteFile);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    uint64_t file_system_object_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return fs_object_id_;
    }

    zx_off_t file_offset() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return file_offset_;
    }

    uint64_t file_contents_memory_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return file_contents_memory_identifier_;
    }

    size_t file_contents_memory_size() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return file_contents_memory_size_;
    }

    zx_paddr_t file_contents_memory_paddr() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return file_contents_memory_paddr_;
    }

protected:
    static constexpr size_t kNumParams = 2;
    static constexpr size_t kWriteBufferMemoryParam = 1;

    uint64_t fs_object_id_;
    zx_off_t file_offset_;
    uint64_t file_contents_memory_identifier_;
    size_t file_contents_memory_size_;
    zx_paddr_t file_contents_memory_paddr_;

private:
    bool TryInitializeMembers();
};

// TruncateFileFileSystemRpcMessage
//
// A `FileSystemRpcMessage` that should be interpreted with the command of truncating a file.
// A `FileSystemRpcMessage` can be converted into a `TruncateFileFileSystemRpcMessage` via a
// constructor.
class TruncateFileFileSystemRpcMessage : public FileSystemRpcMessage {
public:
    // TruncateFileFileSystemRpcMessage
    //
    // Move constructor for `TruncateFileFileSystemRpcMessage`. Uses the default implicit
    // implementation.
    TruncateFileFileSystemRpcMessage(TruncateFileFileSystemRpcMessage&&) = default;

    // TruncateFileFileSystemRpcMessage
    //
    // Constructs a `TruncateFileFileSystemRpcMessage` from a moved-in `FileSystemRpcMessage`.
    explicit TruncateFileFileSystemRpcMessage(FileSystemRpcMessage&& fs_message)
        : FileSystemRpcMessage(std::move(fs_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The file system message passed in should've been valid
        ZX_DEBUG_ASSERT(file_system_command() == FileSystemCommand::kTruncateFile);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    uint64_t file_system_object_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return fs_object_id_;
    }

    uint64_t target_file_size() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return target_file_size_;
    }

protected:
    static constexpr size_t kNumParams = 1;

    uint64_t fs_object_id_;
    uint64_t target_file_size_;

private:
    bool TryInitializeMembers();
};

// RemoveFileFileSystemRpcMessage
//
// A `FileSystemRpcMessage` that should be interpreted with the command of removing a file.
// A `FileSystemRpcMessage` can be converted into a `RemoveFileFileSystemRpcMessage` via a
// constructor.
class RemoveFileFileSystemRpcMessage : public FileSystemRpcMessage {
public:
    // RemoveFileFileSystemRpcMessage
    //
    // Move constructor for `RemoveFileFileSystemRpcMessage`. Uses the default implicit
    // implementation.
    RemoveFileFileSystemRpcMessage(RemoveFileFileSystemRpcMessage&&) = default;

    // RemoveFileFileSystemRpcMessage
    //
    // Constructs a `RemoveFileFileSystemRpcMessage` from a moved-in `FileSystemRpcMessage`.
    explicit RemoveFileFileSystemRpcMessage(FileSystemRpcMessage&& fs_message)
        : FileSystemRpcMessage(std::move(fs_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The file system message passed in should've been valid
        ZX_DEBUG_ASSERT(file_system_command() == FileSystemCommand::kRemoveFile);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    uint64_t path_memory_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return path_mem_id_;
    }

    size_t path_memory_size() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return path_mem_size_;
    }

    zx_paddr_t path_memory_paddr() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return path_mem_paddr_;
    }

protected:
    static constexpr size_t kNumParams = 2;
    static constexpr size_t kFileNameParamIndex = 1;

    uint64_t path_mem_id_;
    size_t path_mem_size_;
    zx_paddr_t path_mem_paddr_;

private:
    bool TryInitializeMembers();
};

// RenameFileFileSystemRpcMessage
//
// A `FileSystemRpcMessage` that should be interpreted with the command of renaming a file.
// A `FileSystemRpcMessage` can be converted into a `RenameFileFileSystemRpcMessage` via a
// constructor.
class RenameFileFileSystemRpcMessage : public FileSystemRpcMessage {
public:
    // RenameFileFileSystemRpcMessage
    //
    // Move constructor for `RenameFileFileSystemRpcMessage`. Uses the default implicit
    // implementation.
    RenameFileFileSystemRpcMessage(RenameFileFileSystemRpcMessage&&) = default;

    // RenameFileFileSystemRpcMessage
    //
    // Constructs a `RenameFileFileSystemRpcMessage` from a moved-in `FileSystemRpcMessage`.
    explicit RenameFileFileSystemRpcMessage(FileSystemRpcMessage&& fs_message)
        : FileSystemRpcMessage(std::move(fs_message)) {
        ZX_DEBUG_ASSERT(is_valid()); // The file system message passed in should've been valid
        ZX_DEBUG_ASSERT(file_system_command() == FileSystemCommand::kRenameFile);

        is_valid_ = is_valid_ && TryInitializeMembers();
    }

    bool should_overwrite() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return should_overwrite_;
    }

    uint64_t old_file_name_memory_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return old_file_name_mem_id_;
    }

    size_t old_file_name_memory_size() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return old_file_name_mem_size_;
    }

    zx_paddr_t old_file_name_memory_paddr() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return old_file_name_mem_paddr_;
    }

    uint64_t new_file_name_memory_identifier() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return new_file_name_mem_id_;
    }

    size_t new_file_name_memory_size() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return new_file_name_mem_size_;
    }

    zx_paddr_t new_file_name_memory_paddr() const {
        ZX_DEBUG_ASSERT_MSG(is_valid(), "Accessing invalid OP-TEE RPC message");
        return new_file_name_mem_paddr_;
    }

protected:
    static constexpr size_t kNumParams = 3;
    static constexpr size_t kOldFileNameParamIndex = 1;
    static constexpr size_t kNewFileNameParamIndex = 2;

    bool should_overwrite_;
    uint64_t old_file_name_mem_id_;
    size_t old_file_name_mem_size_;
    zx_paddr_t old_file_name_mem_paddr_;
    uint64_t new_file_name_mem_id_;
    size_t new_file_name_mem_size_;
    zx_paddr_t new_file_name_mem_paddr_;

private:
    bool TryInitializeMembers();
};

} // namespace optee
