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 /// Hardware model name (`PROP_DEV_MODEL`) — what the board *is*, where
24 /// `DEV_VERSION` is what it *runs*. Optional and ungated: a device
25 /// that cannot name its own hardware refuses the get.
26 pub const DEV_MODEL: u32 = 4;
27 /// Supported capability list (`PROP_CAPS`).
28 pub const CAPS: u32 = 5;
29 /// Seconds since the device booted (`PROP_UPTIME`). Optional and
30 /// ungated, like `DEV_MODEL`: a device with no monotonic clock to
31 /// answer from refuses the get. Reads next to `LAST_STATUS`, which
32 /// says why the device last reset — this says how long ago.
33 pub const UPTIME: u32 = 6;
34 /// PHY enabled flag (`PROP_PHY_ENABLED`).
35 pub const PHY_ENABLED: u32 = 32;
36 /// Frequency in kHz (`PROP_PHY_FREQ`).
37 pub const PHY_FREQ: u32 = 35;
38 /// TX power in dBm (`PROP_PHY_TX_POWER`).
39 pub const PHY_TX_POWER: u32 = 37;
40 /// Current RSSI in dBm (`PROP_PHY_RSSI`).
41 pub const PHY_RSSI: u32 = 38;
42 /// LoRa bandwidth in Hz (`PROP_PHY_LORA_BW`).
43 pub const PHY_LORA_BW: u32 = 39;
44 /// LoRa spreading factor (`PROP_PHY_LORA_SF`).
45 pub const PHY_LORA_SF: u32 = 40;
46 /// LoRa coding rate (`PROP_PHY_LORA_CR`).
47 pub const PHY_LORA_CR: u32 = 41;
48 /// Maximum `STR_PHY_RAW` data size in octets (`PROP_PHY_MTU`).
49 pub const PHY_MTU: u32 = 42;
50 /// LoRa sync word, SX126x-style 16-bit (`PROP_PHY_LORA_SW`).
51 pub const PHY_LORA_SW: u32 = 43;
52 /// Deliver all received frames, bypassing host receive filtering
53 /// (`PROP_MAC_PROMISCUOUS`). Session-scoped.
54 pub const MAC_PROMISCUOUS: u32 = 48;
55 /// Whether a saved snapshot exists (`PROP_SAVED`).
56 pub const SAVED: u32 = 49;
57 /// Carry the host on a point-to-point link to the device's own node
58 /// instead of the shared medium (`PROP_MAC_BACKHAUL`). Session-scoped.
59 pub const MAC_BACKHAUL: u32 = 50;
60 /// Device identity public key (`PROP_DEV_KEY`).
61 pub const DEV_KEY: u32 = 64;
62 /// Device identity private key, write-only (`PROP_DEV_PRIVATE_KEY`).
63 pub const DEV_PRIVATE_KEY: u32 = 65;
64 /// Device identity channel keys (`PROP_DEV_CHANNEL_KEYS`).
65 pub const DEV_CHANNEL_KEYS: u32 = 66;
66 /// Device identity peer list (`PROP_DEV_PEERS`).
67 pub const DEV_PEERS: u32 = 67;
68 /// Human-readable device name (`PROP_DEV_NAME`).
69 pub const DEV_NAME: u32 = 68;
70 /// Battery status snapshot (`PROP_BATTERY`).
71 pub const BATTERY: u32 = 69;
72 /// Autonomous MAC-layer repeater/forwarding enable (`PROP_MAC_REPEATER_ENABLED`).
73 ///
74 /// First of the device-behavior settings range (70–95), which is
75 /// subdivided as 70–79 repeater and identity, 80–87 advertisement
76 /// policy (80–84 allocated, 85–87 spare), 88–93 positioning, 94–95
77 /// environmental sensing (94 illuminance, 95 spare — the board's
78 /// thermistor is the expected claimant). A
79 /// single-octet identifier is the scarce resource, so the positioning
80 /// range holds the enable toggle and the fix telemetry a host reads
81 /// and the device announces continually; the rarely-touched
82 /// positioning *configuration* lives in the extended device range
83 /// alongside `PROP_TIME`. A persisted, device-domain boolean: when
84 /// set, the device identity's on-board MAC forwards overheard routable
85 /// frames and advertises the `REP` capability bit. The advertised
86 /// *role* is a separate matter — see `IDENT_ROLE`.
87 pub const MAC_REPEATER_ENABLED: u32 = 70;
88 /// The device identity's complete signed node-identity blob
89 /// (`PROP_IDENT`), served through a deferred signing effect.
90 pub const IDENT: u32 = 71;
91 /// Advertised `ROLE` byte of the device identity (`PROP_IDENT_ROLE`).
92 /// Empty means "derive it from what the device is actually doing".
93 pub const IDENT_ROLE: u32 = 72;
94 /// Whether the device identity advertises the `MOB` capability bit
95 /// (`PROP_IDENT_MOBILE`) — mobile versus fixed, which is orthogonal
96 /// to tethered versus standalone.
97 pub const IDENT_MOBILE: u32 = 73;
98 /// Regions the device identity flood-forwards for
99 /// (`PROP_MAC_REPEATER_REGIONS`) — multiple-value, each item 1 to 24
100 /// octets of UTF-8 naming a region in its string form, empty for
101 /// "forward regardless of region code". The device derives the
102 /// 2-octet forwarding codes itself; the strings are what it
103 /// advertises, since a hash-derived code names nothing.
104 pub const MAC_REPEATER_REGIONS: u32 = 74;
105 /// Region code inserted into untagged flood packets
106 /// (`PROP_MAC_REPEATER_DEFAULT_REGION`) — one 2-octet code, or empty
107 /// to never tag.
108 pub const MAC_REPEATER_DEFAULT_REGION: u32 = 75;
109 /// Minimum received RSSI in dBm for flood forwarding
110 /// (`PROP_MAC_REPEATER_MIN_RSSI`) — INT16, or empty for no threshold.
111 pub const MAC_REPEATER_MIN_RSSI: u32 = 76;
112 /// Minimum received SNR in whole dB for flood forwarding
113 /// (`PROP_MAC_REPEATER_MIN_SNR`) — INT8, or empty for no threshold.
114 pub const MAC_REPEATER_MIN_SNR: u32 = 77;
115 /// Whether the device identity answers Identity Requests
116 /// (`PROP_DEV_DISCOVERABLE`) — BOOL, default 1. Requires
117 /// `CAP_DEV_IDENTITY`.
118 pub const DEV_DISCOVERABLE: u32 = 78;
119 /// Locate-alert state (`PROP_ALERT`) — what the device is currently
120 /// doing to draw attention to where it physically is. Volatile: never
121 /// saved, unaffected by `CMD_RST`, `ALERT_NONE` after every reset.
122 /// Requires `CAP_ALERT`.
123 pub const ALERT: u32 = 79;
124 /// Seconds between unsolicited advertisements (`PROP_ADVERT_INTERVAL`)
125 /// — UINT32, 0 to send none. An advertisement carries the signed node
126 /// identity and goes out with no flood hops and no source route, so it
127 /// reaches the neighbours that can hear the device directly and stops
128 /// there. The accepted range is [`MIN_AUTO_ANNOUNCE_INTERVAL_S`] to
129 /// [`MAX_AUTO_ANNOUNCE_INTERVAL_S`], and the value is a floor rather
130 /// than a period: the device scatters each send later by up to a
131 /// quarter of it. Requires `CAP_ADVERT`.
132 pub const ADVERT_INTERVAL: u32 = 80;
133 /// Seconds between unsolicited beacons (`PROP_BEACON_INTERVAL`) —
134 /// UINT32, 0 to send none. A beacon carries no payload and goes out
135 /// with a flood budget and the trace-route and trace-signal options,
136 /// so what it announces is the path back to the device rather than who
137 /// the device is. Same range and same scatter as
138 /// [`ADVERT_INTERVAL`]. Requires `CAP_ADVERT`.
139 pub const BEACON_INTERVAL: u32 = 81;
140 /// Whether the device emits one beacon once it comes up
141 /// (`PROP_STARTUP_BEACON`) — BOOL, default 1. Requires `CAP_ADVERT`.
142 pub const STARTUP_BEACON: u32 = 82;
143 /// Location the device identity advertises (`PROP_IDENT_LOCATION`) —
144 /// 0–7 octets in the variable-precision interleaved format, empty to
145 /// advertise none. The value carries its own precision, so a location
146 /// entered by hand needs no separate precision setting.
147 ///
148 /// This and [`IDENT_ALTITUDE`] are where the advertised identity gets
149 /// its position, whether a fix wrote them or an administrator did.
150 /// [`GNSS_IDENT_UPDATE`] set, the device writes them itself from each
151 /// fix and refuses a write with `STATUS_INVALID_STATE`; cleared, they
152 /// are writable and hold whatever they last held. Requires
153 /// `CAP_IDENT`, not `CAP_GNSS` — a fixed repeater with no receiver
154 /// still has somewhere to be.
155 pub const IDENT_LOCATION: u32 = 83;
156 /// Altitude the device identity advertises (`PROP_IDENT_ALTITUDE`) —
157 /// a minimal-length signed integer (see [`crate::sint`]) of meters
158 /// above the WGS-84 ellipsoid, or empty. Advertised only alongside a
159 /// location. Same writability rule as [`IDENT_LOCATION`]; requires
160 /// `CAP_IDENT`.
161 pub const IDENT_ALTITUDE: u32 = 84;
162 /// Whether the GNSS receiver is powered (`PROP_GNSS_ENABLED`) — BOOL,
163 /// default 0. Off means the lowest power state the receiver reaches;
164 /// a board whose receiver RTC is the board's only clock keeps that
165 /// domain alive regardless. Requires `CAP_GNSS`.
166 pub const GNSS_ENABLED: u32 = 88;
167 /// Last position fix (`PROP_GNSS_LOCATION`) — 0–7 octets in the
168 /// variable-precision interleaved format. Empty means no fix has been
169 /// obtained this power cycle. Requires `CAP_GNSS`.
170 pub const GNSS_LOCATION: u32 = 89;
171 /// Altitude of the last fix (`PROP_GNSS_ALTITUDE`) — `INT32_LE`
172 /// meters above the WGS-84 ellipsoid, matching the units of node
173 /// identity option 2. Empty when there is no fix. Requires `CAP_GNSS`.
174 pub const GNSS_ALTITUDE: u32 = 90;
175 /// Fix quality (`PROP_GNSS_FIX`) — `UINT8`, 0 none, 1 two-dimensional,
176 /// 2 three-dimensional. Reads 0 while the receiver is disabled.
177 /// Requires `CAP_GNSS`.
178 pub const GNSS_FIX: u32 = 91;
179 /// Estimated horizontal accuracy of the last fix
180 /// (`PROP_GNSS_PRECISION`) — `UINT16_LE` decimeters. An estimate
181 /// derived from the receiver's dilution of precision, not a measured
182 /// error bound. Empty when there is no fix. Requires `CAP_GNSS`.
183 pub const GNSS_PRECISION: u32 = 92;
184 /// Satellite counts (`PROP_GNSS_SATELLITES`) — `UINT8` satellites used
185 /// in the solution, optionally followed by `UINT8` satellites in view.
186 /// Reads 0 while the receiver is disabled. Requires `CAP_GNSS`.
187 pub const GNSS_SATELLITES: u32 = 93;
188 /// Ambient illuminance (`PROP_ILLUMINANCE`) — `UINT32_LE` millilux.
189 /// Millilux rather than lux because the interesting region for an
190 /// indicator that should not be intrusive at night is below one lux.
191 /// Sampled when read; empty when the sensor could not be read. A
192 /// board reports its clamped maximum above the sensor's saturation
193 /// point rather than extrapolating past it. Requires
194 /// `CAP_ILLUMINANCE`.
195 pub const ILLUMINANCE: u32 = 94;
196 /// Tethered host identity public key (`PROP_HOST_KEY`).
197 pub const HOST_KEY: u32 = 96;
198 /// Host channel keys (`PROP_HOST_CHANNEL_KEYS`).
199 pub const HOST_CHANNEL_KEYS: u32 = 97;
200 /// Host pairwise peer keys (`PROP_HOST_PEER_KEYS`).
201 pub const HOST_PEER_KEYS: u32 = 98;
202 /// Host receive filter table (`PROP_HOST_RX_FILTERS`).
203 pub const HOST_RX_FILTERS: u32 = 99;
204 /// Acknowledgement-delegation enable (`PROP_HOST_AUTO_ACK`).
205 pub const HOST_AUTO_ACK: u32 = 100;
206 /// Frames currently queued (`PROP_HOST_RX_QUEUE_COUNT`).
207 pub const HOST_RX_QUEUE_COUNT: u32 = 101;
208 /// Inbound queue capacity in frames (`PROP_HOST_RX_QUEUE_CAPACITY`).
209 pub const HOST_RX_QUEUE_CAPACITY: u32 = 102;
210 /// Cumulative frames dropped from the queue (`PROP_HOST_RX_QUEUE_DROPPED`).
211 pub const HOST_RX_QUEUE_DROPPED: u32 = 103;
212 /// Transmit duty usage over the past hour (`PROP_PHY_DUTY_NOW`).
213 pub const PHY_DUTY_NOW: u32 = 4820;
214 /// Duty-cycle limit (`PROP_PHY_DUTY_LIMIT`).
215 pub const PHY_DUTY_LIMIT: u32 = 4822;
216 /// Frames that reached the air (`PROP_STAT_TX_PACKETS`) — `UINT32_LE`,
217 /// counted for every client of the radio, the attached host included.
218 /// Requires `CAP_STATS`. See [`crate::stats`] for what the counters
219 /// share: they wrap, they are not saved, `CMD_RST` does not touch
220 /// them, and the only value a write may carry is zero.
221 pub const STAT_TX_PACKETS: u32 = 4832;
222 /// Transmits the channel-activity check held back
223 /// (`PROP_STAT_TX_CHANNEL_BUSY`) — `UINT32_LE`. Counted per attempt,
224 /// so one frame that retries several times before it airs is counted
225 /// several times here and once in
226 /// [`STAT_TX_PACKETS`]. Requires `CAP_STATS`.
227 pub const STAT_TX_CHANNEL_BUSY: u32 = 4833;
228 /// Receptions off the air that are UMSH packets
229 /// (`PROP_STAT_RX_PACKETS`) — `UINT32_LE`, counted whoever they were
230 /// addressed to. Requires `CAP_STATS`.
231 pub const STAT_RX_PACKETS: u32 = 4834;
232 /// Receptions the radio rejected on CRC (`PROP_STAT_RX_BAD_CRC`) —
233 /// `UINT32_LE`. These never reach the MAC: the bytes are unusable and
234 /// the frame is dropped where it was demodulated. A count that climbs
235 /// with a quiet packet count is interference or a marginal link.
236 /// Requires `CAP_STATS`.
237 pub const STAT_RX_BAD_CRC: u32 = 4835;
238 /// Receptions that passed CRC but are not UMSH packets
239 /// (`PROP_STAT_RX_NON_UMSH`) — `UINT32_LE`. The test is the first
240 /// octet's protocol version and reserved bits, so a truncated UMSH
241 /// frame still counts as UMSH; this is somebody else's traffic on the
242 /// same sync word. Requires `CAP_STATS`.
243 pub const STAT_RX_NON_UMSH: u32 = 4836;
244 /// Receptions the device's own node acted on
245 /// (`PROP_STAT_RX_ACCEPTED`) — `UINT32_LE`. Frames addressed to an
246 /// attached host's identity are that host's business and are not
247 /// counted here. Requires `CAP_STATS` and `CAP_REPEATER`.
248 pub const STAT_RX_ACCEPTED: u32 = 4837;
249 /// Receptions this node chose to repeat (`PROP_STAT_FORWARDED`) —
250 /// `UINT32_LE`, counted at the decision rather than at the transmit,
251 /// so a repeat the channel never let out is counted here and not in
252 /// [`STAT_TX_PACKETS`]. Requires `CAP_STATS`
253 /// and `CAP_REPEATER`.
254 pub const STAT_FORWARDED: u32 = 4838;
255 /// Receptions this node would have repeated and declined under the
256 /// operator's forwarding policy (`PROP_STAT_FORWARD_DROPPED`) —
257 /// `UINT32_LE`: an exhausted flood budget, a signal below the
258 /// configured minimum RSSI or SNR, or a region the repeater does not
259 /// serve. Duplicates and traffic addressed to this device are not
260 /// policy decisions and are not counted. Requires `CAP_STATS` and
261 /// `CAP_REPEATER`.
262 pub const STAT_FORWARD_DROPPED: u32 = 4839;
263 /// Queued repeats dropped after the destination's acknowledgement was
264 /// overheard (`PROP_STAT_FORWARD_CANCELLED`) — `UINT32_LE`. Airtime
265 /// this node did not have to spend. Requires `CAP_STATS` and
266 /// `CAP_REPEATER`.
267 pub const STAT_FORWARD_CANCELLED: u32 = 4840;
268 /// Persisted, write-only BLE pairing passkey (`PROP_BLE_PAIRING_PIN`).
269 pub const BLE_PAIRING_PIN: u32 = 4864;
270 /// Nodes authorized to manage this device over the mesh
271 /// (`PROP_DEV_ADMINS`) — a multiple-value property whose items are
272 /// 32-octet Ed25519 public keys, reported verbatim. An empty list
273 /// disables node management. Requires `CAP_ADMIN`.
274 pub const DEV_ADMINS: u32 = 4865;
275 /// Wall-clock time (`PROP_TIME`) — `UINT32_LE` seconds since the Unix
276 /// epoch, or **empty** when the device does not know what time it is.
277 /// Unsigned, so the encoding is wrap-free into 2106. Requires
278 /// `CAP_TIME`.
279 pub const TIME: u32 = 4866;
280 /// Local time-zone offset from UTC (`PROP_TZ_OFFSET`) — `INT16_LE`
281 /// minutes, default 0. Unlike `PROP_TIME` this always has a value:
282 /// where the device is configured to be is known even when what time
283 /// it is is not. Requires `CAP_TIME`.
284 pub const TZ_OFFSET: u32 = 4867;
285 /// Whether position fixes update the advertised node identity
286 /// (`PROP_GNSS_IDENT_UPDATE`) — BOOL, default 0. Requires `CAP_GNSS`.
287 pub const GNSS_IDENT_UPDATE: u32 = 4868;
288 /// Precision the advertised location is clamped to
289 /// (`PROP_GNSS_IDENT_PRECISION`) — `UINT8` 1–7, default 5. Requires
290 /// `CAP_GNSS`.
291 pub const GNSS_IDENT_PRECISION: u32 = 4869;
292 /// Whether receiver-derived time may set the wall clock
293 /// (`PROP_GNSS_TIME_TRUST`) — BOOL, default 1. Cleared, neither a fix
294 /// nor a receiver-RTC read touches `PROP_TIME`, which leaves a
295 /// manually-set clock proof against a jammed or spoofed sky. Position
296 /// reporting is unaffected. Requires `CAP_GNSS`.
297 pub const GNSS_TIME_TRUST: u32 = 4870;
298 /// Whether the device is reachable over Bluetooth
299 /// (`PROP_BLE_ENABLED`) — BOOL, default 1. Requires `CAP_BLE`.
300 ///
301 /// Cleared, the device stops advertising and drops any attached
302 /// host; bonds survive, and the host reconnects when it is set
303 /// again. It does not claim the radio is powered down: tearing a
304 /// vendor stack down at runtime is not something every platform can
305 /// do, and a property that says "off" while a stack is still up
306 /// would be lying about the thing a user turns it off for.
307 pub const BLE_ENABLED: u32 = 4871;
308 /// How many Bluetooth bonds the device is holding
309 /// (`PROP_BLE_BOND_COUNT`) — `UINT8`, read-only. Requires `CAP_BLE`;
310 /// a device whose bonds it cannot manage answers
311 /// `STATUS_PROP_NOT_FOUND`.
312 ///
313 /// The count is live state rather than configuration, so it is not
314 /// part of the saved snapshot. It says how many hosts are enrolled,
315 /// never which: a bond identifies a host, and a device that named its
316 /// bonded hosts to whoever asked would leak the association its
317 /// pairing ceremony exists to protect.
318 pub const BLE_BOND_COUNT: u32 = 4872;
319 /// How far the Bluetooth transport has got with whoever is on the
320 /// other end of it (`PROP_BLE_LINK`) — `UINT8`, read-only, one of
321 /// [`crate::ble::BleLinkState`]. Requires `CAP_BLE`.
322 ///
323 /// Live transport state, so it is not part of the saved snapshot and
324 /// a protocol reset does not touch it. Read over Bluetooth it always
325 /// answers `BLE_LINK_ATTACHED`, because the session asking is the
326 /// session it is reporting; it earns its keep over the mesh and over
327 /// a cable, where it is the only way to ask whether a phone is on the
328 /// device right now.
329 pub const BLE_LINK: u32 = 4873;
330 /// Whether a pairing window is open (`PROP_BLE_PAIRING`) — BOOL,
331 /// read-write. Requires `CAP_BLE`; a device that does not manage its
332 /// own bonds answers `STATUS_PROP_NOT_FOUND`.
333 ///
334 /// A property rather than a command because a window is a state, not
335 /// an act: it can be opened, closed early, observed, and — the case
336 /// no command can express — it closes on its own, on a new bond or a
337 /// timeout, and the device publishes that transition. Writing 1
338 /// opens (or renews) the window; a device that cannot open one right
339 /// now — locked out after repeated pairing failures, or with its
340 /// Bluetooth disabled — answers `STATUS_INVALID_STATE`. Writing 0
341 /// closes it.
342 ///
343 /// Live transport state like the link and the bond count: not part
344 /// of the saved snapshot, and untouched by `CMD_RST`.
345 pub const BLE_PAIRING: u32 = 4874;
346}
347
348/// `PROP_SAVED` values.
349///
350/// A snapshot that exists but cannot be read is distinguishable from no
351/// snapshot at all, and running on an older generation than the one last
352/// written is distinguishable from running on the newest.
353pub mod saved {
354 /// Nothing is saved.
355 pub const NONE: u8 = 0;
356 /// The newest saved generation is in effect.
357 pub const CURRENT: u8 = 1;
358 /// A newer generation was rejected; an older one is in effect.
359 pub const FALLBACK: u8 = 2;
360 /// A snapshot exists but no generation could be read.
361 pub const UNREADABLE: u8 = 3;
362}
363
364/// Stream identifiers.
365pub mod stream {
366 /// Raw radio frame stream (`STR_PHY_RAW`).
367 pub const PHY_RAW: u32 = 113;
368}
369
370/// Capability codes advertised via `PROP_CAPS`.
371pub mod cap {
372 /// `CAP_WRITABLE_RAW_STREAM`
373 pub const WRITABLE_RAW_STREAM: u32 = 8;
374 /// `CAP_PHY_DUTY_LIMIT`
375 pub const PHY_DUTY_LIMIT: u32 = 16;
376 /// `CAP_PHY_LORA`
377 pub const PHY_LORA: u32 = 515;
378 /// `CAP_HOST_FILTER`
379 pub const HOST_FILTER: u32 = 32;
380 /// `CAP_HOST_RX_QUEUE` (requires `CAP_HOST_FILTER`)
381 pub const HOST_RX_QUEUE: u32 = 33;
382 /// `CAP_HOST_KEYS` (requires `CAP_HOST_FILTER`)
383 pub const HOST_KEYS: u32 = 34;
384 /// `CAP_HOST_AUTO_ACK` (requires `CAP_HOST_KEYS` and `CAP_HOST_RX_QUEUE`)
385 pub const HOST_AUTO_ACK: u32 = 35;
386 /// `CAP_SAVE`
387 pub const SAVE: u32 = 36;
388 /// `CAP_DEV_IDENTITY`
389 pub const DEV_IDENTITY: u32 = 37;
390 /// `CAP_DEV_NAME`
391 pub const DEV_NAME: u32 = 38;
392 /// `CAP_BATTERY`
393 pub const BATTERY: u32 = 39;
394 /// `CAP_REPEATER` — the device can act as an autonomous mesh repeater
395 /// (`PROP_MAC_REPEATER_ENABLED`). Requires `CAP_DEV_IDENTITY`.
396 pub const REPEATER: u32 = 40;
397 /// `CAP_IDENT` — the device serves and configures its own advertised
398 /// node identity (`PROP_IDENT`, `PROP_IDENT_ROLE`,
399 /// `PROP_IDENT_MOBILE`). Requires `CAP_DEV_IDENTITY`.
400 pub const IDENT: u32 = 41;
401 /// `CAP_ALERT` — the device has some means of making itself
402 /// physically conspicuous on demand (`PROP_ALERT`). It says nothing
403 /// about *which* means, so a host must not assume audibility.
404 pub const ALERT: u32 = 42;
405 /// `CAP_ADMIN` — the device can be managed over the mesh by the nodes
406 /// listed in `PROP_DEV_ADMINS`. Requires `CAP_DEV_IDENTITY`, since an
407 /// administrator addresses the device identity, and `CAP_CMD_MULTI`,
408 /// so an administrator may rely on the multi-property commands.
409 pub const ADMIN: u32 = 43;
410 /// `CAP_TIME` — the device keeps a wall clock (`PROP_TIME`,
411 /// `PROP_TZ_OFFSET`). It says nothing about where the time comes from
412 /// or whether it survives a power cycle.
413 pub const TIME: u32 = 44;
414 /// `CAP_GNSS` — a GNSS receiver is fitted, so the positioning
415 /// properties exist and the wall clock has a source that can set
416 /// itself. Requires `CAP_TIME`.
417 pub const GNSS: u32 = 45;
418 /// `CAP_ADVERT` — the device announces itself on a schedule of its own
419 /// (`PROP_ADVERT_INTERVAL`, `PROP_BEACON_INTERVAL`,
420 /// `PROP_STARTUP_BEACON`). Requires `CAP_DEV_IDENTITY`, since what an
421 /// advertisement carries is the device identity.
422 pub const ADVERT: u32 = 46;
423 /// `CAP_ILLUMINANCE` — an ambient light sensor is fitted, so
424 /// `PROP_ILLUMINANCE` reads a measurement rather than nothing.
425 pub const ILLUMINANCE: u32 = 47;
426 /// `CAP_MAC_BACKHAUL` — the device can carry the host on a
427 /// point-to-point link to its own node (`PROP_MAC_BACKHAUL`).
428 /// Requires `CAP_REPEATER`: without a repeater there is nothing on
429 /// the far side of that link to carry the host's traffic onward.
430 pub const MAC_BACKHAUL: u32 = 48;
431 /// `CAP_CMD_MULTI` — the device accepts `CMD_PROP_MULTI_GET` and
432 /// `CMD_PROP_MULTI_SET` and answers them with `CMD_PROP_ARE`.
433 pub const CMD_MULTI: u32 = 49;
434 /// `CAP_BLE` — the device has a Bluetooth transport whose
435 /// reachability it can turn on and off (`PROP_BLE_ENABLED`,
436 /// `PROP_BLE_LINK`). It says nothing about the stack underneath, and
437 /// in particular does not promise that clearing `PROP_BLE_ENABLED`
438 /// powers a radio down.
439 ///
440 /// The only Bluetooth capability there is. What else a given
441 /// transport will do — manage its own bonds, hold a pairing PIN — a
442 /// host learns by asking for the property or sending the command and
443 /// reading the refusal, which is a question it has to be able to
444 /// answer anyway.
445 pub const BLE: u32 = 50;
446 /// `CAP_REBOOT` — the device can restart its hardware on command
447 /// (`CMD_REBOOT`). A device that cannot — one whose ULCP session is
448 /// a process rather than a board — leaves this out and answers the
449 /// command `STATUS_UNIMPLEMENTED`.
450 pub const REBOOT: u32 = 51;
451 /// `CAP_STATS` — the device keeps traffic counters and will report
452 /// them (`PROP_STAT_*`). The forwarding counters additionally require
453 /// [`REPEATER`]: a session with no node of its own
454 /// behind it never repeats anything, and reporting zero forwards
455 /// would read as a repeater that has done nothing rather than as no
456 /// repeater at all.
457 pub const STATS: u32 = 52;
458}
459
460/// Whether a property is reachable from a mesh administrator.
461///
462/// The out-of-reach set is small and named explicitly by the spec rather
463/// than derived, because "device domain" is not a property of the key: a
464/// host-domain table and a device-domain one differ only by which half of
465/// the device they configure. A device answers all three with
466/// `STATUS_PROP_NOT_FOUND` — an administrator learns that the property does
467/// not exist for it, not that it exists and was refused — and an
468/// administrator that reads this first spends no airtime asking.
469pub fn admin_reachable(key: u32) -> bool {
470 !matches!(
471 key,
472 // The host domain in full: the assistance the device owes to
473 // whatever host it serves is that host's business.
474 prop::HOST_KEY
475 | prop::HOST_CHANNEL_KEYS
476 | prop::HOST_PEER_KEYS
477 | prop::HOST_RX_FILTERS
478 | prop::HOST_AUTO_ACK
479 | prop::HOST_RX_QUEUE_COUNT
480 | prop::HOST_RX_QUEUE_CAPACITY
481 | prop::HOST_RX_QUEUE_DROPPED
482 // Session state: an exchange is not an attach, so there is no
483 // session for it to describe.
484 | prop::MAC_PROMISCUOUS
485 | prop::MAC_BACKHAUL
486 // A device identity cannot be installed over the mesh.
487 | prop::DEV_PRIVATE_KEY
488 )
489}
490
491/// Value used in `PROP_PHY_DUTY_LIMIT` to disable duty-cycle limiting.
492pub const DUTY_LIMIT_DISABLED: u16 = 0xFFFF;
493
494/// Shortest accepted `PROP_ADVERT_INTERVAL` / `PROP_BEACON_INTERVAL`, in
495/// seconds.
496///
497/// An absolute floor, and one a device may only ever round *up* from:
498/// scheduling jitter delays an announcement and never brings it forward,
499/// so no configuration can put an unsolicited broadcast on the air more
500/// often than this. The duty ledger remains the airtime control; this is
501/// what keeps a mistyped interval from spending the whole budget on
502/// announcements before anything else can speak.
503pub const MIN_AUTO_ANNOUNCE_INTERVAL_S: u32 = 20 * 60;
504
505/// Longest accepted `PROP_ADVERT_INTERVAL` / `PROP_BEACON_INTERVAL`, in
506/// seconds.
507///
508/// A ceiling on how stale the mesh's picture of a node may get while that
509/// node still considers itself to be announcing. Past a day the schedule
510/// has stopped being one, and 0 says so more honestly.
511pub const MAX_AUTO_ANNOUNCE_INTERVAL_S: u32 = 24 * 60 * 60;
512
513/// Default `PROP_ADVERT_INTERVAL`, in seconds.
514pub const DEFAULT_ADVERT_INTERVAL_S: u32 = 4 * 60 * 60;
515
516/// Default `PROP_BEACON_INTERVAL`, in seconds.
517pub const DEFAULT_BEACON_INTERVAL_S: u32 = 60 * 60;