wasefire_board_api/vendor.rs
1// Copyright 2025 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Vendor interface.
16
17use alloc::vec::Vec;
18use core::fmt::Debug;
19use core::hash::Hash;
20
21use derive_where::derive_where;
22use wasefire_error::Error;
23use wasefire_logger::MaybeFormat;
24
25use crate::Failure;
26use crate::applet::{Handlers, Memory};
27
28/// Vendor event.
29#[cfg_attr(feature = "defmt", derive(defmt::Format))]
30#[derive_where(Debug, PartialEq, Eq)]
31pub struct Event<B: crate::Api + ?Sized>(pub <crate::Vendor<B> as Api>::Event);
32
33impl<B: crate::Api> From<Event<B>> for crate::Event<B> {
34 fn from(event: Event<B>) -> Self {
35 crate::Event::Vendor(event)
36 }
37}
38
39/// Vendor key.
40pub type Key<B> = <super::Vendor<B> as Api>::Key;
41
42/// Vendor interface.
43pub trait Api: Send {
44 /// Vendor event.
45 ///
46 /// Event equality is used by the scheduler. If an applet receives 2 equal events and did not
47 /// process the first when the second arrives, then the second event is ignored.
48 ///
49 /// Use [`NoEvent`] if you don't need events.
50 type Event: MaybeFormat + Debug + Eq + Send;
51
52 /// Vendor key.
53 ///
54 /// The key of an even defines which applet event handler will process it.
55 ///
56 /// Use `()` if you don't need events.
57 type Key: MaybeFormat + Debug + Copy + Hash + Ord + Send;
58
59 /// Returns the key of an event.
60 fn key(event: &Self::Event) -> Self::Key;
61
62 /// Vendor syscall.
63 ///
64 /// The returned value in an encoded `Result<u32, Error>`. In particular, the `u32` must not
65 /// exceed `i32::MAX` otherwise the platform will panic.
66 fn syscall(
67 memory: impl Memory, handlers: impl Handlers<Self::Key>, x1: u32, x2: u32, x3: u32, x4: u32,
68 ) -> Result<u32, Failure>;
69
70 /// Vendor callback.
71 ///
72 /// This function should convert the event into parameters to the applet handler. The number of
73 /// parameters should be fixed for the event key. It cannot call `handlers.register()`.
74 fn callback(
75 memory: impl Memory, handlers: impl Handlers<Self::Key>, event: Self::Event,
76 params: &mut Vec<u32>,
77 );
78
79 /// Disables an event.
80 ///
81 /// Events can be enabled (and disabled) with [`Self::syscall()`] by applets. This function is
82 /// used by the scheduler when an applet dies with registered handlers. The event keys of those
83 /// handlers are disabled.
84 fn disable(key: Self::Key) -> Result<(), Error>;
85}
86
87/// Helper type to indicate the vendor interface does not have events.
88#[cfg_attr(feature = "defmt", derive(defmt::Format))]
89#[derive(Debug, PartialEq, Eq)]
90pub enum NoEvent {}