Skip to content

Add Downlink TDoA ranging measurements and notifications - #144

Merged
sameer merged 1 commit into
mainfrom
dl-tdoa
Oct 29, 2026
Merged

sameer merged 1 commit into
mainfrom
dl-tdoa

Conversation

@sameer

@sameer sameer commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

After #143, Pica supports DL-TDoA session setup. This PR adds support for DL-TDoA measurements and notifications during active sessions.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements Downlink Time Difference of Arrival (DL-TDoA) ranging support. It introduces new configuration structures, parsing logic, and helper methods for managing DL-TDoA anchors and sessions, alongside the core measurement synthesis and notification encoding logic. The test suite is also updated to validate these changes. The feedback suggests removing an unused import of pdl_runtime::Packet in src/app_config.rs.

Comment thread src/app_config.rs
@sameer
sameer added this pull request to stack #145 October 22, 2026 21:24
@sameer
sameer force-pushed the dl-tdoa branch 2 times, most recently from f2205e9 to cf07b6f Compare October 23, 2026 00:28
@sameer
sameer force-pushed the dl-tdoa branch 3 times, most recently from 992f8cc to 377379e Compare October 25, 2026 18:42
Base automatically changed from dl-tdoa-config to main October 26, 2026 02:01
sameer added a commit that referenced this pull request Oct 26, 2026
This PR lays the groundwork for Dl-TDoA support in Pica by accepting and validating configs. #144 does the actual implementation.
@sameer
sameer force-pushed the dl-tdoa branch 3 times, most recently from 12fc0e4 to 81739c1 Compare October 27, 2026 03:45
@sameer
sameer requested a review from schilit October 27, 2026 03:46
#143 added Downlink TDoA packet definitions, session configuration, and
round update commands, but Pica does not yet simulate DL-TDoA ranging
rounds or send measurement notifications during active sessions.

This CL:
- Advertises Downlink TDoA support in device capability TLVs.
- Validates active tag and anchor ranging rounds before session start.
- Simulates Poll, Response, and Final DTM exchanges across anchors.
- Emits DL-TDoA session info notifications to tags.
sameer added a commit that referenced this pull request Oct 28, 2026
Although PR #144 introduced DL-TDoA roles, ranging methods, and
active-round limits on top of UCI 2.0, Pica still reported MAC and
PHY version 1.3, and DEFAULT_CAPS_INFO retained untyped FiRa 1.1
byte slices. Consequently, capability tag IDs were shifted relative
to FiRa 2.0, mandatory FiRa 2.0 tags were missing, and scheduling
bitmasks were incorrect.

Bump MAC_VERSION and PHY_VERSION to 2.0, update CapTlvType in PDL
and uci.py to FiRa 2.0 tag IDs, and replace DEFAULT_CAPS_INFO with a
typed Capabilities struct covering all mandatory FiRa 2.0 and
optional DL-TDoA, CCC, and Aliro capabilities.

Closes #146
sameer added a commit that referenced this pull request Oct 28, 2026
Although PR #144 introduced DL-TDoA roles, ranging methods, and
active-round limits on top of UCI 2.0, Pica still reported MAC and
PHY version 1.3, and DEFAULT_CAPS_INFO retained untyped FiRa 1.1
byte slices. Consequently, capability tag IDs were shifted relative
to FiRa 2.0, mandatory FiRa 2.0 tags were missing, and scheduling
bitmasks were incorrect.

Bump MAC_VERSION and PHY_VERSION to 2.0, update CapTlvType in PDL
and uci.py to FiRa 2.0 tag IDs, and replace DEFAULT_CAPS_INFO with a
typed Capabilities struct covering all mandatory FiRa 2.0 and
optional DL-TDoA, CCC, and Aliro capabilities.

Closes #146
sameer added a commit that referenced this pull request Oct 28, 2026
While PR #144 added start-time DL-TDoA active-rounds validation,
separate SessionSetAppConfigCmd calls can leave AppConfig internally
inconsistent across MAC address mode, controlee count, and ranging
duration, while SessionStatusNtf.reason_code remained an untyped u8.

Type SessionStatusNtf.reason_code as ReasonCode in PDL and uci.py with
0x40 and 0x41 promoted out of RFU_REASON_CODE_RANGE_2, and extend
Session::invalid_start_reason to validate MAC address widths,
controlee counts, unicast mode, and FiRa slot budget at session_start.

