fix(calls): drive HFP modem MAC from --device, remove hardcoded PII#134
Conversation
…tincan-i4sqk)
call_controller.py had _IPHONE_MAC_FRAGMENT = "d0_6b_78_33_46_20" committed
as a module-level constant — the operator's iPhone MAC, in plain text, in a
public repo. It also blocked any other device from using call control.
Accept device_addr in __init__ and compute self._mac_fragment from it
(lowercase, colons → underscores — matches the oFono modem path format).
An empty device_addr ("" fragment) matches any HFP modem path, preserving
the no-device fallback. Pass the --device / TINCAN_DEVICE value from __main__.
Update _make_controller() test helper with a device_addr parameter (defaults
to "D0:6B:78:33:46:20") so existing MAC-fragment fixture paths still match.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Thanks @quad341 — clean catch and exactly the right fix. Pulling the hardcoded I traced the empty- Reviewers: Qwen (local) — ok · Claude (claude-opus-4-8[1m]) — ok · Codex (gpt-5.5) — ok Verified locally + tests pass. Ready to merge — clicking the button is the only step left. |
) After #134 the MAC fragment is derived from device_addr, so the _make_controller_with_modems fixture must pass a device_addr matching the fixture modems — otherwise _mac_fragment is empty and matches every HFP modem, breaking test_non_matching_modem_not_bound. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(calls): bind the Online HFP modem, skip stale offline ones _discover_modem bound the first MAC-matching iPhone HFP modem without checking Online. With the iPhone HFP-connected on two adapters it could bind an offline modem (no VoiceCallManager) — every Dial/Answer then failed with UnknownMethod. Prefer an Online modem (sort Online-first). Proven live: with both adapters Online, tincand binds the live (dongle) modem and Dial places the call. Regression test tracked as a follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(calls): _discover_modem must prefer the Online HFP modem (tincan-a6yeb) Add §6 TestDiscoverModemOnlinePreference covering the regression fixed in the previous commit: when GetModems returns multiple iPhone HFP modems, the Online one must be bound (an offline modem has no VoiceCallManager → Dial fails with UnknownMethod). Four cases: online wins listed-second, online wins listed-first, offline-only falls back to first candidate, non-matching MAC is ignored. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: release gate PASS for tincand-prefer-online-modem * test(calls): thread device_addr through the modem fixture (adapt to #134) After #134 the MAC fragment is derived from device_addr, so the _make_controller_with_modems fixture must pass a device_addr matching the fixture modems — otherwise _mac_fragment is empty and matches every HFP modem, breaking test_non_matching_modem_not_bound. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What this changes
CallControllerpreviously had_IPHONE_MAC_FRAGMENT = "d0_6b_78_33_46_20"as a module-level constant — the operator's iPhone Bluetooth MAC, in plain text, committed to a public repository. This also made call control device-specific: any device with a different MAC would never match and calls would silently fail.The constant is removed.
CallController.__init__now accepts adevice_addrparameter and derivesself._mac_fragmentat construction time (addr.lower().replace(":", "_")— matches oFono modem path format).__main__.pypassesargs.device or os.environ.get("TINCAN_DEVICE", ""), so the runtime device selection already in place is now threaded through to call control.An empty
device_addrproduces an empty fragment, which matches any HFP modem path — the prior no-device behavior is preserved as a fallback.Review notes
tincand/call_controller.py:_IPHONE_MAC_FRAGMENTconstant removed;__init__gainsdevice_addr: str = ""param;_is_hfp_iphone_modemand_teardown_call_audioupdated to useself._mac_fragment.tincand/__main__.py:CallController(service, contact_store, device_addr=_device_addr)— one-line change.tests/tincand/test_call_controller.py:_make_controller()gainsdevice_addrparam (default"D0:6B:78:33:46:20") so existing fixture paths still match without changing all call sites.device_addr=""causesself._mac_fragment=""which matches any HFP modem path via"" in path. Not reachable when--deviceis set. Follow-up: tincan-kf2h0.Test plan
python -m pytest tests/ -q)release-gates/call-controller-device-mac-i4sqk-gate.md🤖 Deployed by actual-factory