Build a P25/DMR Cross-Mode Bridge

Quoted from, credit to the admin of the original page
This tutorial will serve as a BASIC guide to building your own cross-mode bridge from P25 to/from a Brandmeister DMR talk group. This tutorial is based on a Raspberry Pi 3B+ hardware, however it should be very similar on Ubuntu 18.04 or other current flavors of Linux. 

Software packages include: DVSwitch from N4IRS: and the P25 Client software from G4KLX at

If you’re not comfortable with compiling source code, setting file permissions, or modifying firewalls/port-forwarding – Google for these things! There is plenty of help available for your specific software and hardware…

Terminal commands are in Italics, and must be run one line at a time…


You'll be installing and configuring several software components that all play together to transcode a DMR data stream to P25 and vice-versa using DVSwitch The DVSwitch packages support other modes as well (NXDN, YaesuFusion, D-Star), and while this document does not cover them, they do not seem wildly different from what we're doing here.

So - let's get on with it!


P25Reflector<->P25Gateway<->AnalogBridgeP25<->AnalogBridgeDMR<->MMDVMHost<->BM Master


We are going to build from the P25 side to the Brandmeister side. The first component is the P25 Reflector. First, download the P25Clients source code from G4KLX from 


With the method of your choice, download and extract the client software to its default path (P25Clients-master) in /Downloads, and from there. Open a terminal window and.

cd /P25Clients-master/P25Reflector
ls -la

Confirm that you have source files, and they're in the right place: there should be a “P25Reflector.cpp” in this folder.

Copy the ini file to its new home:

sudo cp P25Reflector.ini /etc

Tweak the .ini file - Change “Daemon=1” to “Daemon=0”

sudo vi /etc/P25Reflector.ini

Save and Exit the editor.

Compile (Make sure you’re in ~/Downloads/P25Clients-master/P25Reflector)


Copy the compiled executable file and script to their new location: 

sudo cp p25Reflector /usr/local/bin/

sudo cp /usr/local/bin/

sudo chmod +x /usr/local/bin/

Test it!

cd /usr/local/bin
sudo ./ start /etc/P25Reflector.ini &

On first run, you should see something like this (ignore the error)

P25R Start

Leave this terminal window open for now... it should show repeating "No Repeaters Linked" messages... 


P25Gateway creation is very similar to the P25Reflector. Open a new terminal window and:

cd /P25Clients-master/P25Gateway
ls -la

Confirm that you have source files, and they're in the right place: there should be a “P25Gateway.cpp” in this folder.

Copy the ini and P25Hosts file to their new home:

sudo cp P25Hosts.txt /etc

sudo cp P25Gateway.ini /etc



Copy the P25Gateway to its new location: 

cp P25Gateway /opt/P25Gateway/


Steve, N4IRS has made installing and configuring his tools very easy. Follow his instructions for adding the software repository and install the Analog Bridge and the MMDVM_Bridge using his instructions at

The 'short version' from Steve's notes: 

cd /tmp
chmod +x install-dvswitch-repo
 apt-get update


sudo apt-get install dvswitch

You should now have a P25Gateway, Analog_Bridge, md380-emu and MMDVM_Bridge folder in /opt - confirm that: 

ls -la /opt

Copy the MMDVM_Bridge.ini to /etc

cp /opt/MMDVM_Bridge.ini /etc

Understanding the next few steps are critical - you'll recall from the Architecture section that 2 instances of Analog_Bridge are needed. We are going to create those and their associated .ini files now.

cd /opt/Analog_Bridge
cp Analog_Bridge Analog_Bridge_p25
cp Analog_Bridge.ini /etc/Analog_Bridge_p25.ini
cp Analog_Bridge Analog_Bridge_DMR
cp Analog_Bridge.ini /etc/Analog_Bridge_DMR.ini


You should now have all of the software installed. Let's make sure the ini files that were copied to new folders have landed where we intended. The following files should be in your /etc folder (there will be others - including other .ini files...)

List the .ini files in /etc: 

ls -la /etc|grep .ini
  • P25Reflector.ini
  • P25Gateway.ini
  • Analog_Bridge_DMR.ini
  • Analog_Bridge_P25.ini
  • MMDVM_Bridge.ini
Should all be there... 

Likewise, the following FILES should be in these locations: 
  • /usr/local.bin/P25Reflector/
  • /usr/local.bin/P25Reflector/P25Reflector
  • /opt/Analog_Bridge/Analog_Bridge_DMR
  • /opt/Analog_Bridge/Analog_Bridge_P25
  • /opt/MMDVM_Bridge/MMDVM_Bridge


There's no nice way to say this - the following section will require tedious, exacting, precise trial and error. :) The various components installed need to communicate with each other and do so via a collection of ports and everything needs to line up. It can be tricky. Remember we're working from P25 to DMR, and will 'follow the data' through each step. Thankfully, Steve N4IRS makes this as easy as possible - but it does require some very precise changes. You may have noticed during installation that we copied all of the .ini files to /etc - make sure you're editing these, and not the original files from /opt or /usr/local/bin. Worst case, if an edit goes bad you can always copy the default version back into /etc and start again. P25Reflector.ini needs very little tweaking, and we did that at install. (Changed Daemon from "1" to "0"). 


