Anytone AT-D878UV and Bluetooth

So I got myself an Anytone AT-D878UV, and I’ve been trying to get it to do tricks.

My particular radio, and probably, most examples of this model out in the wild, comes with built-in Bluetooth. This is clearly meant for hands-free usage, primarily in cars, but my idea was to get it paired with a phone and potentially, get digital modes – NBEMS, maybe – to work with it without a cable at all. Or use APRSDroid to send APRS messages, which the radio does not do by itself, even though it does analog APRS positioning. Wouldn’t it be nice?

Well, turned out this isn’t quite as easy as you might expect. I’ll go right out and say I didn’t succeed, (see below) but I did learn some intriguing things.

The Bluetooth module used is rather bizarre and I can’t seem to find any technical information on its internals, except the interesting fact that it presents as two separate devices, a regular Bluetooth and a Bluetooth LE. That second one is used to upload firmware to the thing, for which you need an Android phone – you can find the details on this site in the section titled “BT FW upgrade for D578UV and D878UV”.1 Which is… a strange way to do it, to say the least. Something of interest can probably be gained by taking a disassembler to the firmware, but I’m not skilled at that particular kind of embedded programming. Cursory investigations, however, show a list of what looks like AT-commands, with certain interesting things in there, like +SPKGAIN or +MICGAIN, which makes me think that you can control the radio over Bluetooth, at least in some respects.

When seeking Bluetooth devices, the radio does not select for any device profile, and finds anything that is discoverable. However, pairing with an Android phone universally fails. I’ve tried every which way, and was eventually able to determine that this happens because the BT Pin code set in the radio is always sent to the device it wants to pair with, without getting the other party to prompt for it – which is fine when you’re trying to pair to a car’s handsfree kit, or any kind of Bluetooth headset, which hardly ever let you enter anything. When pairing to a phone, this simply leads to failure to pair. It would work, if you could force the phone to require a specific pin code, like 0000, and enter it on the radio, there just isn’t any user interface to let you do it.

After a substantial amount of mucking around and voodoo, this discovery permitted me to pair the radio to my Linux PC, which required Blueman, starting the pairing process from both directions at once, and a lot of quick menuing to change the pin code while it was in progress. I can’t seem to get the radio to initiate the connection, but the PC can connect to the radio’s serial port, and trying to connect causes the radio to accept it as if it were a headset.

For whatever reason, the serial port does not respond, and I don’t know what the correct settings for it are anyway.2 However, while receiving, the radio sends SCO packets, which the PC drops on the floor:

[ 4270.014483] Bluetooth: hci0: SCO packet for unknown connection handle 0

Which basically means that once I register any kind of service that will accept them and present itself as a soundcard, I’ll have what I wanted to start with, i.e. a cable-less audio connection. The documentation on how to do that has been tricky to find, however, because of the glut of stupid tutorials to do the reverse. I’ll keep working on it, but I believe it’s possible.

Unfortunately, I suspect it’s not possible to interact with the Bluetooth services in Android at a sufficiently low level to actually make a phone pretend it’s a headset.

A few hours later

There we go, a recipe to pair a Linux PC with Anytone AT-D878UV and get it to pretend to be a headset:

  1. Invoke bluetoothctl.
  2. Use this incantation in it:
discoverable on
pairable on
agent KeyboardOnly
default-agent
  1. Start pairing from the radio. It might not work on the first try, but repeat until you see something like this:
[NEW] Device 00:1B:10:2A:3C:2C Anytone
Request confirmation
[agent] Confirm passkey 096894 (yes/no): yes
[CHG] Device 00:1B:10:2A:3C:2C UUIDs: 0000111f-0000-1000-8000-00805f9b34fb
[CHG] Device 00:1B:10:2A:3C:2C UUIDs: 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device 00:1B:10:2A:3C:2C UUIDs: 0000111f-0000-1000-8000-00805f9b34fb
[CHG] Device 00:1B:10:2A:3C:2C ServicesResolved: yes
[CHG] Device 00:1B:10:2A:3C:2C Paired: yes
Authorize service
[agent] Authorize service 0000111e-0000-1000-8000-00805f9b34fb (yes/no): yes

What you’re looking for is the “Confirm passkey” prompt, and the subsequent “Authorize service” prompt, which is what lets PulseAudio pretend to be a headset. Obviously, answer yes to all prompts. You will see an extra sound card named “Anytone” which presents you with input and output ports. This should work with Direwolf, and any other reasonable amateur radio software that is compatible with PulseAudio, which is most of it.

Whether it’s possible to get any use out of the serial port or not remains a question.


  1. And I’m not linking directly because the actual page I want to reference is a PDF file. Why are most amateur radio sites so bizarre?! ↩︎

  2. They might be discovered by disassembling the above mentioned Bluteooth firmware, but like I said, this needs its own hero. ↩︎