RFC 7702

Interworking between the Session Initiation Protocol (SIP) and the Extensible Messaging and Presence Protocol (XMPP): Groupchat

πŸ“… published December 2015, from ietf

RFC 7702: Interworking between SIP and XMPP, Groupchat ✨

Okay bestie, let's start with the header tea 🫢 This is RFC 7702, and the title is Interworking between the Session Initiation Protocol (SIP) and the Extensible Messaging and Presence Protocol (XMPP): Groupchat. It comes from the Internet Engineering Task Force (IETF) 🌸 and it was published in December 2015. It's on the Standards Track, so it's a real Internet Standard πŸ‘‘ Its ISSN is 2070-1721.

The authors are P. Saint-Andre (from &yet), S. Ibarra (from AG Projects), and S. Loreto (from Ericsson) πŸ’… The header doesn't have an Obsoletes or Updates line, so this one isn't replacing or patching any other document πŸŽ€

Abstract

Okay so this document defines a two-way protocol mapping for swapping instant messages in a multi-party chat session between people on the Session Initiation Protocol (SIP) and people on the Extensible Messaging and Presence Protocol (XMPP) πŸ¦‹ The specific pairing is the SIP-based Message Session Relay Protocol (MSRP) and the XMPP Multi-User Chat (MUC) extension. It's giving bridge between two worlds 🌈

Status of This Memo

This is an Internet Standards Track document πŸŽ€

It's a product of the Internet Engineering Task Force (IETF), so it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check Section 2 of RFC 5741 ✨

For the current status, any errata, and where to send feedback, head to http://www.rfc-editor.org/info/rfc7702 πŸ”₯

Copyright (c) 2015 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) as they stand on the date this document was published. Please read these carefully, because they spell out your rights and restrictions for this document πŸ™ˆ Code Components pulled out of this document must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions. They come with no warranty, as described in the Simplified BSD License.

Table of Contents

1. Introduction ....................................................4
2. Intended Audience ...............................................4
3. Terminology .....................................................5
4. Architectural Assumptions .......................................5
5. Multi-party Messaging Session from XMPP MUC to MSRP .............8
   5.1. Enter Room ................................................11
   5.2. Set Nickname ..............................................14
   5.3. Conference Subscription ...................................14
   5.4. Presence Broadcast ........................................15
   5.5. Exchange Messages .........................................19
        5.5.1. Send a Message to All Occupants ....................19
        5.5.2. Send a Private Message .............................21
   5.6. Change Nickname ...........................................22
   5.7. Invite Another User to a Room .............................23
   5.8. Exit Room .................................................25
6. MSRP Multi-party Messaging Session to XMPP MUC .................25
   6.1. Enter Room ................................................28
   6.2. Presence Broadcast ........................................30
   6.3. Exchange Messages .........................................32
        6.3.1. Send a Message to All Occupants ....................32
        6.3.2. Send a Private Message .............................34
   6.4. Change Nickname ...........................................34
   6.5. Invite Another User to a Room .............................35
   6.6. Exit Room .................................................36
7. Handling of Nicknames and Display Names ........................37
8. Message Size ...................................................38
9. Security Considerations ........................................38
10. References ....................................................39
   10.1. Normative References .....................................39
   10.2. Informative References ...................................40
Acknowledgements ..................................................42
Authors' Addresses ................................................43

1. Introduction 🌸

Both the Session Initiation Protocol (SIP) [RFC3261] and the Extensible Messaging and Presence Protocol (XMPP) [RFC6120] can handle multi-party text chat over the Internet πŸ’¬ To make sure these two can talk to each other, it's important to define mappings that work in both directions 🫢

The architectural assumptions behind these mappings are in [RFC7247], which also covers how addresses and error conditions get mapped ✨ This document covers mappings for multi-party text chat sessions (often called "groupchat"). Specifically, it maps the XMPP Multi-User Chat (MUC) extension [XEP-0045] to SIP-based multi-party chat using Message Session Relay Protocol (MSRP) [RFC4975], as specified in [RFC7701] πŸ¦‹

Both MUC and MSRP are packed with features, like administering rooms, kicking out and banning users, reserving a nickname in a room, changing the room subject, turning on room moderation, and destroying the room πŸ‘‘ This document only covers a basic subset of groupchat features πŸ“ That means joining a room, setting or changing a room nickname (but not permanently registering one), changing presence info inside the room, sending a message to everyone, sending a private message to one person, inviting another user to the room, and leaving the room. Future documents might map more features beyond this set 🧚

2. Intended Audience πŸŽ€

The documents in this series are for software developers who already have a system built on one of these technologies (for example SIP) and want to let that system talk to systems built on the other one (for example XMPP) πŸ’– We're assuming readers already know the core specifications for SIP [RFC3261] and XMPP [RFC6120], the base document for this series [RFC7247], and these groupchat specs:

  • Multi-party Chat Using MSRP [RFC7701]
  • Multi-User Chat [XEP-0045]

3. Terminology πŸ’…

A bunch of technical terms used here are defined in [RFC3261], [RFC4975], [RFC6120], and [XEP-0045] πŸ“š

In the flow diagrams, MSRP traffic is drawn with arrows like %%%>, SIP traffic is drawn with arrows like ***>, and XMPP traffic is drawn with arrows like ...> 🌈

In the protocol flows and examples, provisional SIP responses have been left out to keep things short ✨

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

4. Architectural Assumptions ✨

okay so XMPP and MSRP have totally different vibes when it comes to groupchat traffic πŸ’… In XMPP, a groupchat message is just another stanza. The XMPP server handles it directly, or hands it off to an associated server component for multi-user chat. 🫢

MSRP is more of a main character situation πŸŽ€ Sessions (groupchat ones included) get treated like a type of media, kinda like audio/video calls. Setting up, managing, and tearing down the session is the job of a "conference focus" [RFC4353] (here we're assuming it's reached via SIP) πŸ“ž But the actual session data gets handled by a separate entity called an MSRP switch. How the conference focus and MSRP switch talk to each other is up to whoever implements and deploys them, so it's not something this doc locks down πŸ€·β€β™€οΈ

Here's a diagram of a possible gateway deployment πŸ¦‹ These are the entities and what they mean:

  • romeo@example.org -- a SIP user πŸ’œ
  • romeo@example.org;gr=dr4hcr0st3lup4c -- a particular endpoint associated with the SIP user πŸ“±
  • example.org -- a SIP proxy with an associated SIP-to-XMPP gateway ("S2X GW") to XMPP 🌸
  • chat.example.org -- a SIP-based conference focus and MSRP switch with an associated MSRP-to-SIP gateway ("M2X GW") to XMPP 🧚
  • montague@chat.example.org -- a conference at an MSRP switch; not shown in diagram πŸ“
  • juliet@example.com -- an XMPP user πŸ’–
  • juliet@example.com/yn0cl4bnw0yr3vym -- a particular endpoint associated with the XMPP user πŸ’…
  • example.com -- an XMPP server with an associated XMPP-to-SIP gateway ("X2S GW") to SIP and an XMPP-to-MSRP gateway ("X2M GW") to MSRP πŸ‘‘
  • rooms.example.com -- an XMPP MUC service associated with example.com 🌈
  • capulet@rooms.example.com -- a chat room at an XMPP MUC service; not shown in diagram πŸ”₯
#####################################################################
#                                                                   #
#                  +------------------+                             #
#  &&&&&&&&&&&&&&&&| chat.example.org |<%%%%%%%%%%%                 #
#  &           &&&&| (MSRP switch) +-----+        %                 #
#  &           &   +---------------| M2X |        %                 #
#  &           &           %       | GW  |        %                 #
#  &           &           %       +-----+        %                 #
#  &           &           %        :             %                 #
#  &           &           %     ///////////////////////////////////#
#  &           &           %     /  :             %                 #
#  &           &           %     /  :          +-----+              #
#  &           &           %     /  :          | X2M |              #
#  &           &           %     /  :  +-------| GW  |---+          #
#  &           &           %     /  :.>|       +-----+   |          #
#  &           &           %     /     |                 |          #
#  & +------------------+  %     / +-----+               |          #
#  & | chat.example.org |<*******/*| X2S | example.com   |          #
#  & | (conference      |  %   **/*| GW  | (XMPP server) |          #
#  & | focus)     +-----+  %   * / +-----+               |          #
#  & +------------| S2X |  %   * /     |     +-------------------+  #
#  &       *      | GW  |......*./....>|     | rooms.example.com |  #
#  &       *      +-----+  %   * /     +-----| (MUC service)     |  #
#  &       *               %   * /       ^ : +-------------------+  #
#  & +---------------+     %   * /       : :                        #
#  &&| example.org   |<********* /       : :                        #
#    | (SIP proxy) +-----+ %     /       : :                        #
#    +-------------| S2X | %     /       : :                        #
#          *       | GW  |......./........ :                        #
#          *       +-----+ %     /         :                        #
#          *               %     /         :                        #
#          romeo@example.org     /         juliet@example.com       #
#          ;gr=dr4hcr0st3lup4c   /         /yn0cl4bnw0yr3vym        #
#                                /                                  #
#      --SIP/MSRP DOMAIN--       /         --XMPP DOMAIN--          #
#                                /                                  #
#####################################################################

