RFC 5806

Diversion Indication in SIP

πŸ“… published March 2010, from ietf

RFC 5806: Diversion Indication in SIP ✨

Independent Submission 🌸 This one came in through the independent stream, not a working group.

Author: S. Levy (Cisco Systems) πŸ’–

Editor: M. Mohali, Ed. (Orange Labs) 🫢

Category: Historic πŸ“œ It's published for the historical record.

ISSN: 2070-1721

Date: March 2010 πŸ¦‹

The title block doesn't list anything this RFC obsoletes or updates, so it's a solo little legend πŸ’…

Abstract

okay so this RFC is basically the text of an Internet Draft that was first submitted to the SIP Working Group. It's getting published now for the historical record, and so later Informational RFCs have something to point at πŸ“š

here's the main idea πŸ”₯ this document proposes an extension to the Session Initiation Protocol (SIP). The extension lets the called SIP user agent figure out who the call was diverted from, and why it got diverted. It defines a general header called Diversion, which carries that diversion info from other SIP user agents and proxies over to the called user agent πŸ’Œ

and it's giving feature support πŸ’… it helps with Unified Messaging, Third-Party Voicemail, and Automatic Call Distribution (ACD). SIP user agents and SIP proxies that receive diversion info can use it as extra context when they decide whether to invoke a feature 🧚

Status of This Memo

this document is not an Internet Standards Track specification πŸ™ˆ it's published purely for the historical record.

it defines a Historic Document for the Internet community. It's a contribution to the RFC Series, independent of any other RFC stream. The RFC Editor chose to publish it at their discretion and makes no statement about its value for implementation or deployment. Documents the RFC Editor approves for publication aren't candidates for any level of Internet Standard. See Section 2 of RFC 5741 for that.

for the latest status, errata, and feedback info, check http://www.rfc-editor.org/info/rfc5806 πŸ”—

IESG Note

this one was an early proposal to the IETF SIP Working Group that didn't get chosen for standardization 😭 the discussion ended up producing the informational RFC 3325, "Private Extensions to the Session Initiation Protocol (SIP) for Asserted Identity within Trusted Networks". The standard solution that got picked is RFC 4244, "An Extension to the Session Initiation Protocol (SIP) for Request History Information" πŸŽ€

Copyright (c) 2010 IETF Trust and the persons identified as the document authors. All rights reserved.

this document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication. Please read those carefully, because they spell out your rights and restrictions for this document πŸ“–

Table of Contents

   1. Introduction ....................................................4
   2. Terminology .....................................................4
      2.1. Requirements Language ......................................4
      2.2. Definitions ................................................4
      2.3. Abbreviations ..............................................5
   3. Overview ........................................................5
      3.1. When Is the Diversion Header Used? .........................6
   4. Extension Syntax ................................................6
   5. Detailed Semantics ..............................................7
      5.1. UAS Behavior ...............................................7
      5.2. UAC Behavior ...............................................7
      5.3. Redirect Server Behavior ...................................7
      5.4. Proxy Server Behavior ......................................7
   6. Examples Using Diversion Header .................................8
      6.1. Call Forward Unconditional .................................8
      6.2. Call Forward on Busy ......................................13
      6.3. Call Forward on No-Answer .................................17
      6.4. Call Forward on Unavailable ...............................21
      6.5. Multiple Diversions .......................................24
   7. Security Considerations ........................................27
   8. Further Examples ...............................................27
      8.1. Night Service/Automatic Call Distribution (ACD)
           Using Diversion Header ....................................27
      8.2. Voicemail Service Using Diversion Header ..................36
      8.3. Questions and Answers on Alternative Approaches ...........41
 9. Mapping ISUP/ISDN Redirection Information to SIP
      Diversion Header ...............................................42
      9.1. Mapping ISUP/ISDN Diversion Reason Codes ..................42
      9.2. Mapping ISUP Redirection Information to SIP
           Diversion Header ..........................................43
      9.3. Mapping ISDN Redirection Information to SIP
           Diversion Header ..........................................47
      9.4. Information Loss in SIP to ISUP/ISDN Translation ..........52
   10. Contributors ..................................................53
   11. Acknowledgements ..............................................53
   12. Normative References ..........................................53

1. Introduction ✨

this RFC is, again, the text of an Internet Draft that was first submitted to the SIP Working Group. It's being published now for the historical record and to give later Informational RFCs a reference πŸ¦‹

so, in the legacy telephony network, redirection info gets passed around inside ISDN/ISUP (ISDN User Part) signaling messages πŸ“ž various service providers and business apps use that info to build enhanced features for end users πŸ’…

the idea here is to create an analogous mechanism for SIP users, so they can get those same enhanced features too 🌈

The Diversion header lets you build feature logic around who the call was diverted from πŸŽ€

2. Terminology πŸ“

2.1. Requirements Language

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

2.2. Definitions

diversion: πŸ“ this is a change to the ultimate destination endpoint of a request. It's a change in the Request-URI of a request that wasn't caused by a routing decision. People also call it a deflection or a redirection.

A diversion can happen when the "user" portion of the Request-URI changes for a reason other than expansion or translation.

A diversion can also happen when only the "host" portion of the Request-URI has changed, as long as the change was due to a non-routing decision.

divertor: the entity that diverted the call 🫒

recursing: a SIP proxy or user agent that handles a received or internally generated 3xx response by forking new request(s) itself πŸ”

non-recursing: a SIP proxy or user agent that handles a received or internally generated 3xx response by forwarding it upstream ⬆️

2.3. Abbreviations

   CFUNC: Call Forward Unconditional

   CFTOD: Call Forward Time-of-Day

   CFB:   Call Forward on Busy

   CFNA:  Call Forward on No Answer

   CFUNV: Call Forward Unavailable

   ACD:   Automatic Call Distribution

3. Overview 🧚

so, to build certain third-party features like Third-Party Voicemail and Automatic Call Distribution (ACD) apps, the called third party needs diversion info so they can respond to the caller intelligently πŸ’œ when a call gets diverted, the party receiving it needs answers to two questions:

Question 1: From whom was the request diverted?

Question 2: Why was the request diverted?

this document proposes using the Diversion header to answer both of those for the party receiving the diverted call πŸ’–

Putting the previous Request-URI (from before the diversion happened) into the Diversion header answers question 1 πŸ™Œ

Putting the "reason" tag into the Diversion header (added by the divertor) answers question 2 ✨

3.1. When Is the Diversion Header Used?

The Diversion header SHOULD be added when a SIP proxy server, SIP redirect server, or SIP user agent changes the ultimate endpoint that will receive the call.

Diversion info SHOULD NOT be added for normal call routing changes to the Request-URI πŸ™…β€β™€οΈ so the Diversion header isn't added when features like speed dial change the Request-URI.

When a diversion happens, a Diversion header SHOULD be added to the forwarded request or the forwarded 3xx response. The Diversion header MUST contain the Request-URI of the request prior to the diversion. The Diversion header SHOULD contain a reason that the diversion occurred πŸŽ€

Existing Diversion headers received in an incoming request MUST NOT be removed or changed in forwarded requests. No touching them, bestie 🫢

Existing Diversion headers received in an incoming response MUST NOT be removed or changed in the forwarded response. Same rule, different direction πŸ’…

A Diversion header gets added when features like call forwarding or call deflection change the Request-URI πŸ¦‹

4. Extension Syntax 🌸

the syntax of the Diversion header is below πŸ‘‡ (it's a grammar, so it's staying in code exactly as written)

   Diversion = "Diversion" ":" 1# (name-addr *( ";" diversion_params ))
   diversion-params = diversion-reason | diversion-counter |
                      diversion-limit | diversion-privacy |
                      diversion-screen | diversion-extension
   diversion-reason = "reason" "="
                   ( "unknown" | "user-busy" | "no-answer" |
                     "unavailable" | "unconditional" |
                     "time-of-day" | "do-not-disturb" |
                     "deflection" | "follow-me" |
                     "out-of-service" | "away" |
                     token | quoted-string )
   diversion-counter = "counter" "=" 1*2DIGIT
   diversion-limit = "limit" "=" 1*2DIGIT
   diversion-privacy = "privacy" "=" ( "full" | "name" |
                       "uri" | "off" | token | quoted-string )
   diversion-screen = "screen" "=" ( "yes" | "no" | token |
                                        quoted-string )
   diversion-extension = token ["=" (token | quoted-string)]

this is an extension of tables 4 and 5 in [RFC3261] for the Diversion header πŸ“Š

                       where  enc.  e-e ACK BYE CAN INV OPT REG
   _____________________________________________________________
   Diversion              R           h   -   -   -   o   -   -
   Diversion             3xx          h   -   -   -   o   -   -

5. Detailed Semantics πŸ’Ž

5.1. UAS Behavior

A SIP User Agent Service (UAS) that receives a request and returns a 3xx SHOULD add a Diversion header containing the previous Request-URI and the reason for the diversion 🌈

5.2. UAC Behavior

A SIP UAC that receives a 3xx containing a Diversion header SHOULD copy the Diversion header into each downstream forked request that resulted from the 3xx πŸ’

