Content

Page tree

This article describes the way how to enable and alter the device presence feature based on the RFCs 3265 – 3865 -3863 -4480. The feature leverages the built-in XML definitions capability of our D-series phones.

The only prerequisite is that the phone has firmware version 10.1.90.0 or higher.

Presence works on two fronts, like a normal BLF. The first one is the phone which has to send a SIP message indicating its status to the PBX. The second one is the monitoring phone which receives a SIP message from the PBX containing the status of the monitored phone. The difference is that the messages will not be of type DIALOG, but PRESENCE.

Part 1: Send the PUBLISH message

We use the setting: general_purpose_xml_descriptions to store the XML definition code without tying them to a specific key.

The following code works exclusively for Identity 1 (change the value of <identity value="1"/> to change the identity number). For more informations about XML definitions please check these pages: XML Definitions, XML Definitions Tutorial, XML Definitions Syntax


<general type="phone_status_xml"/>
<initialization>
  <state value='off'/>
  <identity value="1"/>
  <variable name='presence_state' value='inital'/>
  <variable name='basic_state' value='closed'/>
  <variable name='person_id' value='intial'/>
  <variable name='activity' value="&lt;rpid:unknown/&gt;"/>
  <variable name="da" value="initial"/>
  <reference name='account' module='setting' id='user_name[$(identity)]'/>
  <reference name='domain' module='setting' id='user_host[$(identity)]'/>
  <reference name='uuid' module='setting' id='user_uid[$(identity)]'/>
  <reference name='ringnum' module='identity.$(identity)' id='ringing_number'/>
  <reference name='phonestat' module='identity.$(identity)' id='phone_status'/>
</initialization>
<action>
  <assign when="after initialization">
    <source value="sip:$(account)@$(domain)"/>
    <destination context="this entity" id="da"/>
  </assign>
  <assign when="on change" reference="phonestat" value_not_in="Alerting,Forwarded">
    <source value="$(uuid)-$(identity)"/>
    <destination context="this entity" id="person_id"/>
  </assign>
  <assign when="on change" reference="phonestat" value_in="Alerting">
    <source value="Ring-$(ringnum)"/>
    <destination context="this entity" id="person_id"/>
  </assign>
  <assign when="on change" reference="phonestat" value_in="Forwarded">
    <source value="Forwarded"/>
    <destination context="this entity" id="person_id"/>
  </assign>
  <assign when="on change" reference="phonestat" value_in="In_A_Call">
    <source value="&lt;rpid:on-the-phone/&gt;"/>
    <destination context="this entity" id="activity"/>
  </assign>
  <assign when="on change" reference="phonestat" value_not_in="In_A_Call">
    <source value="&lt;rpid:unknown/&gt;"/>
    <destination context="this entity" id="activity"/>
  </assign>
    <assign when="on change" reference="phonestat" value_in="Dnd_All">
    <source value="&lt;rpid:busy/&gt;"/>
    <destination context="this entity" id="activity"/>
  </assign>
  <assign when="on change" reference="phonestat" value_in="Offline">
    <source value="closed"/>
    <destination context="this entity" id="basic_state"/>
  </assign>
  <assign when="on change" reference="phonestat" value_not_in="Offline">
    <source value="open"/>
    <destination context="this entity" id="basic_state"/>
  </assign>
  <assign when="on change" reference="phonestat" value_in="Offline">
    <source value=''/>
    <destination context="this entity" id="presence_state"/>
  </assign>
  <assign when="on change" reference="phonestat" value_in="Dnd_All">
    <source value="Do not disturb"/>
  <destination context="this entity" id="presence_state"/>
  </assign>
  <assign when="on change" reference="phonestat" value_in="Available,Forwarded">
    <source value="Idle"/>
    <destination context="this entity" id="presence_state"/>
  </assign>
  <assign when="on change" reference="phonestat" value_in="Alerting">
    <source value="Ring"/>
    <destination context="this entity" id="presence_state"/>
  </assign>
  <assign when="on change" reference="phonestat" value_in="In_A_Call">
    <source value="On the phone"/>
    <destination context="this entity" id="presence_state"/>
  </assign>
  <publish when="on change" reference="phonestat" expires="300" target="$(da)" from="$(da)">
    <body content_type="application/pidf+xml" event="presence">
      <presence xmlns="urn:ietf:params:xml:ns:pidf" xmlns:dm="urn:ietf:params:xml:ns:pidf:data-model" xmlns:rpid="urn:ietf:params:xml:ns:pidf:rpid" entity="$(da)">
        <tuple xmlns="urn:ietf:params:xml:ns:pidf" id="$(uuid)-$(identity)">
          <status xmlns="urn:ietf:params:xml:ns:pidf">
            <basic>$(basic_state)</basic>
          </status>
          <note>$(presence_state)</note>
        </tuple>
        <dm:person id="$(person_id)">
          <rpid:activities>$(activity)</rpid:activities>
          <dm:note>$(presence_state)</dm:note>
        </dm:person>
      </presence>
    </body>
  </publish>
  <publish when="on change" reference="phonestat" value_in="Offline" expires="0" target="$(da)"/>
</action>


With this code the phone automatically check its own status and, when the status change (when="on change"), sends a PUBLISH type SIP message including the information in the message body XML code.
The possible statuses are:

  • Offline
  • Available
  • In_A_Call
  • Forwarded
  • Dnd_All


This is an example of a PUBLISH message sent when the phone change from Available to In_A_Call. As you can see in the body, the phone built the XML code to inser <note>On the phone</note>. This information will be read from the PBX and translated into a NOTIFY message for the monitoring phones.


