Radio Firmware tool
| Manufacturer | Radio | Fw Write | Fw Wrap | Codeplug Read | Codeplug Write | Tried on a radio |
|---|---|---|---|---|---|---|
| TYT | MD-2017, MD-9600, MD-UV380, MD-UV390, MD-390, MD-380, MD-446, MD-280 | ✅ | ✅ | ✅ | ✅ | ❌ |
| Baofeng | DM-1701 | ✅ | ✅ | ✅ | ✅ | ✅ all four |
| Baofeng | DM-1801, RD-5R, BF-5R | ✅ | ✅ | ❌ | ❌ | ❌ |
| Radioddity | GD-77, GD-77S | ✅ | ✅ | ❌ | ❌ | ❌ |
| Baofeng | UV-5R, UV-82, UV-6, F11 (cable) | ❌ | ❌ | ✅ | ✅ | ❌ |
| Baofeng | UV-5R Mini, UV-5G Mini, UV-17Pro, UV-17ProGPS (Bluetooth) | ❌ | ❌ | ✅ | ✅ | ✅ UV-5R Mini read only |
| Connect Systems | CS800, CS800D | ❌ | ✅ | ❌ | ❌ | ❌ |
| Ailunce | HD1 | ✅ | ✅ | ❌ | ❌ | ❌ |
| Yaesu | FT-70D | ✅ | ✅ | ❌ | ❌ | ❌ |
Fw = Firmware
Pre-built binaries are attached to each release.
cd rust
cargo build --release
./target/release/radio_tool --helpOn Linux you need libudev-dev libdbus-1-dev pkg-config. Without root, USB radios need the udev rules in rust/udev/99-radio-tool.rules.
cargo testCI also runs cargo fmt --check and cargo clippy -- -D warnings.
radio_tool with no arguments, or with one file, opens a window. On the left are the radios: USB ones are found by scanning, a Baofeng on a cable or Bluetooth needs its model picked. On the right are cards for what that radio can do. Writing a codeplug, flashing, setting the clock and restarting each ask before they start. A firmware or codeplug file dropped on the window is described, a codeplug with its channels.
| path | what it holds |
|---|---|
rust/crates/radio-tool |
the command line tool and the window |
rust/crates/firmware |
firmware container formats and the XOR ciphers |
rust/crates/codeplug |
codeplug (channel memory) formats |
rust/crates/device |
USB, HID, serial and Bluetooth protocols |
test/firmware |
sha256 manifest of the vendor firmware corpus, and recover.py to fetch what survives |
references/ |
third party sources the protocols were checked against, with their licences in manifest.tsv |
The corpus test round trips real vendor firmware and skips when none is present:
python3 test/firmware/recover.py --download
cargo test -p firmware --test corpusRun against a real radio:
| radio | over | result |
|---|---|---|
| Baofeng DM-1701 | USB DFU | identify, firmware write, codeplug read and write, bootloader dump, clock, reboot all work |
| Baofeng UV-5R Mini | Bluetooth | scan and codeplug read work |
| Radioddity GD-77 | USB HID | detected in bootloader mode. Firmware write is untested |
Tested against fakes only, never against a radio: codeplug write for the UV-17Pro family, the TYT HID protocol for SGL radios, YMODEM for the Ailunce HD1, H8SX for the Yaesu FT-70D, and UV-5R codeplug read over a cable.
The flags below are the original interface and still work. New use is better served by subcommands (radio_tool help), where anything that writes to a radio only checks the file unless given --write. Examples: fw-info, wrap, unwrap, flash, usb-read-codeplug, usb-write-codeplug, read-codeplug, write-codeplug, ble-scan, models.
This tool moves a codeplug to and from the radio and does not edit it. For the DM-1701 family dmrconfig does the editing:
radio_tool usb-read-codeplug --output dm1701.img
dmrconfig dm1701.img > dm1701.conf
$EDITOR dm1701.conf
dmrconfig -c dm1701.img dm1701.conf
radio_tool usb-write-codeplug --input dm1701.img --writeUsage:
radio_tool [OPTION...]
General options:
-h, --help [=<command>(=)] Show this message
-l, --list List devices
-d, --device <index> Device to use
--port </dev/ttyUSB0> Serial port to use, for radios which clone
over a serial cable
--ble <00:11:22:33:44:55>
Bluetooth LE address, for radios which
clone over Bluetooth
--ble-adapter <hci0> Bluetooth adapter to use, if this machine
has more than one
-i, --in <file> Input file
-o, --out <file> Output file
Programming options:
-f, --flash Flash firmware
-p, --program Upload codeplug
--read-codeplug Download the codeplug from the radio to --out
Firmware options:
--fw-info Print info about a firmware file
--wrap Wrap a firmware bin (use --help wrap, for more info)
--unwrap Unwrap a fimrware file
--make-xor Try to make an XOR key for the input firmware
All radio options:
--info Print some info about the radio
--get-status Print the current DFU Status
TYT Radio options:
--get-time Gets the radio time
--set-time Sets the radio time
--dump-reg <register> Dump a register from the radio
--reboot Reboot the radio
--dump-bootloader Dump bootloader (Mac only)
Serial radio options:
--list-serial-models List the models which can be used with --port
or --ble
--list-ble Scan for Bluetooth LE devices in range
Codeplug options:
--codeplug-info Print info about a codeplug file
radio_tool -d 0 -f -i new_firmware.binThese radios clone over a plain USB serial cable, which cannot be told apart from any other serial cable, so the port and the model are given explicitly. Turn the radio off, seat the cable fully in the mic/speaker jack, then turn the radio back on before running:
radio_tool --port /dev/ttyUSB0 --radio UV5R --read-codeplug -o my_radio.img
radio_tool --codeplug-info -i my_radio.imgThe image is byte compatible with a CHIRP .img for the same radio, so it can be opened
in CHIRP as well. Run
--list-serial-models for the accepted --radio values.
The UV-17Pro family, which includes the UV-5R Mini and UV-5G Mini, has no programming cable at all and clones over Bluetooth LE. Enable Bluetooth on the radio, then find it and read it:
radio_tool --list-ble
0C:64:8F:1E:00:75 walkie-talkie
radio_tool --ble 0C:64:8F:1E:00:75 --radio UV5RMINI --read-codeplug -o my_radio.imgUse --ble-adapter hci1 if the machine has more than one Bluetooth adapter. A BLE link
answers far more slowly than a cable, and a radio only advertises intermittently, so
finding it can take several seconds.
radio_tool --wrap -o wrapped.bin -r DM1701 -s 0x0800C000:main.binOutput file in this case is a file prefix, the filename will be unwrapped_0x0800C000 and others if you have
firmware will more than one segment
radio_tool --unwrap -i wrapped.bin -o unwrapped 
