wasefire-protocol 0.4.0

Wasefire protocol between platform and host
Documentation
// 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.

use wasefire_common::platform::Side;
use wasefire_error::Error;
use wasefire_wire::Wire;
#[cfg(feature = "host")]
use wasefire_wire::Yoke;

use crate::common::{AppletKind, Hexa, Name};

#[derive(Debug)]
#[cfg(feature = "host")]
pub enum DynInfo {
    V3(Yoke<Info3<'static>>),
    V2(Yoke<_Info2<'static>>),
    V1(Yoke<_Info1<'static>>),
    V0(Yoke<_Info0<'static>>),
}

#[cfg(feature = "host")]
impl DynInfo {
    pub fn serial(&self) -> &Hexa<'_> {
        match self {
            DynInfo::V3(x) => &x.get().serial,
            DynInfo::V2(x) => &x.get().serial,
            DynInfo::V1(x) => &x.get().serial,
            DynInfo::V0(x) => &x.get().serial,
        }
    }

    pub fn applet_kind(&self) -> Option<AppletKind> {
        match self {
            DynInfo::V3(x) => Some(x.get().applet_kind),
            DynInfo::V2(x) => Some(x.get().applet_kind),
            DynInfo::V1(_) => None,
            DynInfo::V0(_) => None,
        }
    }

    pub fn running_side(&self) -> Option<Side> {
        match self {
            DynInfo::V3(x) => Some(x.get().running_side),
            DynInfo::V2(x) => Some(x.get().running_side),
            DynInfo::V1(x) => Some(x.get().running_side),
            DynInfo::V0(_) => None,
        }
    }

    pub fn running_name(&self) -> Option<&Name<'_>> {
        match self {
            DynInfo::V3(x) => Some(&x.get().running_info.name),
            DynInfo::V2(_) => None,
            DynInfo::V1(_) => None,
            DynInfo::V0(_) => None,
        }
    }

    pub fn running_version(&self) -> &Hexa<'_> {
        match self {
            DynInfo::V3(x) => &x.get().running_info.version,
            DynInfo::V2(x) => &x.get().running_version,
            DynInfo::V1(x) => &x.get().running_version,
            DynInfo::V0(x) => &x.get().version,
        }
    }

    pub fn opposite_name(&self) -> Option<Result<&Name<'_>, Error>> {
        Some(match self {
            DynInfo::V3(x) => try { &x.get().opposite_info.as_ref()?.name },
            DynInfo::V2(_) => return None,
            DynInfo::V1(_) => return None,
            DynInfo::V0(_) => return None,
        })
    }

    pub fn opposite_version(&self) -> Option<Result<&Hexa<'_>, Error>> {
        Some(match self {
            DynInfo::V3(x) => try { &x.get().opposite_info.as_ref()?.version },
            DynInfo::V2(x) => try { x.get().opposite_version.as_ref()? },
            DynInfo::V1(x) => try { x.get().opposite_version.as_ref()? },
            DynInfo::V0(_) => return None,
        })
    }
}

#[derive(Debug, Wire)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Info3<'a> {
    pub serial: Hexa<'a>,
    pub applet_kind: AppletKind,
    pub running_side: Side,
    pub running_info: SideInfo0<'a>,
    pub opposite_info: Result<SideInfo0<'a>, Error>,
}

/// Information about a platform side.
#[derive(Debug, Wire)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SideInfo0<'a> {
    /// Name of the platform.
    ///
    /// This field has no particular interpretation.
    pub name: Name<'a>,

    /// Version of the platform.
    ///
    /// This field is interpreted by lexicographical order.
    pub version: Hexa<'a>,
}

#[derive(Debug, Wire)]
#[cfg(feature = "host")]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct _Info2<'a> {
    pub serial: Hexa<'a>,
    pub applet_kind: AppletKind,
    pub running_side: Side,
    pub running_version: Hexa<'a>,
    pub opposite_version: Result<Hexa<'a>, Error>,
}

#[derive(Debug, Wire)]
#[cfg(feature = "host")]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct _Info1<'a> {
    pub serial: Hexa<'a>,
    pub running_side: Side,
    pub running_version: Hexa<'a>,
    pub opposite_version: Result<Hexa<'a>, Error>,
}

#[derive(Debug, Wire)]
#[cfg(feature = "host")]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct _Info0<'a> {
    pub serial: Hexa<'a>,
    pub version: Hexa<'a>,
}