RFC 7088

Session Initiation Protocol Service Example -- Music on Hold

πŸ“… published February 2014, from ietf

RFC 7088: Session Initiation Protocol Service Example -- Music on Hold πŸŽ€

okay bestie, this one is RFC 7088 πŸ“žβœ¨ It's an Informational doc (published for info, not a Standards Track spec) from February 2014 (ISSN 2070-1721), written by D. Worley from Ariadne πŸ’–. The header has no Obsoletes or Updates line, so it doesn't list anything it replaces or changes.


Abstract 🌸

"Music on hold" is one of the features that business phone buyers want most πŸ’Ό When one party has a call "on hold", their phone plays an audio stream (often music) for the other person to hear. SIP's architecture makes it hard to do this in a way that's fully standards-compliant 😀 The method in this doc is fully effective, standards-compliant, and has a bunch of perks over the older methods. It's less likely to cause weird UI effects and more likely to work in systems that do authentication, compared to the music-on-hold method in Section 2.3 of RFC 5359 πŸ’…

Status of This Memo πŸ“š

This is not an Internet Standards Track spec. It's just published for info 🫢

This is an IETF product and it reflects the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). Not every IESG-approved doc is a candidate for any level of Internet Standard, so check Section 2 of RFC 5741 for the details πŸ”

For the current status, any errata, and how to give feedback, go to http://www.rfc-editor.org/info/rfc7088 πŸ¦‹

Copyright (c) 2014 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 of this document. Please read these carefully, because they spell out your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Simplified BSD License πŸ“œ

Table of Contents πŸ—‚οΈ

1. Introduction ....................................................4
   1.1. Requirements Language ......................................4
2. Technique .......................................................4
   2.1. Placing a Call on Hold and Establishing an External
        Media Stream ...............................................5
   2.2. Taking a Call off Hold and Terminating the External
        Media Stream ...............................................6
   2.3. Example Message Flow .......................................6
   2.4. Receiving Re-INVITE and UPDATE from the Remote UA .........17
   2.5. Receiving INVITE with Replaces ............................17
   2.6. Receiving REFER from the Remote UA ........................19
   2.7. Receiving Re-INVITE and UPDATE from the
        Music-on-Hold Source ......................................21
   2.8. Handling Payload Type Numbers .............................22
        2.8.1. Analysis ...........................................22
        2.8.2. Solution to the Problem ............................23
        2.8.3. Example of the Solution ............................24
   2.9. Dialog/Session Timers .....................................28
   2.10. When the Media Stream Directionality is "inactive" .......28
   2.11. Multiple Media Streams ...................................28
3. Advantages .....................................................29
4. Caveats ........................................................30
   4.1. Offering All Available Media Formats ......................30
   4.2. Handling Re-INVITES in a B2BUA ............................31
5. Security Considerations ........................................31
   5.1. Network Security ..........................................31
   5.2. SIP (Signaling) Security ..................................32
   5.3. RTP (Media) Security ......................................32
   5.4. Media Filtering ...........................................32
6. Acknowledgments ................................................33
7. References .....................................................34
   7.1. Normative References ......................................34
   7.2. Informative References ....................................34

1. Introduction πŸŽ€

In systems built on SIP [RFC3261], people really want features like the ones in traditional phone systems πŸ“± One of the most requested is "music on hold": when one party has the call "on hold", their phone plays an audio stream (often music) for the other party to hear 🎢

SIP's architecture makes it hard to do music on hold in a way that's fully standards-compliant 😭 This doc describes a method that's reasonably simple and still fully effective and standards-compliant. It has big advantages over other methods already in use, which Section 3 covers 🌈

Every current music-on-hold method works with every other one. The two user agents in a call can use different methods and still get the same functionality as if both used the same method. So you lose nothing if different user agents in a phone system use different methods, or if one user agent switches methods between calls or even partway through a single call 🧚

1.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. Technique πŸ’…

The core idea is this πŸ‘‘ The executing user agent (UA) (the user's own UA) sends a re-INVITE to the remote UA (the other user's UA) to set the hold state. It leaves out the Session Description Protocol (SDP) [RFC4566] offer [RFC3264] [RFC6337], which forces the remote UA to make an SDP offer. The executing UA then takes that offer from the remote UA's 2xx response and uses it as the offer SDP in a new INVITE to the external media source. That way the media source sends its media straight to the remote UA. The media source's answer SDP goes back to the remote UA in the ACK to the re-INVITE πŸ¦‹

2.1. Placing a Call on Hold and Establishing an External Media Stream ⏸️

  1. The executing user tells the executing UA to put the dialog on hold πŸ™‹
  2. The executing UA sends a re-INVITE without SDP to the remote UA. This forces the remote UA to put an SDP offer in its 2xx response. The Contact header of the re-INVITE includes the '+sip.rendering="no"' field parameter to show that it's putting the call on hold ([RFC4235], Section 5.2) πŸ’–
  3. The remote UA sends a 2xx to the re-INVITE, and its SDP offer gives its own listening address/port. If the remote UA understands the sip.rendering feature parameter, the offer may say it won't send media by setting the media directionalities to recvonly (the reverse of "on hold") or inactive. But the remote UA may also offer to send media πŸ€·β€β™€οΈ
  4. The executing UA uses this offer to build the offer SDP of an initial INVITE that it sends to the configured music-on-hold (MOH) source. The SDP in this request is mostly copied from the SDP the remote UA returned in the previous step, especially the listening address/port and the payload type numbers. The media directionalities are restricted to recvonly or inactive, whichever fits. The executing UA may want or need to change the o= line. It may also need to add some a=rtpmap lines to control how RTP payload type numbers get assigned (Section 2.8) ✨
  5. The MOH source sends a 2xx response to the INVITE. Its SDP answer should include its media source address as its listening address/port. This SDP must necessarily set sendonly or inactive as the directionality for all media streams [RFC3264] 🎡

Even though this address/port shouldn't receive any RTP, the port it specifies decides the port for receiving RTP Control Protocol (RTCP) packets. By convention it also sends RTCP from that port [RFC4961] πŸ“‘

