[VoiceOps] Call Forwarding is broken; or, when CF meets LCR

Nathan Anderson nathana at fsr.com
Sat Mar 16 04:28:44 EDT 2013

(Maybe there is a better place to discuss this, like SIPForum or SIP-Implementors, but because of the chance that there is something I'm missing here, I decided to float this by y'all first for feedback.  BTW, I'd also LOVE any input from various carriers & termination providers that might be subscribed to this list...perhaps you have implemented solutions of your own to this problem that I am unaware of.)

So, I got to thinking about call forwarding recently, and how it seems to me that CF, specifically at the point where IP meets PSTN (such as with interconnected VoIP providers like ourselves), is inherently broken.  (Although it could also be argued that the PSTN itself is inherently broken, being filled with layers of legacy cruft and overly burdened with decades of bass-ackwards regulation, but I digress.)

Allow me to explain.

In pure IP land, because SIP endpoints have intelligence and are not mere dumb terminals, CF is easy.  If the target peer is set to divert calls elsewhere, it can just signal back to the calling party (typically using SIP 3xx response codes) what address it should, in fact, be calling instead to reach this user, and it's then up to the caller's user agent to directly INVITE the forwarding target.  Or if a call transfer is desired after media is already established between peers, REFER is used to cause the transferee to generate a new direct INVITE to the transfer target.  The end result in either case is that the responsibility for ultimately taking the *action* needed to forward or transfer a call belongs to the original caller or transferee, *not* the callee or transferor.  The caller/transferee's endpoint simply uses signalling information it's been given to, in essence, hang up the existing call and then place a new call to the new target.

In the PSTN, things are more complicated due to billing issues, as well as due to the fact that by-and-large the intelligence is all in the switching infrastructure instead of the handsets, but overall it's still pretty simple to understand.  As I understand it, a call forward is really, at its most basic level, the hairpinning of a call within the target switch.  Neither the caller nor the caller's switch even need know that a call forward was requested or is occurring.  This is only fair when you think about it: since the caller pays for the call, it wouldn't be good if a call forward on the PSTN caused the caller's switch to blindly divert the call elsewhere upon instruction from a remote switch without the caller's consent, since this could potentially lead to the caller paying a higher rate for the call than he/she assumed the rate would be based on the originally dialed number (for example, if the caller dialed a local number that was in turn set to forward to a number on the other side of the country).  So, typically, the callee who put the call forward in place picks up the tab on the forwarded leg of the call.

Now, as an interconnected VoIP provider which gives their users the option of configuring their account to forward to off-network numbers, this is the problem we face: as far as I am aware or have been able to determine (and I hope I'm wrong/missing something), most SIP-based termination providers blend ANI and Calling Number ID together.  They'll either use PAI as the ANI/CNID, or, if PAI isn't present, use From.  But both ANI and CNID for that call will be determined by a single parameter, and so will always match each other.

Why is that a problem?  Well, since we are interconnected to the PSTN, we can't just pass back any SIP 3xx responses we get to the carrier during call set-up and expect them to just deal with it for us and bill us appropriately, or in the case where the call forward is set on our side and our customer's endpoint is never even sent an INVITE, we can't generate a SIP 3xx response to the originating carrier ourselves.  (I suppose if we used the same carrier for origination and termination, it might be an option to send back SIP 3xx to them as a response to an incoming INVITE, but I'm not sure how most carriers would deal with or respond to that...I imagine it varies.  But we use different carriers for origination and termination anyway, so that's not even an option "in theory.")  To forward off-net, we have to generate a second call leg ourselves by INVITEing out through our term provider, and then bridging the two calls.  When we do this, we are faced with a decision: what do we use as ANI/CNID for the forwarded call?  Since we can't specify both ANI and CNID separately, we are forced to choose one number to represet both.

The problem is that there are really only two options, and neither option does exactly the right thing.

Our first option is to stuff my subscriber's number -- the dialed TN (DNIS) -- into PAI and From, but then the phone being forwarded to would not show the number of the actual caller to the recipient, and I think most people want and EXPECT their phone to always show them the caller's CNID, and not the number that is being billed for the forwarding (although perhaps some people might find it helpful to know whether the person calling was redirected to this phone and from where, or whether the caller dialed this phone directly).

The second option is to stuff the caller's CNID into PAI and From, which would display the right thing on the phone at the end of the forwarding chain.  However, there is a huge problem with this!  The term network bases their routing/LCR decisions on these fields, and the rate that is charged for the call is also based on these fields.  So even though the callee that put the forward in place is picking up the tab on this leg of the call, the call is being BILLED and ROUTED based on the CALLER'S Caller-ID, NOT based on my subscriber's ANI!  This is wrong, wrong, wrong!  What happens if one of my subscribers has a forward in place on his main TN to a number outside of his LATA, and someone from within the LATA of the number he is forwarding to calls his main TN?  I get dinged for an intraLATA call that *should* have been classified as interLATA, that's what!

We need some way of being able to signal ANI and CNID *separately* to SIP->PSTN termination providers, so that the call is routed properly AND the correct Caller-ID number shows up on the final telephone at the end of the chain.  You shouldn't have to pick between the two; native PSTN calls don't.  As far as I can tell, there is no standard way of doing this.  I have even run some experiments, and so far have not been able to make a correct educated guess about how some of these providers *might* have decided to implement such a feature on their side (whether documented or undocumented), assuming that any of them have.  Here are two options that I thought might be reasonable enough to try:

1) PAI is an optional SIP header field; if it is present and does not match From, perhaps From should be used as CNID, and PAI as ANI.  In my experience, SIP term providers typically only consult From as a last resort if PAI is not present; if it is, From is ignored completely.  I haven't found an example of one that honors both fields in this way.

2) When a call forward occurs on the PSTN, RDNIS/RGN (forwarding number) is typically included in the SS7 signalling at the final switch.  There are a couple of SIP header fields that people have conjured up to fill a similar role: Diversion (which was described in an IEFT draft and has seemingly become a "de facto" standard of sorts, much like Remote-Party-ID was before PAI arrived), and History-Info (which actually made it into an RFC, 4244).  Perhaps, in the event of a forwarded call, it would make sense for term providers to use Diversion or History-Info to inform them of what to use as ANI.  I attempted to send calls out with one field or the other included in the header, but it made no difference: either PAI (if present) or From (if PAI not present) continued to be used as the sole source for both ANI and CNID.

Am I missing something here?  Is there a standard way of doing this (or at least a not-exactly-standard-but-generally-accepted way)?  Or is this really something that nobody has paid the attention that (I would argue) it's due?

Thanks for any suggestions or feedback you may have.


Nathan Anderson
First Step Internet, LLC
nathana at fsr.com

More information about the VoiceOps mailing list