As stated in my post about getting winlink going with a Raspberry Pi and my TH-D74a, I wasn’t having success getting my radio connected to the Pi using bluetooth.
Well, tonight, that’s changed. I managed to do it. It’s glorious.
The first thing I figured out that I was doing wrong the other day, was in bluetoothctl
I was trying to connect
to my radio. What I needed to do was pair
. Then I ran into all sorts of other confusing things that I’m still not 100% sure on, but I’m going to try to explain them here.
Tools you’ll need:
bluetoothctl
sdptool
rfcomm
kissattach
kissparms
And of course, your text editor of choice.
In this case, these instructions are going to be specifically for Raspbian Stretch, but they might just work with other things? I’m also going to try to link to where I found instructions or assistance that helped me along the way, but I had so many tabs open and searching for stuff it’s hard to remember where I first saw things.
Anywho, here goes!
Radio setup
The first thing you’ll need to do is configure your radio for KISS over bluetooth.
- Turn Bluetooth on (menu 930)
- Turn KISS to Bluetooth (menu 983)
- Turn other Bluetooth things off (menu 98*) – This may not be strictly necessary, but I did it as a way to isolate just KISS in case there were some strange conflicts happening. I’d love to hear success/failure if other things are enabled!
And that should be that for radio configuration.
Raspberry Pi setup
First you need to modify the bluetooth service to enable the Serial Port Profile. via
sudo $EDITOR /etc/systemd/system/dbus-org.bluez.service
- At the end of the
StartCommand=
line, add-C
– This seems to enablesdptool
to actually work, apparently it has been deprecated in Bluez 5? - Add an
ExecStartPost=
line to enable the SP profile:ExecStartPost=/usr/bin/sdptool add SP
Save the file and reboot. You might only need to restart bluetoothd. YMMV.
Pair the radio with the Pi
Now you need to pair the radio with the Pi. This is the bit where I messed up before, hopefully these instructions will help you not make the same mistakes I did!
- Turn on pairing mode on the radio (menu 934)
- On the Pi:
bluetoothctl
agent on
(within the bluetoothctl shell) – This seems to be required to enable pairing.scan on
(within the bluetoothctl shell) – This scans for the radio.
Note that if your pairing mode on your radio has timed out you may need to start it over. It’s no big deal, and once scan is on your radio will eventually show up.
The radio should show up in the list:
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:A8:5A:4F Discovering: yes
[...]
[CHG] Device 4C:2C:65:EF:94:74 RSSI: -74
[CHG] Device 59:C6:33:9F:30:63 RSSI: -77
[CHG] Device 5B:1F:D6:7C:AE:6D RSSI: -91
[NEW] Device 56:D4:9A:25:4E:D8 56-D4-9A-25-4E-D8
[NEW] Device 24:71:89:A2:4A:68 TH-D74
The 24:71:89:A2:4A:68
there is the mac address of the device, and also the ID you’ll need going forward. Note that it’ll be different for your radio as MAC addresses are meant to be mostly globally unique.
Then you pair 24:71:89:A2:4A:68
(use your radio’s mac address, not mine ;-) and it will show a code on the radio and ask you if that’s correct. Don’t do like I did and type in the code, that doesn’t work. Just confirm whether or not they match!
[bluetooth]# pair 24:71:89:A2:4A:68
Attempting to pair with 24:71:89:A2:4A:68
[CHG] Device 24:71:89:A2:4A:68 Connected: yes
Request confirmation
[agent] Confirm passkey 187740 (yes/no): yes
[CHG] Device 24:71:89:A2:4A:68 UUIDs: 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device 24:71:89:A2:4A:68 UUIDs: 00001112-0000-1000-8000-00805f9b34fb
[CHG] Device 24:71:89:A2:4A:68 ServicesResolved: yes
[CHG] Device 24:71:89:A2:4A:68 Paired: yes
Pairing successful
[CHG] Device 24:71:89:A2:4A:68 ServicesResolved: no
[CHG] Device 24:71:89:A2:4A:68 Connected: no
And finally, tell the bluetooth system to trust the radio so it will automatically connect when available:
trust 24:71:89:A2:4A:68
Now your radio should be paired to the Raspberry Pi.
Note that if you’ve previously paired your radio and Pi you might run into Failed to pair: org.bluez.Error.AuthenticationFailed
. This is because your radio still thinks it’s paired to the Pi, even though the Pi doesn’t think so anymore. Go into the connect menu (menu 931), highlight the Pi, and then press Menu. This will bring up a submenu where you can “clear” the device, which makes the radio forget about it. Then try the above steps again! via TH-D74a manual
rfcomm
Ok, so this is where I got really confused. The instructions I’ve found online say to do this:
rfcomm connect 0 24:71:89:A2:4A:68 2
What does any of that even mean?
So, my understanding of it is that rfcomm
is what actually goes about creating the /dev/rfcommN
devices that you can then connect to as serial port devices. The 0
in the above command is which one you’d like to configure. As far as I can tell, this is arbitrary, just needs to not already be in use by another rfcomm
. The 24:71:89:A2:4A:68
is, of course, the mac address of the radio. And the 2
is the channel. I’m still pretty foggy on what the channel is, but I know that, at least on my radio, it needs to be 2. 1 “works”, but it doesn’t actually work. 2, however, works. YMMV. And I’d love to know more about how to even discover what this should be. UPDATE: I know why now!
This command, if it works will stay running in the foreground:
root@raspberrypi:~# rfcomm connect 0 24:71:89:A2:4A:68 2
Connected /dev/rfcomm0 to 24:71:89:A2:4A:68 on channel 2
Press CTRL-C for hangup
Once you’ve gone through all of this and have it up and running, you can use rfcomm bind
instead of rfcomm connect
and it will launch into the background and connecting to the /dev/rfcomm0
device will automatically bring up the connection to the radio (i.e. kissattach
).
axports file
The rest of this pretty much follows Pat’s excellent documentation for setting up ax25, but I’ll reproduce it here.
In the /etc/ax25/axports
file, add a line like:
wl2k MYCALL 9600 255 7 Winlink
According to axports(5)
this means:
wl2k
– the unique identifier of the port. You’ll use this in the pat config file.MYCALL
– replace this with your callsign.9600
– the speed of the interface. 9600 seems to be fine. I feel like it could be faster, maybe 115200, but it doesn’t really matter as you can’t actually send that fast over the air anyways.paclen
– the default maximum packet size. This value comes straight out of Pat’s docs.7
– the default window size. This value also comes straight out of Pat’s docs.Winlink
– a description of the interface. Doesn’t need to be Winlink. It can be literally anything.
kissattach / kissparms
Unlike in my previous post, we won’t be using /dev/ttyACM0
this time, since that’s the USB version of this. We’ll be using the device rfcomm
created above: /dev/rfcomm0
(if your first argument to rfcomm
was not 0, use that number instead). The kissparms
command will be the same.
sudo kissattach /dev/rfcomm0 wl2k
sudo kissparms -p wl2k -t 300 -l 10 -s 12 -r 80 -f n
And then you should be able to use Pat like normal!
slow first connection
Note that I’ve found the first connection to take a bit of extra time, which has many times led me to believe it wasn’t working correctly. Looking in /var/log/syslog
I see some things:
May 11 22:03:12 raspberrypi pat[1012]: 2019/05/11 22:03:12 Connecting to W7LT-10 (ax25)...
May 11 22:03:12 raspberrypi kernel: [ 1923.347019] mkiss: ax0: Trying crc-smack
May 11 22:03:22 raspberrypi kernel: [ 1933.918389] mkiss: ax0: Trying crc-flexnet
May 11 22:03:44 raspberrypi pat[1012]: 2019/05/11 22:03:44 Connected to W7LT-10 (AX.25)
(I’m running Pat under systemd which is why the logs are showing up in syslog)
Note that it takes about 30 seconds to make that first connection. Subsequent connections are much faster, I’m assuming the KISS/AX.25 bits have figured out how to talk to the radio and remember that for later:
May 11 22:05:48 raspberrypi pat[1012]: 2019/05/11 22:05:48 Connecting to W7LT-10 (ax25)...
May 11 22:05:50 raspberrypi pat[1012]: 2019/05/11 22:05:50 Connected to W7LT-10 (AX.25)
May 11 22:05:52 raspberrypi pat[1012]: WELCOME TO PORTLAND AMATEUR RADIO CLUB'S WINLINK PACKET GATEWAY - CN85RK
kissparms(8)
suggests that you can specify the crc mode using it, but I’m not sure what it need to be. The default seems to be auto
and that matches what I’m seeing the radio actually doing.
tearing down
This is all rather finicky to set up, but it’s also pretty finicky to tear down. And you need to tear it down or things will be in weird states when you try to set it up again the next time.
kissattach
launches a background process and keeps the connection to the radio active. Kill the process to exit it.rfcomm
stays in the foreground if usingconnect
. Ctrl-c to exit it out. If you’ve usedbind
instead, you’ll need torfcomm release 0
to release the device.
This can be done in really any order. rfcomm release 0
will error if kissattach
is still running, rfcomm connect
probably won’t exit until kissattach
is killed, etc. Also, if you power off the radio or get out of range, you can still clean it all up. And you’ll want to do this or the next time you’ll get some device already in use
or whatever errors.
what’s next?
So, what kinda set me down this road today is I was playing around with making it so when I plug my radio in via usb, kissattach comes up, kissparms runs, and it’s ready to roll. When I unplug the radio, it tears everything down. I actually got the tearing down bits working, but I had to manually start the systemd service that launched the kissattach
and such when plugging the radio in. Still better than doing it all manually every time. I’d still like to complete that work, if for no other reason than it provides a learning opportunity for how to use systemd. But I’d also like to do this for the bluetooth side of things. That would mean I can grab my laptop, turn my radio on, open the pat web interface, check my winlink email, and tear it all down without logging into the pi at all. That would be perfect. So, I’m going to play around with trying to do that. If/when I am successful, I will of course post about it here :)
If you’ve made it this far, thanks for reading! If this helped you, I’d love to hear about it! If you’re having trouble, I’d definitely love to hear about it and try to get you working!
Update: Channel info!
Above I mentioned I wasn’t sure why channel 2 was what it should be. I now know why. sdptool records 24:71:89:A2:4A:68
via
root@raspberrypi:~# sdptool records 24:71:89:A2:4A:68
Service RecHandle: 0x10000
Service Class ID List:
"Headset Audio Gateway" (0x1112)
"Generic Audio" (0x1203)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 1
Language Base Attr List:
code_ISO639: 0x656e
encoding: 0x6a
base_offset: 0x100
Profile Descriptor List:
"Headset" (0x1108)
Version: 0x0102
Service Name: Serial Port
Service RecHandle: 0x10001
Service Class ID List:
"Serial Port" (0x1101)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 2
Language Base Attr List:
code_ISO639: 0x656e
encoding: 0x6a
base_offset: 0x100
Profile Descriptor List:
"Serial Port" (0x1101)
Version: 0x0100
As you can see in that second stanza, it says RFCOMM
and Channel: 2
. So, that makes sense!