Closes #125
sameer added a commit that referenced this pull request Oct 28, 2026
While PR #144 added DL-TDoA measurement generation alongside Two-Way
Ranging, Pica populated local azimuth and elevation AoA fields across
TWR and DL-TDoA measurements even when disabled by AOA_RESULT_REQ. Pica
also evaluated AoA notification bounds on disabled axes and ignored
FiRa Note 2 notification filtering rules under disabled AoA.

Zero disabled local AoA angles and figures of merit while preserving
aoa_destination_* fields. Normalize SESSION_INFO_NTF_CONFIG via
effective_session_info_ntf_config() according to FiRa Table 28 / Table 38
Note 2, and restrict AOA_BOUND_CONFIG filtering to enabled AoA axes.

Closes #147
sameer added a commit that referenced this pull request Oct 28, 2026
Building on the DL-TDoA groundwork in PR #144, Pica still ignored
the RSSI_REPORTING (0x13) session configuration and hardcoded 0xFF in
ranging reports. Android decodes 0xFF as -127 dBm rather than
RSSI_UNKNOWN, distorting client signal metrics.

Advertise vendor capability SUPPORTED_RSSI_REPORTING (0xE6), emit 0x00
when disabled, and emit -50 dBm (100 in unsigned Q7.1 format) across
Two-Way Ranging and DL-TDoA measurements when enabled.

Closes #148
sameer added a commit that referenced this pull request Oct 28, 2026
Although PR #144 introduced DL-TDoA roles, ranging methods, and
active-round limits on top of UCI 2.0, Pica still reported MAC and
PHY version 1.3, and DEFAULT_CAPS_INFO retained untyped FiRa 1.1
byte slices. Consequently, capability tag IDs were shifted relative
to FiRa 2.0, mandatory FiRa 2.0 tags were missing, and scheduling
bitmasks were incorrect.

Bump MAC_VERSION and PHY_VERSION to 2.0, update CapTlvType in PDL
and uci.py to FiRa 2.0 tag IDs, and replace DEFAULT_CAPS_INFO with a
typed Capabilities struct covering all mandatory FiRa 2.0 and
optional DL-TDoA, CCC, and Aliro capabilities.

Closes #146
sameer added a commit that referenced this pull request Oct 28, 2026
While PR #144 added start-time DL-TDoA active-rounds validation,
separate SessionSetAppConfigCmd calls can leave AppConfig internally
inconsistent across MAC address mode, controlee count, and ranging
duration, while SessionStatusNtf.reason_code remained an untyped u8.

Type SessionStatusNtf.reason_code as ReasonCode in PDL and uci.py with
0x40 and 0x41 promoted out of RFU_REASON_CODE_RANGE_2, and extend
Session::invalid_start_reason to validate MAC address widths,
controlee counts, unicast mode, and FiRa slot budget at session_start.

Closes #125
sameer added a commit that referenced this pull request Oct 28, 2026
Although PR #144 introduced DL-TDoA roles, ranging methods, and
active-round limits on top of UCI 2.0, Pica still reported MAC and
PHY version 1.3, and DEFAULT_CAPS_INFO retained untyped FiRa 1.1
byte slices. Consequently, capability tag IDs were shifted relative
to FiRa 2.0, mandatory FiRa 2.0 tags were missing, and scheduling
bitmasks were incorrect.

Bump MAC_VERSION and PHY_VERSION to 2.0, update CapTlvType in PDL
and uci.py to FiRa 2.0 tag IDs, and replace DEFAULT_CAPS_INFO with a
typed Capabilities struct covering all mandatory FiRa 2.0 and
optional DL-TDoA, CCC, and Aliro capabilities.

Closes #146
sameer added a commit that referenced this pull request Oct 28, 2026
While PR #144 added start-time DL-TDoA active-rounds validation,
separate SessionSetAppConfigCmd calls can leave AppConfig internally
inconsistent across MAC address mode, controlee count, and ranging
duration, while SessionStatusNtf.reason_code remained an untyped u8.

Type SessionStatusNtf.reason_code as ReasonCode in PDL and uci.py with
0x40 and 0x41 promoted out of RFU_REASON_CODE_RANGE_2, and extend
Session::invalid_start_reason to validate MAC address widths,
controlee counts, unicast mode, and FiRa slot budget at session_start.