By convention, UAs use their declared RTP listening ports as their RTP source ports too [RFC4961]. The answer SDP reaches the remote UA, which tells it the address/port the MOH media will come from. That presumably stops the remote UA from ignoring the MOH media if it filters media packets by source address. This only works if the SDP answer has the sending address in the c= line, even though the MOH source doesn't receive RTP πŸ›‘οΈ

  1. The executing UA sends this SDP answer as its SDP answer in the ACK for the re-INVITE to the remote UA. The o= line in the answer must be changed so it fits in the sequence of o= lines the executing UA already made in the dialog. Any dynamic payload type number assignments made in the answer must be recorded in the state of the original dialog 🧾
  2. Because of the sip.rendering feature parameter in the re-INVITE's Contact header and the media directionality in the SDP answer inside the ACK, the on-hold state of the dialog gets set up (at the executing end) πŸŽ‰
  3. From here on, the MOH source makes RTP with the music-on-hold media and sends it straight to the remote UA's listening address/port. The executing UA keeps two dialogs (one with the remote UA, one with the MOH source), but it never sees or handles the MOH RTP πŸ™ˆ

2.2. Taking a Call off Hold and Terminating the External Media Stream πŸ“²

  1. The executing user tells the executing UA to take the dialog off hold πŸ™Œ
  2. The executing UA sends a re-INVITE to the remote UA with SDP that asks to receive media. The re-INVITE's Contact header doesn't include the '+sip.rendering="no"' field parameter. (It may have a sip.rendering field parameter set to "yes" or "unknown", or it may leave the field parameter out.) So this re-INVITE clears the on-hold state of the dialog (at the executing end) πŸ’« The version in the o= line of the offered SDP has to account for the SDP versions that came through from the MOH source. Any payload type numbers that were assigned in SDP from the MOH source must be respected too 🧠
  3. When the remote UA sends a 2xx response to the re-INVITE, the executing UA sends a BYE request in the dialog to the MOH source πŸ‘‹
  4. From here on, the MOH source stops making RTP, and ordinary RTP flow comes back in the original dialog 🌸

2.3. Example Message Flow ✈️

This section walks through a message flow for the technique. Alice calls Bob, Bob puts her on hold with music from an external source, and then he takes her off hold 🎢 Bob's UA is the executing UA, and Alice's UA is the remote UA. This is just one possible flow, though. The standards allow a bunch of variations on these operations ✨

Alice establishes the call:

  |                |              |
  |    INVITE F1   |              |
  |--------------->|              |
  | 180 Ringing F2 |              |
  |<---------------|              |
  |    200 OK F3   |              |
  |<---------------|              |
  |     ACK F4     |              |
  |--------------->|              |
  |       RTP      |              |
  |<==============>|              |
  |                |              |

Bob places Alice on hold, compelling Alice's UA to provide SDP: πŸ™ˆ

  |                |              |
  |   INVITE F5    |              |
  |   (no SDP)     |              |
  |<---------------|              |
  |   200 OK F6    |              |
  |   (SDP offer)  |              |
  |--------------->|              |
  |                |              |

Bob's UA initiates music on hold: 🎡

  |                |              |
  |                |  INVITE F7   |
  |                |  (SDP offer, |
  |                |   rev. hold) |
  |                |------------->|
  |                | 200 OK F8    |
  |                | (SDP answer, |
  |                |  hold)       |
  |                |<-------------|
  |                |    ACK F9    |
  |                |------------->|
  |                |              |

Bob's UA provides an SDP answer containing the address/port of Music Source: πŸ¦‹

  |                |              |
  | ACK F10        |              |
  | (SDP answer,   |              |
  |  hold)         |              |
  |<---------------|              |
  |    no RTP      |              |
  |<..............>|              |
  |     Music-on-hold RTP         |
  |<==============================|
  |                |              |

The music on hold is active πŸ’–

Bob takes Alice off hold: πŸ’…

  |                |              |
  |  INVITE F11    |              |
  |  (SDP offer)   |              |
  |<---------------|              |
  |   200 OK F12   |              |
  |   (SDP answer) |              |
  |--------------->|              |
  |     ACK F13    |              |
  |<---------------|              |
  |                |    BYE F14   |
  |                |------------->|
  |                |    200 F15   |
  |                |<-------------|
  |       RTP      |              |
  |<==============>|              |
  |                |              |

And the normal media session between Alice and Bob is back on 🌈✨

Here are the actual messages, one at a time πŸŽ€

/* Alice calls Bob. */

F1 INVITE Alice -> Bob

INVITE sips:bob@biloxi.example.com SIP/2.0
Via: SIP/2.0/TLS atlanta.example.com:5061
 ;branch=z9hG4bK74bf9
Max-Forwards: 70
From: Alice <sips:alice@atlanta.example.com>;tag=1234567
To: Bob <sips:bob@biloxi.example.com>
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
Contact: <sips:a8342043f@atlanta.example.com;gr>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces, gruu
Content-Type: application/sdp
Content-Length: [omitted]

v=0
o=alice 2890844526 2890844526 IN IP4 atlanta.example.com
s=
c=IN IP4 atlanta.example.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
F2 180 Ringing Bob -> Alice

SIP/2.0 180 Ringing
Via: SIP/2.0/TLS atlanta.example.com:5061
 ;branch=z9hG4bK74bf9
 ;received=192.0.2.103
From: Alice <sips:alice@atlanta.example.com>;tag=1234567
To: Bob <sips:bob@biloxi.example.com>;tag=23431
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
Contact: <sips:bob@biloxi.example.com>
Content-Length: 0
F3 200 OK Bob -> Alice

SIP/2.0 200 OK
Via: SIP/2.0/TLS atlanta.example.com:5061
 ;branch=z9hG4bK74bf9
 ;received=192.0.2.103
From: Alice <sips:alice@atlanta.example.com>;tag=1234567
To: Bob <sips:bob@biloxi.example.com>;tag=23431
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
Contact: <sips:bob@biloxi.example.com>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces
Content-Type: application/sdp
Content-Length: [omitted]

v=0
o=bob 2890844527 2890844527 IN IP4 biloxi.example.com
s=
c=IN IP4 biloxi.example.com
t=0 0
m=audio 3456 RTP/AVP 0
a=rtpmap:0 PCMU/8000
F4 ACK Alice -> Bob

