Shell Access to your Raspberry Pi over Bluetooth

I wanted to be able to shell into my RPi without the hassle of carrying a keyboard and HDMI display with me all the time - after all, that's why that thing is supposed to be portable. A  network cable was OK, but not the ideal solution because it is enough hassle to connect that thing to my laptop. My next option was finally giving my Bluetooth dongle a good use, and that's what I have been working on for a month or so.

My first idea was to set up Bluetooth networking in my RPi at boot time. That turned out to be overly complicated, especially with the useless linux-bluetooth mailing list where people don't have time to answer your questions. Then I read about  RFCOMM and learned there's a way to set up a text device using basic serial communication over Bluetooth. As much of the Bluez documentation you find around, the information in these links are a bit outdated so I'm sharing my setup for anyone who wants to try this at home.

My setup is an RPi running ArchLinux ARM (installed off from a May image), running Bluez version 5.21, with a Sabrent Bluetooth USB dongle recognized as Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode). My laptop has integrated Bluetooth and is running Sabayon Linux with Bluez version 5.18. For the initial setup, you do need network access, so you should have either wired or wireless network set up (see ArchLinux's guide for ideas).

After pairing up the devices (that information can be found elsewhere because that has not changed much in the Linux Bluetooth stack) you basically need to listen to an RFCOMM connection from boot and start a console over that connection. A console is started by running a program like getty. In my RPi, I have agetty so that is what I used to have this working. Finally, I crafted my own service file for SystemD to have this enabled on boot, this goes to /etc/systemd/system/ in the RPi.

[Unit]
Description=Virtual Distributed Ethernet

[Service]
ExecStart=/usr/bin/rfcomm watch rfcomm0 1 /sbin/agetty --noclear rfcomm0 38400 linux

[Install]
WantedBy=multi-user.target

This file just instructs SystemD to watch for a connection to the rfcomm0 device on channel 1 and, after a new connection is detected, run agetty on that device. After adding that file, you need to enable this using

# systemctl enable rfcomm

so that it will start after a reboot (or issue an additional systemctl start rfcomm to make it start without rebooting). One last bit of setup you need in your RPi is letting it know it is safe to connect through the rfcomm0 device, by adding it to the list of secure terminals at /etc/securetty. Now, from a terminal with root access in your host computer you can connect to the RPi using

# rfcomm connect rfcomm0 <bt address> 1

which should have created a device at /dev/rfcomm0 (here, <bt address> is the Bluetooth address of your RPi). This is just the device, now you need to start a terminal to read and write to that device. People recommend minicom but I had some bad experiences with it not closing properly when the device goes away. I instead used screen as follows

$ screen /dev/rfcomm0 38400

note that it does not need to run from a terminal with root access, and it should match the speed used in the system file. You will initially get a black screen, but after pressing Enter you should get a login prompt and a shell session. Enjoy!

No comments so far

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>