ASL3 DTMF to DVSwitch to change DMR Talk Group

Setup Information

Use sudo asl-show-version to obtain this information from the console or SSH

********** AllStarLink [ASL] Version Info **********

OS : Debian GNU/Linux 12 (bookworm)
OS Kernel : 6.12.34+rpt-rpi-2712

Asterisk : 22.4.1+asl3-3.5.4-1.deb12
ASL [app_rpt] : 3.5.4

Installed ASL packages :

Package Version
============================== ==============================
allmon3 1.5.1-1.deb12
asl3 3.8-1.deb
asl3-asterisk 2:22.4.1+asl3-3.5.4-1.deb12
asl3-asterisk-config 2:22.4.1+asl3-3.5.4-1.deb12
asl3-asterisk-modules 2:22.4.1+asl3-3.5.4-1.deb12
asl3-menu 1.14-1.deb12
asl3-pi-appliance 1.10.0-1.deb12
asl3-tts 1.0.1-1.deb12
asl3-update-nodelist 1.5.1-1.deb12
cockpit 287.1-0+deb12u3
cockpit-bridge 287.1-0+deb12u3
cockpit-networkmanager 287.1-0+deb12u3
cockpit-packagekit 287.1-0+deb12u3
cockpit-sosreport 287.1-0+deb12u3
cockpit-storaged 287.1-0+deb12u3
cockpit-system 287.1-0+deb12u3
cockpit-wifimanager 1.1.1-1.deb12
cockpit-ws 287.1-0+deb12u3
dahdi 1:3.1.0-2
dahdi-dkms 1:3.4.0-6+asl
dahdi-linux 1:3.4.0-6+asl

Inquiry

I have a simplex ASL3 node with a public AllStar number of 65635. On this same node I have installed DVSwitch specifically for DMR and it's tied to private node 1999. I have 65635 connected to 1999. It is working perfectly and I can use the command line option: /opt/MMDVM_Bridge/dvswitch.sh tune XXXXX to switch talk groups. I want to be able to switch talk groups through my radio using DTMF. From my research I found documentation and links that said I need to setup Autopatch, in this case *091, with a link to an extensions.conf context, I used [tgtune], and then the talk group number. Dialing the autopatch code should match my [tgtune] dialing context and first tell me "DMR Talk Group XXXXX" and then execute the DVSwitch command line option for Tune to set the Talk Group. I have tried dialing the following trying to connect to Talk Group 7374:
*0917374 - fail
*091 send tones, 7374 send tones, *090 - fail
*0917374# - fail

I don't hear the step 2 item to SayAlpha "tg7374" or actually change the talk group with step 3.

I have tried and failed using: sudo asterisk -r and then entering: rpt fun 65635 *0917374

I'd appreciate any guidance you can provide

Joe - KK7PZE

sudo nano /etc/asterisk/rpt.conf

[functions]
;;;;; Autopatch Commands ;;;;;
090 = autopatchdn
091 = autopatchup,context = tgtune,dialtime = 6000,farenddisconnect = 1,noct = 1,quiet = 1

65635
rxchannel = SimpleUSB/65635
duplex = 1
; Tried the below VOX settings but they didn't help
;voxtimeout = 10000 ; vox timeout time in ms
;voxrecover = 2000 ; vox recover time in ms
;simplexpatchdelay = 25 ; Delay for transmit while in patch in 20ms increments

1999
rxchannel = USRP/127.0.0.1:50002:50001
duplex = 0

sudo nano /etc/asterisk/extensions.conf

tryinclude "custom/extensions.conf"

sudo nano /etc/asterisk/custom/extensions.conf

[tgtune]
exten => _X.,1,Wait(3) ; this gives you a chance (3 seconds) to cancel by hitting the '#' key if incorrect.
exten => _X.,2,SayAlpha(TG${EXTEN}) ; Crude message to user
exten => _X.,3,System(/opt/MMDVM_Bridge/dvswitch.sh tune ${EXTEN}) ; run the script dvswitch.sh with a parameter passwd from the function
exten => _X.,4,Hangup ; Done, return to normal operation

I'VE ALSO TRIED exten = rather than =>
I'VE ALSO TRIED TO PUT THIS WHOLE SECTION AT THE BOTTOM OF THE MAIN extensions.conf

asterisk -r

rpt fun 65635 *0917374