ACK sips:bob@biloxi.example.com SIP/2.0
Via: SIP/2.0/TLS atlanta.example.com:5061
 ;branch=z9hG4bK74bfd
Max-Forwards: 70
From: Alice <sips:alice@atlanta.example.com>;tag=1234567
To: Bob <sips:bob@biloxi.example.com>;tag=23431
Call-ID: 12345600@atlanta.example.com
CSeq: 1 ACK
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces
Content-Length: 0
/* Bob places Alice on hold. */

/* The re-INVITE contains no SDP, thus compelling Alice's UA
   to provide an offer. */

F5 INVITE Bob -> Alice

INVITE sips:a8342043f@atlanta.example.com;gr SIP/2.0
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bK874bk
To: Alice <sips:alice@atlanta.example.com>;tag=1234567
From: Bob <sips:bob@biloxi.example.com>;tag=23431
Call-ID: 12345600@atlanta.example.com
CSeq: 712 INVITE
Contact: <sips:bob@biloxi.example.com>;+sip.rendering="no"
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces
Content-Length: 0
/* Alice's UA provides an SDP offer.
   Since it does not know that it is being put on hold,
   the offer is the same as the original offer and describes
   bidirectional media. */

F6 200 OK Alice -> Bob

SIP/2.0 200 OK
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bK874bk
 ;received=192.0.2.105
To: Alice <sips:alice@atlanta.example.com>;tag=1234567
From: Bob <sips:bob@biloxi.example.com>;tag=23431
Call-ID: 12345600@atlanta.example.com
CSeq: 712 INVITE
Contact: <sips:a8342043f@atlanta.example.com;gr>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces, gruu
Content-Type: application/sdp
Content-Length: [omitted]

v=0
o=alice 2890844526 2890844526 IN IP4 atlanta.example.com
s=
c=IN IP4 atlanta.example.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
a=active
/* Bob's UA initiates music on hold. */

/* This INVITE contains Alice's offer, but with the media
   direction set to "reverse hold", receive-only. */

F7 INVITE Bob -> Music Source

INVITE sips:music@source.example.com SIP/2.0
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bKnashds9
Max-Forwards: 70
From: Bob <sips:bob@biloxi.example.com>;tag=02134
To: Music Source <sips:music@source.example.com>
Call-ID: 4802029847@biloxi.example.com
CSeq: 1 INVITE
Contact: <sips:bob@biloxi.example.com>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces, gruu
Content-Type: application/sdp
Content-Length: [omitted]

v=0
o=bob 2890844534 2890844534 IN IP4 atlanta.example.com
s=
c=IN IP4 atlanta.example.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
a=recvonly
F8 200 OK Music Source -> Bob

SIP/2.0 200 OK
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bKnashds9
 ;received=192.0.2.105
From: Bob <sips:bob@biloxi.example.com>;tag=02134
To: Music Source <sips:music@source.example.com>;tag=56323
Call-ID: 4802029847@biloxi.example.com
Contact: <sips:music@source.example.com>;automaton
     ;+sip.byeless;+sip.rendering="no"
CSeq: 1 INVITE
Content-Length: [omitted]

v=0
o=MusicSource 2890844576 2890844576 IN IP4 source.example.com
s=
c=IN IP4 source.example.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
a=sendonly
F9 ACK Bob -> Music Source

ACK sips:music@source.example.com SIP/2.0
Via: SIP/2.0/TLS source.example.com:5061
 ;branch=z9hG4bK74bT6
From: Bob <sips:bob@biloxi.example.com>;tag=02134
To: Music Source <sips:music@source.example.com>;tag=56323
Max-Forwards: 70
Call-ID: 4802029847@biloxi.example.com
CSeq: 1 ACK
Content-Length: 0
/* Bob's UA now sends the ACK that completes the re-INVITE
   to Alice and completes the SDP offer/answer.
   The ACK contains the SDP received from Music Source and thus
   contains the address/port from which Music Source will send media,
   and implies the address/port that Music
   Source will use to send/receive RTCP. */

F10 ACK Bob -> Alice

ACK sips:a8342043f@atlanta.example.com;gr SIP/2.0
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bKq874b
To: Alice <sips:alice@atlanta.example.com>;tag=1234567
From: Bob <sips:bob@biloxi.example.com>;tag=23431
Call-ID: 12345600@atlanta.example.com
CSeq: 712 ACK
Contact: <sips:bob@biloxi.example.com>;+sip.rendering="no"
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces
Content-Length: [omitted]

v=0
o=bob 2890844527 2890844528 IN IP4 biloxi.example.com
s=
c=IN IP4 source.example.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
a=sendonly
/* Bob picks up the call by sending a re-INVITE to Alice. */


F11 INVITE Bob -> Alice

INVITE sips:a8342043f@atlanta.example.com;gr SIP/2.0
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bK874bk
To: Alice <sips:alice@atlanta.example.com>;tag=1234567
From: Bob <sips:bob@biloxi.example.com>;tag=23431
Call-ID: 12345600@atlanta.example.com
CSeq: 713 INVITE
Contact: <sips:bob@biloxi.example.com>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces
Content-Type: application/sdp
Content-Length: [omitted]

v=0
o=bob 2890844527 2890844529 IN IP4 biloxi.example.com
s=
c=IN IP4 biloxi.example.com
t=0 0
m=audio 3456 RTP/AVP 0
a=rtpmap:0 PCMU/8000
F12 200 OK Alice -> Bob

SIP/2.0 200 OK
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bK874bk
 ;received=192.0.2.105
To: Alice <sips:alice@atlanta.example.com>;tag=1234567
From: Bob <sips:bob@biloxi.example.com>;tag=23431
Call-ID: 12345600@atlanta.example.com
CSeq: 713 INVITE
Contact: <sips:a8342043f@atlanta.example.com;gr>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces, gruu
Content-Type: application/sdp
Content-Length: [omitted]

v=0
o=alice 2890844526 2890844527 IN IP4 atlanta.example.com
s=
c=IN IP4 atlanta.example.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
F13 ACK Bob -> Alice

