Skip to content

add MacOS support - #24

Open
alabalag1 wants to merge 3 commits into
aaronsb:mainfrom
alabalag1:main
Open

add MacOS support#24
alabalag1 wants to merge 3 commits into
aaronsb:mainfrom
alabalag1:main

Conversation

@alabalag1

@alabalag1 alabalag1 commented Jul 22, 2026

Copy link
Copy Markdown

Summary

  • Adds macOS support to the Python implementation: pybmap now talks BMAP over native IOBluetooth RFCOMM (via PyObjC) instead of Linux AF_BLUETOOTH sockets, and discovers paired devices through IOBluetoothDevice.pairedDevices() instead of bluetoothctl.
  • Rust and C++ builds now compile and test cleanly on macOS by stubbing the Linux-only BlueZ paths — they fail loudly with "use the Python CLI" rather than failing to build.
  • Linux behaviour is unchanged: every platform-specific branch is selected at import/compile time, and the existing Linux code paths were moved, not modified.

Changes

Python (python/pybmap/) — the real functional change.

  • transport.py: split into LinuxRfcommTransport (the existing socket code, moved verbatim) and a new MacOsRfcommTransport. RfcommTransport is bound to one of them on sys.platform, so all callers are untouched. The macOS path does an SDP query, opens the baseband connection, opens RFCOMM channel 2, and pumps NSRunLoop while a delegate collects inbound data on a queue — this is what IOBluetooth requires instead of a blocking socket. Same send_recv(packet, drain=) contract, same BmapConnectionError/BmapTimeoutError.
  • discovery.py: same split. macOS enumerates paired devices and matches product IDs against the existing catalog; connected devices are still preferred over paired-but-disconnected, same as Linux.

Rust / C++ — build-fix only, no macOS transport.

  • cpp/transport.cpp and cpp/discovery.cpp get __APPLE__ branches: the transport constructor throws with a message pointing at the Python CLI, discovery returns nullopt. CMakeLists.txt skips linking libbluetooth on Apple.
  • Tests added on both sides asserting exactly that behaviour (cpp/tests/test_transport.cpp, plus #[cfg(target_os = "macos")] tests in rust/src/{transport,discovery}.rs), so the stubs can't silently rot into something that looks supported.

Tooling

  • macOS_install.sh: installs PyObjC and symlinks bosectl into /usr/local/bin.
  • Makefile: make test installs PyObjC into the venv on Darwin only, so the suite runs out of the box on both platforms.
  • bosectl: realpath instead of abspath so the launcher resolves python/ correctly when invoked through the symlink the installer creates.
  • README: platform badge/prose, macOS prerequisites, install section, updated test counts.

Device Impact

Transport-layer change only — no protocol or per-device logic was touched, so this is device-agnostic in principle. It does need real hardware on macOS to confirm the IOBluetooth path, since none of that is exercisable in unit tests.

  • QC Ultra 2 — verified on macOS against real hardware
  • QC35 — untested on macOS; no reason to expect a difference, but unverified
  • New device: ___

Linux users are unaffected; the Linux socket code is byte-identical, just relocated into a class.

Checklist

  • Python, Rust, and C++ implementations stay in sync — with the caveat that macOS support is Python-only by design. Rust and C++ get compile parity and explicit "unsupported" errors, not a second and third IOBluetooth transport. Happy to go further if you'd rather all three be functional on macOS.
  • Tests pass (make test) — on macOS 15 (Darwin 25.5): 121 Python passed / 18 skipped (integration tests needing --integration), 63 Rust, 54 C++. Not re-run on Linux — worth a CI check, since the Linux paths were relocated even though not edited.
  • Protocol notes updated in NOTES.md — not applicable, no protocol changes.
  • Architecture docs updated — not done. docs/architecture.md still describes the transport layer as Linux/BlueZ only. Tell me if you want that in this PR or as a follow-up.

‼️ Generated with AI (Claude Code)

@alabalag1
alabalag1 requested a review from aaronsb as a code owner July 22, 2026 14:33
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.

1 participant