Sunday Feb 01, 2009

Cisco Call Manager Express SIP Trunking and Broadworks Voice Mail

For the last few weeks I've been doing some interop testing for Cisco Call Manager Express with our Broadworks platform and I decided to give the Broadworks Voice Messaging a try in a SIP trunking deployment.

Devices and Versions

  • Broadworks R13
  • Acme Packet Net-Net 4250 SBC 4.1.1p68
  • Cisco 2811 Router 12.4(22)T with CME

Broadworks Configuration

By default Broadworks will send unsolicited SIP NOTIFY messages to a user whenever a voice mail is received, deleted, or changed in some fashion (for instance, saving a played message turns off the MWI light). In R14, it is also possible to use subscriptions for MWI which opens up some additional configuration options.

In this example, we will assume that the Broadworks Voice Messaging is configured on each trunk group user that will use voice mail. The send calls to voice mail on busy and unanswered should be unchecked within the user messaging configuration. We will be configuring the PBX to divert calls to VM when necessary.

Example Numbers:

  • Trunk Group Pilot - 7025001000
  • User 1 - 7025001005
  • User 2 - 7025001006
  • Voice Mail Pilot - 7025001020

Acme Packet

This configuration assumes a standard SIP Connect configuration on the SBC

DNS

A DNS entry should be created that contains A records for each SBC pair in the network. This is important due to the lack of DNS SRV lookups in the CME MWI server configuration. In networks where geographical redundancy is employed endpoints may move from one SBC pair to another. CME uses the results of a DNS lookup on the mwi server address to populate the list of IPs it will accept notifies from.

Call Manager Express

CME should be configured for a SIP trunking deployment. A Cisco example can be found here: http://www.cisco.com/en/US/products/sw/voicesw/ps4625/products_configuration_example09186a00808f9666.shtml

Ensure that the following is configured:

sip-ua 
 mwi-server dns:mwi.sip.provider.com expires 3600 port 5060 transport udp unsolicited
 connection-reuse
 host-registrar
In this example we are configuring the router to use mwi.sip.provider.com as the mwi server hostname. It is assumed that this DNS record contains each of the IPs that any SIP NOTIFY messages will ever originate from (SBC VIP addresses). Support for unsolicited notifies is also enabled. connection-reuse is enabled for interoperability with the Acme Packet SBCs which require the SIP source port on the router to remain consistent throughout the registration. host-registrar enables the use of the SIP domain name in place of router IP in Diversion and History-Info headers.

Configure the telephone-service voice mail parameters:

telephony-service
 voicemail 97025001020
 mwi relay

Configure each ephone-dn to route calls on busy to the voice mail pilot number:

ephone-dn  1  octo-line
 number 7025001005 no-reg primary
 label SIP Trunk 1005
 call-forward busy 97025001020
 call-forward noan 97025001020 timeout 18
 mwi-type both

Whenever a call is received and the line is busy, or unanswered CME will divert the call back to the Broadworks Voice Portal which will use the original dialed PBX user number as the mailbox number. Users should be able to press the messages button on their phone, or dial 7025001020, to check their voice mail.

Asterisk Diversion and History-Info for Broadworks

Recently I've been busy so I haven't had much time to pay attention to this blog. However, I came up with another way to have Asterisk generate Diversion and History-Info headers when an internal phone uses a 302 Moved Temporary response to deflect a call to another destination. This is far easier than trying to use an AGI script of some sort within the outbound dialing context to decipher if the call needs a header or not.

Diversion

[local-exten]

exten => setdiversion,1,SIPAddHeader(Diversion: <sip:${CALLERID(rdnis)}@sip.provider.com>\;reason=deflection)
exten => setdiversion,2,Return

exten => _91NXXNXXXXXX,1,GosubIf($["${CALLERID(rdnis)}" != ""]?setdiversion,1)
exten => _91NXXNXXXXXX,n,Dial(${TRUNK}/${EXTEN:1}|600)
exten => _91NXXNXXXXXX,n,Hangup
The concept here is fairly simple. Determine if the Asterisk channel variable RDNIS is not null, and if it contains a value, jump to a subroutine and add a Diversion header using the value of the channel variable. This should be a starting point in designing a dial plan that would suit most needs.

History-Info

[local-exten]

exten => setdiversion,1,SIPAddHeader(History-Info: <sip:${CALLERID(rdnis)}@sip.provider.com>\;Reason=Diversion%3bcause%3ddeflection>\;index=1)
exten => setdiversion,2,Return

exten => _91NXXNXXXXXX,1,GosubIf($["${CALLERID(rdnis)}" != ""]?setdiversion,1)
exten => _91NXXNXXXXXX,n,Dial(${TRUNK}/${EXTEN:1}|600)
exten => _91NXXNXXXXXX,n,Hangup
The History-Info variant is almost identical. In this example we statically set the index to 1 since we are basing our header on the RDNIS variable which will only contain a single redirect depth of information.

I think should cover most use cases for call forwarding. I strongly recommend against adding a Diversion header to all outbound calls unless absolutely necessary. It's designed for deflection and many voice mail and PBX systems depend on the content of the RDNIS field. Setting this value can produce unwanted effects such as calling in to a voice mail pilot number with the intent of checking your voice mail actually routing you to leave a voice mail for a invalid mailbox. In that case the system checked the RDNIS (which would be set to your PBX number), saw it was present, and tried to leave a message in the mailbox for the RDNIS number which does not exist.

Friday Nov 28, 2008

Multiple Trunk Groups on a Cisco IOS ISDN PRI

Ever had a need to segment a PRI on a Cisco IOS router into multiple separate trunk groups? Here is an interesting feature I came across while looking to do exactly this. Here is an example configuration.

controller T1 0/3/1
 clock source internal
 pri-group timeslots 1-24
 trunk-group PBXGROUP1 timeslots 1-8
 trunk-group PBXGROUP2 timeslots 9-15
 trunk-group PBXGROUP3 timeslots 16-23

The configuration above creates 3 trunk groups using a single PRI with a single D channel. The application for this type of configuration would be cases where a customer wants to receive specific numbers on certain channels, maybe for a call center application, or perhaps the deployment is for a multiple tenant building such as an executive suite where a PBX is segmented out for different businesses.

Saturday Nov 15, 2008

Cisco's Diversion Header Enhancements in 12.4(22)T

I was pleasantly surprised to learn that in IOS 12.4(22)T Cisco finally introduced the ability to set the SIP Diversion domain with a command line option. This removes the previous requirement for Acme Packet Header Manipulation rules to rewrite the host portion of the Diversion header on INVITE events destined for the Broadworks platform. All that is required is to add the "host-registrar" command to the sip-ua.

SIP User-Agent Configuration Example:

sip-ua 
 credentials username "AUTH USERNAME" password "PASSWORD HERE" realm BroadWorks
 authentication username "AUTH USERNAME" password "PASSWORD HERE" realm BroadWorks
 no remote-party-id
 set pstn-cause 34 sip-status 486
 set pstn-cause 47 sip-status 486
 registrar dns:sbc.example.com expires 3600
 sip-server dns:sbc.example.com
 connection-reuse
 host-registrar

Continued problems with SIP source ports

I had previously done some configuration with the Acme that was intended to disable the layer 4 source port checking for CPE to Broadworks invites. This works, sometimes. It seems that there are some situations where the SBC still rejects the Invite if the port changes even with the configuration applied to the sip interfaces on the SBC. The easiest solution to this in the case of the Cisco SIP UA is to use the "connection-reuse" hidden parameter in the sip-ua. This restricts the IOS SIP UA from generating new outbound SIP connections. Eventually I hope to find a real solution to disabling the source port checking on the SBC, but for the time being this is the workaround.

Sunday Oct 12, 2008

Managing Network Device Test Results

I've recently been looking to test plan and issue management systems that work well in network device testing environments. Most platforms I've found are designed specifically with software development in mind more so than lab testing various network elements.

Probably one of the most well known vendors in the software testing arena is Atlassian. I've noticed a large number of organizations where their corporate IT developers use JIRA for defect tracking. Bamboo seems to be an interesting possibility for tracking test plan failure cases as well.

Currently I use Bugzilla for tracking defects found in the lab and I ran across an interesting add-on for the platform called Testopia. The project homepage is here: http://www.mozilla.org/projects/testopia/. Overall it's a fairly comprehensive system but can be a bit intimidating the first time you use it. Here is a screenshot of a quick test plan I created: Test Plan Cases

I'm curious if anyone else has had experience with other systems and what the pros and cons of each has been.

Sunday Sep 14, 2008

SIP Diversion with Cisco IOS

***Update*** Cisco did fix this in 12.4(22)T. See here for the solution: http://www.cytek.biz/roller/designbox/entry/cisco_s_diversion_header_enhancements

Ok... I actually received a call from someone who was a bit disappointed that I had not finished the series on SIP Connect and Diversion. With that in mind, I apologize to those that were following this blog and how long it has taken to have an update. I've been busy and honestly updating a blog has to take second place. (Although some people would have a difference of opinion on that...). This post, although specific to Cisco IOS SIP Diversion, is really a continuation of the series.

The Problem

By default, SIP Diversion headers generated by a Cisco IOS UA will contain the IP address of the SIP UA in the host element of the Diversion URI. For example:

Diversion: <sip:9498351991@208.57.21.106>;privacy=off;screen=no

Technically this is valid. However, this causes a problem when using a SIP trunk to Broadworks since the Application Server uses the host element of the URI to determine which realm to search for the subscriber in. Sending an Invite with the Diversion header in this format will usually result in a 604 Does Not Exist Anywhere in cases of Call Forwarding or External Transfer.

A Solution (Not necessarily THE solution)

A solution? There are probably dozens of different ways to solve this problem, but if you have an Acme Packet SBC using SIP Header Manipluation is a quick and simple way to remedy the issue. Here is an example HMR that will translate any incoming Diversion headers containing an IP address into a specific DNS FQDN. The DNS FQDN configured here should be the subscriber domain on your Broadworks Application Server.

sip-manipulation
    name                           CPEFixes
    description                    Fixes for CPE Header Inconsistencies
    header-rule
        name                           Diversion
        header-name                    Diversion
        action                         manipulate
        comparison-type                case-sensitive
        match-value                    
        msg-type                       request
        new-value                      
        methods                        INVITE
        element-rule
            name                           DiversionHost
            parameter-name                 
            type                           uri-host
            action                         replace
            match-val-type                 ip
            comparison-type                case-sensitive
            match-value                    
            new-value                      my.broadworks.realm

You will need to apply this rule to your Access SIP interface "in-manipulationid" parameter. One thing to point out about this solution is it will not work if you virtual host multiple Broadworks domains on the same Acme Realm.

Cisco IOS Diversion Configuration

One request that constantly comes in is a fix for Call Forwarding and External Transfer on SIP to PRI applications and I've discussed some of the difficulties with this in previous posts. Part of the problem is the lack of PBX systems that actually support sending the ISDN RDNIS informational element which would be translated by the IAD into the diversion header. In theory this would be the customer or the customer vendor's problem but in practice it usually falls to the Service Provider to find a solution. One way to "remedy" the situation is to assign a static redirecting number (Diversion URI) to all outgoing calls. One specific case you would NOT want to send the Diversion is with calls where Caller ID Blocking is desired. So it's important to remember to build specific dial-peers for calls where Diversion is not intended. The following is a partial configuration that gives an example of assigning the fixed number 9498351990 as the Diversion URI user. This would result in this Diversion header being inserted into outgoing Invites.

Diversion: <sip:9498351990@208.57.21.106>;privacy=off;screen=no
voice translation-rule 1
 rule 1 /^1\(..........\)$/ /\1/
!
voice translation-rule 5
 rule 1 // /9498351990/
!
voice translation-profile Broadworks
 translate calling 1
 translate called 1
 translate redirect-called 5
!
dial-peer voice 50 voip
 translation-profile outgoing Broadworks
 huntstop
 destination-pattern 1..........
 session protocol sipv2
 session target sip-server
 dtmf-relay rtp-nte
 codec transparent

What this example achieves is inserting the Diversion header for any calls beginning with 1 and having any 10 digits following (Basic 1+10 dialing). Another translation-profile could be built that does not include the redirect-called element for dial-peers that match *67 for Caller ID Blocking.

And there we have it, how to statically assign Diversion on Cisco IOS. This will work for both TDM PRI and SIP trunking customers using Cisco Unified Border Element.

Sadly, this is a Cisco only solution. Adtran has not yet developed an AOS equivalent of Cisco's translation-profile and until they reach that point it will be a struggle. As of A01.03 they claim to have implemented basic ISDN RDNIS to SIP Diversion functionality but I have not had an opportunity to verify if it works properly with Broadworks. Stay tuned for that one...