Fix operator tracks collapsing onto op-Unknown-BasicID_0 (v2.3.2) - #11
Merged
Conversation
Measured on a live box (aryaos-4f11, DroneScout DS110), 30s of CoT on the
Mesh SA group attributed by source IP:
from 192.168.0.13 (DroneScout, MAVLink serial):
op-Unknown-BasicID_0 x62 <-- every operator on ONE track
RID.1787F04BM24010011195.uas x54 correct
op-1787F04BM24010011195 x54 correct
from 192.168.0.44 (Wi-Fi RID, SAME drone):
op-4A:BE:41:9D:E3:34 x14 correct, MAC fallback working
So the aircraft UID resolved while the operator UID did not, and every
operator seen by that receiver merged into a single track.
Cause: the MAVLink path called rid_normalize.odid_parsed_to_rid_dict
directly and attached NO "data" metadata at all, unlike the wireless path
(bytes_to_rid_dict, which builds it via uas_meta_defaults). With neither a
MAC nor a sensor_id, a pack carrying only System/OperatorID and no BasicID
had no transmitter identity to key on, so functions._rid_identity fell
through every rung to Unknown-BasicID_0.
MAVLink OpenDroneID carries a 20-byte id_or_mac naming the transmitter,
which the code ignored. It is the only per-aircraft grouping key a serial
feed offers -- there is no radio MAC in the metadata. Measured on the
DS110: populated on 58 of 58 packs, db:13:81:94:13:55 + 14 zero bytes.
* attach metadata on both MAVLink paths, carrying id_or_mac as the
advertiser MAC and the CONFIGURED SENSOR_ID
* only accept a MAC-shaped id_or_mac (6 significant bytes then padding).
The field may instead hold an opaque ID string, and calling that a MAC
would put a wrong-looking value in the UID, so those feeds keep the
previous behaviour until there is hardware to test against.
* _rid_identity: look for sensor_id at BOTH levels. The MAC was already
checked at both because "MQTT and serial feeds put it at the top
level"; the same is true of sensor_id, so that rung silently never
fired for them.
Second effect of the missing metadata, also fixed: CoT was attributed to
the default dronecot_<hostname> instead of the configured SENSOR_ID, so on
a box with two receivers you could not tell which one saw a contact.
_adsb_vehicle_to_rid_dict stays a static pure function with metadata
injected by the caller, so its existing unit tests keep working.
13 new tests using the real captured id_or_mac. Verified they catch the
bug: reverting the metadata attachment fails exactly the three identity
tests with 'Unknown-BasicID_0' == 'Unknown-BasicID_0'. Full suite 85
passed, 1 skipped.
This is the same CLASS of bug as the aggregator fix in 2.3.0, which I
verified on the UAS path only and not the operator path.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0197da7dhvcPoHxYKamrYqyM
The version lives in src/dronecot/VERSION (setup.cfg reads it with 'version = file:'), not in __init__.py. My bump targeted __init__.py, the assertion caught that it was not there, but the commit went ahead anyway -- so the fix landed on 2.3.1's version string.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #10, which was branched off a stale local
main(missing #9) and so showed as CONFLICTING — and GitHub runs no CI at all on a conflicting PR. This is the same work rebased onto currentmain; during the rebase git correctly dropped my two already-upstream commits.Measured on a live box (
aryaos-4f11, DroneScout DS110), 30 s of CoT on the Mesh SA group, attributed by source IP:The aircraft UID resolved; the operator UID did not. Every operator seen by that receiver merged into one track.
Cause
The MAVLink path called
rid_normalize.odid_parsed_to_rid_dictdirectly and attached nodatametadata at all — unlike the wireless path, which builds it viabytes_to_rid_dict→uas_meta_defaults. With neither a MAC nor asensor_id, a pack carrying only System/OperatorID and no BasicID had no transmitter identity to key on, so_rid_identityfell through every rung — including #9's newFEED-rung — toUnknown-BasicID_0.MAVLink OpenDroneID carries a 20-byte
id_or_macnaming the transmitter, which the code ignored. It's the only per-aircraft grouping key a serial feed offers — there's no radio MAC in the metadata. Measured on the DS110: populated on 58 of 58 packs,db:13:81:94:13:55+ 14 zero bytes, one distinct value for one drone.Changes
id_or_macas the advertiser MAC and the configuredSENSOR_ID.id_or_mac(6 significant bytes then padding). The field may instead hold an opaque ID string, and calling that a MAC would put a wrong-looking value in the CoT UID — those feeds keep the previous behaviour until there's hardware to test against._rid_identity: look forsensor_idat both levels. The MAC was already checked at both because "MQTT and serial feeds put it at the top level" — the same is true ofsensor_id, so Give MAC-less feeds a distinct UID instead of a shared placeholder #9's rung silently never fired for exactly the feeds it was written for.Second bug the missing metadata caused, also fixed: CoT was attributed to the default
dronecot_<hostname>instead of the configuredSENSOR_ID, so on a box with two receivers you couldn't tell which one saw a contact._adsb_vehicle_to_rid_dictstays a static pure function with metadata injected by the caller, so its existing unit tests keep working untouched.Tests
13 new tests using the real captured
id_or_mac, including that two transmitters don't collapse (the DS110 reports many aircraft over one port).Verified they catch the bug — reverting the metadata attachment fails exactly the three identity tests:
Full suite on the rebased tree: 85 passed, 1 skipped.
Worth saying plainly
This is the same class of bug as the aggregator work in 2.3.0 and #9. Both were verified on the UAS path and not the operator path, so it shipped half-fixed twice.
🤖 Generated with Claude Code
https://claude.ai/code/session_0197da7dhvcPoHxYKamrYqyM