Closes #125
@sameer
sameer merged commit 03f1e93 into main Oct 29, 2026
13 checks passed
sameer added a commit that referenced this pull request Oct 29, 2026
While PR #144 added start-time DL-TDoA active-rounds validation,
separate SessionSetAppConfigCmd calls can leave AppConfig internally
inconsistent across MAC address mode, controlee count, and ranging
duration, while SessionStatusNtf.reason_code remained an untyped u8.

Type SessionStatusNtf.reason_code as ReasonCode in PDL and uci.py with
0x40 and 0x41 promoted out of RFU_REASON_CODE_RANGE_2, and extend
Session::invalid_start_reason to validate MAC address widths,
controlee counts, unicast mode, and FiRa slot budget at session_start.

Closes #125
@sameer
sameer deleted the dl-tdoa branch October 29, 2026 01:34
sameer added a commit that referenced this pull request Oct 29, 2026
While PR #144 introduced block stride handling and notification intervals
for DL-TDoA, Two-Way Ranging ignored BLOCK_STRIDE_LENGTH (0x2D) and
still hardcoded current_ranging_interval to 0 in TWR SessionInfoNtf.

Unify AppConfig::block_stride across DL-TDoA tags and TWR Controllers,
reschedule next_ranging_at on active Session::set_app_config updates,
and populate current_ranging_interval in TWR notifications.

Closes #149
sameer added a commit that referenced this pull request Oct 29, 2026
While PR #144 added start-time DL-TDoA active-rounds validation,
separate SessionSetAppConfigCmd calls can leave AppConfig internally
inconsistent across MAC address mode, controlee count, and ranging
duration, while SessionStatusNtf.reason_code remained an untyped u8.

Type SessionStatusNtf.reason_code as ReasonCode in PDL and uci.py with
0x40 and 0x41 promoted out of RFU_REASON_CODE_RANGE_2, and extend
Session::invalid_start_reason to validate MAC address widths,
controlee counts, unicast mode, and FiRa slot budget at session_start.

Closes #125
sameer added a commit that referenced this pull request Oct 29, 2026
While PR #144 added DL-TDoA measurement generation alongside Two-Way
Ranging, Pica populated local azimuth and elevation AoA fields across
TWR and DL-TDoA measurements even when disabled by AOA_RESULT_REQ. Pica
also evaluated AoA notification bounds on disabled axes and ignored
FiRa Note 2 notification filtering rules under disabled AoA.

Zero disabled local AoA angles and figures of merit while preserving
aoa_destination_* fields. Normalize SESSION_INFO_NTF_CONFIG via
effective_session_info_ntf_config() according to FiRa Table 28 / Table 38
Note 2, and restrict AOA_BOUND_CONFIG filtering to enabled AoA axes.

Closes #147
sameer added a commit that referenced this pull request Oct 29, 2026
While PR #144 added start-time DL-TDoA active-rounds validation,
separate SessionSetAppConfigCmd calls can leave AppConfig internally
inconsistent across MAC address mode, controlee count, and ranging
duration, while SessionStatusNtf.reason_code remained an untyped u8.

Type SessionStatusNtf.reason_code as ReasonCode in PDL and uci.py with
0x40 and 0x41 promoted out of RFU_REASON_CODE_RANGE_2, and extend
Session::invalid_start_reason to validate MAC address widths,
controlee counts, unicast mode, and FiRa slot budget at session_start.

Closes #125
sameer added a commit that referenced this pull request Oct 29, 2026
Building on the DL-TDoA groundwork in PR #144, Pica still ignored
the RSSI_REPORTING (0x13) session configuration and hardcoded 0xFF in
ranging reports. Android decodes 0xFF as -127 dBm rather than
RSSI_UNKNOWN, distorting client signal metrics.

Advertise vendor capability SUPPORTED_RSSI_REPORTING (0xE6), emit 0x00
when disabled, and emit -50 dBm (100 in unsigned Q7.1 format) across
Two-Way Ranging and DL-TDoA measurements when enabled.

Closes #148
sameer added a commit that referenced this pull request Oct 29, 2026
While PR #144 added start-time DL-TDoA active-rounds validation,
separate SessionSetAppConfigCmd calls can leave AppConfig internally
inconsistent across MAC address mode, controlee count, and ranging
duration, while SessionStatusNtf.reason_code remained an untyped u8.

Type SessionStatusNtf.reason_code as ReasonCode in PDL and uci.py with
0x40 and 0x41 promoted out of RFU_REASON_CODE_RANGE_2, and extend
Session::invalid_start_reason to validate MAC address widths,
controlee counts, unicast mode, and FiRa slot budget at session_start.

Closes #125
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants