Simple NAT Traversal with Asterisk

As an experiment, I configured Asterisk for full NAT traversal so that my SIP server could be accessed from the Internet.  This isn’t usually what you want, but here’s how you do it…

DANGER – Doing this will expose your Asterisk SIP server directly to the Internet, and you’ll get all manner of violated by SIP spammers.  Be aware of what you’re doing and what the implications are.

I’m assuming that you have a typical home NAT setup, where you have a dynamic IP, you’re in control of the border firewall (so you can do port forwarding), and your Asterisk install is on an internal network.

Step 1- Port Forwarding

First up, on your firewall, port forward the following ports to your Asterisk box;

5060/udp         # SIP control channel
10000:11000/udp  # the ports we will use for RTP

Step 2 – RTP Port Ranges

Right.  Now, create an rtp.conf in your Asterisk config, containing the following;

[general]
rtpstart=10000
rtpend=11000

This constrains the list of allowed RTP ports for SIP to use for communications.

Step 3 – Lockdown

Now, a word on security.  Put the following into the [general] section of your sip.conf;

context=incoming-public
allowguest=no
alwaysauthreject=yes

Now in your extensions.conf, define that context and put nothing in it.  Anyone who dials in anonymously to your SIP server will be directed to that context and go nowhere.  This is what you want (presumably).  For the love of God, do not put anything outbound in that context!

Step 4 – Configure NAT Traversal

In your sip.conf, in the [general] section (it must be there), add the following;

externhost=PUT-YOUR-DYNAMIC-DNS-HOSTNAME-HERE
localnet=192.168.0.0/255.255.255.0

This causes the Contact headers of outbound SIP packets to be substituted with the IP address of the DNS name you specified there, if the destination is not in the localnet field.  This is important to make NAT traversal work.

Step 5 – Configure SIP peers

For each of your peers, configure them to use NAT traversal as follows (some of these options may not be strictly required, but this is what I did and it worked);

nat=force_rport
qualify=yes
canreinvite=no
directmedia=no

Step 6 – Wait for the bots

Now, if this has all worked, you should now be able to connect to your SIP server from the Internet.

May God have mercy on your server.

Music-On-Hold for Asterisk

Got Music On Hold (MOH) working for Asterisk 1.8.  Turns out that it’s not that hard, but there’s some specific requirements to get it going if you don’t want to use mpg123 or something.

First, you’ll need some source music to use.  If you go to Wikipedia, you can find a whole bunch of OGG music that’s free to use.  I grabbed something by Brahms.  I’d suggest you use stuff from there, that way you aren’t license encumbered and at risk of getting sued by the RIAA hit squads.

Once you have that, you’ll need to convert it to an 8000Hz, single-channel, OGG Vorbis sound file, by using SoX (available for Cygwin, which is what I did).  The command you’ll need is;

sox input.ogg output.ogg channels 1 rate 8000

Asterisk is very fussy about the format, so it must be exactly like that.  Next up, fire up the Asterisk console (asterisk -r) and run the following;

core show file formats

Look through that and verify that ogg_vorbis is listed.  Next, we’ll verify that Asterisk can actually transcode ogg to whatever codec your VOIP is using.  Run the following;

core show translation recalc 10

And verify that for the ‘slin’ row there is a number printed in the columns that correspond to the codecs that you’re using (in my case, that’s alaw, ulaw and g729).

Drop your ogg files into /usr/share/asterisk/sounds/moh/ (in my case).  You will now need to put the following into musiconhold.conf to make it work;

[default]
mode=files
directory=/usr/share/asterisk/sounds/moh
sort=random

Your music-on-hold channel should be set to default anyway, so that should ‘just work’.  If you want, you can create a fake extension in extensions.conf like this to test it;

exten = 444,1,Answer()
same = n,MusicOnHold()

Ringing that extension should result in hearing music.  Consult your Asterisk logs, common issues will be the OGG files not being in the exact format required.

Good luck.

Cisco 7965 Phone Directory Setup

The Cisco 7965 has a Directory button, which can retrieve an XML document from a website and format that as a phone directory.  Setting it up is pretty simple.

In the SEPxxxx.cnf.xml for your phone, find the directoryURL tag and set that;

<directoryURL>http://intranet.example.com/directory.xml</directoryURL>

Then, create that file on your web server.  An example appears below;

<CiscoIPPhoneMenu>
<Title>Home Directory</Title>
<Prompt>Select a number</Prompt>
<MenuItem>
 <Name>Extension-511</Name>
 <URL>Dial:511</URL>
</MenuItem>
<MenuItem>
 <Name>Pizza Shop</Name>
 <URL>Dial:55511123</URL>
</MenuItem>
</CiscoIPPhoneMenu>

The items appear in the order they are listed.  I’m sure there’s more cleverness you can do with the directory, but that should get you started.

Cisco 7965 VOIP Phones Standalone (with Asterisk)

My work has a number of older Cisco 7965 VOIP Unified Communications phones, which are being disposed of.  I thought I’d grab one and see if I could make it work.  These phones are intended to be used with a Cisco Unified Call Manager & using Cisco’s proprietary SCCP protocol.  But it’s possible to re-flash them with a SIP-based firmware and configure them without UCM.

Firstly, you will need the following components;

  • A SIP server on your local network (eg, Asterisk).  That SIP server needs to support any of g729, u-law and/or a-law codecs.
  • A DHCP server on your local network, which you can customize DHCP options for.
  • A TFTP server that you can point your phone at.
  • The Cisco 7965 SIP Firmware Bundle.  I won’t link it here, but you can find it by looking through the references at the end of this article.  The exact version I used was cmterm-7945_7965-sip.9-3-1SR4-1.zip (md5 4088c17c622a1e181b1c2b1265349df6).
  • A Cisco 7965 phone (duh) and some way to power it.

And some references.

Let’s get started.

Reflashing the Phone

Extract the entire firmware package (it should contain a number of .sbn and .loads files) into the root of your TFTP server.  Then, in that root, create a new XMLDefault.cnf.xml containing the following;

<loadInformation8 model="Cisco 7965">SIP45.9-3-1SR4</loadInformation8>

In your DHCP configuration, add option 66 and option 150 pointing to the IP address of your TFTP server.

Power up the phone, and hold down the hash (#) button until the line buttons alongside the display start blinking.  Now, enter 123456789*0# on the keypad.  The screen should flash a few times and it should then enter the updater which will reflash the firmware from your TFTP server and do a factory reset at the same time.

Once that’s done, you can verify under Settings->Model Information that the Call Control Protocol is listed as SIP.

Configuring Asterisk

I’m assuming here you are using users.conf to generate extensions into extensions.conf, and have an otherwise normal Asterisk setup.  It’s critical that the extension which the phone is using has specified ‘nat=no’, otherwise it will simply refuse to register.  Obviously change your names, secrets and extensions to suit your setup!

Put this into users.conf;

[c7965]
fullname = My-VOIP-Phone
secret = PASSWORD
hassip=yes
host=dynamic
context = my-context
qualify = yes
alternateexts = 502
nat=no
disallow=all
allow=g729,alaw,ulaw

If your Asterisk setup doesn’t support g729, remove it from the codec list.  Reload Asterisk, and you’re nearly there.

Configure Phone XML

Now the hard bit.  You need to create a SEPxxxx.cnf.xml file in the root of your TFTP server where xxxx is the UPPERCASED version of your device’s MAC address.

You must get all parts of this file exactly right.  Even one tiny typo will stop the phone from reading the config.  I’ll put my file here with some adjustments to protect the innocent.  Interesting parts are bolded.

In order to reboot the phone, press Settings and then (quickly) enter **#** .

<device xsi:type="axl:XIPPhone" ctiid="1234567890">
<deviceProtocol>SIP</deviceProtocol>
<sshUserId>SSHUSERHERE</sshUserId>
<sshPassword>SSHPASSWORDHERE</sshPassword>
<devicePool>
 <dateTimeSetting>
 <!-- FIXME: Set your preferred date format and timezone here -->
 <dateTemplate>D/M/Y</dateTemplate>
 <timeZone>Cen. Australia Standard/Daylight Time</timeZone>
 <ntps>
 <!-- NTP might not actually work, but the phone can set the
 date/time from the SIP response headers -->
 <ntp>
 <name>pool.ntp.org</name>
 <ntpMode>Unicast</ntpMode>
 </ntp>
 </ntps>
 </dateTimeSetting>

 <!-- This section probably does not do anything useful. -->
 <callManagerGroup>
 <members>
 <member priority="0">
 <callManager>
 <ports>
 <ethernetPhonePort>2000</ethernetPhonePort>
 <sipPort>5060</sipPort>
 <securedSipPort>5061</securedSipPort>
 </ports>
 <processNodeName>YOURSIPSERVERHERE</processNodeName>
 </callManager>
 </member>
 </members>
 </callManagerGroup>
</devicePool>
<sipProfile>
 <sipProxies>
 <registerWithProxy>true</registerWithProxy>
 </sipProxies>
 <sipCallFeatures>
 <cnfJoinEnabled>true</cnfJoinEnabled>
 <callForwardURI>x-serviceuri-cfwdall</callForwardURI>
 <callPickupURI>x-cisco-serviceuri-pickup</callPickupURI>
 <callPickupListURI>x-cisco-serviceuri-opickup</callPickupListURI>
 <callPickupGroupURI>x-cisco-serviceuri-gpickup</callPickupGroupURI>
 <meetMeServiceURI>x-cisco-serviceuri-meetme</meetMeServiceURI>
 <abbreviatedDialURI>x-cisco-serviceuri-abbrdial</abbreviatedDialURI>
 <rfc2543Hold>false</rfc2543Hold>
 <callHoldRingback>2</callHoldRingback>
 <localCfwdEnable>true</localCfwdEnable>
 <semiAttendedTransfer>true</semiAttendedTransfer>
 <anonymousCallBlock>2</anonymousCallBlock>
 <callerIdBlocking>2</callerIdBlocking>
 <dndControl>0</dndControl>
 <remoteCcEnable>true</remoteCcEnable>
 </sipCallFeatures>
 <sipStack>
 <sipInviteRetx>6</sipInviteRetx>
 <sipRetx>10</sipRetx>
 <timerInviteExpires>180</timerInviteExpires>
 <!-- Force short registration timeout to keep NAT connection alive -->
 <timerRegisterExpires>180</timerRegisterExpires>
 <timerRegisterDelta>5</timerRegisterDelta>
 <timerKeepAliveExpires>120</timerKeepAliveExpires>
 <timerSubscribeExpires>120</timerSubscribeExpires>
 <timerSubscribeDelta>5</timerSubscribeDelta>
 <timerT1>500</timerT1>
 <timerT2>4000</timerT2>
 <maxRedirects>70</maxRedirects>
 <remotePartyID>false</remotePartyID>
 <userInfo>None</userInfo>
 </sipStack>
 <autoAnswerTimer>1</autoAnswerTimer>
 <autoAnswerAltBehavior>false</autoAnswerAltBehavior>
 <autoAnswerOverride>true</autoAnswerOverride>
 <transferOnhookEnabled>false</transferOnhookEnabled>
 <enableVad>false</enableVad>
 <preferredCodec>none</preferredCodec>
 <dtmfAvtPayload>101</dtmfAvtPayload>
 <dtmfDbLevel>3</dtmfDbLevel>
 <dtmfOutofBand>avt</dtmfOutofBand>
 <alwaysUsePrimeLine>false</alwaysUsePrimeLine>
 <alwaysUsePrimeLineVoiceMail>false</alwaysUsePrimeLineVoiceMail>
 <kpml>3</kpml>
 <natEnabled>false</natEnabled>
 <natAddress></natAddress>
 <!-- FIXME: This will appear in the upper right corner of the display -->
 <phoneLabel>MyVOIP-Phone</phoneLabel>
 <stutterMsgWaiting>1</stutterMsgWaiting>
 <callStats>false</callStats>
 <silentPeriodBetweenCallWaitingBursts>10</silentPeriodBetweenCallWaitingBursts>
 <disableLocalSpeedDialConfig>false</disableLocalSpeedDialConfig>
 <startMediaPort>16384</startMediaPort>
 <stopMediaPort>16391</stopMediaPort>
 <sipLines>
 <line button="1">
 <featureID>9</featureID>
 <featureLabel>MyVOIP-Phone</featureLabel>
 <proxy>USECALLMANAGER</proxy>
 <port>5060</port>
 <name>c7965</name>
 <displayName>MyVOIP-Phone</displayName>
 <autoAnswer>
 <autoAnswerEnabled>2</autoAnswerEnabled>
 </autoAnswer>
 <callWaiting>3</callWaiting>
 <authName>c7965</authName>
 <authPassword>PASSWORD</authPassword>
 <sharedLine>false</sharedLine>
 <messageWaitingLampPolicy>3</messageWaitingLampPolicy>
 <messagesNumber>501</messagesNumber>
 <ringSettingIdle>4</ringSettingIdle>
 <ringSettingActive>5</ringSettingActive>
 <contact>502</contact>
 <forwardCallInfoDisplay>
 <callerName>true</callerName>
 <callerNumber>false</callerNumber>
 <redirectedNumber>false</redirectedNumber>
 <dialedNumber>true</dialedNumber>
 </forwardCallInfoDisplay>
 </line>
 <line button="2">
 <featureID>21</featureID>
 <featureLabel>SomeOtherNumber</featureLabel>
 <speedDialNumber>55512345</speedDialNumber>
 </line>
 </sipLines>

 <voipControlPort>5060</voipControlPort>
 <dscpForAudio>184</dscpForAudio>
 <ringSettingBusyStationPolicy>0</ringSettingBusyStationPolicy>
 <dialTemplate>dialplan.xml</dialTemplate>
</sipProfile>
<commonProfile>
 <phonePassword></phonePassword>
 <backgroundImageAccess>true</backgroundImageAccess>
 <callLogBlfEnabled>2</callLogBlfEnabled>
</commonProfile>
<!-- FIXME: Change this to upgrade the firmware -->
<loadInformation>SIP45.9-3-1SR4-1S</loadInformation>
<vendorConfig>
 <disableSpeaker>false</disableSpeaker>
 <disableSpeakerAndHeadset>false</disableSpeakerAndHeadset>
 <pcPort>0</pcPort>
 <settingsAccess>1</settingsAccess>
 <garp>0</garp>
 <voiceVlanAccess>1</voiceVlanAccess>
 <videoCapability>0</videoCapability>
 <autoSelectLineEnable>0</autoSelectLineEnable>
 <webAccess>0</webAccess>
 <sshAccess>0</sshAccess>
 <sshPort>22</sshPort>

 <!-- For Sunday (1) and Saturday (7):
 <daysDisplayNotActive>1,2,3,4,5,6,7</daysDisplayNotActive>
 Current default is to enable the display 24/7.
 -->
 <daysDisplayNotActive>1,2,3,4,5,6,7</daysDisplayNotActive>
 <displayOnTime>00:00</displayOnTime>
 <displayOnDuration>00:01</displayOnDuration>
 <displayIdleTimeout>00:05</displayIdleTimeout>
 <spanToPCPort>1</spanToPCPort>
 <loggingDisplay>1</loggingDisplay>
 <loadServer></loadServer>
 <g722CodecSupport>2</g722CodecSupport>
</vendorConfig>
<versionStamp></versionStamp>
<userLocale>
 <name>English_United_States</name>
<uid>1</uid>
 <langCode>en_US</langCode>
<version>1.0.0.0-1</version>
 <winCharSet>iso-8859-1</winCharSet>
</userLocale>
<networkLocale>United_States</networkLocale>
<networkLocaleInfo>
 <name>United_States</name>
<uid>64</uid>
 <version>1.0.0.0-1</version>
</networkLocaleInfo>
<deviceSecurityMode>0</deviceSecurityMode>
<!--
<authenticationURL>http://yourwebserver/authenticate.php</authenticationURL>
<directoryURL>http://yourwebserver/directory.xml</directoryURL>
-->
<authenticationURL></authenticationURL>
<directoryURL></directoryURL>
<idleURL></idleURL>
<informationURL></informationURL>
<messagesURL></messagesURL>
<proxyServerURL></proxyServerURL>
<!--
 <servicesURL>http://phone-xml.berbee.com/menu.xml</servicesURL>
-->
<dscpForSCCPPhoneConfig>96</dscpForSCCPPhoneConfig>
<dscpForSCCPPhoneServices>0</dscpForSCCPPhoneServices>
<dscpForCm2Dvce>96</dscpForCm2Dvce>
<transportLayerProtocol>2</transportLayerProtocol>
<capfAuthMode>0</capfAuthMode>
<capfList>
 <capf>
 <phonePort>3804</phonePort>
 </capf>
</capfList>
<certHash></certHash>
<encrConfig>false</encrConfig>
<advertiseG722Codec>1</advertiseG722Codec>
</device>

Fill in the details as suiting your environment, and reboot the phone.  Cross your fingers.  Changing the timezones is a particular bugbear, you’ll need to dig around to find the correct values for your timezone.  Preferred codecs can be set to g711ulaw, g711alaw, g729a, or none.

The SSH username/password just gets you past the SSH challenge, you still need a login for the phone itself (log/log will show the logs remotely though).

You can configure the six line buttons to be any combination of SIP clients or speed-dials.  An example of each is above.  Now for the one piece remaining, the dial plan.

Configuring the Dial Plan

Create a new dialplan.xml in the root of your TFTP server, containing this;

<DIALTEMPLATE>
 <TEMPLATE MATCH="5.." Timeout="0"/>
 <TEMPLATE MATCH="000" Timeout="0"/>
 <TEMPLATE MATCH="106" Timeout="0"/>

 <TEMPLATE MATCH="1831-" Timeout="2"/>
 <TEMPLATE MATCH="1832-" Timeout="2"/>

 <TEMPLATE MATCH="13........" Timeout="0"/>
 <TEMPLATE MATCH="18........" Timeout="0"/>
 <TEMPLATE MATCH="19........" Timeout="0"/>

 <TEMPLATE MATCH="13...." Timeout="0"/>

 <TEMPLATE MATCH="61........." Timeout="0" Rewrite="0........"/>
 <TEMPLATE MATCH="001....-" Timeout="5"/>
 <TEMPLATE MATCH="02........" Timeout="0"/>
 <TEMPLATE MATCH="03........" Timeout="0"/>
 <TEMPLATE MATCH="04........" Timeout="0"/>
 <TEMPLATE MATCH="07........" Timeout="0"/>
 <TEMPLATE MATCH="08........" Timeout="0"/>
 <TEMPLATE MATCH="111" Timeout="0"/>

 <TEMPLATE MATCH="2......." Timeout="0"/>
 <TEMPLATE MATCH="3......." Timeout="0"/>
 <TEMPLATE MATCH="4......." Timeout="0"/>
 <TEMPLATE MATCH="5......." Timeout="0"/>
 <TEMPLATE MATCH="6......." Timeout="0"/>
 <TEMPLATE MATCH="7......." Timeout="0"/>
 <TEMPLATE MATCH="8......." Timeout="0"/>
 <TEMPLATE MATCH="9......." Timeout="0"/>

 <TEMPLATE MATCH="*.." Timeout="0"/>
 <TEMPLATE MATCH="*" Timeout="15"/>
</DIALTEMPLATE>

There’s a bit of redundancy and probably errors in this, but this is what I use.  Obviously this is engineered for Australia, so it’s formatted for Australian numbers.

At the very least, that dial plan should get you started.

Hope it worked!

If all has gone well, the C7965 has registered to Asterisk, and you can test a call.  Try and receive a call first, then try and deliver one.  Use the ‘sip show users’ command to check that the phone is registering, and the ‘sip show channels’ command to view the codec that’s being used when in a call.

Good luck!

ATA Dial Plan Adjustments

As discussed in the last post, I adjusted my dial plan to the following;

(000S0|106S0|183[12]x.|1[389]xxxxxxxxS0|13[1-9]xxxS0|0[23478]xxxxxxxxS0|[2-9]xxxxxxxS0|001xxxx.S5|111S0|*xx.)

This dial plan gives me immediate dialing for known phone numbers, and appears to work pretty nicely.  However…  My VOIP provider delivers caller ID numbers in internationalized format (but only for national numbers!), so a call from (0412 345 678) comes through to caller ID as 61412345678.

This means that on my cordless phone, I have to add an entry into the phonebook for that number exactly.  And therefore when I go to dial, I’m dialing a number that starts with 6 with no international number prefix (0011).  Therefore, what actually happens is the dial plan component [2-9]xxxxxxxS0 triggers, and dials 61412345, discarding the last three numbers.  Whoops.

What I need is an adjustment to my dial plan so that I can dial eleven-digit stupid numbers that start with 61, having them automatically translated to start with 0, while still allowing me to dial 8-digit numbers that start with 6, WITHOUT introducing an annoying delay in the dial plan.

(000S0|106S0|183[12]x.|1[389]xxxxxxxxS0|13[1-9]xxxS0|<61:0>[23478]xxxxxxxxS0|0[23478]xxxxxxxxS0|[2-9]xxxxxxxS1|001xxxx.S5|111S0|*xx.)

The highlighted sections are the relevant pieces.  What happens here is that if you enter an eight digit number starting with 6 (in this example), it will trigger the second highlighted section which gives you one second to type additional digits before dialing.  If you dial additional digits it triggers the first highlighted section.  That section takes a number which starts with 61 and replaces that with 0 and dials.

So, if I dial 61412345 and stop typing, the sequence of events is;

  • Receive eight digits (61412345)
  • Second dial plan is matched, set interdigit short delay to 1 second
  • No more digits received, dial 61412345

And if I dial 61412345678 with no gaps and then stop typing, the sequence is;

  • Receive eight digits (61412345)
  • Second dial plan is matched, set interdigit short delay to 1 second
  • Additional digits received (678), first dial plan is matched
  • Translate leading 61 to a 0, dial 0412345678

And the correct thing happens!  The other way around this would be to change all the S0 matches to S1’s (so you have a little time to finish dialing before things happen), and then have a catchall ‘xx.’ rule at the end to match anything.  That way an 11 digit dial would fall through to the catchall rule and result in a dial.  But doing that would cause the fallthrough rule to only match after 3 seconds, causing a delay whenever you used the phone book.

VOIP Analog Telephone Adapters – Dial Plans

Picked myself up a Cisco SPA112 to replace the wonky built-in VOIP capability of my router.  However, I seem to have some unusual behaviour.  Namely, when I take my cordless phone off the hook, I only get about 4 seconds to start entering numbers before the ATA switches over to the “off hook alarm” mode and rejects any further digits.  Unfortunately, the phone’s built-in dialer waits a few seconds before starting to dial, so it’s pretty random whether you can dial or not.

It turns out the problem here was the dial plan!  There’s a few timeouts in play here – the off-hook timer (5 seconds), the interdigit long delay (10 seconds) and the interdigit short delay (3 seconds).  My dial plan was causing the interdigit short delay to start counting as soon as the phone was taken off the hook!  Here’s what I used;

(000|106|0[23478]xxxxxxxx|[2-9]xxxxxxx|*xx|111|*9xx|13[1-9]xxx|1[389]00xxxxxx|001xxx.|x.)

What causes the issue here is the “x.” plan.  That translates to “any digit, zero or more times”.  This means as soon as the phone is taken off of the hook, the interdigit short delay is triggered because the entered digits (none) match at least one rule in the dial plan.

The solution here is to use a (much) better dial plan, namely;

(000S0|106S0|183[12]x.|1[389]xxxxxxxxS0|13[1-9]xxxS0|0[23478]xxxxxxxxS0|[2-9]xxxxxxxS0|001xxxx.S5|111S0|*xx.)

This plan is fairly complicated, so I’ll break it down piece by piece.  Notably, this plan won’t allow arbitrary number dialing like the first one does, all numbers have to match something in the plan somewhere.

  • 000S0, 106S0, 111S0 – Immediately dial these numbers (emergency numbers) as soon as they are entered without waiting for further digits (S0 sets the interdigit short delay to zero)
  • 183[12]x. – Dial any number which starts with 1831 or 1832, after waiting until no digits have been entered until the interdigit short delay timer (3 seconds) expires.  Note that the period means “match the preceding token zero or more times”.
  • 1[389]xxxxxxxxS0 – Immediately dial a 13, 18, or 19 number once ten entered digits have been reached
  • 13[1-9]xxxxS0 – Immediately dial a 13 number once six digits have been reached.  Note that this would conflict with the rule above it, except all ten-digit 13 numbers are 130 numbers meaning they don’t match this rule.
  • 0[23478]xxxxxxxxS0 – Immediately dial a standard Australian STD number including area code (two digit area code starting with 0, eight digit number)
  • [2-9]xxxxxxxS0 – Immediately dial a standard Australian local number with no area code (eight digits)
  • 01xxxx.S5 – Dial an International number of five or more digits, resetting the interdigit short delay to 5 seconds for this dial (to give more time to dial numbers)
  • *xx. – Dial a star-code of one or more digits after waiting for the interdigit short delay to expire (3 seconds)

The immediate dials reduce time delay for the dialer (ie, waiting 3 seconds after dialing for something to happen), but they can also conflict if two rules match a possible number.

For example, if you tried to dial 1301234567 with that plan (which is a theoretically valid ten-digit 13 number), you’ll find that you will actually dial 130123 and the rest of your digits will be discarded.  This isn’t a problem here because 130 is never used for ten-digit 13 numbers.

You can do an awful lot with dial plan codes, as well as bust things in weird ways.