ACK sips:a8342043f@atlanta.example.com;gr SIP/2.0
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bKq874b
To: Alice <sips:alice@atlanta.example.com>;tag=1234567
From: Bob <sips:bob@biloxi.example.com>;tag=23431
Call-ID: 12345600@atlanta.example.com
CSeq: 713 ACK
Contact: <sips:bob@biloxi.example.com>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces
Content-Length: 0

And now for the last bit of the call flow, F14 BYE Bob -> Music Source 🫢

BYE sips:music@source.example.com SIP/2.0
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bK74rf
Max-Forwards: 70
From: Bob <sips:bob@biloxi.example.com>;tag=02134
To: Music Source <sips:music@source.example.com>;tag=56323
Call-ID: 4802029847@biloxi.example.com
CSeq: 2 BYE
Contact: <sips:bob@biloxi.example.com>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces, gruu
Content-Length: [omitted]
F15 200 OK Music Source -> Bob

SIP/2.0 200 OK
Via: SIP/2.0/TLS atlanta.example.com:5061
 ;branch=z9hG4bK74rf
 ;received=192.0.2.103
From: Bob <sips:bob@biloxi.example.com>;tag=02134
To: Music Source <sips:music@source.example.com>;tag=56323
Call-ID: 4802029847@biloxi.example.com
Contact: <sips:music@source.example.com>;automaton
     ;+sip.byeless;+sip.rendering="no"
CSeq: 2 BYE
Content-Length: 0

/* Normal media session between Alice and Bob is resumed. */

2.4. Receiving Re-INVITE and UPDATE from the Remote UA πŸŽ€

Okay so, while the call is on hold, the remote UA can totally send a request to change the SDP or the feature parameters in its Contact header πŸ“. It can do this with either an INVITE or an UPDATE method, and honestly both of them hit pretty much the same way when it comes to MOH 🎢.

A super common reason for a re-INVITE is when the remote UA wants to put the dialog on hold on its end πŸ™ˆ. Because this case matters so much, an implementation must process INVITEs and UPDATEs during the on-hold state, as described below. No skipping this one, bestie πŸ’….

The executing UA handles these by echoing requests and responses πŸ¦‹. An incoming request from the remote UA makes the executing UA send a similar request to the MOH source, and an incoming response from the MOH source makes the executing UA send a similar response back to the remote UA ✨. In every case, any SDP offers or answers that come in get added as bodies to the stimulated request or response going to the other UA πŸ’–.

The passed-through SDP will usually need its "o=" line modified 🧚. The directionality attributes might need to be restricted too, by changing "active" to "recvonly" and "sendonly" to "inactive", since the executing UA will not render media from the remote UA 🌸. (If all of the passed-through directionality attributes are "inactive", the optimization described in Section 2.10 may be applied.) And when it comes to payload type numbers, the mapping has already been set up within the MOH dialog, so "a=rtpmap" lines don't need to be added πŸ’œ.

2.5. Receiving INVITE with Replaces πŸ‘‘

The executing UA must be prepared to receive an INVITE request with a Replaces header that specifies the dialog with the remote UA πŸ”₯. If the executing UA wants to create this new dialog in the on-hold state, it creates a new dialog with the MOH source to get MOH πŸŽ€. The executing UA negotiates the SDP within the dialog created by the INVITE with Replaces. It does this by passing the offer through to the new MOH dialog (if the INVITE contains an offer), or by creating the new MOH dialog with an offerless INVITE (if the INVITE does not contain an offer) 🫢.

Continuing the example of Section 2.3, the executing UA receives an INVITE with Replaces that contains an offer πŸ“:

Alice             Bob       Music Source          Carol

(For example, Alice has called Carol and initiates an attended transfer by sending a REFER to Carol, causing Carol to send an INVITE with Replaces to Bob.)

Bob receives INVITE with Replaces from Carol 😭:

  |                |              |                 |
  |                |              | INVITE/Replaces |
  |                |              | From: Carol     |
  |                |              | To: Bob         |
  |                |              | (SDP offer)     |
  |                |<-------------------------------|
  |                | INVITE       |                 |
  |                | From: Bob    |                 |
  |                | To: Music Source               |
  |                | (SDP offer,  |                 |
  |                |  rev. hold)  |                 |
  |                |------------->|                 |
  |                | 200 OK       |                 |
  |                | From: Bob    |                 |
  |                | To: Music Source               |
  |                | (SDP answer, |                 |
  |                |  hold)       |                 |
  |                |<-------------|                 |
  |                | ACK          |                 |
  |                | From: Bob    |                 |
  |                | To: Music Source               |
  |                |------------->|                 |
  |                |              | 200 OK          |
  |                |              | From: Carol     |
  |                |              | To: Bob         |
  |                |              | (SDP answer,    |
  |                |              |  hold)          |
  |                |------------------------------->|
  |                |              | ACK             |
  |                |              | From: Carol     |
  |                |              | To: Bob         |
  |                |<-------------------------------|
  |                |              | Music-on-hold RTP
  |                |              |================>|
  |                |              |                 |

Bob terminates the previous dialog with Alice πŸ‘‹:

  |                |              |                 |
  | BYE            |              |                 |
  | From: Bob      |              |                 |
  | To: Alice      |              |                 |
  |<---------------|              |                 |
  | 200 OK         |              |                 |
  | From: Bob      |              |                 |
  | To: Alice      |              |                 |
  |--------------->|              |                 |
  |                |              |                 |

Bob terminates the MOH dialog for the dialog with Alice πŸ₯€:

  |                |              |                 |
  |                | BYE          |                 |
  |                | From: Bob    |                 |
  |                | To: Music Source               |
  |                |------------->|                 |
  |                | 200 OK       |                 |
  |                | From: Music Source             |
  |                | To: Bob      |                 |
  |                |<-------------|                 |
  |                |              |                 |

The new session continues on hold, between Bob and Carol 🌈 that's the vibe!

2.6. Receiving REFER from the Remote UA 🧁

The executing UA must be prepared to receive a REFER request within the dialog with the remote UA πŸ’Œ. The SDP within the dialog created by the REFER gets negotiated by sending an offerless INVITE (or offerless re-INVITE) to the MOH source to obtain an offer, and then using that offer in the INVITE to the refer target 🫧.