[2025-07-17 18:54:07.676] WARNING[251166]: app_rpt/rpt_bridging.c:568 rpt_play_tone: Cannot start tone on DAHDI/pseudo-1850948390
[2025-07-17 18:54:13.859] WARNING[251166]: app_rpt/rpt_bridging.c:568 rpt_play_tone: Cannot start tone on DAHDI/pseudo-1850948390

tail -f /var/log/asterisk/messages.log
This running while trying to change the TG via DTMF

[2025-07-17 18:50:32.641] DTMF[227750] channel.c: DTMF begin '' received on SimpleUSB/65635
[2025-07-17 18:50:32.641] DTMF[227750] channel.c: DTMF begin passthrough '
' on SimpleUSB/65635
[2025-07-17 18:50:32.833] DTMF[227750] channel.c: DTMF end '' received on SimpleUSB/65635, duration 191 ms
[2025-07-17 18:50:32.833] DTMF[227750] channel.c: DTMF end accepted with begin '
' on SimpleUSB/65635
[2025-07-17 18:50:32.833] DTMF[227750] channel.c: DTMF end passthrough '*' on SimpleUSB/65635
[2025-07-17 18:50:32.893] DTMF[227750] channel.c: DTMF begin '0' received on SimpleUSB/65635
[2025-07-17 18:50:32.893] DTMF[227750] channel.c: DTMF begin passthrough '0' on SimpleUSB/65635
[2025-07-17 18:50:33.089] DTMF[227750] channel.c: DTMF end '0' received on SimpleUSB/65635, duration 195 ms
[2025-07-17 18:50:33.089] DTMF[227750] channel.c: DTMF end accepted with begin '0' on SimpleUSB/65635
[2025-07-17 18:50:33.089] DTMF[227750] channel.c: DTMF end passthrough '0' on SimpleUSB/65635
[2025-07-17 18:50:33.149] DTMF[227750] channel.c: DTMF begin '9' received on SimpleUSB/65635
[2025-07-17 18:50:33.149] DTMF[227750] channel.c: DTMF begin passthrough '9' on SimpleUSB/65635
[2025-07-17 18:50:33.345] DTMF[227750] channel.c: DTMF end '9' received on SimpleUSB/65635, duration 195 ms
[2025-07-17 18:50:33.345] DTMF[227750] channel.c: DTMF end accepted with begin '9' on SimpleUSB/65635
[2025-07-17 18:50:33.345] DTMF[227750] channel.c: DTMF end passthrough '9' on SimpleUSB/65635
[2025-07-17 18:50:33.405] DTMF[227750] channel.c: DTMF begin '1' received on SimpleUSB/65635
[2025-07-17 18:50:33.405] DTMF[227750] channel.c: DTMF begin passthrough '1' on SimpleUSB/65635
[2025-07-17 18:50:33.622] DTMF[227750] channel.c: DTMF end '1' received on SimpleUSB/65635, duration 216 ms
[2025-07-17 18:50:33.622] DTMF[227750] channel.c: DTMF end accepted with begin '1' on SimpleUSB/65635
[2025-07-17 18:50:33.622] DTMF[227750] channel.c: DTMF end passthrough '1' on SimpleUSB/65635
[2025-07-17 18:50:33.662] DTMF[227750] channel.c: DTMF begin '7' received on SimpleUSB/65635
[2025-07-17 18:50:33.662] DTMF[227750] channel.c: DTMF begin ignored '7' on SimpleUSB/65635
[2025-07-17 18:50:33.878] DTMF[227750] channel.c: DTMF end '7' received on SimpleUSB/65635, duration 215 ms
[2025-07-17 18:50:33.878] DTMF[227750] channel.c: DTMF begin emulation of '7' with duration 215 queued on SimpleUSB/65635
[2025-07-17 18:50:33.938] DTMF[227750] channel.c: DTMF begin '3' received on SimpleUSB/65635
[2025-07-17 18:50:33.938] DTMF[227750] channel.c: DTMF begin ignored '3' on SimpleUSB/65635
[2025-07-17 18:50:34.098] DTMF[227750] channel.c: DTMF end emulation of '7' queued on SimpleUSB/65635
[2025-07-17 18:50:34.102] WARNING[242949] app_rpt/rpt_bridging.c: Cannot start tone on DAHDI/pseudo-1876465716
[2025-07-17 18:50:34.118] DTMF[227750] channel.c: DTMF end '3' received on SimpleUSB/65635, duration 179 ms
[2025-07-17 18:50:34.156] DTMF[227750] channel.c: DTMF end '3' received on SimpleUSB/65635, duration 179 ms
[2025-07-17 18:50:34.156] DTMF[227750] channel.c: DTMF begin emulation of '3' with duration 179 queued on SimpleUSB/65635
[2025-07-17 18:50:34.196] DTMF[227750] channel.c: DTMF begin '7' received on SimpleUSB/65635
[2025-07-17 18:50:34.196] DTMF[227750] channel.c: DTMF begin ignored '7' on SimpleUSB/65635
[2025-07-17 18:50:34.336] DTMF[227750] channel.c: DTMF end emulation of '3' queued on SimpleUSB/65635
[2025-07-17 18:50:34.376] DTMF[227750] channel.c: DTMF end '7' received on SimpleUSB/65635, duration 180 ms
[2025-07-17 18:50:34.396] DTMF[227750] channel.c: DTMF end '7' received on SimpleUSB/65635, duration 180 ms
[2025-07-17 18:50:34.396] DTMF[227750] channel.c: DTMF begin emulation of '7' with duration 180 queued on SimpleUSB/65635
[2025-07-17 18:50:34.436] DTMF[227750] channel.c: DTMF begin '4' received on SimpleUSB/65635
[2025-07-17 18:50:34.436] DTMF[227750] channel.c: DTMF begin ignored '4' on SimpleUSB/65635
[2025-07-17 18:50:34.576] DTMF[227750] channel.c: DTMF end emulation of '7' queued on SimpleUSB/65635
[2025-07-17 18:50:34.636] DTMF[227750] channel.c: DTMF end '4' received on SimpleUSB/65635, duration 199 ms
[2025-07-17 18:50:34.636] DTMF[227750] channel.c: DTMF begin emulation of '4' with duration 199 queued on SimpleUSB/65635
[2025-07-17 18:50:34.837] DTMF[227750] channel.c: DTMF end emulation of '4' queued on SimpleUSB/65635
[2025-07-17 18:50:39.903] WARNING[242949] app_rpt/rpt_bridging.c: Cannot start tone on DAHDI/pseudo-1876465716

