Getting Bumble - Python Bluetooth Stack going on Mac and Linux with QEMU + UTM
I tried to follow the example here: (https://github.com/google/bumble/blob/main/examples/README.md#running-run_controllerpy-with-a-bluez-host-running-on-linux) but it may need updating to change the order of running stuff and some of the params to the example file (or I need to read it more carefully).
Anyway, I had a freshly installed QEMU based VM running Debian Bookworm - got this started via the UTM app which was new to me and handy for this quick hack. Also useful for quick hacks, I used the default networking offerd by the UTM inteface (host networking or whatever it is called) to avoid having to deal with ports and routing. Installed a few bits, most relevantly bluez and socat.
On my host machine (mac) I cloned the Bumble repo, venv-ed, pipped and so on so I could run the example code.
(I am sure I ever knew why, but seemed to run ok after I ran pip inside my activated venv as : pip install -e .
)
In the examples directory:
python run_controller.py F2:F3:F4:F5:F6:F7 device1.json udp:0.0.0.0:22333,VIRTUAL_MACHINE_IP:22333
(maybe it would have worked with the hostname not IP but I didn't try)
Also I cut this down to make it a bit easier to follow - only creates the one controller - see my copy
On the virtual machine in user home dir:
socat -d -d -x PTY,link=./hci_pty,rawer UDP-SENDTO:HOST_MACHINE_IP:22333,bind=:22333
This creates a pseudo terminal that socat conveniently symlinks for us to ./hci_pty. The -d -d and -x parts are there to give us nice debug output of what is going through socat. It also create a socket on local port 22333 communicating with host port 22333 (I don't think they need to be the same port number- just should agree with whatever the previous command specified). Then it creates a bidirectional stream between the pty and the udp socket. Somehow (and I don't know how yet), that means stuff that comes thru the pty magically gets converted into datagrams and vice versa. Not entirely sure how socat knows when to send a datagram - must be some kind of additional signal on the pty or something?
As the run_controller script is emitting lots of nice-controller side output, get some host-side outputs by running btmon
sudo btmon
(has to be sudo - something like permissions to open the management socket or something - probably fixable I guess)
In the home dir again on the vm:
sudo btattach -P h4 -B hci_pty
Where -B is --bredr (aka bluetooth classic) -P H4 is protocol type (this may go some way to answer my question about conversion to datagrams) and hci_pty is the link created by socat.
Should be able to see both host side (btmon) and controller side (run_controller.py) with lots of messages suggesting they are talking to each other. For extra fun, run hcitool
commands - most of them wont work but will show some trace of the message exchange.