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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
//! First-class Rust access to [Lager](https://lagerdata.com) nets, so
//! embedded developers can write their entire hardware-in-the-loop test
//! suite in Rust and run it with `cargo test` — no Python required.
//!
//! The crate is a pure HTTP/JSON client of the Lager box's API on port
//! 9000: power supplies, battery simulators, e-loads, solar simulators,
//! GPIO, ADC, DAC, thermocouples, watt meters, energy analyzers, SPI, I2C,
//! USB hub ports, robot arms, webcams, routers, and (behind the `uart`
//! feature) streaming UART. Box-level capabilities — the box's own BLE adapter
//! ([`LagerBox::ble`]), WiFi interface ([`LagerBox::wifi`]), and BluFi
//! ESP32 provisioning ([`LagerBox::blufi`]) — are exposed the same way.
//! Debug-probe nets ([`nets::debug::DebugNet`]) talk to the box's debug
//! service on port 8765 for flash/erase/reset/memory-read and RTT log
//! streaming.
//!
//! # Quickstart
//!
//! ```toml
//! [dev-dependencies]
//! lager = { package = "lager-net", version = "0.2" }
//! ```
//!
//! ```no_run
//! # #[cfg(feature = "blocking")]
//! # mod demo {
//! use lager::{LagerBox, Level};
//!
//! #[test]
//! fn dut_boots_at_3v3() -> lager::Result<()> {
//! let lager = LagerBox::from_env()?; // reads LAGER_BOX_HOST
//! let supply = lager.supply("supply1");
//! let boot_ok = lager.gpio("boot_ok");
//!
//! supply.set_voltage(3.3)?;
//! supply.enable()?;
//! // Hardware-timed wait on the box; returns elapsed seconds.
//! let t = boot_ok.wait_for_level(Level::High, 5.0)?;
//! println!("booted in {t:.3}s");
//! supply.disable()
//! }
//! # }
//! # fn main() {}
//! ```
//!
//! # Concurrency
//!
//! The box serializes access per physical instrument (a single-owner
//! hardware service with per-device locks), so parallel cargo tests can
//! never interleave I/O on one instrument. Tests sharing a *net* still
//! observe each other's state changes — partition nets across tests or run
//! `cargo test -- --test-threads=1` when that matters.
//!
//! # Boxes behind an authenticating gateway
//!
//! Boxes fronted by an authenticating reverse proxy (gateway) reject
//! unauthenticated traffic with 401 + an `X-Gateway-Auth-Url` header. The
//! crate handles this transparently: it reuses the session created by
//! `lager login <auth_url>` (the Lager CLI's token store in
//! `~/.lager_gateway_auth`), attaches `Authorization: Bearer` to every
//! request — including debug-service and UART Socket.IO traffic — and
//! refreshes expired access tokens automatically. For CI or machines
//! without a CLI login, pin a token with
//! [`LagerBoxBuilder::bearer_token`] or the `LAGER_GATEWAY_TOKEN`
//! environment variable. Plain (ungated) boxes are unaffected: no header
//! is sent and no code path runs. When no usable credential exists, calls
//! fail with [`Error::AuthRequired`] naming the auth server to log into.
//!
//! # Features
//!
//! - `blocking` *(default)*: the [`LagerBox`] client on `ureq` — no tokio
//! in the dependency tree.
//! - `async`: the [`AsyncLagerBox`] client on `reqwest`/tokio. Both clients
//! share one wire layer ([`wire`]) so they cannot drift.
//! - `uart`: streaming UART sessions over Socket.IO ([`nets::uart::Uart`]).
//!
//! # Not yet on the HTTP API
//!
//! Oscilloscope workflows are not yet exposed on any box HTTP API;
//! [`nets::scope::Scope`] ships as a documented stub returning
//! [`Error::NotSupportedByBox`]. See `MISSING_ENDPOINTS.md` in the crate
//! repository.
pub use ;
/// Environment variable read by `from_env` constructors (`LAGER_BOX_HOST`).
pub const BOX_HOST_ENV: &str = "LAGER_BOX_HOST";
/// Environment variable that overrides the debug-service base URL
/// (`LAGER_DEBUG_SERVICE_URL`), e.g. `http://127.0.0.1:8765` when tunneling.
pub const DEBUG_SERVICE_URL_ENV: &str = "LAGER_DEBUG_SERVICE_URL";
/// Environment variable holding a bearer token for boxes behind an
/// authenticating gateway (`LAGER_GATEWAY_TOKEN`). When set, every request
/// carries `Authorization: Bearer <token>`. Equivalent to
/// `LagerBoxBuilder::bearer_token`.
pub const GATEWAY_TOKEN_ENV: &str = "LAGER_GATEWAY_TOKEN";
/// Environment variable that overrides the path of the Lager CLI's gateway
/// token store (`LAGER_GATEWAY_AUTH_FILE`; default `~/.lager_gateway_auth`).
/// The crate reads sessions created by `lager login` from this file, so the
/// same name/semantics as the CLI are honored.
pub const GATEWAY_AUTH_FILE_ENV: &str = "LAGER_GATEWAY_AUTH_FILE";
pub use ;
pub use ;
// Net handle types and their vocabularies, re-exported at the crate root
// for ergonomic imports (`use lager::{LagerBox, Level, EloadMode};`).
pub use BatteryMode;
pub use ;
pub use EloadMode;
pub use ;
pub use Scope;
pub use ;
/// Debug-service response types.
pub use ;
pub use ;
pub use ;
pub use Uart;
// Structured result types, re-exported from the wire layer.
pub use ;
pub use I2cEffectiveConfig;
pub use SpiEffectiveConfig;