sudo mkdir /var/log/P25Gateway
sudo mkdir /var/log/P25Reflectorcp
sudo mkdir /var/log/mmdvm


 sudo vi /etc/P25Gateway.ini

Callsign={Your callsign here}
Daemon=0 <--CHANGE "0"

[Id Lookup]


HostsFile1=/opt/P25Hosts.txt <--CHANGE to /etc/P25Hosts.txt
Startup={Your P25 Reflector Talkgroup here}


 sudo vi /etc/P25Hosts.txt

Determine what P25 Talkgroup you will use, and supply that in the P25Hosts.txt file in this format: TG(tab)


Save and exit. 


Lets test connectivity between the gateway and the reflector. You should still have the P25Reflector running in a terminal window, and it's probably reporting "No Repeaters Linked" every several seconds. We will start the P25Gateway and see if it connects to the P25Reflector:

cd /opt/P25Gateway
./P25Gateway /etc/P25Gateway.ini & 

You should see a process ID number - not an error message. Gateway Start 

Now - in the P25Reflector terminal session, you should see the connection after a few seconds ('P25GATEWAY is my 'Callsign' in the .ini)Reflector Start

"Can't get MMDVM user" error? I've heard reports that the Daemon setting in the P25Gateway file may actially need to be 0


 sudo vi /etc/Analog_Bridge_P25.ini

The Analog Bridge files only need a couple of modifications - only those lines are listed below: 

decoderFallBack = true     
useEmulator = false   

server =
fromDMRPort = 34100 {IMPORTANT}
toDMRPort = 34103 {IMPORTANT}
ambeMode = P25 {IMPORTANT}
minTxTimeMS = 2000
gatewayDmrId = {YOUR DMR-ID+2-Digits. See MMDVM_Bridge notes}
repeaterID = {YOUR DMR-ID+2-Digits. See MMDVM_Bridge notes}
txTg = {YOUR P25 TALKGROUP from P25Hosts.txt HERE}
txTs = 1 
colorCode = 1

server =
toASLPort = 34001 {IMPORTANT}
fromASLPort = 32001 {IMPORTANT}
aslAudio = AUDIO_UNITY
agcGain = -20
dmrAudio = AUDIO_UNITY
dmrGain = 0.35


 sudo vi /etc/Analog_Bridge_DMR.ini

decoderFallBack = true     
useEmulator = false   

server =
fromDMRPort = 31100 {IMPORTANT}
toDMRPort = 31103 {IMPORTANT}
ambeMode = DMR {IMPORTANT}
minTxTimeMS = 2000
gatewayDmrId = {YOUR DMR-ID+2-Digits. See MMDVM_Bridge notes}
repeaterID = {YOUR DMR-ID+2-Digits. See MMDVM_Bridge notes}
txTg = {IMPORTANT - Brandmeister Talkgroup Number to link}
txTs = 1 
colorCode = 1

server =
toASLPort = 32001 {IMPORTANT - must match FROM port in P25.ini}
fromASLPort = 34001 {IMPORTANT -must match TO port in P25.ini}
aslAudio = AUDIO_UNITY
agcGain = -20
dmrAudio = AUDIO_UNITY
dmrGain = 0.35


 sudo vi /etc/MMDVM_Bridge.ini

The MMDVM Bridge connects to the BrandMeister master server, and is essential a 'virtual' hotspot. What you configure here will appear in your BM Dashboard at A note about DMR-IDs: You do NOT need to register for a new DMR-ID for this hotspot. Simply append 2 digits to your existing ID, and BM will know what to do. Example: If my DMR-ID is 1234567, I can use anything from 123456701 through 123456799 for the MMDVM_Bridge ID, or any hotspot. 

MMDVM_BRIDGE is another large file - but only a few lines need to be tweaked from default. 

Callsign={YOUR CALL}
Id={YOUR DMR-ID+2-Digits}

Enable=1 {IMPORTANT}

Enable=1 {IMPORTANT}

[DMR Network]
Enable=1 {IMPORTANT} {IMPORTANT - Set your BM Master per your region!)

[P25 Network]
Enable=1 {IMPORTANT}


Confirm your MMDVM_Bridge connects to Brandmeister. 

cd /opt/MMDVM_Bridge

./MMDVM_Bridge /etc/MMDVM_Bridge.ini &

After a few seconds, you should see "MMDVM_Bridge is Running", followed by a successful connection to the BM master. Log onto your Brandmeister dashboard, and have a look in "My Hotspots" for your new 'hotspot'. 

If this fails - double check the MMDVM_Bridge.ini file....


Once you've verified that the MMDVM_Bridge has connected to BrandMeister - you need to configure a static talk group for your hotspot. This will push the DMR traffic from BM to your hotspot... Use the same DMR talkgroup that you chose in the ANALOG_BRIDGE_DMR.ini file.... 


Optional step for setting up a hotspot running Pi-Star to connect to your bridged Talkgroup. You'll need the IP address or FQDN that Hotspots will use to access your reflector. 

SSH into your Pi-Star via the method of your choosing, and set the filesystem to read/write:


Get permissions to modify files:

sudo su

Add your reflector to the P25Hosts file

sudo vi /root/P25Hosts.txt

Enter your information in the format: {TG#}tab{ReflectorIP}tab(41000) - there are also  instructions shown in the file.

Save and Exit.

Force Pi-star to re-load the P25Host file:

sudo pistar-update

When the update completes, exit the pi-star SSH session, and pull up the Dashboard. You should see the TG and IP domain in the "P25 Startup Host" on the Pi-Star configuration screen. You can set this as your startup now or not... 


OK - so here we are... let's run everything together! First - let's start clean. Reboot your device. 

Run each of these in it's own terminal window initially - this will help with troubleshooting. 
cd /usr/local/bin/
./ start /etc/P25Reflector.ini &

(new window)
cd /opt/P25Gateway
./P25Gateway /etc/P25Gateway.ini &

(new wind0w)
cd /opt/Analog_Bridge
./Analog_Bridge_DMR /etc/Analog_Bridge_DMR.ini &

(new wind0w)
cd /opt/Analog_Bridge
./Analog_Bridge_P25 /etc/Analog_Bridge_P25.ini &

(new window)
cd /opt/MMDVM_Bridge
./MMDVM_Bridge /etc/MMDVM_Bridge.ini &

(Pro-Tip: I have written a script to launch all of these. Once you've worked out any bugs in the setup and are running without issues, grab the script from here and place it in /opt. You can then start everything up with ./ &) 

A note about 


This is the final step, get a P25 radio and make sure you’ve got the frequency, NAC and talkgroup programmed correctly, and transmit.

In the terminal windows, you should see messages indicating DMR and P25 TX/RX activity. Pay particular attention to the P25Reflector and MMDVM_Bridge info - those seem to convey the most in terms of where something may be going sideways. If that happens, check, and re-check, firewall and IP addresses, DMRIDs, ports and talk groups... and check out the DVSwitch board. for support! Thanks to everyone involved in creating and maintaining these software tools! 

7 thoughts to “Build a P25/DMR Cross-Mode Bridge”

    1. yes i am using raspberry pi for my P25, it is only a “page embedded” inside my virtual hosting in datacenter

  1. I’ve been looking at this and wondering why it didn’t look right and then it hit me you missed a copy of MMDVM_Bridge. From my reading and understanding it *should* be:

    If you look at Analog_BridgeP25 it uses the ports:
    fromDMRPort = 34100 {IMPORTANT}
    toDMRPort = 34103 {IMPORTANT}

    Yet they aren’t referenced anywhere else so it’s not connecting to anything. In fact the only reference to P25_Gateway turns up in the single instance of MMDVM_Bridge you have. which would mean it goes straight from P25_Gateway to MMDVM_Bridge missing out the analog bridge completely?

  2. Thank you for the step-by-step, I used it in 2023 March and still working with just a few changes to the DVSwitch download process.
    I am asking if you could please post again the script, this is the only part that still pending. I am able to use “systemctl enable” for more of the service, except for P25Reflector and P25Gateway, then, these two services stop working.
    Thank you

    1. I just use /etc/rc.local to load automatically instead of systemctl

      /bin/bash -c “/opt/P25Reflector/P25Reflector /opt/P25Reflector/P25Reflector.ini” > /dev/null 2>&1 &
      sleep 5
      /opt/P25Parrot/P25Parrot 42011 > /dev/null 2>&1 &
      sleep 5
      /bin/bash -c “/opt/Analog_Bridge/Analog_Bridge_DMR /etc/Analog_Bridge_DMR.ini” > /dev/null 2>&1 &
      sleep 5
      /bin/bash -c “/opt/Analog_Bridge/Analog_Bridge_P25 /etc/Analog_Bridge_P25.ini” > /dev/null 2>&1 &
      sleep 5
      /bin/bash -c “/opt/P25Gateway/P25Gateway /opt/P25Gateway/P25Gateway.ini” > /dev/null 2>&1 &
      sleep 5
      /bin/bash -c “cd /etc/ && /opt/MMDVM_Bridge/MMDVM_Bridge /etc/MMDVM_Bridge.ini” > /dev/null 2>&1 &
      sleep 5
      #/opt/AMBEserver/AMBEserver -s 230400 -d > /dev/null 2>&1
      /opt/AMBEServer/AMBEserver -s 230400 -d > /dev/null 2>&1

      hope it helps

  3. Hi, “P25Reflector” has been removed from “G4KLX” github, and the link “” does not available, can you update the way hot to build !?

  4. Feasibly, this could be used to link something like a Quantar and an MTR3000 at the same site to allow P25 and DMR users to communicate on the same system?

Leave a Reply

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