umsh_ulcp/ids.rs
1//! Property, stream, and capability identifiers, plus protocol
2//! constants. The complete allocation is in
3//! `docs/protocol/src/ulcp-index.md`.
4
5/// Protocol version advertised in `PROP_PROTOCOL_VERSION`.
6pub const PROTOCOL_MAJOR_VERSION: u8 = 6;
7/// Protocol version advertised in `PROP_PROTOCOL_VERSION`.
8pub const PROTOCOL_MINOR_VERSION: u8 = 0;
9
10/// Value of `PROP_INTERFACE_TYPE` for this protocol.
11pub const INTERFACE_TYPE: u32 = 8;
12
13/// Property identifiers.
14pub mod prop {
15 /// Status of the last operation (`PROP_LAST_STATUS`).
16 pub const LAST_STATUS: u32 = 0;
17 /// Protocol major/minor version (`PROP_PROTOCOL_VERSION`).
18 pub const PROTOCOL_VERSION: u32 = 1;
19 /// device firmware version string (`PROP_DEV_VERSION`).
20 pub const DEV_VERSION: u32 = 2;
21 /// Interface type discriminator (`PROP_INTERFACE_TYPE`).
22 pub const INTERFACE_TYPE: u32 = 3;
23 /// Supported capability list (`PROP_CAPS`).
24 pub const CAPS: u32 = 5;
25 /// PHY enabled flag (`PROP_PHY_ENABLED`).
26 pub const PHY_ENABLED: u32 = 32;
27 /// Frequency in kHz (`PROP_PHY_FREQ`).
28 pub const PHY_FREQ: u32 = 35;
29 /// TX power in dBm (`PROP_PHY_TX_POWER`).
30 pub const PHY_TX_POWER: u32 = 37;
31 /// Current RSSI in dBm (`PROP_PHY_RSSI`).
32 pub const PHY_RSSI: u32 = 38;
33 /// LoRa bandwidth in Hz (`PROP_PHY_LORA_BW`).
34 pub const PHY_LORA_BW: u32 = 39;
35 /// LoRa spreading factor (`PROP_PHY_LORA_SF`).
36 pub const PHY_LORA_SF: u32 = 40;
37 /// LoRa coding rate (`PROP_PHY_LORA_CR`).
38 pub const PHY_LORA_CR: u32 = 41;
39 /// Maximum `STR_PHY_RAW` data size in octets (`PROP_PHY_MTU`).
40 pub const PHY_MTU: u32 = 42;
41 /// LoRa sync word, SX126x-style 16-bit (`PROP_PHY_LORA_SW`).
42 pub const PHY_LORA_SW: u32 = 43;
43 /// Deliver all received frames, bypassing host receive filtering;
44 /// the only session-scoped property (`PROP_MAC_PROMISCUOUS`).
45 pub const MAC_PROMISCUOUS: u32 = 48;
46 /// Whether a saved snapshot exists (`PROP_SAVED`).
47 pub const SAVED: u32 = 49;
48 /// Device identity public key (`PROP_DEV_KEY`).
49 pub const DEV_KEY: u32 = 64;
50 /// Device identity private key, write-only (`PROP_DEV_PRIVATE_KEY`).
51 pub const DEV_PRIVATE_KEY: u32 = 65;
52 /// Device identity channel keys (`PROP_DEV_CHANNEL_KEYS`).
53 pub const DEV_CHANNEL_KEYS: u32 = 66;
54 /// Device identity peer list (`PROP_DEV_PEERS`).
55 pub const DEV_PEERS: u32 = 67;
56 /// Human-readable device name (`PROP_DEV_NAME`).
57 pub const DEV_NAME: u32 = 68;
58 /// Battery status snapshot (`PROP_BATTERY`).
59 pub const BATTERY: u32 = 69;
60 /// Autonomous MAC-layer repeater/forwarding enable (`PROP_MAC_REPEATER_ENABLED`).
61 ///
62 /// First of the device-behavior settings range (70–95), which is
63 /// subdivided as 70–79 repeater and identity, 80–87 advertisement
64 /// policy (80–82 allocated, 83–87 spare), 88–93 positioning, 94–95
65 /// environmental sensing (94 illuminance, 95 spare — the board's
66 /// thermistor is the expected claimant). A
67 /// single-octet identifier is the scarce resource, so the positioning
68 /// range holds the enable toggle and the fix telemetry a host reads
69 /// and the device announces continually; the rarely-touched
70 /// positioning *configuration* lives in the extended device range
71 /// alongside `PROP_TIME`. A persisted, device-domain boolean: when
72 /// set, the device identity's on-board MAC forwards overheard routable
73 /// frames and advertises the `REP` capability bit. The advertised
74 /// *role* is a separate matter — see `IDENT_ROLE`.
75 pub const MAC_REPEATER_ENABLED: u32 = 70;
76 /// The device identity's complete signed node-identity blob
77 /// (`PROP_IDENT`), served through a deferred signing effect.
78 pub const IDENT: u32 = 71;
79 /// Advertised `ROLE` byte of the device identity (`PROP_IDENT_ROLE`).
80 /// Empty means "derive it from what the device is actually doing".
81 pub const IDENT_ROLE: u32 = 72;
82 /// Whether the device identity advertises the `MOB` capability bit
83 /// (`PROP_IDENT_MOBILE`) — mobile versus fixed, which is orthogonal
84 /// to tethered versus standalone.
85 pub const IDENT_MOBILE: u32 = 73;
86 /// Region codes the device identity flood-forwards for
87 /// (`PROP_MAC_REPEATER_REGIONS`) — concatenated 2-octet codes, empty
88 /// for "forward regardless of region code".
89 pub const MAC_REPEATER_REGIONS: u32 = 74;
90 /// Region code inserted into untagged flood packets
91 /// (`PROP_MAC_REPEATER_DEFAULT_REGION`) — one 2-octet code, or empty
92 /// to never tag.
93 pub const MAC_REPEATER_DEFAULT_REGION: u32 = 75;
94 /// Minimum received RSSI in dBm for flood forwarding
95 /// (`PROP_MAC_REPEATER_MIN_RSSI`) — INT16, or empty for no threshold.
96 pub const MAC_REPEATER_MIN_RSSI: u32 = 76;
97 /// Minimum received SNR in whole dB for flood forwarding
98 /// (`PROP_MAC_REPEATER_MIN_SNR`) — INT8, or empty for no threshold.
99 pub const MAC_REPEATER_MIN_SNR: u32 = 77;
100 /// Whether the device identity answers Identity Requests
101 /// (`PROP_DEV_DISCOVERABLE`) — BOOL, default 1. Requires
102 /// `CAP_DEV_IDENTITY`.
103 pub const DEV_DISCOVERABLE: u32 = 78;
104 /// Locate-alert state (`PROP_ALERT`) — what the device is currently
105 /// doing to draw attention to where it physically is. Volatile: never
106 /// saved, unaffected by `CMD_RST`, `ALERT_NONE` after every reset.
107 /// Requires `CAP_ALERT`.
108 pub const ALERT: u32 = 79;
109 /// Seconds between unsolicited advertisements (`PROP_ADVERT_INTERVAL`)
110 /// — UINT32, 0 to send none. An advertisement carries the signed node
111 /// identity and goes out with no flood hops and no source route, so it
112 /// reaches the neighbours that can hear the device directly and stops
113 /// there. The accepted range is [`MIN_AUTO_ANNOUNCE_INTERVAL_S`] to
114 /// [`MAX_AUTO_ANNOUNCE_INTERVAL_S`], and the value is a floor rather
115 /// than a period: the device scatters each send later by up to a
116 /// quarter of it. Requires `CAP_ADVERT`.
117 pub const ADVERT_INTERVAL: u32 = 80;
118 /// Seconds between unsolicited beacons (`PROP_BEACON_INTERVAL`) —
119 /// UINT32, 0 to send none. A beacon carries no payload and goes out
120 /// with a flood budget and the trace-route and trace-signal options,
121 /// so what it announces is the path back to the device rather than who
122 /// the device is. Same range and same scatter as
123 /// [`ADVERT_INTERVAL`]. Requires `CAP_ADVERT`.
124 pub const BEACON_INTERVAL: u32 = 81;
125 /// Whether the device emits one beacon once it comes up
126 /// (`PROP_STARTUP_BEACON`) — BOOL, default 1. Requires `CAP_ADVERT`.
127 pub const STARTUP_BEACON: u32 = 82;
128 /// Whether the GNSS receiver is powered (`PROP_GNSS_ENABLED`) — BOOL,
129 /// default 0. Off means the lowest power state the receiver reaches;
130 /// a board whose receiver RTC is the board's only clock keeps that
131 /// domain alive regardless. Requires `CAP_GNSS`.
132 pub const GNSS_ENABLED: u32 = 88;
133 /// Last position fix (`PROP_GNSS_LOCATION`) — 0–7 octets in the
134 /// variable-precision interleaved format. Empty means no fix has been
135 /// obtained this power cycle. Requires `CAP_GNSS`.
136 pub const GNSS_LOCATION: u32 = 89;
137 /// Altitude of the last fix (`PROP_GNSS_ALTITUDE`) — `INT32_LE`
138 /// meters above the WGS-84 ellipsoid, matching the units of node
139 /// identity option 2. Empty when there is no fix. Requires `CAP_GNSS`.
140 pub const GNSS_ALTITUDE: u32 = 90;
141 /// Fix quality (`PROP_GNSS_FIX`) — `UINT8`, 0 none, 1 two-dimensional,
142 /// 2 three-dimensional. Reads 0 while the receiver is disabled.
143 /// Requires `CAP_GNSS`.
144 pub const GNSS_FIX: u32 = 91;
145 /// Estimated horizontal accuracy of the last fix
146 /// (`PROP_GNSS_PRECISION`) — `UINT16_LE` decimeters. An estimate
147 /// derived from the receiver's dilution of precision, not a measured
148 /// error bound. Empty when there is no fix. Requires `CAP_GNSS`.
149 pub const GNSS_PRECISION: u32 = 92;
150 /// Satellite counts (`PROP_GNSS_SATELLITES`) — `UINT8` satellites used
151 /// in the solution, optionally followed by `UINT8` satellites in view.
152 /// Reads 0 while the receiver is disabled. Requires `CAP_GNSS`.
153 pub const GNSS_SATELLITES: u32 = 93;
154 /// Ambient illuminance (`PROP_ILLUMINANCE`) — `UINT32_LE` millilux.
155 /// Millilux rather than lux because the interesting region for an
156 /// indicator that should not be intrusive at night is below one lux.
157 /// Sampled when read; empty when the sensor could not be read. A
158 /// board reports its clamped maximum above the sensor's saturation
159 /// point rather than extrapolating past it. Requires
160 /// `CAP_ILLUMINANCE`.
161 pub const ILLUMINANCE: u32 = 94;
162 /// Tethered host identity public key (`PROP_HOST_KEY`).
163 pub const HOST_KEY: u32 = 96;
164 /// Host channel keys (`PROP_HOST_CHANNEL_KEYS`).
165 pub const HOST_CHANNEL_KEYS: u32 = 97;
166 /// Host pairwise peer keys (`PROP_HOST_PEER_KEYS`).
167 pub const HOST_PEER_KEYS: u32 = 98;
168 /// Host receive filter table (`PROP_HOST_RX_FILTERS`).
169 pub const HOST_RX_FILTERS: u32 = 99;
170 /// Acknowledgement-delegation enable (`PROP_HOST_AUTO_ACK`).
171 pub const HOST_AUTO_ACK: u32 = 100;
172 /// Frames currently queued (`PROP_HOST_RX_QUEUE_COUNT`).
173 pub const HOST_RX_QUEUE_COUNT: u32 = 101;
174 /// Inbound queue capacity in frames (`PROP_HOST_RX_QUEUE_CAPACITY`).
175 pub const HOST_RX_QUEUE_CAPACITY: u32 = 102;
176 /// Cumulative frames dropped from the queue (`PROP_HOST_RX_QUEUE_DROPPED`).
177 pub const HOST_RX_QUEUE_DROPPED: u32 = 103;
178 /// Transmit duty usage over the past hour (`PROP_PHY_DUTY_NOW`).
179 pub const PHY_DUTY_NOW: u32 = 4820;
180 /// Duty-cycle limit (`PROP_PHY_DUTY_LIMIT`).
181 pub const PHY_DUTY_LIMIT: u32 = 4822;
182 /// Persisted, write-only BLE pairing passkey (`PROP_BLE_PAIRING_PIN`).
183 pub const BLE_PAIRING_PIN: u32 = 4864;
184 /// Wall-clock time (`PROP_TIME`) — `UINT32_LE` seconds since the Unix
185 /// epoch, or **empty** when the device does not know what time it is.
186 /// Unsigned, so the encoding is wrap-free into 2106. Requires
187 /// `CAP_TIME`.
188 pub const TIME: u32 = 4866;
189 /// Local time-zone offset from UTC (`PROP_TZ_OFFSET`) — `INT16_LE`
190 /// minutes, default 0. Unlike `PROP_TIME` this always has a value:
191 /// where the device is configured to be is known even when what time
192 /// it is is not. Requires `CAP_TIME`.
193 pub const TZ_OFFSET: u32 = 4867;
194 /// Whether position fixes update the advertised node identity
195 /// (`PROP_GNSS_IDENT_UPDATE`) — BOOL, default 0. Requires `CAP_GNSS`.
196 pub const GNSS_IDENT_UPDATE: u32 = 4868;
197 /// Precision the advertised location is clamped to
198 /// (`PROP_GNSS_IDENT_PRECISION`) — `UINT8` 1–7, default 5. Requires
199 /// `CAP_GNSS`.
200 pub const GNSS_IDENT_PRECISION: u32 = 4869;
201 /// Whether receiver-derived time may set the wall clock
202 /// (`PROP_GNSS_TIME_TRUST`) — BOOL, default 1. Cleared, neither a fix
203 /// nor a receiver-RTC read touches `PROP_TIME`, which leaves a
204 /// manually-set clock proof against a jammed or spoofed sky. Position
205 /// reporting is unaffected. Requires `CAP_GNSS`.
206 pub const GNSS_TIME_TRUST: u32 = 4870;
207}
208
209/// `PROP_SAVED` values.
210///
211/// A snapshot that exists but cannot be read is distinguishable from no
212/// snapshot at all, and running on an older generation than the one last
213/// written is distinguishable from running on the newest.
214pub mod saved {
215 /// Nothing is saved.
216 pub const NONE: u8 = 0;
217 /// The newest saved generation is in effect.
218 pub const CURRENT: u8 = 1;
219 /// A newer generation was rejected; an older one is in effect.
220 pub const FALLBACK: u8 = 2;
221 /// A snapshot exists but no generation could be read.
222 pub const UNREADABLE: u8 = 3;
223}
224
225/// Stream identifiers.
226pub mod stream {
227 /// Raw radio frame stream (`STR_PHY_RAW`).
228 pub const PHY_RAW: u32 = 113;
229}
230
231/// Capability codes advertised via `PROP_CAPS`.
232pub mod cap {
233 /// `CAP_WRITABLE_RAW_STREAM`
234 pub const WRITABLE_RAW_STREAM: u32 = 8;
235 /// `CAP_PHY_DUTY_LIMIT`
236 pub const PHY_DUTY_LIMIT: u32 = 16;
237 /// `CAP_PHY_LORA`
238 pub const PHY_LORA: u32 = 515;
239 /// `CAP_HOST_FILTER`
240 pub const HOST_FILTER: u32 = 32;
241 /// `CAP_HOST_RX_QUEUE` (requires `CAP_HOST_FILTER`)
242 pub const HOST_RX_QUEUE: u32 = 33;
243 /// `CAP_HOST_KEYS` (requires `CAP_HOST_FILTER`)
244 pub const HOST_KEYS: u32 = 34;
245 /// `CAP_HOST_AUTO_ACK` (requires `CAP_HOST_KEYS` and `CAP_HOST_RX_QUEUE`)
246 pub const HOST_AUTO_ACK: u32 = 35;
247 /// `CAP_SAVE`
248 pub const SAVE: u32 = 36;
249 /// `CAP_DEV_IDENTITY`
250 pub const DEV_IDENTITY: u32 = 37;
251 /// `CAP_DEV_NAME`
252 pub const DEV_NAME: u32 = 38;
253 /// `CAP_BATTERY`
254 pub const BATTERY: u32 = 39;
255 /// `CAP_REPEATER` — the device can act as an autonomous mesh repeater
256 /// (`PROP_MAC_REPEATER_ENABLED`). Requires `CAP_DEV_IDENTITY`.
257 pub const REPEATER: u32 = 40;
258 /// `CAP_IDENT` — the device serves and configures its own advertised
259 /// node identity (`PROP_IDENT`, `PROP_IDENT_ROLE`,
260 /// `PROP_IDENT_MOBILE`). Requires `CAP_DEV_IDENTITY`.
261 pub const IDENT: u32 = 41;
262 /// `CAP_ALERT` — the device has some means of making itself
263 /// physically conspicuous on demand (`PROP_ALERT`). It says nothing
264 /// about *which* means, so a host must not assume audibility.
265 pub const ALERT: u32 = 42;
266 /// `CAP_TIME` — the device keeps a wall clock (`PROP_TIME`,
267 /// `PROP_TZ_OFFSET`). It says nothing about where the time comes from
268 /// or whether it survives a power cycle.
269 pub const TIME: u32 = 44;
270 /// `CAP_GNSS` — a GNSS receiver is fitted, so the positioning
271 /// properties exist and the wall clock has a source that can set
272 /// itself. Requires `CAP_TIME`.
273 pub const GNSS: u32 = 45;
274 /// `CAP_ADVERT` — the device announces itself on a schedule of its own
275 /// (`PROP_ADVERT_INTERVAL`, `PROP_BEACON_INTERVAL`,
276 /// `PROP_STARTUP_BEACON`). Requires `CAP_DEV_IDENTITY`, since what an
277 /// advertisement carries is the device identity.
278 pub const ADVERT: u32 = 46;
279 /// `CAP_ILLUMINANCE` — an ambient light sensor is fitted, so
280 /// `PROP_ILLUMINANCE` reads a measurement rather than nothing.
281 pub const ILLUMINANCE: u32 = 47;
282}
283
284/// Value used in `PROP_PHY_DUTY_LIMIT` to disable duty-cycle limiting.
285pub const DUTY_LIMIT_DISABLED: u16 = 0xFFFF;
286
287/// Shortest accepted `PROP_ADVERT_INTERVAL` / `PROP_BEACON_INTERVAL`, in
288/// seconds.
289///
290/// An absolute floor, and one a device may only ever round *up* from:
291/// scheduling jitter delays an announcement and never brings it forward,
292/// so no configuration can put an unsolicited broadcast on the air more
293/// often than this. The duty ledger remains the airtime control; this is
294/// what keeps a mistyped interval from spending the whole budget on
295/// announcements before anything else can speak.
296pub const MIN_AUTO_ANNOUNCE_INTERVAL_S: u32 = 20 * 60;
297
298/// Longest accepted `PROP_ADVERT_INTERVAL` / `PROP_BEACON_INTERVAL`, in
299/// seconds.
300///
301/// A ceiling on how stale the mesh's picture of a node may get while that
302/// node still considers itself to be announcing. Past a day the schedule
303/// has stopped being one, and 0 says so more honestly.
304pub const MAX_AUTO_ANNOUNCE_INTERVAL_S: u32 = 24 * 60 * 60;
305
306/// Default `PROP_ADVERT_INTERVAL`, in seconds.
307pub const DEFAULT_ADVERT_INTERVAL_S: u32 = 4 * 60 * 60;
308
309/// Default `PROP_BEACON_INTERVAL`, in seconds.
310pub const DEFAULT_BEACON_INTERVAL_S: u32 = 60 * 60;