Legend:

    . = XMPP
    % = MSRP
    * = SIP
    & = unstandardized communication paths
    / = separation of administrative domains

Figure 1: Logical Deployment Architecture

These are logical entities, and several of them might be co-located in the same physical entity 🏠 For example, the SIP conference focus, the MSRP switch, and their associated gateways might be part of the same deployed code. The same goes for the XMPP server, the MUC service, and their associated gateways. Also, an XMPP service would probably not have separate gateways for XMPP-to-SIP and XMPP-to-MSRP translation. It would more likely have a single gateway πŸ§ƒ

In SIP, there's no requirement that a SIP user like romeo@example.org use his SIP proxy to join a chat room on the XMPP network πŸ™ˆ He could, for example, try to find a SIP service at example.com directly, or locate a SIP-to-XMPP gateway on his own. As a simplifying assumption, this document shows the more expected path, where you use your "home" SIP proxy and gateways are associated with the sending domain. But nothing in this document should be read as discouraging other deployment architectures or communication paths, like services hosting their own inbound gateways ✨ Literally endless possibilities, bestie 🌈

5. Multi-party Messaging Session from XMPP MUC to MSRP ✨

okay so this section is where the magic happens πŸ¦‹ we're mapping an XMPP MUC session onto an MSRP Multi-party Messaging session, and it's giving full group chat glow-up πŸ’… below is the whole flow of one sample session. It includes some extra bits too (sending messages, changing your nickname, and inviting another user), so it's not just a boring hello and bye 🌸

   XMPP             XMPP               SIP               MSRP
   User            Server           Conference          Switch
    |             + X2S GW            Focus           + M2X GW
    |             & X2M GW          + S2X GW              |
    |                 |                 |                 |
    | (F1) XMPP       |                 |                 |
    | enter room      |                 |                 |
    |................>|                 |                 |
    |                 | (F2) SIP INVITE |                 |
    |                 |****************>|                 |
    |                 |                 | (F3)            |
    |                 |                 | unstandardized  |
    |                 |                 | interaction     |
    |                 |                 |<&&&&&&&&&&&&&&&>|
    |                 | (F4) SIP 200 OK |                 |
    |                 |<****************|                 |
    |                 | (F5) SIP ACK    |                 |
    |                 |****************>|                 |
    |                 | (F6) MSRP SEND (bodiless)         |
    |                 |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%>|
    |                 | (F7) MSRP 200 OK                  |
    |                 |<%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|
    |                 | (F8) MSRP NICKNAME                |
    |                 |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%>|
    |                 | (F9) MSRP 200 OK                  |
    |                 |<%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|
    |                 | (F10) SIP       |                 |
    |                 | SUBSCRIBE       |                 |
    |                 | Event:          |                 |
    |                 | conference      |                 |
    |                 |****************>|                 |
    |                 | (F11) SIP 200 OK|                 |
    |                 |<****************|                 |
    |                 | (F12) SIP NOTIFY|                 |
    |                 |<****************|                 |
    |                 | (F13) SIP 200 OK|                 |
    |                 |****************>|                 |
    | (F14) XMPP      |                 |                 |
    | presence        |                 |                 |
    |<................|                 |                 |
    | (F15) XMPP      |                 |                 |
    | MUC subject     |                 |                 |
    |<................|                 |                 |
    .                 .                 .                 .
    .                 .                 .                 .
    | (F16) XMPP      |                 |                 |
    | groupchat       |                 |                 |
    | message         |                 |                 |
    |................>|                 |                 |
    |                 | (F17) MSRP SEND                   |
    |                 |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%>|
    |                 | (F18) MSRP 200 OK
    |                 |<%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|
    | (F19) XMPP      |                 |                 |
    | groupchat       |                 |                 |
    | message         |                 |                 |
    |<................|                 |                 |
    .                 .                 .                 .
    .                 .                 .                 .
    | (F20) XMPP      |                 |                 |
    | private         |                 |                 |
    | message         |                 |                 |
    |................>|                 |                 |
    |                 | (F21) MSRP SEND                   |
    |                 |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%>|
    |                 | (F22) MSRP 200 OK
    |                 |<%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|
    .                 .                 .                 .
    .                 .                 .                 .
    | (F23) XMPP      |                 |                 |
    | presence:       |                 |                 |
    | change nick     |                 |                 |
    |................>|                 |                 |
    |                 | (F24) MSRP NICKNAME               |
    |                 |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%>|
    |                 | (F25) MSRP 425 Error              |
    |                 |<%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|
    | (F26) XMPP      |                 |                 |
    | presence        |                 |                 |
    | error           |                 |                 |
    |<................|                 |                 |
    .                 .                 .                 .
    .                 .                 .                 .
    | (F27) XMPP      |                 |                 |
    | message:        |                 |                 |
    | invite          |                 |                 |
    |................>|                 |                 |
    |                 | (F28) SIP       |                 |
    |                 | REFER           |                 |
    |                 |****************>|                 |
    |                 | (F29) SIP       |                 |
    |                 | 200 OK          |                 |
    |                 |<****************|                 |
    |                 | (F30) SIP       |                 |
    |                 | NOTIFY          |                 |
    |                 |<****************|                 |
    .                 .                 .                 .
    .                 .                 .                 .
    | (F31) XMPP      |                 |                 |
    | presence:       |                 |                 |
    | exit room       |                 |                 |
    |................>|                 |                 |
    |                 | (F32) SIP BYE   |                 |
    |                 |****************>|                 |
    |                 | (F33) SIP       |                 |
    |                 | 200 OK          |                 |
    |                 |<****************|                 |
    | (F34) XMPP      |                 |                 |
    | presence        |                 |                 |
    | unavailable     |                 |                 |
    |<................|                 |                 |
    |                 |                 |                 |

okay that's the whole vibe πŸŽ€ the detailed flows and mappings get their own sections next, so stay tuned bestie 🫢🌈

5.1. Enter Room πŸ¦‹

Okay bestie, so the XMPP Multi-User Chat (MUC) spec [XEP-0045] says that when an XMPP user (say, "juliet@example.com") wants to join a groupchat room (say, "montague@chat.example.org"), she sends a directed <presence/> stanza [RFC6121] to that chat room. ✨ In that request she also picks the nickname she wants inside the room (say, "JuliC"). In XMPP, that room nickname is the resourcepart of an occupant JID, so it ends up as "montague@chat.example.org/JuliC" πŸ’– The joining client also says "hi, I can do multi-user chat!" by including an empty <x/> element in the initial presence stanza, qualified by the http://jabber.org/protocol/muc namespace 🫢

Example 1: Juliet Enters Room (F1)

<presence from='juliet@example.com/yn0cl4bnw0yr3vym'
          to='montague@chat.example.org/JuliC'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>

Once the XMPP server gets that presence stanza, it has to figure out what the domainpart in the 'to' address is, and it does that by following the procedures in [RFC7247] πŸ” Here we pretend the server worked out that the domain is run by a SIP server, that it has (or can reach) an XMPP-to-SIP gateway or connection manager (which lets it talk natively to SIP servers), and that it hands the presence stanza off to that XMPP-to-SIP gateway πŸš€

Because a multi-user chat service treats that presence stanza as a request to enter a room, the XMPP-to-SIP gateway turns it into a SIP INVITE request πŸ’…

Example 2: SIP Mapping of Room Join (F2)

INVITE sip:montague@chat.example.org SIP/2.0
To: <sip:montague@chat.example.org>
From: "Juliet" <sip:juliet@example.com>;tag=786
Contact: <sip:juliet@example.com>;gr=yn0cl4bnw0yr3vym
Call-ID: BC466C1C-E01D-4FD1-B766-9AD174BAF2E7
CSeq: 1 INVITE
Content-Type: application/sdp
Content-Length: ...

c=IN IP4 x2s.example.org
m=message 7654 TCP/MSRP *
a=accept-types:text/cpim
a=accept-wrapped-types:text/plain text/html
a=path:msrp://x2m.example.com:7654/jshA7weztas;tcp
a=chatroom:nickname private-messages

Here the Session Description Protocol (SDP) offer names the XMPP-to-MSRP gateway on the XMPP side (in the SDP 'path' attribute from [RFC4975]), along with the other session details πŸŽ€

There is no direct mapping for the MSRP URIs. πŸ™ˆ An MSRP URI identifies a session of instant messages at one particular device. It's ephemeral and means nothing outside of that session. So the authority component of the MSRP URI here MUST contain the XMPP-to-MSRP gateway hostname or numeric IP address (and, per [RFC4975], an explicit port number too) πŸ’œ