Several years ago I posted a dialplan function for tuning dvs.
I posted it in the wiki.

You may want to review it a bit and make sure you understand how it works so you can modify it better for any specific purpose.
My advise is to make it work as is before you modify anything unless you are good with working with the dialplan.
But I think it still works as posted with asl3 (?) Can't think of any reason it would not. It's not a complete solution for all modes, but completely functional with a little workaround on some modes/tg.

Thanks for the reply Mike. Your dialplan was the first I started with and it didn't work for me. I had used the identical 97 as an autopatch. I didn't see in your dialplan document any configuration items for the autopatch so I copied another one but did figure out the context=dvs-set to make it use the extensions.conf dialplan info you have it your below. I only used the DMR and YSF portions of your dialplan for testing as that's all I have in my setup. I had your dialplan appended to the end of the main extensions.conf unlike the other example diaplan that I used and showed in my original post. I properly used *97 1 7373 for DMR and *97 3 32453 for YSF. Same failure. Same kind of output from asterisk -r and messages.log as I posted. I then used another example I found which showed the minor differences for ASL2 and ASL3 in the dialplan and that's the example I happened to be using in my request for help. But I did follow yours and it didn't work.

It's not a show stopper as I've written a script that allows me to control the connection of ASL3 public and private nodes, switch between Brandmeister and TGIF and select TGs for DMR. I can also pick YSF or FCS reflectors and rooms with it. I just means I have to SSH in to control things rather than just DTMF. I did setup macros to quickly connect or disconnect all my nodes and that works great. I just love to learn new things and get a bit OCD when I can't get something working. I'll keep at it but if anyone has any suggestions for any updated configurations that are working for them on ASL3 or any other logs I should look at or if they know of any issues related to the WARNING in my log/asterisk -r output that could be related, let me know. Have a great weekend and thanks again!

Joe - KK7PZE

There is currently a bug with quiet = 0 that looks alot like what your logs are showing. Your config "says" quiet = 1, so I'm not sure what is going on with the error.

2025-07-17 18:50:39.903] WARNING[242949] app_rpt/rpt_bridging.c: Cannot start tone on DAHDI/pseudo-1876465716

It looks like the bug is killing the "autopatch" before you get to the commands you are trying to run.

Sorry Franz,
You know I had published that several times in different ways over time.
I never noticed the string for calling the phonepatch info was not in that one.

As @N8RAW mentioned, the phone patch bug does require you use quite=1
And I might add that you need to be sure that *97 does not conflict with any existing command, or you could change it.