5.3. Redirect Server Behavior

A SIP redirect server that receives a request and returns a 3xx containing a Contact that diverts the request to a different endpoint SHOULD add a Diversion header containing the Request-URI from the incoming request and the reason for the diversion 🧁

5.4. Proxy Server Behavior ✨

Okay so, non-recursing SIP proxies, listen up πŸ‘‚. If one of them gets a 3xx that has a Diversion header in it, it SHOULD forward that 3xx upstream unchanged πŸ’….

If a SIP proxy gets a request and runs a feature that changes the Request-URI on the request it forwards (so the call gets diverted to a different endpoint), it SHOULD add a Diversion header. That header carries the Request-URI from the incoming request plus the reason for the diversion πŸ¦‹.

Same energy if a SIP proxy gets a request and sends back a 3xx with a Contact that diverts the call to someone else. It SHOULD add a Diversion header with the incoming Request-URI and the reason πŸŽ€.

5.4.1. Proxy Logic for Diversion Header 🧠

Here's the decision tree, bestie. It's giving flowchart energy 🌳

      if (pdu.is_request()) {
          if (request-URI is changed due to a called feature) {
              if (proxy.is_recursing()) {
                  Add the Diversion header (indicating the reason
                    that the call has been diverted) to
                    the downstream forwarded request(s).
              } else {
                  Add the Diversion header (indicating the reason
                    that the call has been diverted) to
                    the upstream forwarded 3xx response.
              }
          }
      } else if (pdu.is_response()) {
          if (pdu.is_3xx()) {
              if (proxy.is_recursing()) {
                Copy Diversion header into forwarded INVITE(s).
              } else {
                Forward response upstream.
              }
          }
      }

6. Examples Using Diversion Header πŸŽ€

There are a bunch of ways to build call forwarding features, and they can be done by recursing or non-recursing SIP proxies, or by SIP user agents πŸ’œ.

A SIP proxy or user agent that generates or forwards 3xxs upstream is non-recursing. A SIP proxy or user agent that handles received (or internally generated) 3xxs itself is recursing. Iconic terminology, no cap 🫢.

The examples below show how the Diversion header gets used in some of the recursing and non-recursing variants. Let's go πŸš€.

6.1. Call Forward Unconditional πŸ¦‹

Here's how the Diversion header shows up in a few different versions of Call Forward Unconditional πŸ’….

6.1.1. Network Call Forward Unconditional (P2 Recursing) 🌸

In this flow, the call would normally go to Bob@B. But Proxy 2 (P2) recursively implements Call Forward Unconditional (CFUNC) to Carol@C, so it's giving plot twist 😭.

                     +------------------------+
                     | Bob@P2: CFUNC->Carol@C |
                     +------+-----------------+
                             \
                              \
A             P1              P2            B          C
                            recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |              |--INVITE Carol@C------->|
|              |              |  Diversion: Bob@P2     |
|              |              |    ;reason=unconditional
|              |              |             |          |
|              |              |<-200-------------------|
|              |              |             |          |
|              |<-200---------|             |          |
|              |              |             |          |
|<-200---------|              |             |          |
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.1.2. Network Call Forward Unconditional (P1 Non-Recursing, P2 Non-Recursing) 🫧

In this flow, Proxy 2 (P2) non-recursively implements CFUNC to Carol@C. Proxy 1 (P1) is non-recursing too, so nobody's handling the 3xx in the middle πŸ™ˆ.

                     +------------------------+
                     | Bob@P2: CFUNC->Carol@C |
                     +------+-----------------+
                             \
                              \
A              P1             P2            B          C
            non-recursing  non-recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |<-302---------|             |          |
|              |  Contact: Carol@C          |          |
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=unconditional   |          |
|              |              |             |          |
|              |--ACK-------->|             |          |
|              |              |             |          |
|<-302---------|              |             |          |
|  Contact: Carol@C           |             |          |
|  Diversion: Bob@P2          |             |          |
|    ;reason=unconditional    |             |          |
|              |              |             |          |
|--ACK-------->|              |             |          |
|              |              |             |          |
|--INVITE Carol@C------------------------------------->|
|  Diversion: Bob@P2          |             |          |
|    ;reason=unconditional    |             |          |
|              |              |             |          |
|<-200-------------------------------------------------|
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.1.3. Network Call Forward Unconditional (P1 Recursing, P2 Non-Recursing) 🧚

In this flow, Proxy 2 (P2) non-recursively implements CFUNC to Carol@C. This time Proxy 1 (P1) is recursing, so it takes the 3xx and does the INVITE to Carol itself ✨.

                     +------------------------+
                     | Bob@P2: CFUNC->Carol@C |
                     +------+-----------------+
                             \
                              \
A              P1             P2            B          C
            recursing      non-recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |<-302---------|             |          |
|              |  Contact: Carol@C          |          |
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=unconditional   |          |
|              |              |             |          |
|              |--ACK-------->|             |          |
|              |              |             |          |
|              |--INVITE Carol@C---------------------->|
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=unconditional   |          |
|              |              |             |          |
|              |<-200----------------------------------|
|              |              |             |          |
|<-200---------|              |             |          |
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.1.4. Endpoint Call Forward Unconditional (P1 Recursing, P2 Non-Recursing) πŸ’œ

This time it's user agent server B (B) that non-recursively implements CFUNC to Carol@C, so the endpoint is the one doing the forwarding πŸ“±. Proxy 2 (P2) is non-recursing, and Proxy 1 (P1) is recursing.

                                    +-----------------------+
                                    | Bob@B: CFUNC->Carol@C |
                                    +------+----------------+
                                            \
                                             \
A              P1             P2              B          C
            recursing      non-recursing
|              |              |               |          |
|--INV Bob@P1->|              |               |          |
|              |              |               |          |
|              |--INV Bob@P2->|               |          |
|              |              |--INV Bob@B--->|          |
|              |              |               |          |
|              |              |<-302----------|          |
|              |              |  Contact: Carol@C        |
|              |              |  Diversion: Bob@B        |
|              |              |    ;reason=unconditional
|              |              |               |          |
|              |              |--ACK--------->|          |
|              |              |               |          |
|              |<-302---------|               |          |
|              |  Contact: Carol@C            |          |
|              |  Diversion: Bob@B            |          |
|              |    ;reason=unconditional     |          |
|              |              |               |          |
|              |--ACK-------->|               |          |
|              |              |               |          |
|              |--INVITE Carol@C------------------------>|
|              |  Diversion: Bob@B            |          |
|              |    ;reason=unconditional     |          |
|              |              |               |          |
|              |<-200------------------------------------|
|              |              |               |          |
|<-200---------|              |               |          |
|              |              |               |          |
|--ACK-------------------------------------------------->|
|              |              |               |          |
|              |              |               |          |

6.2. Call Forward on Busy πŸ“ž

Next up, the Diversion header in a few different variants of Call Forward on Busy πŸ“.

6.2.1. Network Call Forward on Busy (P2 Recursing)

okay so in this one, Proxy 2 (P2) is the one handling Call Forward on Busy (CFB) to Carol@C, and it's doing it recursively πŸ’… Bob's call goes to P1, P1 passes it to P2, and P2 sends it on to Bob@B. Bob is busy, so B sends back a 486, and then P2 is like "cool, we're forwarding this to Carol" πŸ¦‹

                     +----------------------+
                     | Bob@P2: CFB->Carol@C |
                     +------+---------------+
                             \
                              \
A              P1             P2            B          C
                           recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |              |--INV Bob@B->|          |
|              |              |             |          |
|              |              |<-486--------|          |
|              |              |             |          |
|              |              |--ACK------->|          |
|              |              |             |          |
|              |              |--INVITE Carol@C------->|
|              |              |  Diversion: Bob@P2     |
|              |              |    ;reason=user-busy   |
|              |              |             |          |
|              |              |<-200-------------------|
|              |              |             |          |
|              |<-200---------|             |          |
|              |              |             |          |
|<-200---------|              |             |          |
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.2.2. Network Call Forward on Busy (P1 Non-Recursing, P2 Non-Recursing)

this time P2 is non-recursive with the CFB to Carol@C πŸŽ€ and P1 is non-recursing too, so instead of P1 handling the forward itself, it just gets a 302 with the Contact and Diversion info and bounces it back to the caller. Then the caller sends the INVITE to Carol@C directly. literally so clean 🧚

                     +----------------------+
                     | Bob@P2: CFB->Carol@C |
                     +------+---------------+
                             \
                              \
A              P1             P2            B          C
            non-recursing  non-recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |              |--INV Bob@B->|          |
|              |              |             |          |
|              |              |<-486--------|          |
|              |              |             |          |
|              |              |--ACK------->|          |
|              |              |             |          |
|              |<-302---------|             |          |
|              |  Contact: Carol@C          |          |
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=user-busy       |          |
|              |              |             |          |
|              |--ACK-------->|             |          |
|              |              |             |          |
|<-302---------|              |             |          |
|  Contact: Carol@C           |             |          |
|  Diversion: Bob@P2          |             |          |
|    ;reason=user-busy        |             |          |
|              |              |             |          |
|--ACK-------->|              |             |          |
|              |              |             |          |
|--INVITE Carol@C------------------------------------->|
|  Diversion: Bob@P2          |             |          |
|    ;reason=user-busy        |             |          |
|              |              |             |          |
|<-200-------------------------------------------------|
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.2.3. Network Call Forward on Busy (P1 Recursing, P2 Non-Recursing)

