You should probably follow the updated howto instead.

Sometimes you want to connect to a bluetooth on the console. Likely because you screwed something up with the network or filewall settings.

You could plug in a screen and keyboard, but that’s a hassle. And maybe you didn’t prepare the Pi to force the monitor to be on even if it’s not connected at boot. Then it just doesn’t work.

Even more of a hassle is to plug in a serial console cable into the GPIO pins.

But modern Raspberry Pi’s have bluetooth. So let’s use that!

Setting up the service on the raspberry pi

Create /etc/systemd/system/bluetooth-console.service with this content:

[Unit]
Description=Bluetooth console
After=bluetooth.service
Requires=bluetooth.service

[Service]
ExecStart=/usr/bin/rfcomm watch hci0 1 getty rfcomm0 115200 vt100
Restart=always
RestartSec=10
StartLimitIntervalSec=0

[Install]
WantedBy=multi-user.target

This sets up a console on bluetooth channel 1 with a login prompt. But it doesn’t work yet. Apparently setting After, Required, and even Requisite doesn’t prevent systemd from running this before setting up bluetooth (timestamps in the logs don’t lie). Hence the restart stuff.

I also tried setting ExecStartPre / ExecStartPost there to enable Bluetooth discoverability, since something else in the boot process seems to turn it back off if I set it here.

So I did a terribly ugly solution and added this to /etc/rc.local

(
  while true; do
    sleep 20
    /bin/hciconfig hci0 piscan
  done
) &

If it works it’s not stupid?

Connecting from a laptop or something

Use the bluetooth address from hcitool dev hci0 on the raspberry pi, and bind channel 1 to rfcomm0.

rfcomm bind rfcomm0 XX:YY:ZZ:AA:BB:CC 1

This will make your laptop connect to the raspberry pi on demand. Which means it’ll take a few seconds once you actually try to connect. Alternatively you can use rfcomm connect, which connects immediately, but then continues running in the foreground.

Then you can run minicom or screen /dev/rfcomm1 115200 and be connected to a terminal.

Security

This currently has no PIN to connect over bluetooth. So anyone could just connect and start bruteforcing the password.

So I recommend setting up one-time passwords such as OTPW.

If you don’t trust bluetooth security then you should also assume that anyone can see your connection. And potentially hijack it after you log in. So log out as soon as you’re done. And if the connection mysteriously seems to “hang”, then pull the power to the device. Though it’s far from perfect.

You may also be subject to a MitM attack. This clearly needs more work.

So maybe it would be better to run a network, IP over bluetooth, and use SSH.

But adding more dependencies like that could backfire. What if the thing I broke was SSH, and that’s the reason I need the console? Then I still need to drag out console cables and such.

TODO

I should update this post when I bother setting up a bluetooth PIN. Hell, I don’t even know if not using a PIN means the bluetooth encryption is essentially plaintext.

Also I need to experiment more with making sure it’s not pairable and discoverable 24/7.

Telling bluetoothctl pairable no and discoverable no seems to do it, but this will have to be all for now.

I’ll post this even though it’s not done, since I don’t know when I’ll next get to it.

Update

Jesus christ this takes 35% CPU on a raspberry pi because rfcomm watch checks if the child process has exited once every 200 nanoseconds.

And it’s been that way since 2006.

This really shows how underused Bluetooth is. This bug has not been found for 16 years, presumably because nobody bothers with bluetooth because it’s so often full of compatability problems anyway.

For now I’ve built my own fixed version of rfcomm.