The mapping from XMPP syntax elements to SIP and [RFC4566] syntax elements MUST be exactly what's in this table, no notes πŸ“

Table 1: Message Syntax Mapping from XMPP to SIP/SDP

+-----------------------------+-----------------------------+
|  XMPP Element or Attribute  |  SIP Header or SDP Contents |
+-----------------------------+-----------------------------+
|  from                       |  From                       |
|  to (without the /nick)     |  To                         |
+-----------------------------+-----------------------------+

As we saw in the example above and as [RFC7247] describes, the XMPP-to-SIP gateway MUST map the bare JID ("localpart@domainpart") of the XMPP sender into the SIP From header, and put the resourcepart of the full JID into the Globally Routable User Agent URI (GRUU) portion [RFC5627] of the SIP URI πŸ¦‹ Heads up though, a SIP response uses the same From and To as the SIP request, whereas an XMPP response swaps the from and to attributes. Plot twist, I know 😭

Here we assume the SIP conference focus accepts the session setup. The Contact header field of the SIP 200 OK response includes the 'isfocus' feature tag from [RFC4353], along with other relevant feature tags 🌸 The conference focus also sends back an answer session description that confirms the media choice, gives the MSRP URI of the switch (in the 'path' attribute from [RFC4975]), and includes the extensions from [RFC7701] ✨

Example 3: Chat Room Accepts Session Establishment (F4)

SIP/2.0 200 OK
From: "Juliet" <sip:juliet@example.com>;tag=786
To: <sip:montague@chat.example.org>;tag=087js
Call-ID: BC466C1C-E01D-4FD1-B766-9AD174BAF2E7
CSeq: 1 INVITE
Contact: <sip:montague@chat.example.org;transport=tcp>;isfocus
Content-Type: application/sdp
Content-Length: ...

v=0
c=IN IP4 example.org
s=-
m=message 12763 TCP/MSRP *
a=accept-types:message/cpim
a=accept-wrapped-types:text/plain text/html
a=path:msrp://chat.example.org:12763/kjhd37s2s20w2a;tcp
a=chatroom:nickname private-messages

Once it gets that response, the XMPP-to-SIP gateway sends a SIP ACK to the conference focus on behalf of the joining user πŸ₯°

Example 4: Gateway Sends ACK to Conference Focus (F5)

ACK sip:montague@chat.example.org SIP/2.0
To: <sip:montague@chat.example.org>;tag=087js
From: "Juliet" <sip:juliet@example.com>;tag=786
Call-ID: BC466C1C-E01D-4FD1-B766-9AD174BAF2E7
CSeq: 2 ACK

Per [RFC4975], the gateway sends a bodiless MSRP message (F6) to the switch right away once the connection is up, and the switch acknowledges it (F7) πŸ’«

5.2. Set Nickname πŸ’–

If the chat room server accepted the session, the XMPP-to-MSRP gateway sets up the nickname that came in the presence stanza. That's the resourcepart of the 'to' address, so "JuliC" in "montague@chat.example.org/JuliC" πŸŽ€ This is done using the extension from [RFC7701] πŸ”₯

Example 5: Gateway Sets Up Nickname (F8)

MSRP a786hjs2 NICKNAME
To-Path: msrp://montague@chat.example.org:12763/kjhd37s2s20w2a;tcp
From-Path: msrp://x2m.example.com:7654/jshA7weztas;tcp
Use-Nickname: "JuliC"
-------a786hjs2

The MSRP switch checks the current nickname allocations, accepts the nickname proposal, and replies with a 200 response πŸ‘‘

Example 6: MSRP Switch Accepts Nickname Proposal (F9)

MSRP a786hjs2 200 OK
To-Path: msrp://x2m.example.com:7654/jshA7weztas;tcp
From-Path: msrp://montague@chat.example.org:12763/kjhd37s2s20w2a
           ;tcp
-------a786hjs2

This section assumes the nickname request works out. The error flow for a nickname conflict is covered in Section 5.6 πŸ™ƒ

5.3. Conference Subscription 🧚

As [RFC7701] mentions, the joining user will usually also subscribe to a conference event package (see [RFC4575] and [RFC6502]) at the focus 🌈 [RFC7701] doesn't require that subscription, but in practice the temporary, context-dependent presence subscriptions and room rosters that come with joining an XMPP MUC room are best mapped to the conference event package. That's the vibe πŸ’…

Example 7: Gateway Subscribes to the Conference (F10)

SUBSCRIBE sip:montague@chat.example.org SIP/2.0
To: <sip:montague@chat.example.org>;tag=087js
From: "Juliet" <sip:juliet@example.com>;tag=786
Contact: <sip:juliet@example.com>;gr=yn0cl4bnw0yr3vym
Call-ID: BC466C1C-E01D-4FD1-B766-9AD174BAF2E7
CSeq: 3 SUBSCRIBE
Event: conference
Expires: 600
Accept: application/conference-info+xml
Allow-Events: conference
Content-Length: 0

The focus will accept or reject the request based on its local policy 🫠

Example 8: Focus Accepts Subscription Request (F11)

SIP/2.0 200 OK
To: <sip:montague@chat.example.org>;tag=087js
From: "Juliet" <sip:juliet@example.com>;tag=786
Call-ID: BC466C1C-E01D-4FD1-B766-9AD174BAF2E7
CSeq: 3 SUBSCRIBE
Contact: <sip:montague@chat.example.org;transport=tcp>;isfocus
Expires: 600
Content-Length: 0

If the conference focus accepts the request to enter a room, the XMPP user expects to get presence information back from all the existing occupants of the room πŸ‘€ To make that happen, the XMPP-to-SIP gateway subscribes to the conference event package [RFC4575] at the focus ✨

5.4. Presence Broadcast

When the conference event package subscription is completed, the focus sends to the XMPP-to-SIP gateway a NOTIFY request containing the presence information of all the existing occupants, represented using the format defined in [RFC4575]. okay so this is the moment the room gets its roster πŸ’–βœ¨

Example 9: Conference Focus Sends Presence Information (F12)

NOTIFY sip:montague@chat.example.org SIP/2.0
To: "Juliet" <sip:juliet@example.com>;tag=786
From: <sip:montague@chat.example.org>;tag=087js
Call-ID: BC466C1C-E01D-4FD1-B766-9AD174BAF2E7
CSeq: 4 NOTIFY
Event: conference
Subscription-State: active;expires=3600
Content-Type: application/conference-info+xml
Content-Length: ...

<conference-info version="0" state="full"
    entity="sip:3402934234@chat.example.org">
  <conference-description>
    <subject>Today in Verona</subject>
    <conf-uris>
      <entry>
        <uri>tel:+18882934234</uri>
      </entry>
    </conf-uris>
  </conference-description>
  <users>
    <user entity="sip:montague@chat.example.org;gr=Romeo"
          state="full">
      <display-text>Romeo</display-text>
      <roles>
        <entry>participant</entry>
      </roles>
      <associated-aors>
        <entry>
          <uri>xmpp:romeo@example.org/dr4hcr0st3lup4c</uri>
        </entry>
      </associated-aors>
      <endpoint entity="sip:montague@chat.example.org;gr=Romeo"
                state="full">
        <status>connected</status>
        <joining-info>
          <when>2013-12-12T10:01:03.691128+01:00</when>
        </joining-info>
        <media id="211835820">
          <type>message</type>
        </media>
      </endpoint>
    </user>
    <user entity="sip:montague@chat.example.org;gr=Ben"
          state="full">
      <display-text>Ben</display-text>
      <roles>
        <entry>participant</entry>
      </roles>
      <endpoint entity="sip:montague@chat.example.org;gr=Ben"
                state="full">
        <status>connected</status>
        <media id="211835821">
          <type>message</type>
        </media>
      </endpoint>
    </user>
    <user entity="sip:montague@chat.example.org;gr=JuliC"
          state="full">
      <display-text>JuliC</display-text>
      <roles>
        <entry>participant</entry>
      </roles>
       <endpoint entity="sip:montague@chat.example.org;gr=JuliC"
                 state="full">
         <status>connected</status>
         <media id="211835822">
           <type>message</type>
         </media>
       </endpoint>
    </user>
  </users>
</conference-info>

The syntax mapping from the RFC 4575 payload to the XMPP participant list MUST be as shown in the following table. (Mappings for elements not mentioned are undefined.) this one's a must, bestie, no skipping 🫢

Table 2: Participant list mapping

+--------------------------------+-----------------------------+
|  RFC 4575 Element or Attribute |  XMPP Element or Attribute  |
+--------------------------------+-----------------------------+
|  <conference-info/> 'entity'   |  room JID                   |
|  <subject/>                    |  room subject               |
|  <user/> 'entity'              |  occupant JID               |
|  <display-text/>               |  participant nickname       |
|  <endpoint/> 'entity'          |  occupant JID               |
|  <user/> 'associated-aors'     |  user full JID (if avail.)  |
+--------------------------------+-----------------------------+