so here P2 is still non-recursive with CFB to Carol@C, but now P1 is the one that's recursing 🌸 P2 sends the 302 back up to P1, and P1 is the one that goes "ooh, I got this" and sends the INVITE to Carol@C itself. the Diversion header rides along the whole way πŸŽ€

                     +----------------------+
                     | Bob@P2: CFB->Carol@C |
                     +------+---------------+
                             \
                              \
A              P1             P2            B          C
            recursing      non-recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |              |--INV Bob@B->|          |
|              |              |             |          |
|              |              |<-486--------|          |
|              |              |             |          |
|              |              |--ACK------->|          |
|              |              |             |          |
|              |<-302---------|             |          |
|              |  Contact: Carol@C          |          |
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=user-busy       |          |
|              |              |             |          |
|              |--ACK-------->|             |          |
|              |              |             |          |
|              |--INVITE Carol@C---------------------->|
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=user-busy       |          |
|              |              |             |          |
|              |<-200----------------------------------|
|              |              |             |          |
|<-200---------|              |             |          |
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.2.4. Endpoint Call Forward on Busy (P1 Recursing, P2 Non-Recursing)

this one is a little different bc it's the endpoint, user agent server B (B), doing the non-recursive CFB to Carol@C πŸ’– P2 is non-recursing and P1 is recursing. so B sends the 302 back, and it works its way up through P2 and P1, and P1 is the one that finally sends the INVITE to Carol@C ✨

                               +---------------------+
                               | Bob@B: CFB->Carol@C |
                               +------+--------------+
                                          \
                                           \
A              P1             P2            B          C
            recursing      non-recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |              |--INV Bob@B->|          |
|              |              |             |          |
|              |              |<-302--------|          |
|              |              |  Contact: Carol@C      |
|              |              |  Diversion: Bob@B      |
|              |              |    ;reason=user-busy   |
|              |              |             |          |
|              |              |--ACK------->|          |
|              |              |             |          |
|              |<-302---------|             |          |
|              |  Contact: Carol@C          |          |
|              |  Diversion: Bob@B          |          |
|              |    ;reason=user-busy       |          |
|              |              |             |          |
|              |--ACK-------->|             |          |
|              |              |             |          |
|              |--INVITE Carol@C---------------------->|
|              |  Diversion: Bob@B          |          |
|              |    ;reason-user-busy       |          |
|              |              |             |          |
|              |<-200----------------------------------|
|              |              |             |          |
|<-200---------|              |             |          |
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.3. Call Forward on No-Answer

next up is Call Forward on No-Answer πŸ™ˆ this section shows how the Diversion header gets used across a few different variant setups of it, so you can see how each one plays out 🫢

6.3.1. Network Call Forward on No-Answer (P2 Recursing)

in this flow, P2 is recursive with Call Forward on No Answer (CFNA) to Carol@C 🌈 Bob's phone rings (180), nobody picks up, and when the timeout hits, P2 sends the INVITE to Carol@C with the Diversion header saying ;reason=no-answer. so iconic πŸ‘‘

                     +-----------------------+
                     | Bob@P2: CFNA->Carol@C |
                     +------+----------------+
                             \
                              \
A              P1             P2            B          C
                           recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |              |--INV Bob@B->|          |
|              |              |             |          |
|              |              |<-180--------|          |
|              |              |             |          |
|              |              |             |          |
|              |              |             |          |
|              |           timeout          |          |
|              |              |--INVITE Carol@C------->|
|              |              |  Diversion: Bob@P2     |
|              |              |    ;reason=no-answer   |
|              |              |             |          |
|              |              |<-200-------------------|
|              |              |             |          |
|              |<-200---------|             |          |
|              |              |             |          |
|<-200---------|              |             |          |
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.3.2. Network Call Forward on No-Answer (P1 Non-Recursing, P2 Non-Recursing) πŸ“ž

okay so this one is giving non-recursing on both proxies πŸ’… In this message flow, Proxy 2 (P2) non-recursively implements Call Forward on No Answer (CFNA) to Carol@C. Proxy 1 (P1) is non-recursing too, so P1 just passes the redirect back instead of chasing it. bestie, this is the most chill version 🌸

                     +-----------------------+
                     | Bob@P2: CFNA->Carol@C |
                     +------+----------------+
                             \
                              \
A              P1             P2            B          C
            non-recursing  non-recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |              |--INV Bob@B->|          |
|              |              |             |          |
|              |              |<-180--------|          |
|              |              |             |          |
|              |              |             |          |
|              |              |             |          |
|              |           timeout          |          |
|              |<-302---------|             |          |
|              |  Contact: Carol@C          |          |
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=no-answer       |          |
|              |              |             |          |
|              |--ACK-------->|             |          |
|              |              |             |          |
|<-302---------|              |             |          |
|  Contact: Carol@C           |             |          |
|  Diversion: Bob@P2          |             |          |
|    ;reason=no-answer       |             |          |
|              |              |             |          |
|--ACK-------->|              |             |          |
|              |              |             |          |
|--INVITE Carol@C------------------------------------->|
|  Diversion: Bob@P2          |             |          |
|    ;reason=no-answer        |             |          |
|              |              |             |          |
|<-200-------------------------------------------------|
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |

6.3.3. Network Call Forward on No Answer (P1 Recursing, P2 Non-Recursing) πŸ¦‹

this one flips it up: P2 is still non-recursing for CFNA to Carol@C, but now P1 is recursing πŸ”₯ In this message flow, Proxy 2 (P2) non-recursively implements Call Forward on No Answer (CFNA) to Carol@C. Proxy 1 (P1) is recursing. Watch P1 take the redirect and handle the INVITE to Carol@C itself ✨

                     +-----------------------+
                     | Bob@P2: CFNA->Carol@C |
                     +------+----------------+
                             \
                              \
A              P1             P2            B          C
            recursing      non-recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |              |--INV Bob@B->|          |
|              |              |             |          |
|              |              |<-180--------|          |
|              |              |             |          |
|              |              |             |          |
|              |              |             |          |
|              |            timeout         |          |
|              |<-302---------|             |          |
|              |  Contact: Carol@C          |          |
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=no-answer       |          |
|              |              |             |          |
|              |--ACK-------->|             |          |
|              |              |             |          |
|              |--INVITE Carol@C---------------------->|
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=no-answer       |          |
|              |              |             |          |
|              |<-200----------------------------------|
|              |              |             |          |
|<-200---------|              |             |          |
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.3.4. Endpoint Call Forward on No-Answer (P1 Recursing, P2 Non-Recursing, B Non-Recursing) πŸ’–

this is the endpoint version πŸŽ€ Here, user agent server B (B) is the one non-recursively implementing Call Forward on No Answer (CFNA) to Carol@C. Proxy 2 (P2) is non-recursing, and Proxy 1 (P1) is recursing. So the redirect comes from Bob's own endpoint instead of a proxy, and P1 is the one that keeps going to Carol@C 🧚

                                  +----------------------+
                                  | Bob@B: CFNA->Carol@C |
                                  +------+---------------+
                                          \
                                           \
A              P1             P2            B          C
            recursing      non-recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |              |--INV Bob@B->|          |
|              |              |             |          |
|              |              |             |          |
|              |              |             |          |
|              |              |          timeout       |
|              |              |<-302--------|          |
|              |              |  Contact: Carol@C      |
|              |              |  Diversion: Bob@B      |
|              |              |    ;reason=no-answer   |
|              |              |             |          |
|              |              |--ACK------->|          |
|              |              |             |          |
|              |<-302---------|             |          |
|              |  Contact: Carol@C          |          |
|              |  Diversion: Bob@B          |          |
|              |    ;reason=no-answer       |          |
|              |              |             |          |
|              |--ACK-------->|             |          |
|              |              |             |          |
|              |--INVITE Carol@C---------------------->|
|              |  Diversion: Bob@B          |          |
|              |    ;reason-no-answer       |          |
|              |              |             |          |
|              |<-200----------------------------------|
|              |              |             |          |
|<-200---------|              |             |          |
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |

6.4. Call Forward on Unavailable 🌈

okay, time for Call Forward on Unavailable πŸ’… Here's how the Diversion header shows up across a few variant implementations of it. Each flow below shows a different way the same feature can get wired up, so keep your eyes peeled πŸ‘€

6.4.1. Network Call Forward on Unavailable (P2 Recursing) πŸ‘‘

in this one, Proxy 2 (P2) recursively implements Call Forward on Unavailable (CFUNV) to Carol@C πŸ”₯ P2 keeps retrying Bob@B, then times out and sends the INVITE over to Carol@C itself. honestly so iconic 😭

                     +------------------------+
                     | Bob@P2: CFUNV->Carol@C |
                     +------+-----------------+
                             \
                              \
