Skip to main content

mapping/
protocol.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use anyhow::{Error, anyhow};
6use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
7
8pub const MAPPINGS_COMMAND: u32 = 1;
9pub const CLOSE_BLOB_COMMAND: u32 = 2;
10
11/// A command packet used to communicate extent mappings.
12#[derive(FromBytes, IntoBytes, KnownLayout, Immutable, Copy, Clone, Debug, PartialEq)]
13#[repr(C)]
14pub struct RawMappingCommand {
15    pub opcode: u32,
16    pub offset: u32,
17    pub key: u64,
18    pub metadata_count: u32,
19    pub blob_count: u32,
20}
21
22#[derive(Copy, Clone, Debug, PartialEq)]
23pub enum MappingCommand {
24    /// Informs the driver of the extent mappings for a blob.
25    /// The VMO payload contains `blob_count` data extent mappings followed by `metadata_count`
26    /// Merkle extent mappings.
27    Mappings {
28        /// Session-unique identifier for the blob.
29        key: u64,
30        /// Byte offset within the shared VMO where the extent descriptors begin.
31        offset: u32,
32        /// Number of Merkle tree metadata extent mappings.
33        metadata_count: u32,
34        /// Number of Blob data extent mappings.
35        blob_count: u32,
36    },
37    /// Informs the driver that the blob session is closed and mappings can be discarded.
38    CloseBlob {
39        /// Session-unique identifier for the blob.
40        key: u64,
41    },
42}
43
44impl From<MappingCommand> for RawMappingCommand {
45    fn from(cmd: MappingCommand) -> Self {
46        match cmd {
47            MappingCommand::Mappings { key, offset, metadata_count, blob_count } => {
48                RawMappingCommand {
49                    opcode: MAPPINGS_COMMAND,
50                    offset,
51                    key,
52                    metadata_count,
53                    blob_count,
54                }
55            }
56            MappingCommand::CloseBlob { key } => RawMappingCommand {
57                opcode: CLOSE_BLOB_COMMAND,
58                offset: 0,
59                key,
60                metadata_count: 0,
61                blob_count: 0,
62            },
63        }
64    }
65}
66
67impl TryFrom<RawMappingCommand> for MappingCommand {
68    type Error = Error;
69
70    fn try_from(cmd: RawMappingCommand) -> Result<Self, Self::Error> {
71        match cmd.opcode {
72            MAPPINGS_COMMAND => Ok(MappingCommand::Mappings {
73                key: cmd.key,
74                offset: cmd.offset,
75                metadata_count: cmd.metadata_count,
76                blob_count: cmd.blob_count,
77            }),
78            CLOSE_BLOB_COMMAND => Ok(MappingCommand::CloseBlob { key: cmd.key }),
79            _ => Err(anyhow!("Unknown opcode: {}", cmd.opcode)),
80        }
81    }
82}