Upon receiving such a response, the XMPP-to-SIP gateway sends a SIP 200 OK response to the conference focus (example not shown) and translates the participant list into a series of XMPP presence stanzas. the gateway literally turns the roster into presence stanzas, it's giving teamwork 🌸

Example 10: XMPP Mapping of Chat Room Presence (F14)

<presence from='montague@chat.example.org/Romeo'
          to='juliet@example.com/yn0cl4bnw0yr3vym'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='participant'/>
  </x>
</presence>

<presence from='montague@chat.example.org/Ben'
          to='juliet@example.com/yn0cl4bnw0yr3vym'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='participant'/>
  </x>
</presence>

<presence from='montague@chat.example.org/JuliC'
          to='juliet@example.com/yn0cl4bnw0yr3vym'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='participant'/>
    <status code='110'/>
  </x>
</presence>

If the NOTIFY request included a subject, the gateway converts that into a separate XMPP message. πŸ’…

Example 11: XMPP Mapping of Chat Room Subject (F15)

<message from='montague@chat.example.org/mayor'
         to='juliet@example.com/yn0cl4bnw0yr3vym'
         id='mbh2vd68'>
  <subject>Today in Verona</subject>
</message>

The mapping of SIP and [RFC4575] payload syntax elements to XMPP syntax elements MUST be as shown in the following table. (Mappings for elements not mentioned are undefined.) more mapping tea, and again the must is non-negotiable πŸ“

Table 3: Message Syntax Mapping from SIP to XMPP

+---------------------------------+-----------------------------+
| SIP Header or RFC 4575 Contents | XMPP Element or Attribute   |
+---------------------------------+-----------------------------+
|  <user/> 'entity'               |  from                       |
|  To with <display-text>         |  occupant JID               |
|  <role>participant</role>       |  role='participant'         |
|  [N/A]                          |  affiliation='none'         |
+---------------------------------+-----------------------------+

5.5. Exchange Messages

Once the user has joined the chat room, the user can exchange an unbounded number of messages, both public and private. the chat is OPEN, besties πŸ¦‹

The mapping of XMPP syntax elements to MSRP syntax elements MUST be as shown in the following table. (Mappings for elements not mentioned are undefined.) 🧚

Table 4: Message Syntax Mapping from XMPP Message to MSRP

+-----------------------------+-----------------------------+
|  XMPP Element or Attribute  |  CPIM Header                |
+-----------------------------+-----------------------------+
|  to                         |  To                         |
|  from                       |  From                       |
|  <body/>                    |  body of the SEND request   |
+-----------------------------+-----------------------------+

5.5.1. Send a Message to All Occupants

When Juliet wants to sends a message to all other occupants in the room, she sends a message of type "groupchat" to the <room@service> itself (in our example, <montague@chat.example.org>). main character Juliet energy, iykyk πŸ‘‘

The following examples show an exchange of a public message.

Example 12: Juliet Sends Message to All Occupants (F16)

<message from='juliet@example.com/yn0cl4bnw0yr3vym'
         to='montague@chat.example.org'
         type='groupchat'
         id='lzfed24s'>
      <body>Who knows where Romeo is?</body>
</message>

Upon receiving such a message, the XMPP-to-MSRP gateway translates it into an MSRP SEND message. 🌈

Example 13: Gateway Maps XMPP Message to MSRP (F17)

MSRP a786hjs2 SEND
To-Path: msrp://chat.example.org:12763/kjhd37s2s20w2a;tcp
From-Path: msrp://x2m.example.com:7654/jshA7weztas;tcp
Message-ID: 87652491
Byte-Range: 1-*/*
Content-Type: message/cpim

To: <sip:montague@chat.example.org>
From: "Juliet" <sip:juliet@example.com>
DateTime: 2008-10-15T15:02:31-03:00
Content-Type: text/plain

Who knows where Romeo is?
-------a786hjs2$

Upon receiving the SEND request, if the request either contains a Failure-Report header field value of "yes" or does not contain a Failure-Report header at all, the MSRP switch immediately generates and sends a response. the switch replies right away, no lag, very responsive πŸ’€

Example 14: MSRP Switch Returns 200 OK (F18)

MSRP d93kswow 200 OK
To-Path: msrp://x2m.example.com:7654/jshA7weztas;tcp
From-Path: msrp://chat.example.org:12763/kjhd37s2s20w2a;tcp
-------d93kswow$

Since an XMPP MUC room could be moderated and an XMPP user cannot be sure whether her message has been accepted without receiving it back from the server, [XEP-0045] states that the sender needs to receive a reflected copy of the message it sent. So, in this scenario, the XMPP-to-MSRP gateway has to reflect the message back to the sender. This procedure only applies to XMPP endpoints. the reflection is the mirror selfie of messaging πŸͺžβœ¨

Example 15: Gateway Reflects Message to XMPP User (F19)

<message from='montague@chat.example.org/JuliC'
         to='juliet@example.com/yn0cl4bnw0yr3vym'
         type='groupchat'
         id='ix51z73m'>
      <body>Who knows where Romeo is?</body>
</message>

5.5.2. Send a Private Message

Since each occupant has a unique JID, Juliet can send a "private message" to a selected occupant through the service by sending a message to the user's occupant JID. The XMPP message type ought to be "chat" (and is not allowed to be "groupchat"). psst, 1:1 DMs are a whole different vibe πŸ™ˆ

The following examples show an exchange of a private message.

Example 16: Juliet Sends Private Message (F20)

<message from='juliet@example.com/yn0cl4bnw0yr3vym'
         to='montague@chat.example.org/Romeo'
         type='chat'
         id='6sfln45q'>
      <body>O Romeo, Romeo! wherefore art thou Romeo?</body>
</message>

Upon receiving such a message, the XMPP-to-MSRP gateway translates it into an MSRP SEND message. πŸ¦‹

Example 17: Gateway Maps Private Message from XMPP to MSRP (F21)

MSRP a786hjs2 SEND
To-Path: msrp://chat.example.org:12763/kjhd37s2s20w2a;tcp
From-Path: msrp://x2m.example.com:7654/jshA7weztas;tcp
Message-ID: 87652491
Byte-Range: 1-*/*
Content-Type: message/cpim

To: <sip:montague@chat.example.org>;gr=Romeo
From: <sip:juliet@example.org>;gr=yn0cl4bnw0yr3vym
DateTime: 2008-10-15T15:02:31-03:00
Content-Type: text/plain

O Romeo, Romeo! wherefore art thou Romeo?
-------a786hjs2$

After acknowledging the message by sending an MSRP 200 OK message (step F22, not shown), the MSRP switch is responsible for sending the message to the intended recipient. When doing so, it modifies the From header to the sender's address within the chat room. the switch does the glow-up on the From header before delivery πŸ’œ

Example 18: Switch Sends Private Message to SIP User