A              P1             P2            B          C
                           recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|<-100---------|              |             |          |
|              |--INV Bob@P2->|             |          |
|              |<-100---------|             |          |
|              |              |--INV Bob@B->|          |
|              |              |--INV Bob@B->|          |
|              |              |--INV Bob@B->|          |
|              |              |  ...        |          |
|              |              |--INV Bob@B->|          |
|              |           timeout          |          |
|              |              |--INVITE Carol@C------->|
|              |              |  Diversion: Bob@P2     |
|              |              |    ;reason=unavailable
|              |              |             |          |
|              |              |<-200-------------------|
|              |              |             |          |
|              |<-200---------|              |          |
|              |              |             |          |
|<-200---------|              |             |          |
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.4.2. Network Call Forward on Unavailable (P1 Non-Recursing, P2 Non-Recursing) ✨

last one in this part 🫢 Proxy 2 (P2) non-recursively implements Call Forward on Unavailable (CFUNV) to Carol@C, and Proxy 1 (P1) is non-recursing too. so P1 hands the 302 back rather than sending the INVITE on, and the final INVITE to Carol@C goes out from the endpoint side πŸ’œ

                     +------------------------+
                     | Bob@P2: CFUNV->Carol@C |
                     +------+-----------------+
                             \
                              \
A              P1             P2            B          C
            non-recursing  non-recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|              |              |             |          |
|              |--INV Bob@P2->|             |          |
|              |              |             |          |
|              |<-100---------|             |          |
|              |              |             |          |
|<-100---------|              |             |          |
|              |              |--INV Bob@B->|          |
|              |              |--INV Bob@B->|          |
|              |              |--INV Bob@B->|          |
|              |              |  ...        |          |
|              |              |--INV Bob@B->|          |
|              |           timeout          |          |
|              |<-302---------|             |          |
|              |  Contact: Carol@C          |          |
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=unavailable     |          |
|              |              |             |          |
|              |--ACK-------->|             |          |
|              |              |             |          |
|<-302---------|              |             |          |
|  Contact: Carol@C           |             |          |
|  Diversion: Bob@P2          |             |          |
|    ;reason=unavailable      |             |          |
|              |              |             |          |
|--ACK-------->|              |             |          |
|              |              |             |          |
|--INVITE Carol@C------------------------------------->|
|  Diversion: Bob@P2          |             |          |
|    ;reason=unavailable      |             |          |
|              |              |             |          |
|<-200-------------------------------------------------|
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.4.3. Network Call Forward on Unavailable (P1 Recursing, P2 Non-Recursing) πŸ¦‹

okay so in this one, Proxy 2 (P2) is non-recursing and does Call Forward on Unavailable (CFUNV) to Carol@C πŸ“ž. Proxy 1 (P1) is the recursing one πŸ”. Here's how the whole thing plays out ✨

                     +------------------------+
                     | Bob@P2: CFUNV->Carol@C |
                     +------+-----------------+
                             \
                              \
A              P1             P2            B          C
            recursing      non-recursing
|              |              |             |          |
|--INV Bob@P1->|              |             |          |
|<-100---------|              |             |          |
|              |--INV Bob@P2->|             |          |
|              |<-100---------|             |          |
|              |              |--INV Bob@B->|          |
|              |              |--INV Bob@B->|          |
|              |              |--INV Bob@B->|          |
|              |              |  ...        |          |
|              |              |--INV Bob@B->|          |
|              |           timeout          |          |
|              |<-302---------|             |          |
|              |  Contact: Carol@C          |          |
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=unavailable     |          |
|              |              |             |          |
|              |--ACK-------->|             |          |
|              |              |             |          |
|              |--INVITE Carol@C---------------------->|
|              |  Diversion: Bob@P2         |          |
|              |    ;reason=unavailable     |          |
|              |              |             |          |
|              |<-200----------------------------------|
|              |              |             |          |
|<-200---------|              |             |          |
|              |              |             |          |
|--ACK------------------------------------------------>|
|              |              |             |          |
|              |              |             |          |

6.5. Multiple Diversions 🌈

okay, so what happens when a call gets diverted more than once? πŸ‘€ The Diversion header gets used across multiple diversions, and the next two examples show exactly that πŸ’…

6.5.1. Call Forward Unconditional and Call Forward Busy πŸ’œ

in this flow, Proxy 2 (P2) does Call Forward Unconditional (CFUNC) to Carol@C πŸ“². Then Carol's endpoint does Call Forward on Busy (CFB) to 5551234@D πŸ“ž. P2 is non-recursing, P1 is recursing, and C is non-recursing too 🫢

            +------------------------+     +-------------------------+
            | Bob@P2: CFUNC->Carol@C |     | Carol@C: CFB->5551234@D |
            +---------------+--------+     +--------+----------------+
                             \                       \
                              \                       \
A              P1             P2            B          C          D
            recursing      non-recursing          non-recursing
|              |              |             |          |          |
|--INV Bob@P1->|              |             |          |          |
|              |              |             |          |          |
|              |--INV Bob@P2->|             |          |          |
|              |              |             |          |          |
|              |<-302---------|             |          |          |
|              |  Contact: Carol@C          |          |          |
|              |  Diversion: Bob@P2         |          |          |
|              |    ;reason=unconditional   |          |          |
|              |              |             |          |          |
|              |--ACK-------->|             |          |          |
|              |              |             |          |          |
|              |--INVITE Carol@C---------------------->|          |
|              |  Diversion: Bob@P2         |          |          |
|              |    ;reason=unconditional   |          |          |
|              |              |             |          |          |
|              |<-302----------------------------------|          |
|              |  Contact: 5551234@D        |          |          |
|              |  Diversion: Carol@C        |          |          |
|              |    ;reason=user-busy       |          |          |
|              |    ;privacy="full"         |          |          |
|              |  Diversion: Bob@P2         |          |          |
|              |    ;reason=unconditional   |          |          |
|              |              |             |          |          |
|              |--ACK--------------------------------->|          |
|              |              |             |          |          |
|              |--INVITE 5551234@D------------------------------->|
|              |  Diversion: Carol@C        |          |          |
|              |    ;reason=user-busy       |          |          |
|              |    ;privacy="full"         |          |          |
|              |  Diversion: Bob@P2         |          |          |
|              |    ;reason=unconditional   |          |          |
|              |              |             |          |          |
|              |<-200---------------------------------------------|
|              |              |             |          |          |
|<-200---------|              |             |          |          |
|              |              |             |          |          |
|--ACK----------------------------------------------------------->|
|              |              |             |          |          |
|              |              |             |          |          |

6.5.2. Call Forward Unconditional and Call Forward No Answer πŸŽ€

in this one, Proxy 2 (P2) does Call Forward Unconditional (CFUNC) to Carol@C πŸ“². P2 would normally have routed the call to B, but it doesn't here πŸ™ˆ. Then Carol's endpoint does Call Forward on No Answer (CFNA) to 5551234@D πŸ“ž. P2 is recursing, and C is recursing as well πŸ”

         +------------------------+  +--------------------------+
         | Bob@P2: CFUNC->Carol@C |  | Carol@C: CFNA->5551234@D |
         +------------------+-----+  +-----+--------------------+
                             \              \
                              \              \
A              P1             P2       B      C                 D
                            recursing       recursing
|              |              |        |      |                 |
|--INV Bob@P1->|              |        |      |                 |
|              |              |        |      |                 |
|              |--INV Bob@P2->|        |      |                 |
|              |              |        |      |                 |
|              |              |--INV Carol@C->|                 |
|              |              |  Diversion: Bob@P2              |
|              |              |    ;reason=unconditional        |
|              |              |        |      |                 |
|              |              |<--180---------|                 |
|              |              |        |      |                 |
|              |<-180---------|        |      |                 |
|              |              |        |      |                 |
|<-180---------|              |        |      |                 |
|              |              |        |      |                 |
|              |              |        |      |                 |
|              |              |        |    timeout             |
|              |              |        |      |--INV 5551234@D->|
|              |              |        |      |Diversion: Carol@C
|              |              |        |      |  ;reason=no-answer
|              |              |        |      |  ;privacy="full"
|              |              |        |      |Diversion: Bob@P2
|              |              |        |      |  ;reason= unconditional
|              |              |        |      |                 |
|              |              |        |      |<-200------------|
|              |              |        |      |         |       |
|              |              |<-200----------|         |       |
|              |              |        |      |         |       |
|              |<-200---------|        |      |         |       |
|              |              |        |      |         |       |
|<-200---------|              |        |      |         |       |
|              |              |        |      |         |       |
|--ACK--------------------------------------------------------->|
|              |              |        |      |         |       |

7. Security Considerations πŸ”

okay, real talk, this section is super important 😭 There are some privacy considerations when you use the Diversion header πŸ™ˆ Using it kind of implies that the diverting UAS trusts the diverted-to UAS 🀝 Using the Diversion header in SIP proxies or SIP user agents can leak route information and called information to untrusted SIP proxies and to untrusted callers in upstream 3xxs πŸ’€

