1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//! Wire-protocol definitions for the Zendo motion-tracking WebSocket stream.
//!
//! This crate is the single source of truth for the binary protocol that the
//! Zendo desktop app emits and that [`zendo-sdk`](https://crates.io/crates/zendo-sdk)
//! consumes. It owns the port range, the message-type tags, the joint and
//! landmark vocabularies, and the pure decode/encode routines.
//!
//! It has no dependencies, performs no I/O, never allocates, and is `no_std`
//! by default-disabling the `std` feature.
//!
//! # Frame layout
//!
//! Every frame is one binary WebSocket message: byte 0 is the type tag, the
//! rest is the payload. All numeric values are little-endian `f64`.
//!
//! | Message | Tag | Payload |
//! |---|---|---|
//! | Hello | `0x01` | protocol version (`u16` LE) |
//! | Body quaternions | `0x02` | 13 joints x (w, x, y, z) |
//! | Body landmarks | `0x03` | 19 landmarks x (x, y, z, confidence) |
//! | Hand quaternions | `0x04` | 1 side byte + 16 joints x (w, x, y, z) |
//! | Hand landmarks | `0x05` | 1 side byte + 21 landmarks x (x, y, z, confidence) |
//!
//! The server sends the hello frame first on every connection so clients can
//! detect a [`PROTOCOL_VERSION`] mismatch before decoding data frames.
//!
//! # Example
//!
//! ```
//! use zendo_protocol::{decode, Message};
//!
//! # let frame: &[u8] = &{
//! # let mut f = [0u8; 1 + 13 * 4 * 8];
//! # f[0] = zendo_protocol::MSG_BODY_QUATERNION;
//! # f
//! # };
//! match decode(frame) {
//! Ok(Message::BodyQuaternions(q)) => println!("hips: {:?}", q.hips),
//! Ok(other) => println!("other message: {other:?}"),
//! Err(e) => eprintln!("bad frame: {e}"),
//! }
//! ```
pub use ;
pub use ;
pub use ;
pub use ProtocolError;
pub use ;
pub use ;