Fix arrival/departure gates dropping LAA MACs; halve ARP scan interval
The phone/wearable gate used a manual OUI check that missed privately-addressed MACs (iOS 14+/Android 10+ randomize per network). Any phone not pre-configured in device_labels was silently enrolled with no alert, causing ARRIVED/OCCUPIED to never fire. Replacing the gate with is_personal_device() catches OUI, labels, and LAA bit uniformly. ARP scan interval drops from 30s to 15s so worst-case arrival detection is 15s.
This commit is contained in:
@@ -32,7 +32,7 @@ OUI_DB_PATH = "/opt/net_alerter/oui.db"
|
|||||||
ENV_PATH = Path(os.getenv("NET_ALERTER_ENV", "/opt/net_alerter/.env"))
|
ENV_PATH = Path(os.getenv("NET_ALERTER_ENV", "/opt/net_alerter/.env"))
|
||||||
BLE_NAMES_FILE = Path("/opt/net_alerter/ble_names.json")
|
BLE_NAMES_FILE = Path("/opt/net_alerter/ble_names.json")
|
||||||
BLE_CORRELATION_WINDOW = 60 # seconds — how far back to look for nearby BLE devices
|
BLE_CORRELATION_WINDOW = 60 # seconds — how far back to look for nearby BLE devices
|
||||||
ARP_SCAN_INTERVAL = int(os.getenv("NET_ALERTER_ARP_SCAN_INTERVAL", "30"))
|
ARP_SCAN_INTERVAL = int(os.getenv("NET_ALERTER_ARP_SCAN_INTERVAL", "15"))
|
||||||
|
|
||||||
known_devices = {} # {mac: {ip, hostname, vendor, first_seen, last_seen, infrastructure (opt)}}
|
known_devices = {} # {mac: {ip, hostname, vendor, first_seen, last_seen, infrastructure (opt)}}
|
||||||
known_lock = threading.Lock()
|
known_lock = threading.Lock()
|
||||||
@@ -1111,12 +1111,9 @@ def on_arrival(mac: str, ip: str, hostname: str = "") -> None:
|
|||||||
'last_seen': now
|
'last_seen': now
|
||||||
}
|
}
|
||||||
|
|
||||||
# Only alert for phones/wearables (MOBILE_DEVICE_OUIS) or explicitly labeled devices.
|
# Only alert for phones/wearables. Everything else is enrolled silently.
|
||||||
# Everything else is enrolled silently.
|
if not is_personal_device(mac):
|
||||||
oui = mac.replace(":", "").upper()[:6]
|
logging.debug(f"Silent enroll {mac} — not a phone/wearable")
|
||||||
normalized = _normalize_mac(mac)
|
|
||||||
if oui not in MOBILE_DEVICE_OUIS and normalized not in device_labels:
|
|
||||||
logging.debug(f"Silent enroll {mac} — not a phone/wearable OUI and no label")
|
|
||||||
update_occupancy_state()
|
update_occupancy_state()
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1156,11 +1153,10 @@ def on_departure(mac: str) -> None:
|
|||||||
logging.debug(f"Ignoring departure for infrastructure IP {dev['ip']} (MAC:{mac})")
|
logging.debug(f"Ignoring departure for infrastructure IP {dev['ip']} (MAC:{mac})")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Only alert departure for phones/wearables or labeled devices
|
# Only alert departure for phones/wearables
|
||||||
oui = mac.replace(":", "").upper()[:6]
|
if not is_personal_device(mac):
|
||||||
if oui not in MOBILE_DEVICE_OUIS and _normalize_mac(mac) not in device_labels:
|
|
||||||
known_devices.pop(mac, None)
|
known_devices.pop(mac, None)
|
||||||
logging.debug(f"Silent depart {mac} — not a phone/wearable OUI and no label")
|
logging.debug(f"Silent depart {mac} — not a phone/wearable")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check if this is part of an interface flap (suppress simultaneous mass-departure)
|
# Check if this is part of an interface flap (suppress simultaneous mass-departure)
|
||||||
|
|||||||
Reference in New Issue
Block a user