MSRP a786hjs2 SEND
To-Path: msrp://chat.example.org:12763/kjhd37s2s20w2a;tcp
From-Path: msrp://x2m.example.com:7654/jshA7weztas;tcp
Message-ID: 87652491
Byte-Range: 1-*/*
Content-Type: message/cpim

To: <sip:romeo@example.org>
From: <sip:montague@chat.example.org>;gr=JuliC
DateTime: 2008-10-15T15:02:31-03:00
Content-Type: text/plain

O Romeo, Romeo! wherefore art thou Romeo?
-------a786hjs2$

Note: If an XMPP-to-MSRP gateway has support for private messaging, it MUST advertise that fact by adding a "private-messages" value to the a=chatroom SDP attribute it sends to the conference focus, as specified in [RFC7701]. this is the must-advertise moment, don't forget it πŸ“£

a=chatroom:nickname private-messages

5.6. Change Nickname ✨

okay so Juliet is feeling a new name era πŸ’… She can change her nickname by sending an updated presence stanza to the room, with the new nickname in it. Main character energy πŸ‘‘

Example 19: Juliet Changes Her Nickname (F23)

|  <presence from='juliet@example.com/yn0cl4bnw0yr3vym'
|            to='montague@chat.example.org/CapuletGirl'/>

So far we've been assuming the nickname she wants isn't already taken πŸ™ˆ But what happens when it is? Let's talk about it bestie.

The MSRP switch checks the current nickname allocations and spots that the proposed nickname already belongs to another participant. When that happens, the MSRP switch replies with a 425 response. Oof, rude πŸ’€

Example 20: MSRP Switch Does Not Accept Nickname Proposal (F25)

|  MSRP a786hjs2 425 Nickname usage failed
|  To-Path: msrp://x2m.example.com:7654/jshA7weztas;tcp
|  From-Path: msrp://chat.example.org:12763/kjhd37s2s20w2a;tcp
|  -------a786hjs2

When the XMPP-to-MSRP gateway gets that response, it turns it into an XMPP presence stanza of type "error" with a <conflict/> error condition 😭 That basically means the XMPP client has to pick a different nickname and go through the joining process again. Not the vibe, but we move 🫢

Example 21: Conflict Error for Nickname (F26)

|  <presence from='montague@chat.example.org/JuliC'
|            to='juliet@example.com/yn0cl4bnw0yr3vym'
|            type='error'>
|    <x xmlns='http://jabber.org/protocol/muc'/>
|    <error type='cancel' by='montague@chat.example.org'>
|      <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|    </error>
|  </presence>

Also, the gateway could make a new nickname request for the XMPP user on its own, so the XMPP client never has to deal with the conflict error at all. Shielding realness πŸ›‘οΈβœ¨

5.7. Invite Another User to a Room πŸ¦‹

okay so in XMPP there are two ways to invite someone to a room: direct invitations [XEP-0249] (sent straight from the user's real JID, outside the room, to the invitee's real JID) and mediated invitations (sent through the room, from the user's occupant JID to the invitee's JID). In this doc, we're only covering mediated invitations, so that's our lane πŸ’–

Say Juliet wants Benvolio in the room. She sends a message stanza with an invite, and Benvolio's JID goes in it. That JID could be his real JID or an occupant JID in some other room, which is lowkey iconic 🌸

Example 22: Juliet Invites Benvolio to the Room (F27)

|  <message from='juliet@example.com/yn0cl4bnw0yr3vym'
|           id='nzd143v8'
|           to='montague@chat.example.org'>
|    <x xmlns='http://jabber.org/protocol/muc#user'>
|      <invite to='benvolio@example.com'/>
|    </x>
|  </message>

Next, the XMPP-to-SIP gateway sends a SIP REFER request to the conference focus. The Refer-To header says who needs to be invited, as per Section 5.5 of [RFC4579] πŸ“ž

Example 23: SIP Mapping of Invite (F28)

|  REFER sip:montague@chat.example.org SIP/2.0
|  To: <sip:montague@chat.example.org>
|  From: "Juliet" <sip:juliet@example.com>;tag=786
|  Call-ID: BC466C1C-E01D-4FD1-B766-9AD174BAF2E7
|  CSeq: 5 REFER
|  Contact: <sip:juliet@example.com>;gr=yn0cl4bnw0yr3vym
|  Accept: message/sipfrag
|  Refer-To: <sip:benvolio@example.com>
|  Supported: replaces
|  Content-Length: 0

The conference focus replies to that SIP REFER with a 200 OK (step F29, not shown) ✨

The invitation's progress gets tracked through the NOTIFY requests that come in, as per [RFC3515] πŸ””

Example 24: Progress Notification for Invitation (F30)

|  NOTIFY sip:juliet@example.com SIP/2.0
|  To: <sip:juliet@example.com>;tag=786
|  From: <sip:montague@chat.example.org>;tag=087js
|  Call-ID: BC466C1C-E01D-4FD1-B766-9AD174BAF2E7
|  CSeq: 6 NOTIFY
|  Max-Forwards: 70
|  Event: refer
|  Subscription-State: active;expires=60
|  Contact: <sip:montague@chat.example.org;transport=tcp>;isfocus
|  Content-Type: message/sipfrag;version=2.0
|  Content-Length: ...
Note: Implementers might want to be aware that a few recently published specs change how REFER requests handle SIP notifications (see [RFC7647] and [RFC7614]). Read those too, bestie 🧐

5.8. Exit Room πŸ’œ

When Juliet is done and wants to leave the chat room, her client sends a directed presence stanza of type "unavailable" to the occupant JID she's using in the room (here <montague@chat.example.org/JuliC>). Bye bye πŸ‘‹

Example 25: Juliet Exits Room (F31)

|  <presence from='juliet@example.com/yn0cl4bnw0yr3vym'
|            to='montague@chat.example.org/JuliC'
|            type='unavailable'/>

When the XMPP-to-SIP gateway gets that stanza, it ends the SIP session by sending a SIP BYE to the conference focus. The conference focus answers with a SIP 200 OK (steps F32 and F33, not shown) πŸ“΄

Juliet can also add a custom exit message to her presence stanza of type "unavailable". If she does, it gets broadcast to the other participants using the methods described above, so she gets a dramatic goodbye 🎭

Example 26: Juliet Exits the Chat Room (F31)

|  <presence from='juliet@example.com/yn0cl4bnw0yr3vym'
|            to='montague@chat.example.org/JuliC'
|            type='unavailable'>
|    <status>O, look! methinks I see my cousin's ghost</status>
|  </presence>

6. MSRP Multi-party Messaging Session to XMPP MUC 🌈

okay this is the flip side πŸ”„ Here we map a Multi-party Instant Message (IM) MSRP session onto an XMPP MUC session. Same as before, the diagram below shows the overall protocol flow for a sample session. It includes some optional stuff too, like sending messages, changing nicknames, and inviting someone, so it's giving full group chat energy πŸ’¬

SIP               SIP               MSRP             XMPP
User             Proxy             Switch           Server
 |             + S2X GW          + M2X GW          +X2S GW
 |                 |                 |             +X2M GW
 |                 |                 |                 |
 | (F35) SIP       |                 |                 |
 | INVITE          |                 |                 |
 |****************>|                 |                 |
 | (F36) SIP       |                 |                 |
 | 200 OK          |                 |                 |
 |<****************|                 |                 |
 | (F37) SIP ACK   |                 |                 |
 |****************>|                 |                 |
 | (F38) SIP       |                 |                 |
 | SUBSCRIBE       |                 |                 |
 | Event:          |                 |                 |
 | conference      |                 |                 |
 |****************>|                 |                 |
 | (F39) SIP       |                 |                 |
 | 200 OK          |                 |                 |
 |<****************|                 |                 |
 |                 | (F40) XMPP presence: enter room   |
 |                 |..................................>|
 |                 | (F41) XMPP presence               |
 |                 |<..................................|
 | (F42) SIP       |                 |                 |
 | NOTIFY          |                 |                 |
 |<****************|                 |                 |
 | (F43) SIP       |                 |                 |
 | 200 OK          |                 |                 |
 |****************>|                 |                 |
 .                 .                 .                 .
 .                 .                 .                 .
 | (F44) MSRP SEND                   |                 |
 |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%>|                 |
 |                 |                 | (F45) XMPP      |
 |                 |                 | groupchat       |
 |                 |                 | message         |
 |                 |                 |................>|
 |                 |                 | (F46) XMPP      |
 |                 |                 | groupchat       |
 |                 |                 | message         |
 |                 |                 |<................|
 | (F47) MSRP 200 OK                 |                 |
 |<%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|                 |
 .                 .                 .                 .

 .                 .                 .                 .
 | (F48) MSRP SEND                   |                 |
 |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%>|                 |
 | (F49) MSRP 200 OK                 |                 |
 |<%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|                 |
 |                 |                 | (F50) XMPP      |
 |                 |                 | message         |
 |                 |                 |................>|
 .                 .                 .                 .
 .                 .                 .                 .
 | (F51) MSRP NICKNAME               |                 |
 |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%>|                 |
 |                 |                 | (F52) XMPP      |
 |                 |                 | presence        |
 |                 |                 |................>|
 |                 |                 | (F53) XMPP      |
 |                 |                 | presence        |
 |                 |                 | error           |
 |                 |                 |<................|
 | (F54) MSRP 425 Error              |                 |
 |<%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|                 |
 .                 .                 .                 .
 .                 .                 .                 .
 | (F55) SIP REFER |                 |                 |
 |****************>|                 |                 |
 | (F56) SIP       |                 |                 |
 | 200 OK          |                 |                 |
 |<****************|                 |                 |
 | (F57) SIP       |                 |                 |
 | NOTIFY          |                 |                 |
 |<****************|                 |                 |
 |                 | (F58) XMPP message invite         |
 |                 |..................................>|
 .                 .                 .                 .
 .                 .                 .                 .
 | (F59) SIP BYE   |                 |                 |
 |****************>|                 |                 |
 |                 | (F60) XMPP presence unavailable   |
 |                 |..................................>|
 |                 | (F61) XMPP presence unavailable   |
 |                 |<..................................|
 | (F62) SIP       |                 |                 |
 | 200 OK          |                 |                 |
 |<****************|                 |                 |
 |                 |                 |                 |

Quick heads-up on timing πŸ•°οΈ If the XMPP presence stanza shows up before the SIP SUBSCRIBE dialog is set up for the conference event, the server SHOULD cache the participant list until the subscription is established and the list gets delivered in a SIP NOTIFY request. Patience is a virtue, bestie 🫢

6.1. Enter Room πŸšͺ✨

Okay bestie, so when the SIP user ("Romeo") wants to join a groupchat room ("capulet"), he first has to start the SIP session by sending a SIP INVITE request. The offer includes an MSRP media line with mandatory 'path' and 'chatroom' attributes πŸ’Œ. We're assuming Romeo's user agent already knows about an MSRP switch (chat.example.org) it can use. The media line also has an 'accept-types' attribute that supports a Message/CPIM [RFC3862] top-level wrapper for the MSRP message πŸŽ€.

Example 27: SIP User Starts Session (F35)

INVITE sip:capulet@rooms.example.com SIP/2.0
From: "Romeo" <sip:romeo@example.org>;tag=43524545
To: <sip:capulet@rooms.example.com>
Contact: <sip:romeo@example.org>;gr=dr4hcr0st3lup4c
Call-ID: 08CFDAA4-FAED-4E83-9317-253691908CD2
CSeq: 1 INVITE
Content-Type: application/sdp
Content-Length: ...

c=IN IP4 s2x.example.org
m=message 7313 TCP/MSRP *
a=accept-types:message/cpim text/plain text/html
a=accept-wrapped-types:text/plain text/html
a=path:msrp://chat.example.org:7313/ansp71weztas;tcp
a=chatroom:nickname private-messages

When the INVITE lands, the SIP proxy has to figure out the domain part of the Request-URI or To header πŸ”. It does that by following the procedures in [RFC7247]. We're assuming the proxy finds out the domain is run by an XMPP server, that it has (or can reach) a SIP-to-XMPP gateway or connection manager that speaks XMPP natively 🌸, and that the proxy hands the message off to that gateway.

Implementations MAY wait until the nickname is set with an MSRP NICKNAME chunk before joining the XMPP MUC, or they MAY pick a temporary nickname (like the SIP From header display name) and use it to join the room 🧚. We're going with the second option here.

Example 28: SIP-to-XMPP Gateway ACKs Session (F36)

SIP/2.0 200 OK
From: "Romeo" <sip:romeo@example.org>;tag=43524545
To: <sip:capulet@rooms.example.com>;tag=a3343df32
Contact: <sip:rooms.example.com;transport=tcp>;isfocus
Call-ID: 08CFDAA4-FAED-4E83-9317-253691908CD2
CSeq: 1 INVITE
Content-Type: application/sdp

m=message 8763 TCP/MSRP *
a=accept-types:message/cpim text/plain text/html
a=accept-wrapped-types:text/plain text/html
a=path:msrp://chat.example.org:8763/lkjh37s2s20w2a;tcp
a=chatroom:nickname private-messages

Next up, the SIP/MSRP user agent subscribes to a conference event package at the destination groupchat service πŸ“‘.

Example 29: Gateway Subscribes to the Conference (F38)

SUBSCRIBE sip:capulet@rooms.example.com SIP/2.0
To: <sip:capulet@rooms.example.com>;tag=a3343df32
From: "Romeo" <sip:romeo@example.org>;tag=43524545
Contact: <sip:romeo@example.org>;gr=dr4hcr0st3lup4c
Call-ID: 08CFDAA4-FAED-4E83-9317-253691908CD2
CSeq: 2 SUBSCRIBE
Event: conference
Expires: 600
Accept: application/conference-info+xml
Allow-Events: conference
Content-Length: 0

Once the conference subscription request gets acknowledged, the SIP-to-XMPP gateway sends presence from Romeo to the MUC chat room πŸŽ‰.

Example 30: Romeo Enters XMPP Chat Room (F40)

<presence from='romeo@example.org/dr4hcr0st3lup4c'
          to='montague@chat.example.org/Romeo'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>

6.2. Presence Broadcast πŸ“£

If the MUC service can add the SIP/MSRP user to the room, it sends presence from every existing occupant's room JID to the new occupant's full JID 🫢. That presence includes extended info about roles, carried in an <x/> element.

Example 31: XMPP Service Sends Presence from Existing Occupants to New Occupant (F41)

<presence from='capulet@rooms.example.com/Romeo'
          to='romeo@example.org/dr4hcr0st3lup4c'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='participant'/>
    <status code='110'/>
  </x>
</presence>

<presence from='capulet@rooms.example.com/Ben'
          to='romeo@example.org/dr4hcr0st3lup4c'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='participant'/>
  </x>
</presence>

<presence from='capulet@rooms.example.com/JuliC'
          to='romeo@example.org/dr4hcr0st3lup4c'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none' role='participant'/>
  </x>
</presence>

Here's the tea β˜•. When these presence stanzas arrive, and the conference focus has already finished subscribing to the conference event package [RFC4575], the XMPP-to-SIP gateway turns them into a SIP NOTIFY request. That request carries the participant list, written in the conference-info format from [RFC4575] πŸ“‹.

Example 32: SIP Mapping of XMPP Participant Presence Stanzas (F42)

NOTIFY sip:romeo@example.org SIP/2.0
To: <sip:romeo@example.org>;tag=43524545
From: <sip:capulet@rooms.example.com>;tag=a3343df32
Call-ID: 08CFDAA4-FAED-4E83-9317-253691908CD2
CSeq: 3 NOTIFY
Event: conference
Subscription-State: active;expires=3600
Content-Type: application/conference-info+xml
Content-Length: ...

<conference-info version="0" state="full"
    entity="sip:capulet@rooms.example.com">
  <conference-description>
    <subject>Today in Verona</subject>
    <conf-uris>
      <entry>
        <uri>tel:+18882934234</uri>
        <uri>sip:capulet@rooms.example.com</uri>
      </entry>
    </conf-uris>
 </conference-description>
 <users>
   <user entity="sip:capulet@rooms.example.com;gr=JuliC"
         state="full">
     <display-text>JuliC</display-text>
     <roles>
       <entry>participant</entry>
     </roles>
     <endpoint entity="sip:capulet@rooms.example.com;gr=JuliC"
               state="full">
       <status>connected</status>
       <media id="211835821">
         <type>message</type>
       </media>
     </endpoint>
   </user>
   <user entity="sip:capulet@rooms.example.com;gr=Ben"
         state="full">
     <display-text>Ben</display-text>
     <roles>
       <entry>participant</entry>
     </roles>
     <endpoint entity="sip:capulet@rooms.example.com;gr=Ben"
               state="full">
       <status>connected</status>
       <media id="211835822">
         <type>message</type>
       </media>
     </endpoint>
   </user>
 </users>
</conference-info>

Now, this part is a little tricky πŸ™ˆ. In XMPP, the "room roster" arrives as a bunch of separate presence stanzas, one per participant. In SIP, though, the whole participant list shows up in one single conference information document. So the SIP-to-XMPP gateway has to keep track of the user's SIP URI and how that URI maps to an XMPP address πŸ—ΊοΈ. Based on that mapping, it has to figure out when it has a complete room roster from the MUC room. That moment is when it has received the in-room presence of the SIP user, which according to [XEP-0045] is the last presence stanza in the initial batch sent after joining πŸ₯Ή. Once that happens, the SIP-to-XMPP gateway can build the conference information document with the full participant list and send it to the SIP user πŸ’….


6.3. Exchange Messages πŸ’¬

Once the user is in the chat room, they can send an unbounded number of messages, both public and private 🌈.

The mapping of MSRP syntax elements to XMPP syntax elements MUST be as shown in the following table. (Mappings for elements not mentioned are undefined.)

Table 5: Message Syntax Mapping from MSRP Message to XMPP

    +-----------------------------+-----------------------------+
    |  CPIM Header                |XMPP Element or Attribute    |
    +-----------------------------+-----------------------------+
    |  To                         |  to                         |
    |  From                       |  from                       |
    |  body of the SEND request   |  <body/>                    |
    +-----------------------------+-----------------------------+

6.3.1. Send a Message to All Occupants πŸ“’

When Romeo wants to message every other occupant in the room, he sends an MSRP SEND request to <room@service> (<capulet@rooms.example.com> in our example) 🌹.

Here's an exchange of a public message πŸ‘€.

Example 33: Romeo Sends a Message to the Chat Room (F44)

MSRP a786hjs2 SEND
To-Path: msrp://room.example.com:7313/ansp71weztas;tcp
From-Path: msrp://chat.example.org:8763/lkjh37s2s20w2a;tcp
Message-ID: 87652492
Byte-Range: 1-*/*
Content-Type: message/cpim