Leakage of this information can be mitigated by having a recursing trusted upstream proxy server. πŸ›‘οΈ

For a SIP network architecture where all proxies are required to be non-recursive, Diversion header hiding may be considered necessary so that route information doesn't leak to the caller πŸ‘€ To do Diversion header hiding, a trusted upstream proxy would add a Record-Route header and use a secret key to encrypt the contents of the Diversion header in 3xxs that get forwarded upstream πŸ”‘ When re-INVITEs come in, the proxy would decrypt the contents of the Diversion header (using its secret key) and then forward the INVITE πŸ¦‹

There is no currently defined interaction between the Diversion and Hide headers. Question: Should there be? πŸ€”

8. Further Examples 🌸

Only the relevant headers have been included in the following examples πŸ’… The contents of the Session Description Protocols (SDPs) have also been omitted ✨

8.1. Night Service/Automatic Call Distribution (ACD) Using Diversion Header

okay so bestie, picture this πŸ•πŸŒΉ two totally separate companies, WeSellPizza.com and WeSellFlowers.com, both hired a third company, NightService.com, to pick up their calls at night. so after hours, the same receptionist, Carol, answers for both of them. the Diversion header is what lets Carol tell which company the call was meant for, so she can greet the caller by name. iconic teamwork 🫢

In the first flow, Alice calls for pizza. In the second flow, Alice calls for roses. Both calls land with the same night service company and the same receptionist, Carol. The Diversion header is what makes it work, because it lets Carol customize her greeting to the caller. main character energy πŸ’…

                +-------------------------------------+
                | WeSellPizza@P2: CFTOD->nightserv@P3 |
                +------------+------------------------+
                              \
                               \
UAC             P1             P2                 P3               UAS1
                        (WeSellPizza.com)  (NightService.com)
                                                (ACD)
| [1]           |              |                   |                  |
|-INV pizza@P1->|              |                   |                  |
|               |              |                   |                  |
|               |              |                   |                  |
|               | [2] INVITE WeSellPizza@P2        |                  |
|               |------------->|                   |                  |
|               |              |                   |                  |
|               |              | [3]               |                  |
|               |              |-INV nightserv@P3->|                  |
|               |              | Diversion: WeSellPizza@P2            |
|               |              |   ;reason=time-of-day                |
|               |              |                   |                  |
|               |              |                   | [4]              |
|               |              |                   |-INV Carol@uas1-->|
|               |              |            Diversion: WeSellPizza@P2 |
|               |              |                ;reason=time-of-day   |
|               |              |                   |                  |
|               |              |                   |<-[5] 200---------|
|               |              |<-[6] 200----------|                  |
|               |<-[7] 200-----|                   |                  |
|<-[8] 200------|              |                   |                  |
|               |              |                   |                  |
|--[9] ACK----------------------------------------------------------->|
|               |              |                   |                  |
|<=========================================="Hello, WeSellPizza"======|
|               |              |                   |                  |
|               |              |                   |                  |

Alice calls for pizza. πŸ•

[1] SIP UAC to SIP proxy server 1:

INVITE sip:pizza@p1.isp.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:pizza@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

so the ISP's originating proxy swaps the keyword pizza for the company WeSellPizza.com. ✨

[2] SIP proxy server 1 to SIP proxy server 2 (WeSellPizza.com):

INVITE sip:WeSellPizza@p2.isp.com SIP/2.0
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:pizza@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

it's after midnight and the pizza people are asleep 😴 luckily WeSellPizza.com hired NightService.com to answer their nighttime calls. so P2 does CFTOD to NightService.com. genius, honestly 🧠

[3] SIP proxy server 2 (WeSellPizza.com) to SIP proxy server 3 (NightService.com):

INVITE sip:NightService@p3.isp.com SIP/2.0
Via: SIP/2.0/UDP p2.isp.com
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:pizza@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Diversion: <sip:WeSellPizza@p2.isp.com>
  ;reason=time-of-day
Content-Type: application/sdp

Carol is free and ready to take the call πŸ’β€β™€οΈ

[4] SIP proxy server 3 (NightService.com) to UAS1 (Carol):

INVITE sip:carol@uas1.nightservice.com SIP/2.0
Via: SIP/2.0/UDP p3.isp.com
Via: SIP/2.0/UDP p2.isp.com
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:pizza@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Diversion: <sip:WeSellPizza@p2.isp.com>
  ;reason=time-of-day
Content-Type: application/sdp

the ACD reads the Diversion header and pulls up the WeSellPizza FAQ on Carol's web browser. the whole thing is so organized it's giving πŸŽ€

[5] UAS1 to SIP proxy server 3:

SIP/2.0 200 OK
Via: SIP/2.0/UDP p3.isp.com
Via: SIP/2.0/UDP p2.isp.com
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: carol@uas1.nightservice.com
From: sip:alice@isp.com
To: <sip:pizza@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[6] SIP proxy server 3 to SIP proxy server 2:

SIP/2.0 200 OK
Via: SIP/2.0/UDP p2.isp.com
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: carol@uas1.nightservice.com
From: sip:alice@isp.com
To: <sip:pizza@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[7] SIP proxy server 2 to SIP proxy server 1:

SIP/2.0 200 OK
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: carol@uas1.nightservice.com
From: sip:alice@isp.com
To: <sip:pizza@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[8] SIP proxy server 1 to UAC

SIP/2.0 200 OK
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: carol@uas1.nightservice.com
From: sip:alice@isp.com
To: <sip:pizza@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[9] SIP UAC to UAS1:

ACK sip:uas1.nightservice.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: <sip:pizza@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE

the RTP flows start and Carol picks up with "Hello, WeSellPizza. How may I help you?" πŸ•πŸ«Ά


                 +---------------------------------------+
                 | WeSellFlowers@P4: CFTOD->nightserv@P3 |
                 +-------------+-------------------------+
                                \
                                 \
UAC             P1               P4                 P3              UAS1
                         (WeSellFlowers.com)  (NightService.com)
                                                   (ACD)
| [1]           |                |                   |                |
|-INV roses@P1->|                |                   |                |
|               |                |                   |                |
|               | [2] INVITE WeSellFlowers@P4        |                |
|               |--------------->|                   |                |
|               |                |                   |                |
|               | [3]            |                   |                |
|               |<-302-----------|                   |                |
|               |  Contact: nightservice@P3          |                |
|               |  Diversion: WeSellFlowers@P4       |                |
|               |    ;reason=time-of-day             |                |
|               |                |                   |                |
|               |--[4] ACK------>|                   |                |
|               |                |                   |                |
|               | [5]            |                   |                |
|               |-INVITE nightservice@P3------------>|                |
|               | Diversion: WeSellFlowers@P4        |                |
|               |   ;reason=time-of-day              |                |
|               |                |                   |                |
|               |                |                   | [6]            |
|               |                |               -INV Carol@uas1----->|
|               |                |          Diversion: WeSellFlowers@P4
|               |                |            ;reason=time-of-day
|               |                |                                    |
|               |                |              |<-[7] 200------------|
|               |<-[8] 200---------------------------|                |
|<-[9] 200------|                |                   |                |
|               |                |                   |                |
|--[10] ACK---------------------------------------------------------->|
|               |                |                   |                |

Now Alice calls for roses. 🌹 Same night crew, different flowers.

[1] SIP UAC to SIP proxy server 1:

INVITE sip:roses@p1.isp.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:roses@p1.isp.com
Call-ID: 12345601@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

the ISP's originating proxy translates the keyword roses to the company WeSellFlowers.com. 🌸

[2] SIP proxy server 1 to SIP proxy server 4 (WeSellFlowers.com):

INVITE sip:WeSellFlowers@p4.isp.com SIP/2.0
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:roses@p1.isp.com
Call-ID: 12345601@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[3] SIP proxy server 4 (WeSellFlowers.com) redirects the call to NightService.com. Here the Diversion header is included, and the reason is time-of-day, since it's after hours at the flower shop πŸŒ™

SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: nightservice@p3.isp.com
Diversion: <sip:WeSellFlowers@p4.isp.com>
  ;reason=time-of-day
From: sip:alice@isp.com
To: sip:roses@p1.isp.com
Call-ID: 12345601@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[4] SIP proxy server 1 acknowledges the 302 response to SIP proxy server 4:

ACK sip:WeSellFlowers@p4.isp.com SIP/2.0
Via: SIP/2.0/UDP p1.isp.com
From: sip:alice@isp.com
To: sip:roses@p1.isp.com
Call-ID: 12345601@alice-pc.isp.com
CSeq: 1 INVITE

[5] SIP proxy server 1 sends a new INVITE to the Contact address the 302 gave it, which is NightService.com. The Diversion header rides along:

INVITE sip:nightservice@p3.isp.com SIP/2.0
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:roses@p1.isp.com
Call-ID: 12345601@alice-pc.isp.com
CSeq: 1 INVITE
Diversion: <sip:WeSellFlowers@p4.isp.com>
  ;reason=time-of-day
