Skip to content

Commit 0a0ad7c

Browse files
Merge pull request #3 from siwieme/main
WASI-USB Phase 2 Proposal
2 parents e0896e2 + d6d6813 commit 0a0ad7c

18 files changed

Lines changed: 1032 additions & 212 deletions

File tree

README.md

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,40 @@ A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) A
44

55
### Current Phase
66

7-
WASI USB is currently in Phase 1.
7+
WASI USB is currently in Phase 2.
88

99
### Champions
1010

1111
<!---
1212
Please limit to one champion per company or organization
1313
-->
1414
- Merlijn Sebrechts
15-
- Wouter Hennen
16-
- Warre Dujardin
15+
16+
### Portability Criteria
17+
18+
The API is designed to be portable across different platforms and environments, as it is based on the USB standard and Operating System APIs. The reference implementation can be used as a starting point for porting the API to different platforms. There will be provided at least two independent implementations in order to avoid baking in any libusb-specific behaviour.
19+
20+
| Platform | Architecture | Reference Hardware |
21+
|----------|--------------|--------------------|
22+
| Windows | x86_64 | |
23+
| Linux | x86_64 | |
24+
| Linux | aarch64 | Rasperry Pi 4 |
25+
| MacOS | aarch64 | Macbook Pro M3 MAX |
26+
27+
## Table of Contents
28+
29+
- [Introduction](#introduction)
30+
- [Goals](#goals)
31+
- [Non-goals](#non-goals)
32+
- [API walk-through](#api-walk-through)
33+
- [Considered alternatives](#considered-alternatives)
34+
- [References & acknowledgements](#references--acknowledgements)
1735

1836
### Introduction
1937

2038
The WASI USB proposal adds an API for controlling USB devices. The API is meant to be used to with any kind of USB device, and is more low-level than, for example, accessing USb devices through the filesystem. The API design is based on the [libusb](https://libusb.info/) library, which is an often-used library for accessing USB devices in native programs. Just like libusb, this API aims to be a thin wrapper around the USB standard and Operating System APIs, with improved ergonomics where necessary. Access control can be applied to limit the devices a component can access.
2139

22-
A reference implementation can be found [here](https://github.com/Wouter01/USB_WASI).
23-
24-
### Goals [or Motivating Use Cases, or Scenarios]
40+
### Goals
2541

2642
The goal of the proposal is to offer an API to control USB devices on a low level.
2743

@@ -46,9 +62,12 @@ Being able to use the API in web browsers would be a nice thing to have, but aft
4662

4763
### References & acknowledgements
4864

49-
Many thanks for valuable feedback and advice from:
65+
Many thanks for valuable feedback, work and advice from:
5066

67+
- Michiel Van Kenhove
68+
- Friedrich Vandenberghe
5169
- Warre Dujardin
5270
- Wouter Hennen
71+
- Robbe Leroy
5372

5473
This work has been partially supported by the ELASTIC project, which received funding from the Smart Networks and Services Joint Undertaking (SNS JU) under the European Union’s Horizon Europe research and innovation programme under Grant Agreement No 101139067. Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union. Neither the European Union nor the granting authority can be held responsible for them. This funding supported individual contributor organisations, not the W3C or this community group as a whole.

wit/configuration.wit

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package component:usb@0.2.1;
2+
3+
interface configuration {
4+
/// ConfigValue is used to specify a configuration or an unconfigured state.
5+
variant config-value {
6+
unconfigured, // Corresponds to -1 in libusb (unconfigure device)
7+
value(u8) // A valid configuration value (bConfigurationValue)
8+
}
9+
}

wit/deps/example-dep/example-api.wit

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
package wasi:cli@0.2.5;
2+
3+
@since(version = 0.2.0)
4+
interface environment {
5+
/// Get the POSIX-style environment variables.
6+
///
7+
/// Each environment variable is provided as a pair of string variable names
8+
/// and string value.
9+
///
10+
/// Morally, these are a value import, but until value imports are available
11+
/// in the component model, this import function should return the same
12+
/// values each time it is called.
13+
@since(version = 0.2.0)
14+
get-environment: func() -> list<tuple<string, string>>;
15+
16+
/// Get the POSIX-style arguments to the program.
17+
@since(version = 0.2.0)
18+
get-arguments: func() -> list<string>;
19+
20+
/// Return a path that programs should use as their initial current working
21+
/// directory, interpreting `.` as shorthand for this.
22+
@since(version = 0.2.0)
23+
initial-cwd: func() -> option<string>;
24+
}
25+
26+
@since(version = 0.2.0)
27+
interface exit {
28+
/// Exit the current instance and any linked instances.
29+
@since(version = 0.2.0)
30+
exit: func(status: result);
31+
32+
/// Exit the current instance and any linked instances, reporting the
33+
/// specified status code to the host.
34+
///
35+
/// The meaning of the code depends on the context, with 0 usually meaning
36+
/// "success", and other values indicating various types of failure.
37+
///
38+
/// This function does not return; the effect is analogous to a trap, but
39+
/// without the connotation that something bad has happened.
40+
@unstable(feature = cli-exit-with-code)
41+
exit-with-code: func(status-code: u8);
42+
}
43+
44+
@since(version = 0.2.0)
45+
interface run {
46+
/// Run the program.
47+
@since(version = 0.2.0)
48+
run: func() -> result;
49+
}
50+
51+
@since(version = 0.2.0)
52+
interface stdin {
53+
@since(version = 0.2.0)
54+
use wasi:io/streams@0.2.5.{input-stream};
55+
56+
@since(version = 0.2.0)
57+
get-stdin: func() -> input-stream;
58+
}
59+
60+
@since(version = 0.2.0)
61+
interface stdout {
62+
@since(version = 0.2.0)
63+
use wasi:io/streams@0.2.5.{output-stream};
64+
65+
@since(version = 0.2.0)
66+
get-stdout: func() -> output-stream;
67+
}
68+
69+
@since(version = 0.2.0)
70+
interface stderr {
71+
@since(version = 0.2.0)
72+
use wasi:io/streams@0.2.5.{output-stream};
73+
74+
@since(version = 0.2.0)
75+
get-stderr: func() -> output-stream;
76+
}
77+
78+
/// Terminal input.
79+
///
80+
/// In the future, this may include functions for disabling echoing,
81+
/// disabling input buffering so that keyboard events are sent through
82+
/// immediately, querying supported features, and so on.
83+
@since(version = 0.2.0)
84+
interface terminal-input {
85+
/// The input side of a terminal.
86+
@since(version = 0.2.0)
87+
resource terminal-input;
88+
}
89+
90+
/// Terminal output.
91+
///
92+
/// In the future, this may include functions for querying the terminal
93+
/// size, being notified of terminal size changes, querying supported
94+
/// features, and so on.
95+
@since(version = 0.2.0)
96+
interface terminal-output {
97+
/// The output side of a terminal.
98+
@since(version = 0.2.0)
99+
resource terminal-output;
100+
}
101+
102+
/// An interface providing an optional `terminal-input` for stdin as a
103+
/// link-time authority.
104+
@since(version = 0.2.0)
105+
interface terminal-stdin {
106+
@since(version = 0.2.0)
107+
use terminal-input.{terminal-input};
108+
109+
/// If stdin is connected to a terminal, return a `terminal-input` handle
110+
/// allowing further interaction with it.
111+
@since(version = 0.2.0)
112+
get-terminal-stdin: func() -> option<terminal-input>;
113+
}
114+
115+
/// An interface providing an optional `terminal-output` for stdout as a
116+
/// link-time authority.
117+
@since(version = 0.2.0)
118+
interface terminal-stdout {
119+
@since(version = 0.2.0)
120+
use terminal-output.{terminal-output};
121+
122+
/// If stdout is connected to a terminal, return a `terminal-output` handle
123+
/// allowing further interaction with it.
124+
@since(version = 0.2.0)
125+
get-terminal-stdout: func() -> option<terminal-output>;
126+
}
127+
128+
/// An interface providing an optional `terminal-output` for stderr as a
129+
/// link-time authority.
130+
@since(version = 0.2.0)
131+
interface terminal-stderr {
132+
@since(version = 0.2.0)
133+
use terminal-output.{terminal-output};
134+
135+
/// If stderr is connected to a terminal, return a `terminal-output` handle
136+
/// allowing further interaction with it.
137+
@since(version = 0.2.0)
138+
get-terminal-stderr: func() -> option<terminal-output>;
139+
}
140+
141+
@since(version = 0.2.0)
142+
world imports {
143+
@since(version = 0.2.0)
144+
import environment;
145+
@since(version = 0.2.0)
146+
import exit;
147+
@since(version = 0.2.0)
148+
import wasi:io/error@0.2.5;
149+
@since(version = 0.2.0)
150+
import wasi:io/poll@0.2.5;
151+
@since(version = 0.2.0)
152+
import wasi:io/streams@0.2.5;
153+
@since(version = 0.2.0)
154+
import stdin;
155+
@since(version = 0.2.0)
156+
import stdout;
157+
@since(version = 0.2.0)
158+
import stderr;
159+
@since(version = 0.2.0)
160+
import terminal-input;
161+
@since(version = 0.2.0)
162+
import terminal-output;
163+
@since(version = 0.2.0)
164+
import terminal-stdin;
165+
@since(version = 0.2.0)
166+
import terminal-stdout;
167+
@since(version = 0.2.0)
168+
import terminal-stderr;
169+
@since(version = 0.2.0)
170+
import wasi:clocks/monotonic-clock@0.2.5;
171+
@since(version = 0.2.0)
172+
import wasi:clocks/wall-clock@0.2.5;
173+
@unstable(feature = clocks-timezone)
174+
import wasi:clocks/timezone@0.2.5;
175+
@since(version = 0.2.0)
176+
import wasi:filesystem/types@0.2.5;
177+
@since(version = 0.2.0)
178+
import wasi:filesystem/preopens@0.2.5;
179+
@since(version = 0.2.0)
180+
import wasi:sockets/network@0.2.5;
181+
@since(version = 0.2.0)
182+
import wasi:sockets/instance-network@0.2.5;
183+
@since(version = 0.2.0)
184+
import wasi:sockets/udp@0.2.5;
185+
@since(version = 0.2.0)
186+
import wasi:sockets/udp-create-socket@0.2.5;
187+
@since(version = 0.2.0)
188+
import wasi:sockets/tcp@0.2.5;
189+
@since(version = 0.2.0)
190+
import wasi:sockets/tcp-create-socket@0.2.5;
191+
@since(version = 0.2.0)
192+
import wasi:sockets/ip-name-lookup@0.2.5;
193+
@since(version = 0.2.0)
194+
import wasi:random/random@0.2.5;
195+
@since(version = 0.2.0)
196+
import wasi:random/insecure@0.2.5;
197+
@since(version = 0.2.0)
198+
import wasi:random/insecure-seed@0.2.5;
199+
}
200+
@since(version = 0.2.0)
201+
world command {
202+
@since(version = 0.2.0)
203+
import environment;
204+
@since(version = 0.2.0)
205+
import exit;
206+
@since(version = 0.2.0)
207+
import wasi:io/error@0.2.5;
208+
@since(version = 0.2.0)
209+
import wasi:io/poll@0.2.5;
210+
@since(version = 0.2.0)
211+
import wasi:io/streams@0.2.5;
212+
@since(version = 0.2.0)
213+
import stdin;
214+
@since(version = 0.2.0)
215+
import stdout;
216+
@since(version = 0.2.0)
217+
import stderr;
218+
@since(version = 0.2.0)
219+
import terminal-input;
220+
@since(version = 0.2.0)
221+
import terminal-output;
222+
@since(version = 0.2.0)
223+
import terminal-stdin;
224+
@since(version = 0.2.0)
225+
import terminal-stdout;
226+
@since(version = 0.2.0)
227+
import terminal-stderr;
228+
@since(version = 0.2.0)
229+
import wasi:clocks/monotonic-clock@0.2.5;
230+
@since(version = 0.2.0)
231+
import wasi:clocks/wall-clock@0.2.5;
232+
@unstable(feature = clocks-timezone)
233+
import wasi:clocks/timezone@0.2.5;
234+
@since(version = 0.2.0)
235+
import wasi:filesystem/types@0.2.5;
236+
@since(version = 0.2.0)
237+
import wasi:filesystem/preopens@0.2.5;
238+
@since(version = 0.2.0)
239+
import wasi:sockets/network@0.2.5;
240+
@since(version = 0.2.0)
241+
import wasi:sockets/instance-network@0.2.5;
242+
@since(version = 0.2.0)
243+
import wasi:sockets/udp@0.2.5;
244+
@since(version = 0.2.0)
245+
import wasi:sockets/udp-create-socket@0.2.5;
246+
@since(version = 0.2.0)
247+
import wasi:sockets/tcp@0.2.5;
248+
@since(version = 0.2.0)
249+
import wasi:sockets/tcp-create-socket@0.2.5;
250+
@since(version = 0.2.0)
251+
import wasi:sockets/ip-name-lookup@0.2.5;
252+
@since(version = 0.2.0)
253+
import wasi:random/random@0.2.5;
254+
@since(version = 0.2.0)
255+
import wasi:random/insecure@0.2.5;
256+
@since(version = 0.2.0)
257+
import wasi:random/insecure-seed@0.2.5;
258+
259+
@since(version = 0.2.0)
260+
export run;
261+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package wasi:clocks@0.2.5;
2+
3+
interface monotonic-clock {
4+
use wasi:io/poll@0.2.5.{pollable};
5+
6+
type instant = u64;
7+
8+
type duration = u64;
9+
10+
now: func() -> instant;
11+
12+
resolution: func() -> duration;
13+
14+
subscribe-instant: func(when: instant) -> pollable;
15+
16+
subscribe-duration: func(when: duration) -> pollable;
17+
}
18+
19+
interface wall-clock {
20+
record datetime {
21+
seconds: u64,
22+
nanoseconds: u32,
23+
}
24+
25+
now: func() -> datetime;
26+
27+
resolution: func() -> datetime;
28+
}
29+
30+
interface timezone {
31+
use wall-clock.{datetime};
32+
33+
record timezone-display {
34+
utc-offset: s32,
35+
name: string,
36+
in-daylight-saving-time: bool,
37+
}
38+
39+
display: func(when: datetime) -> timezone-display;
40+
41+
utc-offset: func(when: datetime) -> s32;
42+
}
43+

0 commit comments

Comments
 (0)