Sent to Udp:xxx from Udp:192.168.1.85:5060 at Jun 15 11:09:39.163 (1224 bytes):

PUBLISH sip:xxx SIP/2.0
Via: SIP/2.0/UDP 192.168.1.85:5060;branch=z9hG4bK-pebykx4s7s7u;rport
From: <sip:xxx>;tag=kja9amhabe
To: <sip:xxx>
Call-ID: d3a1a9624e27-7obccpq5b0zk
CSeq: 1 PUBLISH
Max-Forwards: 70
User-Agent: snomD785/10.1.101.11
Event: presence
Proxy-Authorization: Digest username="xxx",realm="xxx",nonce="414d535962a9a20a67:55e9afe4485dbc0f71f5b02f720d4376",uri="sip:xxx",response="dfca4547a8f49694ae3104a3efc860a2",algorithm=MD5
Expires: 300
Content-Type: application/pidf+xml
Content-Length: 598

<presence xmlns="urn:ietf:params:xml:ns:pidf" xmlns:dm="urn:ietf:params:xml:ns:pidf:data-model" xmlns:rpid="urn:ietf:params:xml:ns:pidf:rpid" entity="sip:xxx">
<tuple xmlns="urn:ietf:params:xml:ns:pidf" id="5227a428-5444-4071-8c3d-0004139AC933-1">
<status xmlns="urn:ietf:params:xml:ns:pidf">
<basic>open</basic>
</status>
<note>On the phone</note>
</tuple>
<dm:person id="5227a428-5444-4071-8c3d-0004139AC933-1">
<rpid:activities><rpid:on-the-phone/></rpid:activities>
<dm:note>On the phone</dm:note>
</dm:person>
</presence>


Part 2: Receive and manage NOTIFY messages

On the monitoring phone we need a new type of key, able to process the incoming presence NOTIFY and to reach this result we will use the ReplacementPlan tag and specifically the <key> tag that defines a key-type that will get listed in fkey-WUI-page as type for a line-key
https://docs.snom.com/display/wiki/%3CReplacementPlan%3E+tag

After provisioning the Snom phone with the following code, we will see a new type of key in the fkey drop-down menu, called PresenceBLF. In the Number field we will inser the monitored extension and the phone will send a Presence type SUBSCRIBE for that extension.

Press the key to call the extension and call pickup are also possible.

Note: the pickup code is hard coded into the XML, you can change the code here:
<variable name="pickup_code" value="*8"/>


<?xml version="1.0" encoding="UTF-8"?>
<ReplacementPlan>
    <key id="PresenceBLF">
        <general type="PresenceBLF">
            <default_state name="Closed"/>
        </general>
        <initialization>
            <!-- set pickup code prefix -->
            <variable name="pickup_code" value="*8"/>
        </initialization>
        <subscription type="presence" to="&lt;sip:$(ui_argument)@&gt;" for="$(ui_argument)@"/>
        <NotifyParsingRules type="applies">
            <level1 translates_to="OK">/presence[@entity="sip:$(ui_argument)@$(registrar)"]</level1>
        </NotifyParsingRules>
        <NotifyParsingRules type="state">
            <level1 translates_to="Closed">/presence/tuple/status/basic[.="closed"]</level1>
            <level2 translates_to="Forwarded">/presence/dm:person[@id="Forwarded"]</level2>
            <level3 translates_to="Idle">/presence/dm:person/dm:note[.="Idle"]</level3>
            <level4 translates_to="On_the_phone">/presence/dm:person/dm:note[.="On the phone"]</level4>
            <level5 translates_to="Ring">/presence/dm:person/dm:note[.="Ring-"]</level5>
            <level6 translates_to="Ring">/presence/dm:person/dm:note[.="Ring"]</level6>
            <level7 translates_to="Do_not_disturb">/presence/dm:person/dm:note[.="Do not disturb"]</level7>
        </NotifyParsingRules>
        <action>
            <assign type="update on change" when="after initialization">
                  <source context="setting" id="user_host[$(identity)]"/>
                  <destination context="this entity" id="registrar"/>
            </assign>
            <invite when="on press" states="Ring" target="$(pickup_code)$(ui_argument)"/>
            <invite when="on press" states="Idle" target="$(ui_argument)"/>
            <invite when="on press" states="Forwarded" target="$(ui_argument)"/>
            <invite when="on press" states="Closed" target="$(ui_argument)"/>
        </action>
    </key>
</ReplacementPlan>


Thanks to the <NotifyParsingRules type="state"> section, the phone fetch the incoming NOTIFY message looking for a state at a predetermined point in the body of the message. The search is systematic from the first level to the last and when a rule is matched, the following ones are not considered.

The following is a NOFITY body example that match the level4 rule:

<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf" xmlns:dm="urn:ietf:params:xml:ns:pidf:data-model" xmlns:rpid="urn:ietf:params:xml:ns:pidf:rpid" entity="sip:104@registrar">
    <tuple id="79uvNJuBMsWLcEa55Wdz44Ae0fepp5A5">
        <status>
            <basic>open</basic>
        </status>
        <note>On the phone</note>
    </tuple>
<dm:person id="yTU74o-mb.pIeO.sBcrklfW7RovU5YvS">
    <rpid:activities>
        <rpid:on-the-phone/>
    </rpid:activities>
    <dm:note>On the phone</dm:note>
</dm:person>
</presence>




  • No labels