Similar processing is used for an out-of-dialog REFER whose Target-Dialog header refers to the dialog with the remote UA 🌷.

Continuing the example of Section 2.3, the executing UA receives an INVITE with Replaces that contains an offer πŸ’…:

Alice             Bob       Music Source          Carol

(For example, Alice initiates an unattended transfer of the call to Carol by sending a REFER to Bob.)

Bob receives REFER from Alice πŸ“ž:

  |                |              |                 |
  | REFER          |              |                 |
  | From: Bob      |              |                 |
  | To: Alice      |              |                 |
  | Refer-To: Carol|              |                 |
  |--------------->|              |                 |
  |                | re-INVITE    |                 |
  |                | From: Bob    |                 |
  |                | To: Music Source               |
  |                | (no SDP)     |                 |
  |                |------------->|                 |
  |                | 200 OK       |                 |
  |                | From: Bob    |                 |
  |                | To: Music Source               |
  |                | (SDP offer,  |                 |
  |                |  hold)       |                 |
  |                |<-------------|                 |
  |                |              | INVITE          |
  |                |              | From: Bob       |
  |                |              | To: Carol       |
  |                |              | (SDP offer,     |
  |                |              |  hold)          |
  |                |------------------------------->|
  |                |              | 200 OK          |
  |                |              | From: Bob       |
  |                |              | To: Carol       |
  |                |              | (SDP answer,    |
  |                |              |  rev. hold)     |
  |                |------------------------------->|
  |                | ACK          |                 |
  |                | From: Bob    |                 |
  |                | To: Music Source               |
  |                | (SDP answer, |                 |
  |                |  rev. hold)  |                 |
  |                |------------->|                 |
  |                |              | ACK             |
  |                |              | From: Bob       |
  |                |              | To: Carol       |
  |                |------------------------------->|
  |                |              | Music-on-hold RTP
  |                |              |================>|
  |                |              |                 |

Bob terminates the previous dialog with Alice πŸŒ™:

  |                |              |                 |
  | BYE            |              |                 |
  | From: Bob      |              |                 |
  | To: Alice      |              |                 |
  |<---------------|              |                 |
  | 200 OK         |              |                 |
  | From: Bob      |              |                 |
  | To: Alice      |              |                 |
  |--------------->|              |                 |
  |                |              |                 |

2.7. Receiving Re-INVITE and UPDATE from the Music-on-Hold Source 🎡

It is possible for the MOH source to send a re-INVITE or UPDATE request, and the executing UA can support doing that in a similar way to requests from the remote UA 🀍. However, if the MOH source is within the same administrative domain as the executing UA, the executing UA may have knowledge that the MOH source will not (or need not) make such requests. So it can respond to any such request with a failure response, which avoids having to pass the request through πŸ™…β€β™€οΈ. The 403 (Forbidden) response is suitable for this purpose, because [RFC3261] specifies that this response indicates "the request SHOULD NOT be repeated" 🚫.

Heads up: in an environment where Interactive Connectivity Establishment (ICE) [RFC5245] is supported, the MOH source may need to send requests as part of ICE negotiation with the remote UA. So in environments that support ICE, the executing UA must be able to pass through requests from the MOH source as well as requests from the remote UA πŸ§šβ€β™€οΈ.

Again, as SDP is passed through, its "o=" line will need to be modified. In some cases, the directionality attributes will need to be restricted 🌸.

2.8. Handling Payload Type Numbers ✨

2.8.1. Analysis

okay so in this technique the MOH source makes an SDP answer πŸŽ€, and the executing UA hands that answer to the remote UA as an answer inside the original dialog ✨. in basic functionality this is no problem at all, bc [RFC3264], Section 6.1 (right at the very end) says the payload type numbers used in either direction of RTP are the ones from the SDP sent by the recipient of that RTP πŸ’…. so the MOH source sends RTP to the remote UA using the payload type numbers from the offer SDP it got (ultimately) from the remote UA πŸ¦‹

but strict compliance with [RFC3264], Section 8.3.2 is a whole different vibe 😭. it says payload type numbers used in SDP may only duplicate the payload type numbers from any previous SDP sent in the same direction if those numbers still represent the same media format (codec) they did before. the problem is the MOH source has zero knowledge of which payload type numbers were used in the original dialog, so it may accidentally give a different media format to a number that was already used (in its answer, or in a later INVITE or UPDATE it generates) πŸ’€. this wouldn't break media decoding, bc it can't send any format that wasn't in the remote UA's offer, BUT it would still violate [RFC3264] πŸ™ˆ

strictly speaking you can't avoid this, bc the generator of a first answer in its dialog can pick payload numbers totally independently of the ones in the offer, and the MOH server thinks its answer is first in the dialog 🌸. so the only absolute fix is for the executing UA to rewrite the SDP passing through it to reassign payload type numbers, which would also mean rewriting the payload type numbers in the RTP packets too. a very undesirable solution 😬

the difficulty of solving this (and similar problems elsewhere) is kinda the argument that strict adherence shouldn't be required for the rule that payload type numbers not be reused for different codecs 🧚

if an implementation of this technique interacts with a remote UA that requires strict compliance to [RFC3264], that remote UA might reject the SDP the MOH server provided (that SDP is in message F10 in Section 2.3 πŸŽ€). as a result, the MOH session won't get established and the call stays in its initial state πŸ’” implementors who want to dodge this situation need to implement the solution in Section 2.8.2 πŸ’–

2.8.2. Solution to the Problem

we can build a technique that strictly follows the payload type rule by exploiting a SHOULD-level requirement in [RFC3264], Section 6.1 πŸ¦‹: "In the case of RTP, if a particular codec was referenced with a specific payload type number in the offer, that same payload type number SHOULD be used for that codec in the answer". or rather, we exploit the "implied requirement" that if a specific payload number in the offer is used for a particular codec, then the answer should not use that payload number for a different codec 🫢. if the MOH source obeys this restriction, the executing UA can modify the offer SDP to "reserve" every payload type number the executing UA has ever offered, so the MOH source can't use them for different media formats πŸ‘‘