Content-Type: application/sdp

[6] SIP proxy server 3 (NightService.com) forwards the call to Carol. She's free, so the ACD gets to work and loads up the WeSellFlowers page for her. ✨

INVITE sip:carol@uas1.nightservice.com SIP/2.0
Via: SIP/2.0/UDP p3.isp.com
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:roses@p1.isp.com
Call-ID: 12345601@alice-pc.isp.com
CSeq: 1 INVITE
Diversion: <sip:WeSellFlowers@p4.isp.com>
  ;reason=time-of-day
Content-Type: application/sdp

[7] UAS1 (Carol) answers the call:

SIP/2.0 200 OK
Via: SIP/2.0/UDP p3.isp.com
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: carol@uas1.nightservice.com
From: sip:alice@isp.com
To: <sip:roses@p1.isp.com>;tag=uas1
Call-ID: 12345601@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[8] SIP proxy server 3 to SIP proxy server 1:

SIP/2.0 200 OK
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: carol@uas1.nightservice.com
From: sip:alice@isp.com
To: <sip:roses@p1.isp.com>;tag=uas1
Call-ID: 12345601@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[9] SIP proxy server 1 to UAC:

SIP/2.0 200 OK
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: carol@uas1.nightservice.com
From: sip:alice@isp.com
To: <sip:roses@p1.isp.com>;tag=uas1
Call-ID: 12345601@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[10] SIP UAC to UAS1:

ACK sip:uas1.nightservice.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: <sip:roses@p1.isp.com>;tag=uas1
Call-ID: 12345601@alice-pc.isp.com
CSeq: 1 INVITE

Carol picks up with a flower-specific greeting, and the call is officially connected. πŸ’ same receptionist, two totally different vibes, and the Diversion header is the reason she knows which one she's on πŸ‘‘

<=======================================""Hello, WeSellFlowers"=======

Alice calls for roses. 🌹

[1] SIP UAC to SIP proxy server 1:

INVITE sip:roses@p1.isp.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:roses@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

Okay so the ISP's originating proxy sees the keyword roses and translates it to the company WeSellFlowers.com 🌸 that's the glow-up moment!

[2] SIP proxy server 1 to SIP proxy server 4 (WeSellFlowers.com):

INVITE sip:WeSellFlowers@p4.isp.com SIP/2.0
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:roses@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

It's now 1 a.m. and the florists are also in bed. 😴 Fortunately, WeSellFlowers.com has contracted with NightService.com to answer their nighttime calls, too. πŸŒ™ So P4 does a CFTOD to NightService.com. Iconic multitasking, honestly πŸ’…

[3] SIP proxy server 4 (WeSellFlowers.com) to SIP proxy server 1 (NightService.com):

SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: NightService@p3.isp.com
From: sip:alice@isp.com
To: <sip:roses@p1.isp.com>;tag=p4
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Diversion: <sip:WeSellFlowers@p4.isp.com>
  ;reason=time-of-day

[4] SIP proxy server 1 to SIP proxy server 4 (WeSellFlowers.com):

ACK sip:uas1.nightservice.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: <sip:roses@p1.isp.com>;tag=p4
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE

[5] SIP proxy server 1 (WeSellFlowers.com) to SIP proxy server 3 (NightService.com):

INVITE sip:NightService@p3.isp.com SIP/2.0
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:roses@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Diversion: <sip:WeSellFlowers@p4.isp.com>
  ;reason=time-of-day
Content-Type: application/sdp

Carol is available to receive the incoming call. πŸŽ€

[6] SIP proxy server 3 (NightService.com) to UAS1 (Carol):

INVITE sip:carol@uas1.nightservice.com SIP/2.0
Via: SIP/2.0/UDP p3.isp.com
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:roses@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Diversion: <sip:WeSellFlowers@p4.isp.com>
  ;reason=time-of-day
Content-Type: application/sdp

The ACD keys off the Diversion header to pull up the WeSellFlowers FAQ on Carol's web browser. 🧚 That is such a main character move, no cap!

[7] SIP UAS1 to SIP proxy server 3:

SIP/2.0 200 OK
Via: SIP/2.0/UDP p3.isp.com
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: carol@uas1.nightservice.com
From: sip:alice@isp.com
To: <sip:roses@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[8] SIP proxy server 3 to SIP proxy server 1:

SIP/2.0 200 OK
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: carol@uas1.nightservice.com
From: sip:alice@isp.com
To: <sip:roses@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[9] SIP proxy server 1 to UAC

SIP/2.0 200 OK
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: carol@uas1.nightservice.com
From: sip:alice@isp.com
To: <sip:roses@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[10] SIP UAC to SIP UAS1:

ACK sip:uas1.nightservice.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: <sip:roses@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE

The RTP flows begin and Carol answers "Hello, WeSellFlowers. How may I help you?" 🌈 Hostess with the mostest!


8.2. Voicemail Service Using Diversion Header πŸ“¨

Bob has contracted his Voicemail to a third-party company, Voicemail.com. πŸ¦‹ In this message flow, Bob has hit the Do-Not-Disturb button on his phone. The Do-Not-Disturb functionality of Bob's phone is configured to CFUNC (Call Forward Unconditional) to voicemail@isp.com. Because the Diversion header is used, Voicemail.com is able to place the incoming call into Bob's voice mailbox. Ngl, that's a super clean handoff. πŸ’œ

                 +---------------------------------------------+
                 | Bob@UAS1: CFDoNotDisturb->voicemail@isp.com |
                 +--------------------------------------+------+
                                                         \
                                                          \
UAC1               P1                P2            UAS1        UAS2
                                                          Voicemail.com
|                  |                  |              |          |
|--[1] INV Bob@P1->|                  |              |          |
|                  |                  |              |          |
|                  |--[2] INV Bob@P2->|              |          |
|                  |                  |              |          |
|                  |               [3] INV Bob@uas1->|          |
|                  |                  |              |          |
|                  |                [4] <- 302-------|          |
|                  |               Contact: voicemail@isp.com   |
|                  |               Diversion: Bob@uas1          |
|                  |                 ;reason=do-not-disturb     |
|                  |                  |              |          |
|                  |                  |[5] ACK------>|          |
|                  |                  |              |          |
|                  |<-[6] 302---------|              |          |
|                  |  Contact: voicemail@isp.com     |          |
|                  |  Diversion: Bob@uas1            |          |
|                  |    ;reason=do-not-disturb       |          |
|                  |                  |              |          |
|                  |--[7] ACK-------->|              |          |
|<-[8] 302---------|                  |              |          |
|  Contact: voicemail@isp.com         |              |          |
|  Diversion: Bob@uas1                |              |          |
|    ;reason=do-not-disturb           |              |          |
|                  |                  |              |          |
|--[9] ACK-------->|                  |              |          |
|                  |                  |              |          |
|--[10] INVITE voicemail@isp.com------------------------------->|
|  Diversion: Bob@uas1                |              |          |
|    ;reason=do-not-disturb           |              |          |
|                  |                  |              |          |
|<--[11] 200----------------------------------------------------|
|                  |                  |              |          |
|---[12] ACK--------------------------------------------------->|
|                  |                  |              |          |
|                  |                  |              |          |

Alice calls Bob. πŸ“žπŸ’–

[1] SIP UAC to SIP proxy server 1: πŸŽ€

INVITE sip:Bob@p1.isp.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:Bob@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

The ISP's originating proxy routes the request to proxy 2 (P2). πŸ¦‹

[2] SIP proxy server 1 to SIP proxy server 2: 🌸