This whole proceed starts with that phone patch I used as a work around to get past the wall between app_rpt and the asterisk dialplan.

I started using the method myself around 2014 and there was not a issue with quite=0 (default) then.
So I don't know if the stuff I published is older than the bug.
But it is not clear I admit looking at it now.

The most important thing outside of a non-conflicting command for the phone patch is the correct 'context name' i.e. [dvs-set] (or whatever you name it)

It will go to the dialplan under that context to start executing.

Using my mentioned default, it should look like this...

97=autopatchup,context=dvs-set,noct=1,farenddisconnect=1,dialtime=90000,quiet=1

There are other ways to do this when you are comfortable working with the dialplan you might explore at some point. This was a basic framework to get folks started in understanding more ways to control the system with a little work around.

Hey Mike, thanks again. I got it working!!! I have DVSwitch on the same Pi as my primary node and can switch TG's perfectly and I setup a dial plan to be able to switch between Brandmeister or TGIF. I am trying to be able to control YSF/FCS reflectors and rooms also. But, in this case I have a second Pi running ASL3 and DVSwitch for YSF/FCS. So I installed SSHPASS on my primary node so I can SSH with username and password into the YSF Node and pass the dvswitch.sh command to it. I can't get it to work. Playing around I had it log into the other node using a command and just do an: echo ${EXTEN} > extensionpicked.txt and that works but sending a dialplan entry like this:
exten => _X.,3,System(SSHPASS='MyPassword' sshpass -e ssh UserName@192.168.1.1 "/opt/MMDVM_Bridge/dvswitch.sh tune 8${EXTEN}")
(((username and password changed for security)))
This doesn't work. It does match step 2 to say YSF${EXTEN} though so I know the dialplan is matching. Any suggestions?

Thanks again!

Joe - KK7PZE

From shell, you do not have the variable ${EXTEN}
So you will need to send the value for it, not the var

And that string works from the dialplan, not shell. Formatted for asterisk where the var is available in the system which executed it in the dialplan.

You could issue asterisk commands from shell

asterisk-rx xxxxxxxx

Perhaps I am missing something?

Maybe I do not fully understand what you are doing with/on the second system.If so, take one more shot at it.

Let me think on this a while, because I think there may be a better solution for controlling the other dvs from the original computer. Which is what I at least think you are attempting.

Hey Mike, I figured it out. If you look at the extensions.conf section where I'm using the SSHPASS feature to access a remote DVSwitch node I had to add: -o StrictHostKeyChecking=no
Once I did that it all started working. It had no issues passing the ${EXTEN} inline to the command also!

Let me explain my configuration as it may help others.

Below is a "crayon" drawing of my configuration.

HT Radio
|
SR-FRS
|
NODE-PUBLIC--*3Linked---NODE-PRIVATE
DVSwitch DMR DVSwitch YSF
Raspberry PI #1 Raspberry PI #2

Goal is to have access codes for various functions to control DVSwitch on both my DVSwitch for DMR and DVSwitch for YSF/FCS. AutoPatch was used to create the various codes. In the AutoPatch config you will see a context = section. The name put in that section seen below in rpt.conf tells that codes to go look for the configured dialplan in extensions.conf. That is listed below also. So if you look at 091 it has a context=dmr which links to extensions.conf [dmr] dialplan section. The _X. means it will take any digit, any number of digits. The next thing is the step number. There are 4 steps in each dialplan. Step 1 I have waiting for 1 second so you could hit # to cancel. Some may want that number to be larger. Step 2 uses a super basic text to speech function which announces to you whatever you want it to like "DMR7374". So for the DMR dialplan it says DMR followed by the Talk Group number you entered. Step 3 allows system commands. Things like bash scripts or ASL commands or DVSwitch commands. In my case I have it running the DVSwitch.sh script to do whatever function you are trying to accomplish on the DVSwitches. Step 4 hangs up the AutoPatch and free's the "frequency" for continued communications.

So taking my HT and using DTMF to dial *0917374 will connect to my DVSwitch for DMR that's on the same node as my public node. It will put me in Talk Group 7374. Note that it will switch to that talk group but you don't know what DMR Network it's on. Not an issue unless you have multiple DMR networks that you use and switch between.

If I dial *09265635 it will SSH into my private node that has DVSwitch setup for YSF/FCS and pass along 865635 which is the DVSwitch code to put me on YSF Reflector 65635. An 8 as the first digit is for YSF Reflectors.

If I dial *09300390 it will SSH into my private node that has DVSwitch setup for YSF/FCS and pass along 900390 which is the DVSwitch code to put me in FCS Room 00390. A 9 as the first digit is for FCS Rooms.

