DesignXMPP presence
Version 46 (Saúl Ibarra Corretgé, 05/31/2012 05:44 pm) → Version 47/49 (Adrian Georgescu, 05/31/2012 06:48 pm)
h1. SIP-XMPP Presence
The mechanisms described here follows the currently available specifications for SIP-XMPP interoperability:
* http://xmpp.org/internet-drafts/attic/draft-saintandre-sip-xmpp-presence-02.html
h2. SIP presence
SIP protocol defines a single framework for presence ("SIMPLE":http://datatracker.ietf.org/wg/simple/charter/) and then multiple extensions have been published which extend the information that can be conveyed in the payload. Payloads supported for translation to/from XMPP:
* "RFC3863":http://tools.ietf.org/html/rfc3863 - Presence Information Data Format (PIDF)
* "RFC4479":http://tools.ietf.org/html/rfc4479 - A Data Model for Presence
* "RFC4480":http://tools.ietf.org/html/rfc4480 - RPID: Rich Presence Extensions to the Presence Information Data Format (PIDF)
The client is responsible for starting and maintaing subscriptions dialogs as described in "RFC 3265":http://tools.ietf.org/html/rfc5627 by using SUBSCRIBE method. Subscriptions are temporary, so the client needs to take care of refreshing them when they expires. As a result of a SUBSCRIBE, subsequent NOTIFY messages are received back as part of the same dialog.
h2. XMPP presence
XMPP defines two ways for exchanging presence information: simple presence and rich presence.
* Simple presence: The _presence_ stanza is used and it conveys basic information about the user's availability, such as the status, availability note and a timestamp indicating the last time it was seen.
* Rich presence: _IQ_ stanzas are used and it enhances the simple presence by adding information such as the user avatar, music the user is listening to, etc.
In XMPP protocol, the client doesn't create directly a subscription, the server does so on his behalf, by sending a presence stanza of type _probe_ to each of the contacts in his roster. Then each contact will send his presence state and the server will dispatch it back to the clients that requested it. This subscriptions last for as long as a user has a contact in his roster, they don't need to be explicitely refreshed.
XMPP servers maintain one or more TCP connections with other servers in order to exchange stanzas, and any kind of stanza is exchanged over those connections. Subscriptions are permanent (until explicitly revoked).
h2. Subscription model
SylkServer implements the concept of a 'virtual' subscription, by identifying stanzas and abstracting the model so that it matches the one in SIP. The current SylkServer implementation acts as a gateway for XMPP simple presence, support for rich presence will be added at a later stage.
h2. SIP-XMPP presence translation
When a SIP SUBSCRIBE needs to be translated to XMPP a presence stanza of type _subscribe_ will be sent. This is only necessary the first tine a user is subscribed, but this can't be known in advance. Just in case the XMPP server disregards the stanza another presence stanza is sent, this time of type _probe_ in order to instruct the remote XMPP server that it should deliver the last known presence state for the requested user.
!{ 700px, center}xmppgw_presence_s2x.png!
When a SIP SUBSCRIBE is received a 'virtual' XMPP subscription is created between the bare SIP URI and bare XMPP JID. If another SIP client (with the same SIP account) sends a SUBSCRIBE for the same user, the subscription is added to a list of SIP subscriptions for this translation path (SIP user -> XMPP user). That is, there might be multiple SIP subscriptions matching a single XMPP subscription.
When a XMPP presence stanza is received it will be converted to a SIP PIDF following the mechanism defined in the *Payload translation* section and sent as an in-dialog NOTIFY request over each of the SIP subscriptions.
h2. XMPP-SIP presence translation
As mentioned before, in XMPP a user only subscribes to another user once, after that his server will send a _probe_ stanza every time it needs to know the presence state of any contact. When either a _subscribe_ or _probe_ presence stanzas are received over XMPP, SylkServer will create a SIP subscription.
!{ 700px, center}xmppgw_presence_x2s.png!
When a _subscribe_ or _probe_ presence stanza is received a 'virtual' XMPP subscription is created and an outgoing SIP subscription is created mirroring the one received on XMPP. SylkServer was designed to work behind a SIP proxy, thus, SylkServer doesn't need to send multiple SIP SUBSCRIBE requests to get the state of the user across multiple devices, the server will aggregate that information (because SIP proxies implement a presence agent that will do it). Thus, the translation path for XMPP -> SIP maps a single 'virtual' XMPP subscription to a single SIP subscription.
h2. Payload translation
As mentioned earlier, XMPP and SIP have two completely different formats for conveying presence state. The "draft-saintandre-sip-xmpp-presence":http://xmpp.org/internet-drafts/attic/draft-saintandre-sip-xmpp-presence-02.html draft defines a set of rules for translating XMPP stanzas to valid SIP PIDFs, but unfortunately doesn't cover all cases and some adjustments had to be made while implementing the translation mechanism in SylkServer.
This section contains a detailed description of the translation process followed by SylkServer. Some extensions to the PIDF have been defined by following the XML schema extension rules, thus interoperability between SIP clients unaware of this extensions hasn't been compromised.
h4. Status
In XMPP the availability of a given device is either 'available' or 'unavailable' and the _show_ element gives some extra information about it: free for chat, do not disturb, away or extended away. There is no way to map this information to PIDF, unfortunately. PIDF defines the _person_ element and RPID extends it to add activities, but there can only be a single person element per PIDF, so it can't be used as multiple XMPP stanzas need to be aggregated in a single PIDF document.
"SIP SIMPLE Client SDK":http://sipsimpleclient.com used by SylkServer implements an extension to "PIDF":http://sipsimpleclient.com/projects/sipsimpleclient/repository/entry/sipsimple/payloads/pidf.py which adds the _extended_ child element with the following allowed values: available, offline, away, extended-away and busy. Here is an example of the status element with both _basic_ and _extended_ elements:
<pre>
<tuple id='id1234'>
<status>
<basic>open</basic>
<extended>away</extended>
</status>
</tuple>
</pre>
The new _extended_ element is used to translate the _show_ element from XMPP.
To avoid losing information a Person element is also created with the combined activities from all stanzas. Since only a single Person element makes sense in the PIDF document, the ID of the person is set to the MD5sum of the AoR (that is, user@domain) so that elements aggregating PIDF documents will find conflicting elements (ID can't be duplicated) and leave a single Person element.
h4. Resource and URI
According to the "draft":http://xmpp.org/internet-drafts/attic/draft-saintandre-sip-xmpp-presence-02.html the XMPP resource should be used as the PIDF tuple ID. Unfortunately, since the resource can contain arbitrary unicode characters it will need to be encoded. The chosen mechanism is to encode the unicode resource in UTF8 and then hex encode it. The result is prefixed with "ID-" in order to comply with the rules of the XML xs:ID element. Example translation of a resource called "my computer":
<pre>
ID-6d7920636f6d7075746572
</pre>
In a similar manner, when building the Contact element of the PIDF, the XMPP JID will be converted to a SIP URI by encoding the resource as mentioned above and using it as the GRUU. Example URI translating _saul@ag-projects.com/my computer_:
<pre>
sip:saul@ag-projects.com;gr=6d7920636f6d7075746572
</pre>
h4. Device information
PIDF defines a _device_ element which should contain information about the physical device. This information needs to be linked with the _tuple_ element of the PIDF by way of the _deviceid_ element. More than one _deviceid_ elements are allowed in a _tuple_.
In order to make it simpler to identify the device the _device-info_ extension was added to "SIP SIMPLE Client SDK":http://sipsimpleclient.com/, which can only be present once. The _device-info_ element contains the device ID (encoded resource) and a description:
<pre>
<device-info id="ID-6d61696e20636f6d7075746572" description="main computer"/>
</pre>
h4. Notes
Status notes are translated directly as the meaning maps one-to-one and added as notes in the _tuple_ element.
The mechanisms described here follows the currently available specifications for SIP-XMPP interoperability:
* http://xmpp.org/internet-drafts/attic/draft-saintandre-sip-xmpp-presence-02.html
h2. SIP presence
SIP protocol defines a single framework for presence ("SIMPLE":http://datatracker.ietf.org/wg/simple/charter/) and then multiple extensions have been published which extend the information that can be conveyed in the payload. Payloads supported for translation to/from XMPP:
* "RFC3863":http://tools.ietf.org/html/rfc3863 - Presence Information Data Format (PIDF)
* "RFC4479":http://tools.ietf.org/html/rfc4479 - A Data Model for Presence
* "RFC4480":http://tools.ietf.org/html/rfc4480 - RPID: Rich Presence Extensions to the Presence Information Data Format (PIDF)
The client is responsible for starting and maintaing subscriptions dialogs as described in "RFC 3265":http://tools.ietf.org/html/rfc5627 by using SUBSCRIBE method. Subscriptions are temporary, so the client needs to take care of refreshing them when they expires. As a result of a SUBSCRIBE, subsequent NOTIFY messages are received back as part of the same dialog.
h2. XMPP presence
XMPP defines two ways for exchanging presence information: simple presence and rich presence.
* Simple presence: The _presence_ stanza is used and it conveys basic information about the user's availability, such as the status, availability note and a timestamp indicating the last time it was seen.
* Rich presence: _IQ_ stanzas are used and it enhances the simple presence by adding information such as the user avatar, music the user is listening to, etc.
In XMPP protocol, the client doesn't create directly a subscription, the server does so on his behalf, by sending a presence stanza of type _probe_ to each of the contacts in his roster. Then each contact will send his presence state and the server will dispatch it back to the clients that requested it. This subscriptions last for as long as a user has a contact in his roster, they don't need to be explicitely refreshed.
XMPP servers maintain one or more TCP connections with other servers in order to exchange stanzas, and any kind of stanza is exchanged over those connections. Subscriptions are permanent (until explicitly revoked).
h2. Subscription model
SylkServer implements the concept of a 'virtual' subscription, by identifying stanzas and abstracting the model so that it matches the one in SIP. The current SylkServer implementation acts as a gateway for XMPP simple presence, support for rich presence will be added at a later stage.
h2. SIP-XMPP presence translation
When a SIP SUBSCRIBE needs to be translated to XMPP a presence stanza of type _subscribe_ will be sent. This is only necessary the first tine a user is subscribed, but this can't be known in advance. Just in case the XMPP server disregards the stanza another presence stanza is sent, this time of type _probe_ in order to instruct the remote XMPP server that it should deliver the last known presence state for the requested user.
!{ 700px, center}xmppgw_presence_s2x.png!
When a SIP SUBSCRIBE is received a 'virtual' XMPP subscription is created between the bare SIP URI and bare XMPP JID. If another SIP client (with the same SIP account) sends a SUBSCRIBE for the same user, the subscription is added to a list of SIP subscriptions for this translation path (SIP user -> XMPP user). That is, there might be multiple SIP subscriptions matching a single XMPP subscription.
When a XMPP presence stanza is received it will be converted to a SIP PIDF following the mechanism defined in the *Payload translation* section and sent as an in-dialog NOTIFY request over each of the SIP subscriptions.
h2. XMPP-SIP presence translation
As mentioned before, in XMPP a user only subscribes to another user once, after that his server will send a _probe_ stanza every time it needs to know the presence state of any contact. When either a _subscribe_ or _probe_ presence stanzas are received over XMPP, SylkServer will create a SIP subscription.
!{ 700px, center}xmppgw_presence_x2s.png!
When a _subscribe_ or _probe_ presence stanza is received a 'virtual' XMPP subscription is created and an outgoing SIP subscription is created mirroring the one received on XMPP. SylkServer was designed to work behind a SIP proxy, thus, SylkServer doesn't need to send multiple SIP SUBSCRIBE requests to get the state of the user across multiple devices, the server will aggregate that information (because SIP proxies implement a presence agent that will do it). Thus, the translation path for XMPP -> SIP maps a single 'virtual' XMPP subscription to a single SIP subscription.
h2. Payload translation
As mentioned earlier, XMPP and SIP have two completely different formats for conveying presence state. The "draft-saintandre-sip-xmpp-presence":http://xmpp.org/internet-drafts/attic/draft-saintandre-sip-xmpp-presence-02.html draft defines a set of rules for translating XMPP stanzas to valid SIP PIDFs, but unfortunately doesn't cover all cases and some adjustments had to be made while implementing the translation mechanism in SylkServer.
This section contains a detailed description of the translation process followed by SylkServer. Some extensions to the PIDF have been defined by following the XML schema extension rules, thus interoperability between SIP clients unaware of this extensions hasn't been compromised.
h4. Status
In XMPP the availability of a given device is either 'available' or 'unavailable' and the _show_ element gives some extra information about it: free for chat, do not disturb, away or extended away. There is no way to map this information to PIDF, unfortunately. PIDF defines the _person_ element and RPID extends it to add activities, but there can only be a single person element per PIDF, so it can't be used as multiple XMPP stanzas need to be aggregated in a single PIDF document.
"SIP SIMPLE Client SDK":http://sipsimpleclient.com used by SylkServer implements an extension to "PIDF":http://sipsimpleclient.com/projects/sipsimpleclient/repository/entry/sipsimple/payloads/pidf.py which adds the _extended_ child element with the following allowed values: available, offline, away, extended-away and busy. Here is an example of the status element with both _basic_ and _extended_ elements:
<pre>
<tuple id='id1234'>
<status>
<basic>open</basic>
<extended>away</extended>
</status>
</tuple>
</pre>
The new _extended_ element is used to translate the _show_ element from XMPP.
To avoid losing information a Person element is also created with the combined activities from all stanzas. Since only a single Person element makes sense in the PIDF document, the ID of the person is set to the MD5sum of the AoR (that is, user@domain) so that elements aggregating PIDF documents will find conflicting elements (ID can't be duplicated) and leave a single Person element.
h4. Resource and URI
According to the "draft":http://xmpp.org/internet-drafts/attic/draft-saintandre-sip-xmpp-presence-02.html the XMPP resource should be used as the PIDF tuple ID. Unfortunately, since the resource can contain arbitrary unicode characters it will need to be encoded. The chosen mechanism is to encode the unicode resource in UTF8 and then hex encode it. The result is prefixed with "ID-" in order to comply with the rules of the XML xs:ID element. Example translation of a resource called "my computer":
<pre>
ID-6d7920636f6d7075746572
</pre>
In a similar manner, when building the Contact element of the PIDF, the XMPP JID will be converted to a SIP URI by encoding the resource as mentioned above and using it as the GRUU. Example URI translating _saul@ag-projects.com/my computer_:
<pre>
sip:saul@ag-projects.com;gr=6d7920636f6d7075746572
</pre>
h4. Device information
PIDF defines a _device_ element which should contain information about the physical device. This information needs to be linked with the _tuple_ element of the PIDF by way of the _deviceid_ element. More than one _deviceid_ elements are allowed in a _tuple_.
In order to make it simpler to identify the device the _device-info_ extension was added to "SIP SIMPLE Client SDK":http://sipsimpleclient.com/, which can only be present once. The _device-info_ element contains the device ID (encoded resource) and a description:
<pre>
<device-info id="ID-6d61696e20636f6d7075746572" description="main computer"/>
</pre>
h4. Notes
Status notes are translated directly as the meaning maps one-to-one and added as notes in the _tuple_ element.