INVITE sip:Bob@p2.isp.com SIP/2.0
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:Bob@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[3] SIP proxy server 2 to UAS1 (Bob's SIP phone): πŸ’…

INVITE sip:Bob@uas1.isp.com SIP/2.0
Via: SIP/2.0/UDP p2.isp.com
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:Bob@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

Okay so, Bob had hit the Do-Not-Disturb button on his SIP phone πŸ™ˆ, which means Bob's phone forwards the call to his voicemail service. It's giving "not right now, thanks" energy πŸ’€βœ¨

[4] User agent server 1 (UAS1) to SIP proxy server 2 (P2) 🧚

SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/UDP p2.isp.com
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: Voicemail@isp.com
From: sip:alice@isp.com
To: <sip:Bob@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Diversion: <sip:Bob@uas1.isp.com>
  ;reason=do-not-disturb

[5] SIP proxy server 2 to UAS1 (Bob's SIP phone): πŸ“

ACK sip:Bob@uas1.isp.com SIP/2.0
Via: SIP/2.0/UDP p2.isp.com
From: sip:alice@isp.com
To: <sip:Bob@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE

[6] SIP proxy server 2 (P2) to SIP proxy server 1 (P1): 🫢

SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/UDP p1.isp.com
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: Voicemail@isp.com
From: sip:alice@isp.com
To: <sip:Bob@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Diversion: <sip:Bob@uas1.isp.com>
  ;reason=do-not-disturb

[7] SIP proxy server 1 to SIP proxy server 2: 🌈

ACK sip:Bob@p2.isp.com SIP/2.0
Via: SIP/2.0/UDP p1.isp.com
From: sip:alice@isp.com
To: <sip:Bob@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE

[8] SIP proxy server 1 (P1) to UAC (alice-pc): ⭐

SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: Voicemail@isp.com
From: sip:alice@isp.com
To: <sip:Bob@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Diversion: <sip:Bob@uas1.isp.com>
  ;reason=do-not-disturb

[9] SIP UAC to SIP proxy server 1: πŸ‘‘

ACK sip:Bob@p1.isp.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: <sip:Bob@p1.isp.com>;tag=uas1
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE

[10] SIP UAC (alice-pc) to Voicemail server. πŸ’œ

INVITE sip:Voicemail@isp.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: sip:Bob@p1.isp.com
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Diversion: <sip:Bob@uas1.isp.com>
  ;reason=do-not-disturb
Content-Type: application/sdp

[11] Voicemail server to SIP UAC (alice-pc): πŸ¦‹

SIP/2.0 200 OK
Via: SIP/2.0/UDP alice-pc.isp.com
Contact: Voicemail@isp.com
From: sip:alice@isp.com
To: <sip:Bob@p1.isp.com>;tag=uas2
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE
Content-Type: application/sdp

[12] SIP UAC to Voicemail server: πŸŽ€

ACK sip:Voicemail@isp.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.isp.com
From: sip:alice@isp.com
To: <sip:Bob@p1.isp.com>;tag=uas2
Call-ID: 12345600@alice-pc.isp.com
CSeq: 1 INVITE

Because the Diversion header is present, the Voicemail server is able to place Alice's message into Bob's voice mailbox. 🌈🫢

8.3. Questions and Answers on Alternative Approaches

Question 1:

Why do we need the Diversion header when we can see the To: header? πŸ€”

Answer:

a) The To: header is not guaranteed to have significance to the called party.

For example, the To: header may contain a locally significant URL (to the caller) such as a private numbering plan, speed dial digits, telephony escape digits, or telephony prefix digits.

Without a Diversion header, enumerating all possible locally significant To: headers that anyone might use to contact Bob@uas1.isp.com becomes a configuration problem at Voicemail@isp.com and is prone to namespace collision. 😭

Support for Diversion headers enables Bob to contract a third-party service (Voicemail@isp.com) with a single globally significant URL for his voice mailbox (Bob@uas1.isp.com). ✨

b) Given a set of multiple diversions, there is a policy decision of which Diversion header takes precedence for service logic. πŸ’…

Different services (or even different users for the same service) may want to configure this policy differently (first, last, second to last, etc.).

Question 2:

Why do we need the Diversion header when we can see the Via: header? πŸ™ˆ

Answer:

The Via header does not contain information about servers whom have deflected the call (using a 3xx). πŸ’€

9. Mapping ISUP/ISDN Redirection Information to SIP Diversion Header ✨

The discussions below regarding ISUP/ISDN reflect generic elements in ISUP/ISDN. In some variations of ISUP/ISDN, the information elements are represented differently. Regardless of the ISUP/ISDN variant, translation should be performed for the "first redirecting number" and the "last redirecting number". πŸŽ€

In order to prevent ambiguity, it is important to highlight a terminology mismatch between ISUP/ISDN and SIP. In SIP, a "redirect" indicates the act of returning a 3xx response. In ISUP/ISDN, a "redirection" is diversion of a call by a network entity. In ISUP/ISDN, a call may also be deflected (by an endpoint). Diversion is the more generic term that refers to either the act of an network redirection or endpoint deflection. πŸ¦‹

In SIP, Diversion can be implemented as either an upstream 3xx (non-recursive) or an additionally forked downstream request (recursive). In the following text, a lowercase "redirect" indicates the SIP usage, while an uppercase "Redirect" indicates ISUP usage. 🌸

9.1. Mapping ISUP/ISDN Diversion Reason Codes

ISUP and ISDN define the following diversion reasons: πŸ’–

0000 = Unknown
0001 = Call forwarding busy or called DTE busy
0010 = Call forwarding no reply
1111 = Call forwarding unconditional or systematic
       call redirection
1010 = Call deflection or call forwarding by the called DTE
1001 = Call forwarding DTE out of order

Mapping of ISUP/ISDN reason codes to Diversion reason codes is performed as follows: 🧚

ISUP/ISDN reason code       Diversion reason code
0001                        "user-busy"
0010                        "no-answer"
1111                        "unconditional"
1010                        "deflection"
1001                        "unavailable"
0000                        all others

9.2. Mapping ISUP Redirection Information to SIP Diversion Header

This section describes how generic ISUP diversion information elements may be translated across an ISUP/SIP gateway. πŸ“

9.2.1. ISUP Definitions

Called Party Number          The number of the party to which the
                             call is currently being routed.

Redirecting Number           The number to which the call was being
                             routed when the last diversion occurred.

Redirecting Reason           The reason that the last diversion
                             occurred.

Original Called Number       The number to which the call was being
                             routed when the first diversion
                             occurred.

Original Redirecting Reason  The reason that the first diversion
                             occurred.

Redirection Counter          The count of the total number of
                             diversions that have occurred.

Address Presentation         Indication of whether presentation is
                             allowed or restricted.

9.2.2. ISUP Parameters

When a SIP call transits a SIP/ISUP gateway, the following information in the ISUP message should be examined/set when translating SIP Diversion headers to ISUP diversion information: 🌈

  1. Redirecting Number
  2. Redirecting Reason
  3. Redirecting Address Presentation
  4. Original Called Number
  5. Original Redirecting Reason
  6. Original Address Presentation
  7. Redirection Counter

An ISUP message contains information on the first and last diversions that occurred. The Redirection number is the number to which the call was being routed when the last diversion occurred. The Redirecting Reason is the reason that the last diversion occurred. πŸ’…

The Original Called Number is the number to which the call was being routed when the first diversion occurred. The Original Redirecting Reason is the reason that the first diversion occurred. πŸ‘‘

When only one Diversion has occurred, the number to which the call was being routed when the diversion occurred is in the Redirecting Number and the reason for that diversion is carried in the Redirect Reason. πŸ¦‹

9.2.3. ISUP to SIP Translation

The ISUP Redirecting Number SHOULD be used to set the value of the name-addr of the top-most Diversion header. The ISUP Redirecting Number address presentation SHOULD be used to set the value of the diversion-privacy of the top-most Diversion header. The ISUP Redirecting Reason SHOULD be used to set the value of the diversion-reason of the top-most Diversion header. When present, the Original Called Number SHOULD be used to set the name-addr of the bottom-most Diversion header. When present, the Original Redirecting Reason SHOULD be used to set the diversion-reason of the bottom-most Diversion header. When present, the Original Address Presentation SHOULD be used to set the diversion-privacy of the bottom-most Diversion header. πŸŽ€

The Redirection Counter value minus 1 SHOULD be stored in the diversion-counter associated with the top-most Diversion header. Presence of the diversion-counter for the bottom-most Diversion header is optional. If present, the diversion-counter of the bottom-most Diversion header SHOULD be 1. 🌸

9.2.4. SIP to ISUP Translation ✨

okay bestie, going the other way now, from SIP to ISUP πŸ’–. The name-addr of the top-most Diversion header SHOULD be used to set the ISUP Redirecting Number. Its diversion-reason SHOULD set the ISUP Redirecting Reason, and its diversion-privacy SHOULD set the ISUP Redirecting Address Presentation πŸŽ€.

When there are multiple Diversion headers, it's the bottom-most one's turn πŸ‘‘. Its name-addr SHOULD be used to set the ISUP Original Redirecting Number, its diversion-reason SHOULD be used to set the ISUP Original Redirecting Reason, and its diversion-privacy SHOULD be used to set the ISUP Original Redirecting Address Presentation.

Last one, and it's a whole vibe 🌈. The ISUP Redirection Counter SHOULD be set equal to the sum of the counters of all Diversion headers in the SIP message. A Diversion header that doesn't explicitly specify a diversion-counter tag counts as 1 🧚.

9.2.5. Example of ISUP to SIP Translation πŸ¦‹

                                   ISUP/SIP GW
                                       |
--IAM--------------------------------->|
  Called Party Number    =+19195551004 |
  Redirecting Number     =+19195551002 |
    Address Presentation =presentation restricted
  Original Called Number =+19195551001 |
  RedirectionInformation:              |
    Original Redirecting Reason = Unconditional (1111)
    Redirecting Reason = User busy (0001)
    Redirection Counter = 5            |
                                       |
                                       |--INVITE +19195551004------>
                                       |  Diversion: <tel:+19195551002>
                                       |    ;reason=user-busy
                                       |    ;privacy="full"
                                       |    ;counter=4
                                       |  Diversion: <tel:+19195551001>
                                       |    ;reason=unconditional
                                       |    ;counter=1
                                       |
                                       |

9.2.6. Example of SIP to ISUP Translation 🌸

                                   ISUP/SIP GW
                                       |
                                       |<--INVITE +19195551004------
                                       |  Diversion: <tel:+19195551002>
                                       |    ;reason=user-busy
                                       |    ;privacy="full"
                                       |    ;counter=4
                                       |  Diversion: <tel:+19195551001>
                                       |    ;reason=unconditional
                                       |    ;counter=1
                                       |
                                       |
                                       |
