Tagged: rpi

Raspberry Pi Zero 2, Slackware and Bluetooth PAN

(Slackware 15 Sarpi/AARCH64)

I wanted a portable machine to use with an iPad. I like my iPad, it's great for lots of things, but not for real computing. The solution I'm working on is to have a Raspberry Pi Zero 2 that I can connect to from the iPad to be my development server.

The Pi Zero 2 is attractive as a minimal/constrained environment that's relatively easy on power. I can run it from a small battery. I could use a more powerful pi but I think that needing a heat sink is a design flaw. I'm using commmand line tools, like tmux, vim, git, programming languages, apache, so I don't need much power. I haven't got around to looking at other single board computers.

Newer iPads can apparently use their usb C connection with a live video capture app to show the hdmi output of the pi directly, turning the ipad into a monitor. This is cool, but I don't have one.

When I'm at home, I just connect to my local wifi lan, and can ssh from my computer, but public institutional networks often don't allow machine to machine connections, and even if they did, I need to get to the pi to establish a new connection anyway.

The pi can act as a wifi network access point, and I could use that to connect the iPad to it-- but then I wouldn't have internet.

It's possible to use the USB-OTG functionality to turn the pi into an ethernet gadget, which I could connect to the iPad via a usb CCK. But I might want to use the pi's USB for other things.

So I'm using bluetooth Personal Area Network functionality. The pi hosts the bluetooth pan, and gives the iPad an IP when it connects. Both devices can also be connected to a local wifi network if that's available. Getting this to work took a while.

I'm running Slackware on the pi. This effort may have been easier with a systemd based distribution. I've been using Slackware on and off for 30 years, and I like it. So.

There were a few steps to get this working. I'm not sure that what I've come up with is the best way of doing it, or that there's not some extraneous stuff, but I've visited plenty of rabbit holes and have come back out again, and this is working for me, unlike the dozen "solutions" I tried out.

As usual with linux, the internet is awash with howtos, scripts and information, which may have been valid for previous versions of the various bits of software or systems involved, but which are now, at best, clues.

What needs to happen

Here's what worked for me

I tried to do things as simply as possible. This (Wall's true laziness, not false laziness) seems to embody the essence of Slack.

Bluetooth

Create /etc/dbus-1/system.d/bluetooth.conf by copying /usr/share/dbus-1/system.d/bluetooth.conf and add 2 policy lines in the policy section.

<allow send_interface="org.bluez.Network1"/>
<allow send_interface="org.bluez.NetworkServer1"/>

I think this overrides the default setup and allows the rest to work.

Modify /etc/bluetooth/main.conf to change the name of the connection. It would be nice if class worked as well, but it doesn't seem to?

Modify /etc/rc.d/rc.bluetooth to add a dbus_net function. This will enable networking (nap) on the bluetooth adapter using bridge br0.

dbus_net(){
    dbus-send --system --dest=org.bluez /org/bluez/hci0 \
    --type=method_call org.bluez.NetworkServer1.Register \
    string:"nap" string:"br0"
}

I tried to put this dbus_net call in the start function-- it worked when restarting, but not when booting. Some timing issue? So I call it when doing rc.bluetooth restart, and call it explicitly from rc.local.

rc.bluetooth
    ...
    dbus)
      dbus_net
      ;;
    restart)
      stop
      sleep 1
      start
      dbus_net
      ;;
    ... 

rc.local make executable and set last line /etc/rc.d/rc.bluetooth dbus

chmod +x /etc/rc.d/rc.bluetooth to start bluetooth services on boot

Use bluetoothctl to scan for my iPad (or any device), then pair trust and connect. This is an text driven environment, there's help available. When this is done you can connect and disconnect from the device. Mildly satisfying, if not particularly useful.

Network

Add the dummy interface by editing rc.modules.local, add /sbin/modprobe dummy at the end, and make it executable. Loading the dummy interface will automatically create dummy0

Modify /etc/rc.d/rc.inet1.conf to enable the bridge br0. There's a bridge section in that file.

IFNAME[0]="br0"
BRNICS[0]="dummy0"
IPADDRS[0]="192.168.168.1/24" or whatever

Dnsmasq

chmod +x to /etc/rc.d/rc.dnsmasq to run this small dhcp server. Modify /etc/dnsmasq.conf to enable the bridge interface and set the dhcp-range you want to advertise. There's a section of this file where it talks about enabling dhcp on specified interfaces

interface=br0

then later in the file

dhcp-range=192.168.168.2,192.168.168.10,255.255.255.0,12h

