Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ULCP: Radio Control

Radio control is the subsystem the host uses to configure and observe the physical transceiver: frequency, modulation, transmit power, and the transmit duty-cycle budget. Every ULCP device implements it.

The interface is deliberately not LoRa-specific in shape where that can be avoided. The properties that any radio has—enable, frequency, transmit power, RSSI, MTU—are unconditional; the LoRa modulation parameters are gated behind CAP_PHY_LORA, and duty-cycle accounting behind CAP_PHY_DUTY_LIMIT. Traffic counters are exposed by CAP_STATS.

The RF configuration is device-domain state: it belongs to the radio rather than to whichever host is attached, it is part of a saved snapshot, and it survives a change of host.

Capabilities

CodeNameGrants
16CAP_PHY_DUTY_LIMITDuty-cycle accounting and enforcement: PROP_PHY_DUTY_NOW, PROP_PHY_DUTY_LIMIT, and STATUS_DUTY_LIMIT
52CAP_STATSRadio and forwarding traffic counters: PROP_STAT_*
515CAP_PHY_LORAThe LoRa modulation parameters: PROP_PHY_LORA_BW, PROP_PHY_LORA_SF, PROP_PHY_LORA_CR, PROP_PHY_LORA_SW

Properties

IdMnemonicCommandsDescription
32PROP_PHY_ENABLEDGet, SetPHY enabled
35PROP_PHY_FREQGet, SetFrequency in kHz
37PROP_PHY_TX_POWERGet, SetTX power in dBm
38PROP_PHY_RSSIGetCurrent RSSI
39PROP_PHY_LORA_BWGet, SetLoRa bandwidth
40PROP_PHY_LORA_SFGet, SetLoRa spreading factor
41PROP_PHY_LORA_CRGet, SetLoRa coding rate
42PROP_PHY_MTUGetMax size of a frame
43PROP_PHY_LORA_SWGet, SetLoRa sync word (16-bit style)
4820PROP_PHY_DUTY_NOWGetCurrent duty usage
4822PROP_PHY_DUTY_LIMITGet, SetDuty-cycle limit
4832PROP_STAT_TX_PACKETSGet, SetPackets transmitted over the air
4833PROP_STAT_TX_CHANNEL_BUSYGet, SetTransmissions deferred because the channel was busy
4834PROP_STAT_RX_PACKETSGet, SetReceived packets with a UMSH first-octet pattern
4835PROP_STAT_RX_BAD_CRCGet, SetReceptions rejected because of a bad CRC
4836PROP_STAT_RX_NON_UMSHGet, SetReceived packets without a UMSH first-octet pattern
4837PROP_STAT_RX_ACCEPTEDGet, SetReceived packets accepted by this device’s node
4838PROP_STAT_FORWARDEDGet, SetPackets this device chose to forward
4839PROP_STAT_FORWARD_DROPPEDGet, SetForwarding candidates rejected by policy
4840PROP_STAT_FORWARD_CANCELLEDGet, SetQueued forwards cancelled after an acknowledgement

PROP 32: PROP_PHY_ENABLED

  • Type: Single-Value, Read/Write
  • Asynchronous Updates: No
  • Required:
    • CMD_PROP_GET: REQUIRED
    • CMD_PROP_SET: REQUIRED
  • Scope: NLI
  • Value Type: BOOL
  • Post-Reset Value: 0 (false)

Set to 1 if the PHY is enabled, set to 0 otherwise. May be directly enabled to bypass higher-level packet processing in order to implement things like packet sniffers.

PROP 35: PROP_PHY_FREQ

  • Type: Single-Value, Read-Write
  • Asynchronous Updates: No
  • Required: REQUIRED
  • Scope: NLI
  • Value Type: UINT32_LE
  • Units: kHz
  • Post-Reset Value: Unspecified

Value is the radio frequency (in kilohertz) of the current channel.

PROP 37: PROP_PHY_TX_POWER

  • Type: Single-Value, Read-Write
  • Asynchronous Updates: No
  • Required: REQUIRED
  • Scope: NLI
  • Value Type: INT8
  • Units: dBm
  • Post-Reset Value: Implementation-Specific

Value is the radio transmit power in dBm.

A device MUST clamp a written value to the range its radio can reach rather than rejecting it, and the emitted CMD_PROP_IS carries the clamped value. Nothing else publishes that range, so this is how a host discovers it: a host that needs to know what a device will actually transmit at reads the value it gets back rather than the one it wrote.

PROP 38: PROP_PHY_RSSI

  • Type: Single-Value, Read-Only
  • Asynchronous Updates: No
  • Required: REQUIRED
  • Value Type: INT8
  • Unit: dBm (RF Power)
  • Post-Reset Value: Unspecified

Value is the current RSSI (Received Signal Strength Indication) from the radio. This value can be used in energy scans and for determining the ambient noise floor for the operating environment.

Zero dBm represents one milliwatt of power.

Sampling ambient RSSI requires the radio to be actively receiving. If PROP_PHY_ENABLED is false, getting this property fails with STATUS_INVALID_STATE. A get may also fail with STATUS_FAILURE if the radio cannot service the read (for example, mid-reconfiguration).

PROP 39: PROP_PHY_LORA_BW

  • Type: Single-Value, Read-Write
  • Asynchronous Updates: No
  • Required: CAP_PHY_LORA
  • Scope: NLI
  • Value Type: UINT32_LE
  • Units: Hz
  • Post-Reset Value: Implementation-Specific

Value is the configured LoRa bandwidth.