When the executing UA is composing the INVITE to the MOH source, it compiles a list of all the (dynamically assigned) payload type numbers and associated media formats that have been used by it (or by MOH sources on its behalf) in the original dialog. (The executing UA must maintain a list of all previously used payload type numbers anyway, in order to comply with [RFC3264].)

Any payload type number that's in the offer but was previously used by the executing UA in the original dialog for a different media format gets rewritten to describe a dummy media format. (One dummy media format name can be used for many payload type numbers, since multiple payload type numbers can refer to the same media format.) A payload type number is added to describe the deleted media format, and that number is either previously unused or previously used by the executing UA for that media format.

Any further payload type numbers that have been used by the executing UA in the original dialog but aren't mapped to a media format in the current offer then get mapped to a dummy media format.

The result is that the modified offer SDP:

  1. offers the same set of media formats (ignoring dummies) as the original offer SDP (though possibly with different payload type numbers),
  2. associates every payload type number either with a dummy media format or with the media format that the executing UA has previously used it for, and
  3. provides a (real or dummy) media format for every payload type number that the executing UA has previously used.

These properties are sufficient to force an MOH server that obeys the implied requirement to generate an answer that is a correct answer to the original offer and is also compatible with previous SDP from the executing UA ✨

Note that any re-INVITEs from the remote UA that the executing UA passes through to the MOH server need similar modification 🌈. payload type numbers the MOH server received in past offers aren't absolutely reserved against its use (they weren't sent in SDP by the MOH server), and there's no SHOULD-level proscription against using them in the current answer (they don't appear in the current offer).

This should provide an adequate solution to the problems with payload type numbers, as it will fail only if (1) the remote UA is particular that other UAs follow the rule about not redefining payload type numbers, and (2) the MOH server does not follow the implied requirement of [RFC3264], Section 6.1 πŸ₯Ί

2.8.3. Example of the Solution

let's see how this process works by modifying the example of Section 2.3 with this specific assignment of supported codecs πŸ“

Alice supports formats X and Y.

Bob supports formats X and Z.

Music Source supports formats Y and Z.

in this case, the SDP exchanges are:

F1 offers X and Y, F3 answers X and Z.  (Only X can be used.)

F6 offers X and Y, but F7 offers X, Y, and a place-holder to block
use of type 92.

F8/F10 answers Y.

the messages that are changed from Section 2.3 are:

F1 INVITE Alice -> Bob

INVITE sips:bob@biloxi.example.com SIP/2.0
Via: SIP/2.0/TLS atlanta.example.com:5061
 ;branch=z9hG4bK74bf9
Max-Forwards: 70
From: Alice <sips:alice@atlanta.example.com>;tag=1234567
To: Bob <sips:bob@biloxi.example.com>
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
Contact: <sips:a8342043f@atlanta.example.com;gr>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces, gruu
Content-Type: application/sdp
Content-Length: [omitted]

v=0
o=alice 2890844526 2890844526 IN IP4 atlanta.example.com
s=
c=IN IP4 atlanta.example.com
t=0 0
m=audio 49170 RTP/AVP 90 91
a=rtpmap:90 X/8000
a=rtpmap:91 Y/8000
F3 200 OK Bob -> Alice

SIP/2.0 200 OK
Via: SIP/2.0/TLS atlanta.example.com:5061
 ;branch=z9hG4bK74bf9
 ;received=192.0.2.103
From: Alice <sips:alice@atlanta.example.com>;tag=1234567
To: Bob <sips:bob@biloxi.example.com>;tag=23431
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
Contact: <sips:bob@biloxi.example.com>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces
Content-Type: application/sdp
Content-Length: [omitted]
v=0
o=bob 2890844527 2890844527 IN IP4 biloxi.example.com
s=
c=IN IP4 biloxi.example.com
t=0 0
m=audio 3456 RTP/AVP 90 92
a=rtpmap:90 X/8000
a=rtpmap:92 Z/8000
F6 200 OK Alice -> Bob

SIP/2.0 200 OK
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bK874bk
 ;received=192.0.2.105
To: Alice <sips:alice@atlanta.example.com>;tag=1234567
From: Bob <sips:bob@biloxi.example.com>;tag=23431
Call-ID: 12345600@atlanta.example.com
CSeq: 712 INVITE
Contact: <sips:a8342043f@atlanta.example.com;gr>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces, gruu
Content-Type: application/sdp
Content-Length: [omitted]

v=0
o=alice 2890844526 2890844526 IN IP4 atlanta.example.com
s=
c=IN IP4 atlanta.example.com
t=0 0
m=audio 49170 RTP/AVP 90 91
a=rtpmap:90 X/8000
a=rtpmap:91 Y/8000
a=active
F7 INVITE Bob -> Music Source

INVITE sips:music@source.example.com SIP/2.0
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bKnashds9
Max-Forwards: 70
From: Bob <sips:bob@biloxi.example.com>;tag=02134
To: Music Source <sips:music@source.example.com>
Call-ID: 4802029847@biloxi.example.com
CSeq: 1 INVITE
Contact: <sips:bob@biloxi.example.com>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Supported: replaces, gruu
Content-Type: application/sdp
Content-Length: [omitted]

v=0
o=bob 2890844534 2890844534 IN IP4 atlanta.example.com
s=
c=IN IP4 atlanta.example.com
t=0 0
m=audio 49170 RTP/AVP 90 91 92
a=rtpmap:90 X/8000
a=rtpmap:91 Y/8000
a=rtpmap:92 x-reserved/8000
a=recvonly
F8 200 OK Music Source -> Bob

SIP/2.0 200 OK
Via: SIP/2.0/TLS biloxi.example.com:5061
 ;branch=z9hG4bKnashds9
 ;received=192.0.2.105
From: Bob <sips:bob@biloxi.example.com>;tag=02134
To: Music Source <sips:music@source.example.com>;tag=56323
Call-ID: 4802029847@biloxi.example.com
Contact: <sips:music@source.example.com>;automaton
     ;+sip.byeless;+sip.rendering="no"