The interface name br0 (matches what I'm using in dbus-send). The interface range just has to be on the same subnet as the br0 interface. A bluetooth pan can only connect up to 7 clients, so that's plenty

To be able to use friendly names (ie pi.local) for the pi, rather than IPs you can setup the avahi mDNS service. I already had this setup for connecting to the pi over wifi. This isn't part of Slackware. I used the slackbuild to install this and it's dependencies. It installs the /etc/rc.d/rc.avahidaemon and /etc/rc.d/rc.avahidnsconfd, and is run from rc.local.

iPad

The iPad will aggressively close apps, which plays havoc with the connection if you want to switch out to a browser or something. Termius supports mosh: the mobile shell which deals with this issue. Mosh can be installed from slackbuilds, but it took a day to compile on the pi -- there's lots of dependencies, and Google's protobuf3 takes the bulk of the time.

I use the free version of Termius to connect to the pi with SSH. I'd happily pay for it if it weren't subscription software. I may get around to compiling Blink at some point, since it also offers Mosh. The bluetooth connection works straight away when the pi is connected to my home network (iPad isn't), but I find it takes a while for the connection to establish when I'm in a different environment and I haven't yet worked out why. It sometimes takes a couple of tries. It's likely that I'm impatient, and haven't given the pi time to start up. Time in fact may be the issue, since the pi will try and get the time from the network after booting.

Some background info

...that may be useful when my solution doesn't work for you.

Bluetooth

Slackware uses bluez 5.something, which doesn't have great documentation. There's configuration in /etc/bluetooth and /etc/default/bluetooth. /var/log/syslog has lots of bluetooth lines.

The /etc/default/bluetooth file defines the bluetooth interface name as hci0. I didn't find any use for the sdpoptions.

/etc/bluetooth/main.conf is the main bluetooth file, which seems to allow setting the name and the class of the device. Class 0x020100 indicates the Networking service being offered by a computer. Setting this in main.conf doesn't work. It took ages to get the bluetooth device to offer networking service. I'm using the NAP network access mode, though for my purposes GN Group Network Controller or PANU - PAN User might be more appropriate.

There is a /etc/bluetooth/network.conf file, but it doesn't seem to do anything useful. bluetoothd in debug mode whinged about the link security setting, but changing it didn't seem to help anything?

Stopping bluetooth (if it's already running, but not working) using /etc/rc.d/rc.bluetooth stop allows us to do things bit by bit. This is the great thing about Slackware-- no magic. I can work through the rc files step by step and try and work out what they're doing to get an idea of how the system fits together. BUT -- just because it works step by step, doesn't mean that it works on rebooting (as I found out, more than once after thinking I'd fixed it). I'm guessing there's some timing issues?

bluetoothd -n -d runs the bluetooth daemon in the foreground, with debug information. This shows the name being set, and the class being at least read, as well as the various bluetooth plugins being loaded. But after it runs hciconfig -a shows it picked up the name, but the class is set to 0x000100, rather than the 0x020100 that I specified in main.conf.

Some sources said this was because of the hostname plugin, but running bluetoothd with --noplugin=hostname didn't make any difference to this sad fact. Debug info also ends up in /var/log/debug for reference.

I never did find out what was turning it off, but I found the dbus command that, once the network bridge was setup, would turn it on.

To get the networking service I ended up using a dbus-send command. Bluetoothd communicates via dbus. There must be some other way of setting it up, but I couldn't find it.

dbus-send --system --dest=org.bluez /org/bluez/hci0 --type=method_call org.bluez.NetworkServer1.Register string:"nap" string:"br0"

nap is the network service provile, and br0 is the bridge interface to connect it to.

After the dbus-send command hciconfig -a shows the class as 0x020100 and the Networking service.

The policy setup for the dbus system is in /usr/share/dbus-1/, but can be overridden with entries in /etc/dbus-1/, so I've copied system.d/bluetooth.conf and added the 2 lines for networking.

Some sources had sdptool add nap before running the dbus-send but I didn't find this made a difference, and i never got sdptool to return anything useful?

btmon shows info being passed back and forth, and can show some errors, like Server error, bridge not initialized and BNEP server cannot be added. I actually dug into the bluez source to see what was causing the error, since most of the text was cut off.

Networking

The ip command can set up stuff; you can add/remove and show interfaces and addresses easily.

Network configuration is in /etc/rc.d/rc.inet1.conf . The Raspberry Pi Zero 2 doesn't have an ethernet interface, so eth0 isn't used.

I really don't understand how the bridging works -- I think the idea is for a NAP, you want to bridge different networks. I think it's a bit trickier when dealing across wifi and ethernet -- but I'm not doing that. In any case, the network service expects an interface to exist as named by the dbus-send command and it creates interface points and adds them to the bridge as required. After the connection bnep0 will be visible. Each new device will get it's own interface added to the bridge - bnep1, bnep2 etc.

For a while I tried to setup a virtual interface using dummy, then tun, then tap, thinking there needed to be such a thing to be a bridge endpoint. The raspberry pi zero doesn't have a physical ethernet interface; putting eth0 in as the bridge point shows errors when running rc.inet1 restart -- but it seems to work, and it doesn't work if there's nothing there. I kept at it, and found that I didn't need to configure a dummy interface, just adding the dummy module in rc.modules.local will create dummy0, so I'm using that for the bridge, and not getting any errors.

For the connecting interface to automatically be assigned an IP I used dnsmasq, since it's already supported in Slackware.

After connecting the iPad to the pi with bluetooth, there's an ethernet option pop up. While getting this working, it would pop up then dissappear again. If you haven't set up DHCP, you can set the iPad IP manually by clicking on it and going into the PAN settings.

When connected, you can visit the pi's web server (if you have one) by IP or by name if using avahi mDNS.

Dbus

Dbus is a way for programs to send messages to each other using a standard interface. Bluetoothd implements a dbus inteface. The dbus-send command used above just instructs Bluetoothd to provide the Network service (nap) using a particular bridge interface (br0)

I tried to get this to be called by the bluetooth start function -- it seemed to work, but when I rebooted, hciconfig -a didn't show the Networking service. So I call the function from restart, and explicitly from rc.local.

End thoughts

As usual with this sort of problem, I was tempted to say screw it and install a different distro. But the nice thing about Slackware is that the init setup is straightforward -- the inittab can be followed, and I can see what each of the runlevels is calling and how. I can stop services and try to bring them up manually and see what's affected. It's possible, if slow going, to work stuff out, and gradually refine the googling to get somewhere.

Good luck!

References

That were at lease somewhat useful.

Tags: rpi

Date created: 2025-02-14

Mobile computing (draft)

I've spent a few days doing a deep dive into setting up the Raspberry Pi Zero W to use with my iPad. I haven't owned a laptop for a few years, and I want a mobile console environment to program in. My 6th gen iPad is too locked down for some things, but will work fine as a terminal with a bluetooth keyboard.

Things I want to be able to do

Desiderata

I installed Raspberry Pi OS Lite (bookworm) on the pi without any fuss, but then had to spend a few days getting up to speed with the differences from other distributions I'm more familiar with, and the changes from previous versions: systemd, Network Manager, changes to boot filesystem.

There's no shortage of online information. Unfortunately, most of it is outdated, and much of it is of the quick fix -- "Here run this script and you don't have to understand anything" variety. That's fine for an appliance, but not when I want a flexible computing setup.

I successfully set it up as an ethernet gadget, following this info. I liked the idea of a single cable connection. But I couldn't get it to work unless I was powering my (6th gen) iPad through the CCK. It probably works better with newer iPads with their USB C connectors. And using the pi as an ethernet gadget prevents me using the USB port for anything else, so although this is cool, I've abandoned it.

I've setup network manager to try to connect to one of my two home wifi networks (they used to be bridged, but are now separate), and if that fails, to start up an adhoc network.

I found this excellent writeup, which uses Bluetooth PAN to connect the pi to the ipad. This is great; I can power the pi with a slim battery, and the usb port is free. But so far I haven't found out how to set it up to work with Network Manager, so it uses separate systemd startup files. Connecting over pan means I can use the internet from the pi (ie to download some missing software). Apparently this is quite insecure. Oh, well.

Software

On the Pi, mosh (like ssh), tmux and Vim (which I've been using Vim for years), rclone (dropbox syncing)

Mosh is recommended because the iPad will aggressively suspend background apps. Mosh allows it to reconnect where it left off so that this isn't noticeable.

Tmux is great, allowing multiple virtual terminals over a single connection. Particularly useful to split the window between Vim and a shell prompt.

Vim is my text environment. I have over a thousand pages of notes in VimWiki.

rclone is a handy utility for on demand dropbox folder syncing. When I have an internet connection I can pull and push any folders from/to Dropbox.

On the iPad, Termius is the terminal I'm using. It supports mosh. There is a paid version, but the free version meets my needs.

Blink is recommended by some, but I don't do subscription software. It's open source, so I might try to compile it myself -- though that's a different project.

Tags: computing, rpi

Date created: 2024-11-21

Raspberry Pi as iPad host

I could use a raspberry pi as a server, to do web development on iPad.

I could jailbreak the iPad, but it's too much trouble.

The rpi is good, but I don't want to carry a keyboard and screen around.

So I can setup the rpi with TinyCore and openSSL, and ssh to it from iPad using Diet Codea.

TinyCore is minimal and should run fast.

rpi can host an ad-hoc network, though I'd also want to connect to the internet to look stuff up.

Tags: rpi

Date created: 2013-08-13