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;