PROP 40: PROP_PHY_LORA_SF

  • Type: Single-Value, Read-Write
  • Asynchronous Updates: No
  • Required: CAP_PHY_LORA
  • Scope: NLI
  • Value Type: UINT8
  • Post-Reset Value: Implementation-Specific

Value is the configured LoRa spreading factor.

PROP 41: PROP_PHY_LORA_CR

  • Type: Single-Value, Read-Write
  • Asynchronous Updates: No
  • Required: CAP_PHY_LORA
  • Scope: NLI
  • Value Type: UINT8
  • Post-Reset Value: Implementation-Specific

Value is the configured LoRa coding rate.

PROP 42: PROP_PHY_MTU

  • Type: Single-Value, Read-Only
  • Asynchronous Updates: No
  • Required: REQUIRED
  • Scope: NLI
  • Value Type: UINT16_LE
  • Units: octets
  • Post-Reset Value: Implementation-Specific

Maximum size of the DATA field that may be supplied to STR_PHY_RAW.

PROP 43: PROP_PHY_LORA_SW

  • Type: Single-Value, Read-Write
  • Asynchronous Updates: No
  • Required: CAP_PHY_LORA
  • Scope: NLI
  • Value Type: UINT16
  • Post-Reset Value: Implementation-Specific, but 0x1424 is a good suggestion.

Value is the 16-bit (SX126x-style) LoRa sync-word.

PROP 4820: PROP_PHY_DUTY_NOW

  • Type: Single-Value, Read-Only
  • Value Type: u16
  • Units: Percent, 0-65535 -> 0-100%
  • Post-Reset Value: 0%
  • Required Capability: CAP_PHY_DUTY_LIMIT

The radio transmit duty cycle over the past hour, updated in 4-minute intervals.

Under the hood, this is represented as 15 16-bit bins, one for each 4-minute interval. An increment of 1 represents 5ms. For each 5ms of transmission time, the current bin is incremented by 1. So a 20ms transmission would increment the current bin by 4, but a 22ms transmission would increment the bin by 5. At the transition between intervals, the new current bin is reset to zero.

To calculate the current duty cycle, all of the bins are added together, multiplied by 65535, and then divided by 720000.

PROP 4822: PROP_PHY_DUTY_LIMIT

  • Type: Single-Value, Read-Write
  • Value Type: u16
  • Units: Percent, 0-65535 -> 0-100%
  • Post-Reset Value: Settings-dependent
  • Required Capability: CAP_PHY_DUTY_LIMIT

The value for PROP_PHY_DUTY_NOW above which sending additional packets will be prevented. Packets that are prevented from being sent will be dropped with STATUS_DUTY_LIMIT.

Set to 0xFFFF to disable duty-cycle limiting. Note that PROP_PHY_DUTY_NOW will continue to be updated even if duty-cycle limiting is disabled.

Values for common duty cycles:

ValuePercentage
1310720%
655310%
6551%
650.1%

Statistics

A device advertising CAP_STATS exposes cumulative UINT32_LE traffic counters. Values count since boot or the most recent reset of that counter and wrap modulo 2^32. Writing four zero octets resets a counter. A device MUST reject every other value or length with STATUS_INVALID_ARGUMENT.

Statistics are live hardware history rather than configuration. They are not part of a saved snapshot, and CMD_RST MUST NOT clear them. A host can reset several counters with CMD_PROP_MULTI_SET, but the individual resets do not occur simultaneously: traffic arriving during the write sweep can fall on different sides of different counter resets.

PROP_PHY_DUTY_NOW is commonly displayed alongside these counters, but it is a rolling regulatory measurement and is not resettable.

PROP 4832: PROP_STAT_TX_PACKETS

Packets whose transmission completed successfully over the physical radio. Requires CAP_STATS.

PROP 4833: PROP_STAT_TX_CHANNEL_BUSY

Transmission attempts deferred because channel assessment reported the channel busy. Such an attempt does not also increment PROP_STAT_TX_PACKETS. Requires CAP_STATS.

PROP 4834: PROP_STAT_RX_PACKETS

Off-air receptions whose first octet carries the UMSH version and valid reserved bits. This classification does not require the rest of the packet to parse. Requires CAP_STATS.

PROP 4835: PROP_STAT_RX_BAD_CRC

Receptions the physical radio rejected because their payload CRC was invalid. Requires CAP_STATS.

PROP 4836: PROP_STAT_RX_NON_UMSH

Off-air receptions whose first octet does not carry the UMSH version and valid reserved bits. Requires CAP_STATS.

PROP 4837: PROP_STAT_RX_ACCEPTED

Receptions on which this device’s own node acted. Frames addressed to an attached host’s identity are not included. Requires CAP_STATS and CAP_REPEATER.

PROP 4838: PROP_STAT_FORWARDED

Receptions this device’s own node chose to repeat. The counter records the forwarding decision; successful physical transmissions are counted separately by PROP_STAT_TX_PACKETS. Requires CAP_STATS and CAP_REPEATER.

PROP 4839: PROP_STAT_FORWARD_DROPPED

Packets that were eligible for forwarding but were rejected by this repeater’s configured minimum RSSI, minimum SNR, or region policy. Exhausted flood budgets and packet-imposed signal thresholds are normal packet behavior, not administrator policy, and are not included. Duplicates, self-addressed packets, and packets received while forwarding is disabled are also excluded. Requires CAP_STATS and CAP_REPEATER.

PROP 4840: PROP_STAT_FORWARD_CANCELLED

Queued forwards cancelled because the destination’s acknowledgement was overheard before transmission. Requires CAP_STATS and CAP_REPEATER.