Author: N5LSN
Important
As of 8/24/24, ASL3 half-duplex (duplex=0,1) autopatch still has a few bugs to work out before it is fully functional. Incoming calls (reverse autopatch) work fine, but outgoing (autopatch) calls are unable to pass phone audio to the ASL3 node.
Important
Since you will be aquiring a new VOIP number, it is very likely that most carriers will auto-label calls from your autopatch as spam/fraud. Depending on the configuration of the carrier & receiving phone, the autopatch call may be routed straight to voicemail and hidden from the missed call history, and the receiving party may never even know you called. I am unsure how to remedy this other than reaching out to the carriers individually, explaining the legitimacy of your number, and requesting the removal of the spam/fraud label.
This guide will walk you through setting up both Autopatch and Reverse Autopatch functionality on your ASL3 node (not HamVoIP) using VoIP.ms as the service provider. This allows your repeater to make and receive traditional phone calls. This is particularly useful for emergency contact of people outside of the repeater range or otherwise unable to directly use the repeater for communications. It also is great for allowing system administrators remote access to execute DTMF functions from any active phone line.
- Create a VoIP.ms account (use this link to get $10 added to your account balance!).
- Create a Residential acount.
- Add some funds to your account.
- Go to DID Numbers > Order DID(s).
- Choose your area
- Choose from the list of available numbers
Important
Make sure you choose from a list of phone numbers, otherwise you will be placing a backorder which might take a while.
- Scroll down and sleect the Per Minute (Inbound) rate plan
- Choose the POP Server that is closest to you, and note the address (eg.
dallas1.voip.com
) - In Routing Settings, under Main, make sure SIP/IAX is slected, and your main account is selected in the dropdown.
- Click Order DID and confirm your purchase.
Important
Since this is a VoIP service, 911 calls WILL NOT ROUTE unless e911 is activated. You MUST complete e911 activation to enable outgoing 911 calls from the node.
- Go to DID Numbers > e911
- Next to your DID Number, click Activate.
- Enter the information that should be used to route outgoing 911 calls from your node to a local dispatch center.
- Change/Validate the information if prompted.
- Click Yes to update the e911 caller ID to your DID number.
- Go to Main Menu > Account Settings.
- Under the Account Restrictions tab, I suggest setting Max. Call Time to 5 or 10 minutes.
- Click Apply.
- Under the General tab, select Use one of my DIDs and select the DID your purchased in the dropdown.
- Under the Inbound Settings tab, set the protocol to IAX2 and the device type to IP PBX.
- Under the Security tab, in the Main SIP/IAX Password section, click Set Random password and Send Email.
- Check your email for the generated password.
- Either note this password, or use it to change the password to a custom one.
- Apply the changes.
- Go to DID Numbers > Manage DID(s).
- Click the Edit button on your DID.
- In Routing Settings, ensure that Main is set to SIP/IAX and Main Account is selected in the dropdown.
- Make sure DID Point of Presence is set to the server closest to you.
- Apply the changes.
Tip
Optionally, you can click the Contact Card icon next to your DID on the Manage DIDs page to update the CNAM information on your DID. This is the caller ID that pops up on capable phones that do not have the number saved in their contact list.
- Go to Main Menu > Home and take note of the SIP/IAX main username.
Add the following lines to /etc/asterisk/iax.conf
under the [general]
stanza:
; ENTER YOUR VOIP.MS CREDENTIALS AND SERVER HERE
register => VOIPMS_ID:VOIPMS_PASSWORD@VOIPMS_HOST
; Example: register => 123456:supersecretpassword@dallas1.voip.ms
Add this new stanza to iax.conf
:
[voipms]
username=VOIPMS_ID; ENTER YOUR 6-DIGIT VOIP.MS USERNAME HERE
type=friend
context=reverse-autopatch
host=VOIPMS_HOST; ENTER THE VOIP.MS SERVER ADDRESS YOU SELECTED FOR YOUR DID HERE
secret=VOIPMS_PASSWORD; ENTER YOUR VOIP.MS IAX PASSWORD HERE
disallow=all
allow=ulaw
allow=g726aal2
allow=gsm
codecpriority=host
insecure=port,invite
requirecalltoken=yes
Important
Make sure you delete or comment out any existing stanzas that use the names [autopatch]
or [reverse-autopatch]
Add these stanzas to your /etc/asterisk/extensions.conf
:
; AUTOPATCH - REPEATER MAKES OUTGOING CALLS
[autopatch]
; Match any 11-digit number starting with '1' (e.g., North American long-distance format).
exten => _1NXXNXXXXXX,1,Dial(IAX2/voipms/${EXTEN})
; The Dial command routes the call through the IAX2 channel to the "voipms" trunk,
; passing the dialed number (${EXTEN}) to the provider.
; After the call is completed, hang up the line.
exten => _1NXXNXXXXXX,n,Hangup()
; Match any 10-digit number (e.g., North American local format).
exten => _NXXNXXXXXX,1,Dial(IAX2/voipms/${EXTEN})
; The Dial command routes the call through the IAX2 channel to the "voipms" trunk,
; passing the dialed number (${EXTEN}) to the provider.
; After the call is completed, hang up the line.
exten => _NXXNXXXXXX,n,Hangup()
; Match 911
exten => 911,1,Dial(IAX2/voipms/${EXTEN})
; The Dial command routes the call through the IAX2 channel to the "voipms" trunk,
; passing the dialed number (${EXTEN}) to the provider.
; After the call is completed, hang up the line.
exten => 911,n,Hangup()
; Optional: Reroute 911 to another number
; Uncomment the following lines to enable this feature:
; Instead of routing 911 directly, reroute it to the specified number (e.g., 1234567890).
; This could be used to route emergency calls to a different service or internal security.
; exten => 911,1,Dial(IAX2/voipms/1234567890)
; After the rerouted call is completed, hang up the line.
; exten => 911,n,Hangup()
; REVERSE-AUTOPATCH - REPEATER RECEIVES INCOMING CALLS
[reverse-autopatch]
; Answer the incoming call.
exten => _X.,1,Answer()
; Wait for 1 second to ensure the line is stable before playing the prompt.
exten => _X.,n,Wait(1)
; Optional: Bypass PIN for trusted caller
; Uncomment the below line to enable this feature:
; If the incoming call is from a trusted number (5551234567 or 5559876543 in this example),
; skip the PIN code and go directly to the "connect" label.
; exten => _X.,n,GotoIf($["${CALLERID(num)}" = "5551234567"]?connect,1)
; Example of how to "trust" two (or more) phone numbers
; exten => _X.,n,GotoIf($["${CALLERID(num)}" = "5551234567" | "${CALLERID(num)}" = "5559876543"]?connect,1)
; Initialize an attempt counter
exten => _X.,n,Set(ATTEMPTS=0)
; Play a message that asks the caller to enter their PIN followed by the pound/hash key.
; "confbridge-pin" says: "Please enter your personal identification number followed by the pound, or hash key."
exten => _X.,n(start),Playback(confbridge-pin)
; Wait for the caller to enter a 4-digit PIN.
; - "PIN" is the variable where the entered digits will be stored.
; - "beep" will play a beep sound to prompt the user.
; - "4" specifies the PIN length (4 digits).
; - ",,5" sets a 5-second timeout for the user to start entering the PIN.
exten => _X.,n,Read(PIN,beep,4,,,5)
; SET YOUR PIN(s) HERE! THESE PIN(s) WILL BE USED TO PATCH INTO THE REPEATER
; Check if the entered PIN is one of the valid PINs.
; - If the PIN is correct, the call will go to the label "wait-for-pound".
; - If not, it will continue to the next step.
exten => _X.,n,GotoIf($["${PIN}" = "1234"]?wait-for-pound)
; Example of how to set up two (or more) PINs:
; exten => _X.,n,GotoIf($["${PIN}" = "1234" | "${PIN}" = "5678"]?wait-for-pound)
; Increment the attempt counter
exten => _X.,n,Set(ATTEMPTS=$[${ATTEMPTS}+1])
; If the PIN is invalid, play a message saying it was incorrect.
; "confbridge-invalid" says: "You have entered an invalid option."
exten => _X.,n,Playback(confbridge-invalid)
; Check if the attempt counter has reached 3
exten => _X.,n,GotoIf($[${ATTEMPTS} >= 3]?too-many-failures)
; Go back to the start and ask the user to enter the PIN again.
; This gives the user another chance to enter a valid PIN.
exten => _X.,n,Goto(start)
; If the user fails to enter a valid PIN after 3 attempts, play a message saying they have entered too many invalid PINs.
; "confbridge-pin-bad" says: "You have entered too many invalid personal identification numbers."
exten => _X.,n(too-many-failures),Playback(confbridge-pin-bad)
; Hang up the call after the failure message.
exten => _X.,n,Hangup()
; After the valid PIN is entered, wait for the user to press the "#" key.
; - This command waits for the user to press "#" to confirm the PIN entry.
; - The 5-second timeout will give the user time to press "#".
exten => _X.,n(wait-for-pound),WaitExten(5)
; If the user presses "#", go to the "connect" label.
exten => #,1,Goto(connect,1)
; If "#" is not pressed, go to the start label.
exten => _X.,99,Goto(start)
; If the correct PIN was entered and "#" was pressed, play a message confirming the connection.
; "rpt/connected" could say something like: "You are now connected."
exten => connect,1,Playback(rpt/connected)
; Connect the caller to the repeater using the "rpt" command.
; The "|P" option is used to specify "phone" mode in app_rpt.
exten => connect,n,rpt(${NODE}|P)
; Hang up the call after the connection is made.
exten => connect,n,Hangup()
Warning
Now is a good time to go back through all of your copy/pasting and make sure you made all of the required customizations! This includes usernames, passwords, server URLs and PIN codes!
Make sure that you have this line in your /etc/asterisk/modules.conf
, you might have to add it:
load => bridge_simple.so
Also make sure that app_read
is set to load in /etc/asterisk/modules.conf
:
load => app_read.so
Create the following script to handle terminating calls. Without this script, you will be unable to forcefully terminate incoming calls:
nano /var/lib/asterisk/hangupPhones
Paste this script into the file:
#!/bin/bash
# Target pattern to match (adjust as needed for different calls)
TARGET_PATTERN="IAX2/voipms-"
# Get the list of channels and their concise details
CHANNELS=$(asterisk -rx "core show channels concise")
echo "Checking for matching channels..."
echo "--------------------------------"
# Iterate over each line to find the target channel
while IFS= read -r line; do
if [[ $line == $TARGET_PATTERN* ]]; then
CHANNEL=$(echo "$line" | awk -F'!' '{print $1}')
CALLERID=$(echo "$line" | awk -F'!' '{print $3}')
echo "Found matching channel: $CHANNEL with Caller ID: $CALLERID"
echo "Hanging up channel: $CHANNEL"
asterisk -rx "channel request hangup $CHANNEL"
fi
done <<< "$CHANNELS"
Make it executable:
chmod +x /var/lib/asterisk/hangupPhones
In /etc/asterisk/rpt.conf
, in the stanza for the node number that you are enabling autopatch on, set this:
context = autopatch
Make sure you have this in your [functions]
stanza:
;;;;; Autopatch Commands ;;;;;
6 = autopatchup,noct=1,farenddisconnect=1,dialtime=2000,context=autopatch,quiet=1 ; Phone autopatch
0 = cmd,/var/lib/asterisk/hangupPhones ; Hangup All phone patches
; OPTIONS FOR AUTOPATCHUP COMMAND
; context - Override the context specified for the autopatch in rpt.conf
; dialtime - The maximum time to wait between DTMF digits when a telephone number is being dialed. The patch will automatically disconnect if this time is exceeded. The value is specified in milliseconds.
; farenddisconnect - When set to 1, the patch will automatically disconnect when the called party hangs up. The default is to send a circuit busy tone until the radio user brings the patch down.
; noct - When this is set to 1, the courtesy tone during an autopatch call will be disabled. The default is to send the courtesy tone whenever the radio user unkeys.
; quiet - When set to 1, do not send dial tone, voice responses, just try to connect the call.
; voxalways - When set to 1, enables vox mode.
; exten - Overrides the default autopatch extension.
; nostar - Disables the repeater function prefix.
Warning
Don't forget to restart Asterisk!
You can now make and receive calls through your repeater, linking it to a traditional phone system for added functionality and convenience.
Are you using the voipms IVR to handle the access code? You can also handle it within asterisk pretty easily if you want to. This has some added flexibility in case you wanted to dial other nodes or even SIP extensions you might have locally.
In this example, the node number was chosen for the password, but any number can be set.