<--IAM---------------------------------|
  Called Party Number    =+19195551004 |
  Redirecting Number     =+19195551002 |
    Address Presentation =presentation restricted
  Original Called Number =+19195551001 |
  RedirectionInformation:              |
    Original Redirecting Reason = Unconditional (1111)
    Redirecting Reason = User busy (0001)
    Redirection Counter = 5            |

9.3. Mapping ISDN Redirection Information to SIP Diversion Header πŸŽ€

okay so an ISDN message can carry up to two instances of a Redirecting Number information element πŸ’…. When a diversion happens, an additional Redirection number information element gets added. And when a third (or greater) diversion happens, the new Redirecting Number information element replaces the bottom-most Redirection number information element. Lowkey a lot of shuffling, but it works 🫢.

9.3.1. ISDN Definitions πŸ“–

   Called Party Number          The number of the party to which the
                                call is currently being routed.

   Redirecting Number
   information element          Aggregate information element that
                                contains Redirecting number and Reason
                                for diversion.

   Redirecting Number           The number to which the call was being
                                routed when the last diversion occurred.

   Reason for Diversion         The reason that the last diversion
                                occurred.

   Origin of Number             Indicates whether the number is user
                                provided and screened or network
                                provided.

   Presentation Status          Indicates if presentation is allowed or
                                prohibited.

9.3.2. ISDN Parameters 🧚

When a SIP call transits a SIP/ISDN gateway, the following information in the ISDN message should be examined/set when translating SIP Diversion headers to ISDN diversion information:

  1. Redirecting Number of the top-most Redirecting Number information element
  2. Reason for diversion of the top-most Redirection number information element
  3. Origin of Number and Presentation Status of the top-most Redirection number information element
  4. Redirection number of the bottom-most Redirection number information element
  5. Reason for diversion of the bottom-most Redirection number information element
  6. Origin of Number and Presentation Status of the bottom-most Redirection number information element

An ISDN message contains information on the first and last diversions that occurred 🌈. The top-most Redirection number information element holds the details (the Redirecting Number, Origin of Number, Presentation Status, and Reason for diversion) about the last diversion that occurred. The bottom-most Redirection number information element holds those same details about the first diversion that occurred.

If only one diversion has occurred, only one Redirection number information element is present ✨.

The Redirecting Number information element has the same Type of Number/Numbering Plan and Digits as the Calling Party Number information element.

There is no Redirection Counter associated with this ISDN information element.

Notice that the order of the Redirection number information elements in an ISDN message (top=first, bottom=last) is reversed from the order of Diversion headers in a SIP message (top=last, bottom=first). It's giving upside-down energy, and you need to keep it straight πŸ™ƒ.

9.3.3. ISDN to SIP Translation πŸ’œ

The Redirecting Number of the top-most ISDN Redirecting Number information element SHOULD be used to set the value of the name-addr of the bottom-most Diversion header. The Reason for Diversion of the top-most ISDN Redirecting Number information element SHOULD be used to set the value of the diversion-reason of the bottom-most Diversion header.

The Origin of Number of the top-most ISDN Redirecting Number information element SHOULD be used to set the value of the diversion-screen of the bottom-most Diversion header. The Presentation Status of the top-most ISDN Redirecting Number information element SHOULD be used to set the value of the diversion-privacy of the bottom-most Diversion header.

The Redirecting Number of the bottom-most ISDN Redirecting Number information element SHOULD be used to set the value of the name-addr of the top-most Diversion header. The Reason for Diversion of the bottom-most ISDN Redirecting Number information element SHOULD be used to set the value of the diversion-reason of the top-most Diversion header.

The Origin of Number of the bottom-most ISDN Redirecting Number information element SHOULD be used to set the value of the diversion-screen of the top-most Diversion header. The Presentation Status of the bottom-most ISDN Redirecting Number information element SHOULD be used to set the value of the diversion-privacy of the top-most Diversion header.

Presence of the diversion-counter in each of the Diversion headers is optional. If present, the diversion-counter of each Diversion header SHOULD be 1 πŸ”₯.

9.3.4. SIP to ISDN Translation πŸ“

  • The name-addr of the top-most Diversion header SHOULD be used to set the Redirecting Number of the bottom-most ISDN Redirecting Number information element.
  • The diversion-reason of the top-most Diversion header SHOULD be used to set the Reason for Diversion of the bottom-most ISDN Redirecting Number information element.
  • The diversion-screen of the top-most Diversion header SHOULD be used to set the Origin of Number of the bottom-most ISDN Redirecting Number information element.
  • The diversion-privacy of the top-most Diversion header SHOULD be used to set the Presentation Status of the bottom-most ISDN Redirecting Number information element.
  • The name-addr of the bottom-most Diversion header SHOULD be used to set the Redirecting Number of the top-most ISDN Redirecting Number information element.
  • The diversion-reason of the bottom-most Diversion header SHOULD be used to set the Reason for Diversion of the top-most ISDN Redirecting Number information element.
  • The diversion-screen of the bottom-most Diversion header SHOULD be used to set the Origin of Number of the top-most ISDN Redirecting Number information element.
  • The diversion-privacy of the bottom-most Diversion header SHOULD be used to set the Presentation Status of the top-most ISDN Redirecting Number information element.

9.3.5. Example of ISDN to SIP Translation πŸ’–

                        ISDN/SIP GW
                                       |
--Setup------------------------------->|
  Called party number      =+19195551004
  Redirecting Number information element:
    Redirecting Number     =+19195551001
    Reason for redirection = Unconditional (1111)
    Origin of Number       = passed network screening
    Presentation Status    = presentation allowed
  Redirecting Number information element:
    Redirecting Number     =+19195551002
    Reason for redirection = User busy (0001)
    Origin of Number       = passed network screening
    Presentation Status    = presentation prohibited
                                       |
                                       |--INVITE tel:+19195551004---->
                                       |  Diversion: <tel:+19195551002>
                                       |    ;reason=user-busy
                                       |    ;screen="yes"
                                       |    ;privacy="off"
                                       |  Diversion: <tel:+19195551001>
                                       |    ;reason=unconditional
                                       |    ;screen="yes"
                                       |    ;privacy="full"
                                       |
                                       |

9.3.6. Example of SIP to ISDN Translation πŸ¦‹

                                   ISDN/SIP GW
                                       |

9.4. Information Loss in SIP to ISUP/ISDN Translation ✨

okay so bestie, ISUP and ISDN only support a subset of what a SIP Diversion header can carry 😭 which means info gets dropped whenever you cross a SIP/ISUP or SIP/ISDN boundary. it's giving "not everything makes the trip" πŸ§³πŸ’”

9.4.1. Loss of Diversion URI Information πŸ¦‹

ISUP and ISDN only support a subset of URI types, specifically tel: URIs and sip:x@y;user=phone URIs πŸ“ž. So diversion info for any other URI type may be lost when you go from SIP to ISDN or ISUP. not everyone gets an invite to the party πŸŽ€

9.4.2. Loss of Diversion Reason Information 🌸

ISUP and ISDN also only support a subset of the reason codes that the Diversion header supports πŸ’…. So specific reason code info may be lost when crossing from SIP to ISDN or ISUP. the reason gets left at the door, periodt 🫢

9.4.3. Loss of Diversion Counter Information 🧚

ISDN doesn't have a counter field, the one that tracks how many diversions have happened πŸ™ˆ. So counter info may be lost when crossing from SIP to ISDN. the count just vanishes into the void πŸ’€


10. Contributors πŸ‘‘

Special acknowledgement to both Bryan Byerly and JR Yang πŸ’œ. As original authors of this document, both were instrumental in getting this document written 🫢. literal legends.

11. Acknowledgements 🌈

We would like to thank David Williams, Ameet Kher, Satya Khatter, Manoj Bhatia, Shail Bhatnagar, Denise Caballero-Mccann, Kara Adams, Charles Eckel of Cisco Systems, and Bert Culpepper of InterVoice-Brite for their insights, inputs, and comments πŸ“βœ¨. the whole squad showed up, iconic.

12. Normative References πŸ“š

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC3261]  Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston,
           A., Peterson, J., Sparks, R., Handley, M., and E.
           Schooler, "SIP: Session Initiation Protocol", RFC 3261,
           June 2002.

Authors' Addresses πŸ¦‹

Steve Levy
Cisco Systems
7025 Kit Creek Road P.O. Box 14987 Research Triangle Park,
NC  27709
USA

EMail: stlevy@cisco.com

Marianne Mohali (editor)
Orange Labs
38-40 rue du General Leclerc
Issy-Les-Moulineaux Cedex 9  92794
France

Phone: +33145294514
EMail: marianne.mohali@orange-ftgroup.com

and that's a wrap, bestie!! πŸŒˆπŸ’– the whole spec, every detail, served with a bow πŸŽ€πŸ’…

πŸ“¦ where this page comes from