net_alerter: Add Strategy 0 MAC deduplication and fix Strategy 3 overwrite bug

Strategy 0 now checks if a MAC already exists in any identity's wifi_macs/ble_macs
sets before creating a new record. Prevents duplicate identity creation on repeated
mDNS/ARP signals.

Strategy 3 now conditionally updates existing records instead of unconditionally
overwriting them. Preserves signal_count and signal_types accumulation needed for
auto-enrollment (2+ signal types).

Fixes issue where devices seen only via mDNS/ARP never reached enrollment threshold.
This commit is contained in:
Cobra
2026-04-14 13:39:37 -04:00
parent 6a5d1f0670
commit f73ef29c1e
+50 -15
View File
@@ -186,6 +186,7 @@ def _correlate_or_create_identity(mac: str, signal_type: str, dhcp_fp: str = "",
signal_type: "ble", "dhcp", "arp", or "mdns"
Lookup strategy:
0. Check if MAC already exists in any identity's MAC sets
1. If handoff_seq provided, look for matching BLE handoff seq anchor
2. If dhcp_fp provided, look for matching DHCP fingerprint
3. If neither, create new provisional identity
@@ -196,6 +197,18 @@ def _correlate_or_create_identity(mac: str, signal_type: str, dhcp_fp: str = "",
# Determine signal category: 'ble' or 'wifi' (for dhcp/arp/mdns)
signal_category = 'ble' if signal_type == 'ble' else 'wifi'
# Strategy 0: Check if MAC already exists in any identity
for iid, dev in device_store.items():
if mac in dev['wifi_macs'] or mac in dev['ble_macs']:
# Found existing identity for this MAC — update instead of creating new
dev['last_seen'][mac] = time.time()
dev['signal_types'].add(signal_category)
logging.debug(f"MAC {mac} already linked to identity {iid}, updated {signal_category} signal")
# Check if meets enrollment criteria (2+ signal types)
if len(dev['signal_types']) >= 2 and not dev['enrolled']:
_fire_enrollment_callback(iid)
return iid
# Strategy 1: Match by BLE Handoff sequence (most stable)
if handoff_seq is not None:
for iid, dev in device_store.items():
@@ -232,23 +245,45 @@ def _correlate_or_create_identity(mac: str, signal_type: str, dhcp_fp: str = "",
# Provisional identity based on first MAC seen
identity_id = f"prov:{mac}"
dev = _create_identity_record(identity_id)
# Add initial signal
if signal_type == "ble":
dev['ble_macs'].add(mac)
if handoff_seq is not None:
dev['handoff_seq'] = handoff_seq
dev['signal_types'].add('ble')
# Check if this identity already exists (e.g., multiple mDNS/ARP signals for same MAC)
if identity_id in device_store:
dev = device_store[identity_id]
# Update existing record instead of overwriting
if signal_type == "ble":
dev['ble_macs'].add(mac)
if handoff_seq is not None:
dev['handoff_seq'] = handoff_seq
dev['signal_types'].add('ble')
else:
dev['wifi_macs'].add(mac)
if dhcp_fp:
dev['dhcp_fingerprint'] = dhcp_fp
dev['signal_types'].add('wifi')
dev['last_seen'][mac] = time.time()
# Check if meets enrollment criteria (2+ signal types)
if len(dev['signal_types']) >= 2 and not dev['enrolled']:
_fire_enrollment_callback(identity_id)
logging.debug(f"Updated device identity {identity_id} with {signal_type} signal (MAC: {mac})")
else:
dev['wifi_macs'].add(mac)
if dhcp_fp:
dev['dhcp_fingerprint'] = dhcp_fp
dev['signal_types'].add('wifi')
# Create new identity
dev = _create_identity_record(identity_id)
# Add initial signal
if signal_type == "ble":
dev['ble_macs'].add(mac)
if handoff_seq is not None:
dev['handoff_seq'] = handoff_seq
dev['signal_types'].add('ble')
else:
dev['wifi_macs'].add(mac)
if dhcp_fp:
dev['dhcp_fingerprint'] = dhcp_fp
dev['signal_types'].add('wifi')
dev['last_seen'][mac] = time.time()
device_store[identity_id] = dev
logging.debug(f"Created new device identity {identity_id} from {signal_type} signal")
dev['last_seen'][mac] = time.time()
device_store[identity_id] = dev
logging.debug(f"Created new device identity {identity_id} from {signal_type} signal")
return identity_id