CSeq: 1 INVITE
Content-Length: [omitted]
v=0
o=MusicSource 2890844576 2890844576 IN IP4 source.example.com
s=
c=IN IP4 source.example.com
t=0 0
m=audio 49170 RTP/AVP 91
a=rtpmap:91 Y/8000
a=sendonly

2.9. Dialog/Session Timers

the executing UA may discover that either the remote UA or the MOH source wants to use dialog/session liveness timers [RFC4028] ⏰. since the timers verify the liveness of dialogs, not sessions (despite the terminology of [RFC4028]), the executing UA can support the timers on each dialog (to the remote UA and to the MOH source) independently πŸ¦‹. (if the executing UA becomes obliged to initiate a refresh transaction, it must send an offerless UPDATE or re-INVITE, bc if it sends an offer, the remote element gets the chance to give an answer that's different from its previous SDP, and that could not easily be conveyed to the other remote element πŸ™ˆ)

2.10. When the Media Stream Directionality is "inactive"

the directionality of the media stream in the SDP offer in an INVITE or re-INVITE to the music source can be "inactive" if the SDP offer from the remote UA was "sendonly" or "inactive" 🌸. generally this happens when the remote UA also put the call on hold and gave a directionality of "sendonly". in this situation the executing UA can skip establishing the dialog with the music source (or can terminate the existing dialog with the music source) πŸ’€

if the executing UA uses this optimization, it creates the SDP answer itself, with directionality "inactive" and using its own RTP/RTCP ports, and sends that answer back to the remote UA πŸŽ€

the executing UA must be prepared for the remote UA to send a re-INVITE with directionality "active" or "recvonly". in that case the executing UA must initiate a dialog with the music source, as described above 🫢

2.11. Multiple Media Streams πŸŽ€

okay so there can be multiple media streams (multiple "m=" lines) in any of the SDPs involved in the dialogs 🧚 as the SDPs get manipulated, each media description (each starting with an "m=" line) gets handled the way we just went over for a single media stream, mostly independently of the other media streams. but there are some extra moves the executing UA can make to get specific effects ✨

if the executing UA only wants certain media types to be treated as on-hold media, it can pass the offer SDP through and reject any particular media streams by setting the port number in the "m=" line to zero [RFC3264]. this makes sure the answer SDP has a rejection for that "m=" line too πŸ’…

if the executing UA wants to provide its own on-hold media for a particular "m=" line, it can do that by providing the answer information for that "m=" line. it might decide to do this when the offer SDP comes in (by changing the "m=" line to rejected state when it sends it to the music source), or after it gets the answer from the music source and sees that the "m=" line was rejected 🎢

the executing UA may not want to pass a rejected "m=" line from the music source along to the remote UA (when the remote UA gave a non-rejected "m=" line). instead, it may give an answer with directionality "inactive" (and specify its own RTP/RTCP ports) πŸ¦‹


3. Advantages 🌈

this technique for providing music on hold has advantages over other methods now in use, including:

  1. bestie, the original dialog is not transferred to another UA, so the "remote endpoint URI" shown by the remote endpoint's user interface and dialog event package [RFC4235] does not change during the call. this is unlike the method in [RFC5359], Section 2.3. this URI is usually shown to the user as the name and number of the other party on the call, so it's really desirable for it not to switch over to the MOH server πŸ™ˆ
  2. compared to [RFC5359], this method does not require use of an out-of-dialog REFER, which isn't used much in SIP otherwise. out-of-dialog REFERs may not be routed correctly, since neither the From nor Contact URI of the original dialog may route correctly to the remote UA. also, out-of-dialog requests to UA URIs may not be handled correctly by authorization mechanisms πŸ’€
  3. the music-on-hold media goes directly from the music-on-hold source to the remote UA, rather than being relayed through the executing UA. this reduces the computational load on the executing UA and can reduce the load on the network (by eliminating "hairpinning" of the media through the link serving the executing UA) 🧠
  4. the remote UA sees, in the incoming SDP, the address/port that the MOH source will send MOH media from (assuming the MOH source follows the convention of sending its media from its advertised media-listening address/port). so the remote UA will render the MOH media even if it's filtering incoming media based on originating address as a media security measure πŸ”
  5. the technique requires relatively simple manipulation of SDP. in particular, (1) it does not require a SIP element to modify unrelated SDP to be acceptable to be sent within an already established sequence of SDP (a problem with [SIP-SERV-EX], Section 2.3), and (2) it does not require converting an SDP answer into an SDP offer (which was a problem with the initial draft version of this document, as well as with [SIP-SERV-EX]) ✨

4. Caveats 🧁

4.1. Offering All Available Media Formats πŸ’–

unnecessary failures can happen if SDP offerers don't always offer all the media formats they support. doing so is considered best practice ([RFC6337], Sections 5.1 and 5.3), but some SIP elements offer only formats that have already been in use in the dialog.

an example of how omitting media formats in an offer can lead to failure goes like this. suppose the UAs in Section 2.3 each support the following media formats:

Alice supports formats X and Y.

Bob supports formats X and Z.

Music Source supports formats Y and Z.

in this case, the SDP exchanges are:

  1. Alice calls Bob:
    • Alice offers X and Y (message F1).
    • Bob answers X (F3).
  2. Bob puts Alice on hold:
    • Alice (via Bob) offers X and Y (F6 and F7).
    • Music Source (via Bob) answers Y (F8 and F10).
  3. Bob takes Alice off hold:
    • Bob offers X and Z (F11).
    • Alice answers X (F12).
note that in exchange 2, if Alice assumes that because only format X is currently in use she should offer only X, the exchange fails. in exchange 3, Bob offers formats X and Z, even though neither is in use at the time (because Bob is not involved in the media streams).

4.2. Handling Re-INVITES in a B2BUA πŸ”„

lots of UAs provide MOH in the interval while they're processing a blind transfer, between receiving the REFER and receiving the final response to the stimulated INVITE. this process involves switching the user's interface between three media sources: (1) the session of the original dialog, (2) the session with the MOH server, and (3) the session of the new dialog. it also involves a number of race conditions that must be handled correctly. if the UA is a back-to-back user agent (B2BUA) whose "other side" is maintaining a single dialog with another UA, each switching of media sources potentially causes a re-INVITE transaction within the other-side dialog. since re-INVITEs take time and must be sequenced correctly ([RFC3261], Section 14), such a B2BUA must allow the events on each side to be non-synchronous and must coordinate them correctly. failing to do so will lead to "glare" errors (491 or 500), leaving the other-side UA not rendering the correct session 😬


5. Security Considerations πŸ›‘οΈ

this part is seriously important, so read it carefully. these are the security notes for everything above.

5.1. Network Security πŸ”’

some mechanism outside the scope of this document must inform the executing UA of the MOH server that it should use. care must be exercised in selecting the MOH server, because signaling information that is part of the original dialog will be transmitted along the path from the executing UA to the server. if the path between the executing UA and the server is not entirely contained within every network domain that contains the executing UA, the signaling between the UA and the server may be protected by different network security than is applied to the original dialog.

care must also be exercised because media information that is part of the original dialog will be transmitted along the path between the remote UA and the server. if the path between the remote UA and the server does not pass through the same network domains as the path between the remote UA and the executing UA, the media between the UA and the server may be protected by different network security than is applied to the original dialog.

these requirements may be satisfied by selecting an MOH server that is in the same administrative and network domain as the executing UA and whose path to all external addresses is the same as the UA's path to those addresses.

5.2. SIP (Signaling) Security πŸ”

the executing UA and the MOH server will usually be within the same administrative domain, and the SIP signaling path between them will lie entirely within that domain. in this case, the administrator of the domain should configure the UA and server to apply to the dialog between them a level of security that is appropriate for the administrative domain.

if the executing UA and the MOH server are not within the same administrative domain, the SIP signaling between them should be at least as secure as the SIP signaling between the executing UA and the remote UA. thus, the MOH server should support all of the SIP security facilities that are supported by the executing UA, and the executing UA should use in its dialog with the MOH server all SIP security facilities that are used in its dialog with the remote UA.

5.3. RTP (Media) Security 🎧

the RTP for the MOH media will pass directly between the MOH server and the remote UA, and thus may pass outside the administrative domain of the executing UA. while it is uncommon for the contents of the MOH media to be sensitive (and the remote UA will not usually be generating RTP when it is on hold), the MOH RTP should be at least as secure as the RTP between the executing UA and the remote UA. in order to make this possible, the MOH server should support all of the RTP security facilities that are supported by the executing UA.

it is possible that the remote UA and the MOH server support an RTP security facility that the executing UA does not support, and that it is desirable to use this facility for the MOH RTP. to enable doing so, the executing UA should pass the SDP between the remote UA and the MOH server completely, not omitting elements that it does not understand.

5.4. Media Filtering πŸ•΅οΈ

some UAs filter incoming RTP based on the address of origin as a media security measure, refusing to render the contents of RTP packets that originate from an address that is not shown in the remote SDP as an RTP destination address. the remote UA in the original dialog may use this form of media filtering, and if the executing UA does not update the SDP to inform the remote UA of the source address of the MOH media, the remote UA may not render the MOH media. note that the executing UA has no means for detecting that the remote UA uses media filtering, so the executing UA must assume that any remote UA uses media filtering.

the technique described in this document ensures that any UA that should render MOH media will be informed of the source address of the media via the SDP that it receives. this allows such UAs to filter media without interfering with MOH operation πŸ’œ

6. Acknowledgments ✨

okay so this is the thank-you section 🫢 and it's giving "the whole crew showed up." The first version came from Section 2.3 of [SIP-SERV-EX] plus the similar MOH setup in the snom UA πŸŽ€. Venkatesh [VENKATESH] then suggested big upgrades to the sequence of operations, which let the SDP handling get way better πŸ”₯.

John Elwell [ELWELL] was the MVP here πŸ‘‘. He pointed out that the executing UA has to pass through re-INVITEs/UPDATEs so ICE negotiation can happen, suggested mentioning the role of RTCP listening ports πŸ¦‹, and floated leaving out the dialog to the music source when the directionality would be "inactive". He also noticed that with multiple media streams, the executing UA may want to pick which streams get MOH πŸ’œ.

Paul Kyzivat [KYZIVAT-1] [KYZIVAT-2] flagged the headaches around reusing payload type numbers and the ideas for dodging them, which is how Section 2.8 came to be 🧚. Paul also suggested adding Section 4.1 to show why offerers should always include all supported formats πŸ’….

M. Ranganathan pointed out the struggles a B2BUA has (Section 4.2) because of all the changes of media source 🌸. Section 4.1 got a big glow-up after Attila Sipos [SIPOS] shared advice πŸ’–.

Rifaat Shekh-Yusef [SHEKH-YUSEF] is the reason we talk about dialog/session timers in Section 2.9 ⭐.

Robert Sparks clarified what the "Best Current Practice" status is actually for, so this document got switched to "Informational" 🌈.

In his SecDir review, Stephen Kent pointed out that the Security Considerations should cover how the MOH server uses SIP and SDP security features πŸ”₯πŸ™ˆ.

And honestly, tons of the text got better thanks to reviewers, including Rifaat Shekh-Yusef and Richard Barnes 🫢✨. Thank you all, periodt πŸ’…πŸ’œ.

7. References πŸ“š

7.1. 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.
  • [RFC3264] Rosenberg, J. and H. Schulzrinne, "An Offer/Answer Model with Session Description Protocol (SDP)", RFC 3264, June 2002.
  • [RFC4028] Donovan, S. and J. Rosenberg, "Session Timers in the Session Initiation Protocol (SIP)", RFC 4028, April 2005.
  • [RFC4566] Handley, M., Jacobson, V., and C. Perkins, "SDP: Session Description Protocol", RFC 4566, July 2006.

7.2. Informative References

Author's Address πŸ’Œ

Dale R. Worley
Ariadne Internet Services, Inc.
738 Main St.
Waltham, MA  02451
US

Phone: +1 781 647 9199
EMail: worley@ariadne.com

That's the whole doc, bestie! πŸŒˆπŸ¦‹πŸ’– Hit me up if you wanna go over any of the MOH stuff, I'm obsessed with it 🧚✨

πŸ“¦ where this page comes from