If I dial *0987374 it will connect to my DVSwitch for DMR that's on the same node as my public node. It will connect me to the TGIF network for DMR and put me in talk group 7374

If I dial *0987489 it will connect to my DVSwitch for DMR that's on the same node as my public node. It will connect me to the Brandmeister network for DMR and put me in talk group 7489

While the *09X codes are fixed, the digits after that are freeform so the examples listed above are random talk groups, reflectors and rooms.

Configuration of rpt.conf on NODE-PUBLIC:
; Auto Patch used for changing DMR Talk Groups, YSF Reflectors, FCS Rooms
090 = autopatchdn
091 = autopatchup,context = dmr,dialtime = 15000,farenddisconnect = 1,noct = 1,quiet = 1 ; DMR Talk Group
092 = autopatchup,context = ysf,dialtime = 15000,farenddisconnect = 1,noct = 1,quiet = 1 ; YSF Reflector
093 = autopatchup,context = fcs,dialtime = 15000,farenddisconnect = 1,noct = 1,quiet = 1 ; FCS Room
098 = autopatchup,context = tgif,dialtime = 15000,farenddisconnect = 1,noct = 1,quiet = 1 ; DMR TGIF Talk Group
099 = autopatchup,context = bm,dialtime = 15000,farenddisconnect = 1,noct = 1,quiet = 1 ; DMR Brandmeister Talk Group

Configuration of extensions.conf on NODE-PUBLIC:
[dmr]
exten => _X.,1,Wait(1) ; this gives you a chance (1 second) to cancel by hitting the '#' key if incorrect.
exten => _X.,2,SayAlpha(DMR${EXTEN}) ; Crude message to user
exten => _X.,3,System(/opt/MMDVM_Bridge/dvswitch.sh tune ${EXTEN}) ; run the script dvswitch.sh with a parameter passwd from the function
exten => _X.,4,Hangup ; Done, return to normal operation

[ysf]
exten => _X.,1,Wait(1) ; this gives you a chance (1 second) to cancel by hitting the '#' key if incorrect.
exten => _X.,2,SayAlpha(YSF${EXTEN}) ; Crude message to user
exten => _X.,3,System(SSHPASS='sshpassword' sshpass -e ssh -o StrictHostKeyChecking=no username@192.168.254.177 /opt/MMDVM_Bridge/dvswitch.sh tune 8${EXTEN}) ; run the script dvswitch.sh with a parameter passwd from the function
exten => _X.,4,Hangup ; Done, return to normal operation

[fcs]
exten => _X.,1,Wait(1) ; this gives you a chance (1 second) to cancel by hitting the '#' key if incorrect.
exten => _X.,2,SayAlpha(FCS${EXTEN}) ; Crude message to user
exten => _X.,3,System(SSHPASS='sshpassword' sshpass -e ssh -o StrictHostKeyChecking=no username@192.168.254.177 /opt/MMDVM_Bridge/dvswitch.sh tune 9${EXTEN}) ; run the script dvswitch.sh with a parameter passwd from the function
exten => _X.,4,Hangup ; Done, return to normal operation

[tgif]
exten => _X.,1,Wait(1) ; this gives you a chance (1 second) to cancel by hitting the '#' key if incorrect.
exten => _X.,2,SayAlpha(TGIF${EXTEN}) ; Crude message to user
exten => _X.,3,System(/opt/MMDVM_Bridge/dvswitch.sh tune tgifselfservicepassword@tgif.network:62031!${EXTEN}) ; run the script dvswitch.sh with a parameter passwd from the function
exten => _X.,4,Hangup ; Done, return to normal operation

[bm]
exten => _X.,1,Wait(1) ; this gives you a chance (1 second) to cancel by hitting the '#' key if incorrect.
exten => _X.,2,SayAlpha(BM${EXTEN}) ; Crude message to user
exten => _X.,3,System(/opt/MMDVM_Bridge/dvswitch.sh tune brandmeisterselfservicepassword@3102.repeater.net:62031!${EXTEN}) ; run the script dvswitch.sh with a parameter passwd from the function
exten => _X.,4,Hangup ; Done, return to normal operation

Thanks again Mike for the assistance. I hope this explanation makes sense and can help you and others with my weird configuration

Joe

That explains what I was missing. You are still in the dialplan.
Well, I am glad you were able to use that old dialplan and take it a step further.
Thanks for the better explanation to help the next guy.