Crate wasefire_applet_api

Crate wasefire_applet_api 

Source
Expand description

Applet-side of the applet API.

This api crate provides Rust bindings for the Wasm-side of the applet API. Users should not directly use those bindings but instead use the prelude crate that provides higher-level and more convenient access.

The bindings in this crate are automatically generated from a proc-macro based on a procedural description of the applet API defined in the api-desc crate. As such, they follow a precise convention:

  • The module hierarchy in the applet API is mapped to the module hierarchy in this crate.
  • Type definitions (like enums) are mapped to their definition. If an enum is used as an error, it provides a Error::to_result(isize) -> Result<usize, Error> method to convert signed integer results into Rust Result.
  • Functions are mapped to their definition but also to a module of the same name. This module defines 2 structs: Params for the parameters of the function and Results for the results of the function. If a struct is empty, then it is not used.
  • All parameters and results are 32-bits integers mapping to the i32 Wasm type, but their Rust type reflect their role. For example:
    • usize for unsigned integers
    • isize for signed integers (which may represent some Result<u31, u31> where the error type may be converted to some enum)
    • *const u8 and *mut u8 for opaque/polymorphic pointers
    • *const T and *mut T for transparent pointers where T is recursively defined
    • extern "C" fn(data: *const u8, ...) for closures over some opaque data and possibly additional parameters

§WebAssembly-level documentation

§Applet functions

An applet must expose 3 functions to the platform:

  • init: () -> () called exactly once before anything else. It cannot call any platform function except dp (aka debug::println()).
  • main: () -> () called exactly once after init returns. It can call all platform functions.
  • alloc: (size: u32, align: u32) -> (ptr: u32) may be called during any platform function after init returned. It cannot call any platform function. A return value of zero indicates an error and will trap the applet. The applet may assume that size is a non-zero multiple of align and align is either 1, 2, or 4.

§Platform functions

The platform exposes many functions. Each function comes with its own documentation, which may omit the following general properties.

§Parameters and result

At WebAssembly level, all functions use u32 (more precisely i32) as parameters and result (WebAssembly permits multiple results, but platform functions never return more than one value). However, platform functions will be documented with more specific types to better convey the intent.

Languages that compile to WebAssembly may use similar specific types when binding platform functions. Those types should be compatible with u32 in WebAssembly.

§Applet closures

Some functions (usually called register) may register a closure. There is usually an associated function (usually called unregister) that unregisters the registered closure. The register function takes fn { data: *const void, ... } (usually called handler_func) and a *const void (usually called handler_data) as arguments. The unregister function (if it exists) doesn’t have any particular parameters.

After the closure is registered (the register function is called) and as long as it stays registered (the unregister function is not called), the platform may call this closure any time sw (aka scheduling::wait_for_callback()) is called. Note that if main returns and there are registered closures, the applet behaves as if sw is called indefinitely.

An applet closure may call any platform function unless explicitly documented by the register function.

§Reading and writing memory

Some functions take pointers as argument (usually *const u8 or *mut u8). They either document the expected size or take an associated length argument.

The platform may read and write (only for *mut T pointers) the designated region of the WebAssembly memory during the function call. Otherwise (and by default), platform functions don’t read or write the WebAssembly memory.

§Allocating memory

Finally, some functions take nested pointers as argument (usually *mut *mut u8). They either return a usize or take a *mut usize as argument.

Those functions may call alloc (at most once per such nested pointer argument) with a dynamic size but fixed alignment (usually 1). If they do, they will store the non-null result in the *mut *mut u8 argument. Regardless of whether they allocate or not, they store the size in the *mut usize argument (if it exists) or return it (otherwise).

Note that alloc will not be called with a size of zero. So if the size is zero after the function returns, this signifies that alloc was not called (and the *mut *mut u8 not written) and the output is empty (unless otherwise documented like in the case of an absence of output, in which case the size may not be written).

The caller is responsible for managing the allocation after the function returns and the size is non-zero. To avoid memory leaks, the applet should initialize the *mut usize argument (if it exists) to zero and consider having ownership of the *mut *mut u8 pointee if the size is non-zero after the call.

Modules§

button
Button and touch operations.
clock
Clock operations.
crypto
Cryptographic operations.
debug
Debugging operations.
fingerprint
Fingerprint operations.
gpio
Low-level GPIO operations.
led
LED operations.
platform
Platform operations.
rng
Random number generators.
scheduling
store
Persistent storage operations.
timer
Timer operations.
uart
usb
USB operations.
vendor
Vendor interface.