To: <sip:capulet@rooms.example.com>
From: "Romeo" <sip:romeo@example.org>;gr=dr4hcr0st3lup4c
DateTime: 2008-10-15T15:02:31-03:00
Content-Type: text/plain

Romeo is here!
-------a786hjs2$

So here's how it goes. When the SEND request arrives and it either has a Failure-Report header field value of "yes" or has no Failure-Report header at all, the SIP-to-XMPP gateway right away translates it into an XMPP message stanza. Then it generates and sends an MSRP response ⚑.

Example 34: XMPP Mapping of Message (F45)

<message from='romeo@example.org/dr4hcr0st3lup4c'
         to='capulet@rooms.example.com'
         type='groupchat'
         id='8gbx1g4p'>
  <body>Romeo is here!</body>
</message>

Example 35: MSRP Response to Public Message (F47)

MSRP d93kswow 200 OK
To-Path: msrp://rooms.example.com:8763/lkjh37s2s20w2a;tcp
From-Path: msrp://chat.example.org:7313/ansp71weztas;tcp
-------d93kswow$

Note well πŸ“ that the XMPP MUC room reflects the sender's message back to everyone, the sender included. The MSRP-to-XMPP gateway SHOULD wait until it receives this reflected message before it sends an MSRP 200 OK reply to the original sender 🫧.


6.3.2. Send a Private Message 🀫

Romeo can send a "private message" to a chosen occupant through the chat room service by sending a message to that occupant's room nickname πŸ’•.

Here's an exchange of a private message πŸ’Œ.

Example 36: Romeo Sends a Private Message (F48)

MSRP a786hjs2 SEND
To-Path: msrp://rooms.example.com:7313/ansp71weztas;tcp
From-Path: msrp://chat.example.org:8763/lkjh37s2s20w2a;tcp
Message-ID: 87652492
Byte-Range: 1-*/*
Content-Type: message/cpim

To: <sip:capulet@rooms.example.com>;gr=JuliC
From: "Romeo" <sip:romeo@example.org>;gr=dr4hcr0st3lup4c
DateTime: 2008-10-15T15:02:31-03:00
Content-Type: text/plain

I am here!!!
-------a786hjs2$

The MSRP switch is in charge of turning the 'From' address into an in-room address (not shown here) πŸ”„.

Once the MSRP switch passes that message along to the gateway, the gateway translates it into XMPP syntax πŸͺ„.

Example 37: XMPP Mapping of Private Message (F50)

<message from='capulet@rooms.example.com/Romeo'
         to='capulet@rooms.example.com/JuliC'
         type='chat'
         id='rg2ca9k7'>
  <body>I am here!!!</body>
</message>

6.4. Change Nickname

okay so bestie, if Romeo wants a new nickname in the room πŸ’… he just sends a fresh MSRP NICKNAME request. honestly? changing it is exactly the same as reserving and using a nickname the first time πŸ¦‹βœ¨

Example 38: MSRP User Changes Nickname (F51)

|  MSRP a786hjs2 NICKNAME
|  To-Path: msrp://chat.example.org:7313/ansp71weztas;tcp
|  From-Path: msrp://rooms.example.com:8763/lkjh37s2s20w2a;tcp
|  Use-Nickname: "montecchi"
|  -------a786hjs2

once that lands, the MSRP-to-XMPP gateway turns it into an XMPP presence stanza πŸŽ€

Example 39: XMPP Mapping of Nickname Change (F52)

|  <presence from='romeo@example.org/dr4hcr0st3lup4c'
|            to='capulet@rooms.example.com/montecchi'/>

the XMPP server checks the nickname allocation and decides whether the name is free and usable 🧐. if it's taken or not usable, the server sends back a presence stanza of type "error" with a <conflict/> error condition. not it πŸ’€

Example 40: XMPP Conflict Error for Nickname (F53)

|  <presence from='capulet@rooms.example.com/Romeo'
|            to='romeo@example.org/dr4hcr0st3lup4c'
|            type='error'>
|    <x xmlns='http://jabber.org/protocol/muc'/>
|    <error type='cancel' by='capulet@rooms.example.com'>
|      <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|    </error>
|  </presence>

and then the XMPP-to-MSRP gateway replies to the NICKNAME request with code 425 πŸ₯Ί

Example 41: Gateway Translates XMPP Nickname Conflict to MSRP Error Code (F54)

|  MSRP a786hjs2 425 Nickname usage failed
|  To-Path: msrp://chat.example.org:7313/ansp71weztas;tcp
|  From-Path: msrp://rooms.example.com:8763/lkjh37s2s20w2a;tcp
|  -------a786hjs2

6.5. Invite Another User to a Room

okay so if a SIP user wants to bring someone into the conference 🌸 they send a REFER request, and the person they're inviting goes in the Refer-To header. this follows Section 5.5 of [RFC4579] πŸ’œ

Example 42: SIP User Invites Another User (F55)

|  REFER sip:capulet@rooms.example.com SIP/2.0
|  To: <sip:capulet@rooms.example.com>;tag=a3343df32
|  From: "Romeo" <sip:romeo@example.org>;tag=5534562
|  Call-ID: 08CFDAA4-FAED-4E83-9317-253691908CD2
|  CSeq: 4 REFER
|  Contact: <sip:romeo@example.org>;gr=dr4hcr0st3lup4c
|  Accept: message/sipfrag
|  Refer-To: <sip:benvolio@example.com>
|  Supported: replaces
|  Content-Length: 0

the SIP-to-XMPP gateway then says "got it" with a 200 OK response (step F56) ✨

then the gateway sends a NOTIFY request as per [RFC3515] to show the invite is in progress 🫢. the thing is, you can't really know how the invite is going until the person has actually joined, so implementers are advised to end the REFER dialog subscription as soon as the first NOTIFY request arrives, with a status code of 100 Trying πŸ™ˆ

Example 43: Progress Notification for Invitation (F56)

|  NOTIFY sip:romeo@example.org SIP/2.0
|  To: <sip:romeo@example.org>;tag=5534562
|  From: <sip:capulet@rooms.example.com>;tag=a3343df32
|  Call-ID: 08CFDAA4-FAED-4E83-9317-253691908CD2
|  CSeq: 5 NOTIFY
|  Event: refer
|  Subscription-State: terminated;reason=noresource
|  Contact: <sip:capulet@rooms.example.com;transport=tcp>;isfocus
|  Content-Type: message/sipfrag;version=2.0
|  Content-Length: ...
|
|  SIP/2.0 100 Trying

6.6. Exit Room

okay so if Romeo decides to leave the chat room πŸ¦‹, his client sends a SIP BYE to the <montague@chat.example.org> chat room. bye bye bestie πŸ‘‹

Example 44: Romeo Terminates Session (F59)

|  BYE sip:capulet@rooms.example.com SIP/2.0
|  Max-Forwards: 70
|  From: "Romeo" <sip:romeo@example.org>;tag=5534562
|  To: <sip:capulet@rooms.example.com>;tag=a3343df32
|  Call-ID: 08CFDAA4-FAED-4E83-9317-253691908CD2
|  CSeq: 6 BYE
|  Content-Length: 0

when the SIP BYE shows up, the SIP-to-XMPP gateway turns it into a presence stanza of type "unavailable" (F60) and sends it along to the XMPP MUC room service πŸ’…. then the SIP-to-XMPP gateway responds with a 200 OK to the MSRP user (F62) 🌈

Example 45: Romeo Exits Chat Room (F60)

|  <presence from='romeo@example.org/dr4hcr0st3lup4c'
|            to='capulet@rooms.example.com/Romeo'
|            type='unavailable'/>

7. Handling of Nicknames and Display Names ✨

okay so the basic rules for mapping addresses between XMPP and SIP are in [RFC7247] πŸŽ€. but chat rooms have an extra, super specific ID for each participant called a "nickname" 🫢. implementations SHOULD apply the rules for preparing and comparing nicknames from [RFC7700] πŸ’œ

on top of nicknames, some groupchat apps also show display names 🌸. these might or might not match someone's nickname. a display name doesn't have to be unique in a room, it just gives a friendly name for a participant 🧚

in the SIP conference event package, the nickname is the value of the Centralized Conferencing (XCON) 'nickname' attribute of the <user/> element [RFC6501], and the display name is the XML character data of the conference-info <display-text/> element [RFC4575] πŸ¦‹. in XMPP, the nickname is the value of the resourcepart of the occupant JID [XEP-0045], and the display name is the XML character data of the <nick/> element [XEP-0172] πŸ’–.

real talk, the <display-text/> element is treated as canonical in SIP implementations, and the <nick/> element is rarely used in XMPP implementations 😭. so for display purposes, SIP implementations ought to use the <display-text/> element if the XCON 'nickname' attribute is not present, and XMPP implementations ought to use the resourcepart of the occupant JID if the <nick/> element is not present πŸ™ˆ.

if the SIP nickname and the XMPP nickname clash, the SIP-to-XMPP or XMPP-to-SIP gateway is responsible for changing the nickname to avoid the conflict and for telling the SIP or XMPP client which unique nickname it used to join the chat room πŸ”₯.

8. Message Size πŸ“

it's possible for MSRP messages to be bigger than what an XMPP service on the far end of an MSRP-to-XMPP gateway allows 😬. see [RFC7573] for a discussion of this issue πŸ’œ.

9. Security Considerations πŸ”

⚠️ this section is SERIOUS, bestie. read every word. πŸ’€

the security considerations of [RFC3261], [RFC4975], [RFC6120], [RFC7247], [RFC7701], and [XEP-0045] apply 🫢.

this document specifies ways to exchange groupchat messages through a gateway that translates between SIP and XMPP. such a gateway MUST be compliant with the minimum security requirements of the protocols it translates (that is, MSRP/SIP and XMPP) πŸ”₯. adding gateways to the security models of MSRP, SIP, and XMPP brings some new risks 😨. in particular, end-to-end security properties (especially confidentiality and integrity) between user agents that talk through an MSRP-to-XMPP gateway can only be provided if common formats are supported. unfortunately, even though [RFC3862] specifies such a format for one-to-one instant messages, end-to-end security for multi-party messaging has not been solved in a standardized way πŸ’”.

some features this document doesn't cover in its minimal interoperability baseline matter for security, like the ability to administer rooms, kick people out and ban them, and turn on room moderation πŸ›‘οΈ. users who need those features can't get them through a gateway in a standardized way, so they'll need to use native clients for the relevant protocol (MSRP or XMPP) πŸ’….

as [RFC7572] mentions, there are several possible methods for end-to-end encryption of one-to-one instant messages. unfortunately, because there's no widely deployed method for end-to-end encryption of multi-party instant messages, this document can't make a recommendation on that 😭🫢.

10. References πŸ“š

10.1. Normative References πŸŽ€

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119,
           DOI 10.17487/RFC2119, March 1997,
           <http://www.rfc-editor.org/info/rfc2119>.

[RFC3261]  Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston,
           A., Peterson, J., Sparks, R., Handley, M., and E.
           Schooler, "SIP: Session Initiation Protocol", RFC 3261,
           DOI 10.17487/RFC3261, June 2002,
           <http://www.rfc-editor.org/info/rfc3261>.

[RFC4579]  Johnston, A. and O. Levin, "Session Initiation Protocol
           (SIP) Call Control - Conferencing for User Agents",
           BCP 119, RFC 4579, DOI 10.17487/RFC4579, August 2006,
           <http://www.rfc-editor.org/info/rfc4579>.

[RFC4975]  Campbell, B., Ed., Mahy, R., Ed., and C. Jennings, Ed.,
           "The Message Session Relay Protocol (MSRP)", RFC 4975,
           DOI 10.17487/RFC4975, September 2007,
           <http://www.rfc-editor.org/info/rfc4975>.

[RFC5627]  Rosenberg, J., "Obtaining and Using Globally Routable User
           Agent URIs (GRUUs) in the Session Initiation Protocol
           (SIP)", RFC 5627, DOI 10.17487/RFC5627, October 2009,
           <http://www.rfc-editor.org/info/rfc5627>.

[RFC6120]  Saint-Andre, P., "Extensible Messaging and Presence
           Protocol (XMPP): Core", RFC 6120, DOI 10.17487/RFC6120,
           March 2011, <http://www.rfc-editor.org/info/rfc6120>.

[RFC6121]  Saint-Andre, P., "Extensible Messaging and Presence
           Protocol (XMPP): Instant Messaging and Presence",
           RFC 6121, DOI 10.17487/RFC6121, March 2011,
           <http://www.rfc-editor.org/info/rfc6121>.

[RFC7247]  Saint-Andre, P., Houri, A., and J. Hildebrand,
           "Interworking between the Session Initiation Protocol
           (SIP) and the Extensible Messaging and Presence Protocol
           (XMPP): Architecture, Addresses, and Error Handling",
           RFC 7247, DOI 10.17487/RFC7247, May 2014,
           <http://www.rfc-editor.org/info/rfc7247>.

[RFC7573]  Saint-Andre, P. and S. Loreto, "Interworking between the
           Session Initiation Protocol (SIP) and the Extensible
           Messaging and Presence Protocol (XMPP): One-to-One Text
           Chat Sessions", RFC 7573, DOI 10.17487/RFC7573, June 2015,
           <http://www.rfc-editor.org/info/rfc7573>.

[RFC7700]  Saint-Andre, P., "Preparation, Enforcement, and Comparison
           of Internationalized Strings Representing Nicknames",
           RFC 7700, DOI 10.17487/RFC7700, December 2015,
           <http://www.rfc-editor.org/info/rfc7700>.

[RFC7701]  Niemi, A., Garcia-Martin, M., and G. Sandbakken, "Multi-
           party Chat Using the Message Session Relay Protocol
           (MSRP)", RFC 7701, DOI 10.17487/RFC7701, December 2015,
           <http://www.rfc-editor.org/info/rfc7701>.

[XEP-0045] Saint-Andre, P., "Multi-User Chat", XSF XEP 0045, February
           2012, <http://www.xmpp.org/extensions/xep-0045.html>.

10.2. Informative References πŸ“šβœ¨

Okay bestie, these are the extra-credit reads πŸ€“ You don't need them to get the main idea, but they're super useful if you want the full backstory.

[RFC3515] Sparks, R., "The Session Initiation Protocol (SIP) Refer Method", RFC 3515, DOI 10.17487/RFC3515, April 2003, <http://www.rfc-editor.org/info/rfc3515>.

[RFC3862] Klyne, G. and D. Atkins, "Common Presence and Instant Messaging (CPIM): Message Format", RFC 3862, DOI 10.17487/RFC3862, August 2004, <http://www.rfc-editor.org/info/rfc3862>.

[RFC4353] Rosenberg, J., "A Framework for Conferencing with the Session Initiation Protocol (SIP)", RFC 4353, DOI 10.17487/RFC4353, February 2006, <http://www.rfc-editor.org/info/rfc4353>.

[RFC4566] Handley, M., Jacobson, V., and C. Perkins, "SDP: Session Description Protocol", RFC 4566, DOI 10.17487/RFC4566, July 2006, <http://www.rfc-editor.org/info/rfc4566>.

[RFC4575] Rosenberg, J., Schulzrinne, H., and O. Levin, Ed., "A Session Initiation Protocol (SIP) Event Package for Conference State", RFC 4575, DOI 10.17487/RFC4575, August 2006, <http://www.rfc-editor.org/info/rfc4575>.

[RFC6501] Novo, O., Camarillo, G., Morgan, D., and J. Urpalainen, "Conference Information Data Model for Centralized Conferencing (XCON)", RFC 6501, DOI 10.17487/RFC6501, March 2012, <http://www.rfc-editor.org/info/rfc6501>.

[RFC6502] Camarillo, G., Srinivasan, S., Even, R., and J. Urpalainen, "Conference Event Package Data Format Extension for Centralized Conferencing (XCON)", RFC 6502, DOI 10.17487/RFC6502, March 2012, <http://www.rfc-editor.org/info/rfc6502>.

[RFC7572] Saint-Andre, P., Houri, A., and J. Hildebrand, "Interworking between the Session Initiation Protocol (SIP) and the Extensible Messaging and Presence Protocol (XMPP): Instant Messaging", RFC 7572, DOI 10.17487/RFC7572, June 2015, <http://www.rfc-editor.org/info/rfc7572>.

[RFC7614] Sparks, R., "Explicit Subscriptions for the REFER Method", RFC 7614, DOI 10.17487/RFC7614, August 2015, <http://www.rfc-editor.org/info/rfc7614>.

[RFC7647] Sparks, R. and A. Roach, "Clarifications for the Use of REFER with RFC 6665", RFC 7647, DOI 10.17487/RFC7647, September 2015, <http://www.rfc-editor.org/info/rfc7647>.

[XEP-0172] Saint-Andre, P. and V. Mercier, "User Nickname", XSF XEP 0172, March 2012, <http://xmpp.org/extensions/xep-0172.html>.

[XEP-0249] Saint-Andre, P., "Direct MUC Invitations", XSF XEP 0249, September 2011, <http://xmpp.org/extensions/xep-0249.html>.


Acknowledgements πŸ™πŸ’–

Massive thanks to Fabio Forno for coauthoring an early draft version of this document 🫢 and to Ben Campbell for his detailed and insightful reviews πŸ‘‘

Thanks also to Dave Crocker, Philipp Hancke, Olle Johansson, Paul Kyzivat, and Matt Ryan for their feedback 🌸

Leif Johansson reviewed the document on behalf of the Security Directorate πŸ”

Stephen Farrell, Barry Leiba, Pete Resnick, and Martin Stiemerling provided helpful input during IESG review πŸ¦‹

The authors gratefully acknowledge the assistance of Markus Isomaki and Yana Stamcheva as the working group Chairs 🧚 and Gonzalo Camarillo and Alissa Cooper as the sponsoring Area Directors 🌈

Peter Saint-Andre wishes to acknowledge Cisco Systems, Inc., for employing him during his work on earlier draft versions of this document πŸ’œ


Authors' Addresses πŸŽ€

Peter Saint-Andre
&yet

Email: peter@andyet.com
URI:   https://andyet.com/


Saul Ibarra Corretge
AG Projects
Dr. Leijdsstraat 92
Haarlem  2021RK
The Netherlands

Email: saul@ag-projects.com


Salvatore Loreto
Ericsson
Hirsalantie 11
Jorvas  02420
Finland

Email: Salvatore.Loreto@ericsson.com
πŸ“¦ where this page comes from