Content

Page tree

The Cisco phones offer a special Call Parking implementation that includes the option to dynamically select a parking orbit. In this scenario:

  1. the user answers the call
  2. the user presses Call Park
  3. the phone displays a question, to which Parking Orbit (or to which extension) the call needs to be parked (practically where to send the REFER)
  4. the phone initiates call hold
  5. the phone initiates call transfer to the parking orbit

Also important for this scenario is RFC8217: the orbit parameter must be added as an URI Parameter and not as a Header Parameter, which also implies that the Brackets < > must enclose also the parameter, since for such switch the orbit parameter is a URI parameter.

It is possible to implement this feature on Snom phones by using XML Definition and XML Minibrowser.


The configuration consists of two parts.



Part 1: The XML Definition

In this part we will configure a function key with an XML Definition. This XML Definition processes the incoming NOTIFY messages to make the led blink. This is basically the normal BLF function, but in addition the same button needs to initiate the call transfer, or the call pickup as well.

Below is an example XML definition. The value "odef" contains the parking orbit, which is provided to the SIP URL and this is where the user can put the call.

XML Definition
   <general type="CallPark" />
        <initialization>
            <state value="off"/>
            <variable name='park' value='USERPARK'/>
            <variable name='user_proxy' value='HOSTPART'/>
            <variable name='label' value='Call Park'/>
            <variable name='odef' value='ORBIT'/>
        </initialization>
 
    <!-- State of parking orbit -->

    <subscription type="dialog" for="<sip:$(park)@$(user_proxy);orbit=$(odef)>" to="<$(park)@$(user_proxy);orbit=$(odef)>"/>
 
        <NotifyParsingRules type="applies">
            <level1 translates_to='OK'>/dialog-info[@entity="sip:$(park)@$(user_proxy);orbit=$(orbit)"]</level1>
            <level1-1 translates_to='OK'>dialog-info/dialog/direction[.="recipient"]</level1-1>
            <level2 translates_to='OK'>/dialog-info[@entity="sip:$(park)@$(user_proxy);orbit=$(odef)"]</level2>
        </NotifyParsingRules>
        
        <NotifyParsingRules type="state">
            <level1 translates_to="ringing">/dialog-info/dialog/state[.="full"]</level1>
            <level1 translates_to="ringing">/dialog-info/dialog/state[.="early"]</level1>
            <level1-1 translates_to="calling">/dialog-info/dialog[@direction="initiator"]</level1-1>
            <level2 translates_to="ringing">/dialog-info/dialog/state[.="proceeding"]</level2>
            <level2-1 translates_to="calling">/dialog-info/dialog[@direction="initiator"]</level2-1>
            <level3 translates_to="offhook">/dialog-info/dialog/state[.="trying"]</level3>
            <level4 translates_to="in_a_call">/dialog-info/dialog/state[.="confirmed"]</level4>
            <level5 translates_to="free"/>
        </NotifyParsingRules>
        <NotifyParsingRules type="variable" id="call_id" state="ringing">
            <level1 fetch_attribute="call-id">/dialog-info/dialog[@call-id]</level1>
        </NotifyParsingRules>
        <NotifyParsingRules type="variable" id="remote_tag" state="ringing">
            <level1 fetch_attribute="remote-tag">/dialog-info/dialog[@remote-tag]</level1>
        </NotifyParsingRules>
        <NotifyParsingRules type="variable" id="local_tag" state="ringing">
            <level1 fetch_attribute="local-tag">/dialog-info/dialog[@local-tag]</level1>
        </NotifyParsingRules>
        <NotifyParsingRules type="variable" id="remote_uri" state="ringing">
            <level1 fetch_attribute="uri">/dialog-info/dialog/remote/target[@uri]</level1>
        </NotifyParsingRules>

    <action>
    
        <!-- State of own extension -->
        
        <!-- here save the BLF state because we need to overwrite it with own state -->
        <assign when="on press">  
            <source context="this entity" id="state"/>
            <destination context="this entity" id="state_save"/>  
        </assign>

        <assign when="on press">
            <source context="this entity" value=""/>
           <destination context="this entity" id="transfer_id"/>
        </assign>
        <assign when="on press">
            <source context="call" id="id" require1="${state}==connected"/>
            <destination context="this entity" id="transfer_id"/>
        </assign>

        <assign when="on press">
           <source context="this entity" value="me_in_a_call"/>
           <destination context="this entity" id="state" require="$(transfer_id)!= "/>
        </assign>

        <url target="http://server/external/script.xml#var:state=$(state)" when="on release"/>

        <!-- Revert the BLF state back -->
        <assign when="on release">
              <source context="this entity" id="state_save"/>
              <destination context="this entity" id="state"/>
        </assign>
    </action>



Part 2: The XML Minibrowser

This XML Definition above will take care of the led and evaluate the actual status of the call. This (state) will be provided to an XML Minibrowser script (see above: <url target="http://server/external/script.xml#var:state=$(state)" when="on release"/>), which will do the actual transfer. This Minibrowser XML is needed in order to display a question to the user via SnomIPPhoneInput.

XML Minibrowser
<?xml version="1.0" encoding="utf-8"?>
<IPPhoneInput state="relevant" id="parking">
    <If condition="$(var:state)=me_in_a_call">
        <Url>phone://mb_nop#key=TRANSFER&amp;contact_transfer_or_dial=-1%3B"&lt;USERPART@USERPART;orbit=__X__&gt;"%3BENTER</Url>
    </If>
    <Else>
        <Url>phone://mb_nop#action_ifc:CallInterface=make_call,remote=&lt;USERPART@USERPART;orbit=__X__&gt;</Url>
    </Else>
    <InputItem>
    <DisplayName>Parking orbit</DisplayName>
    <InputToken>__X__</InputToken>
    <DefaultValue>$(var_ifc:XmlEntity.LineKey.003::odef)</DefaultValue>
    <InputFlags>n</InputFlags>
    </InputItem>
</IPPhoneInput>



Using the configuration

Here is a summary of using the two parts described above:

  • When the call is in state connected and the function key containing the XML Definition is pressed, the state value will be temporarily set to "me_in_a_call" . Using the url XML Tag, the Minibrowser script will be called

  • The Minibrowser script checks the value of the provided state (IMPORTANT: the var:state is me_in_a_call, while the var_ifc:XmlEntity.LineKey.003::state is free. This is due to the fact that we set the original state back at the end) and according to the state will keep the proper URL Tag:

    <Url>phone://mb_nop#key=TRANSFER&contact_transfer_or_dial=-1%3B"&lt;USERPART@USERPART;orbit=__X__&gt;"%3BENTER</Url>

    This URL will initiate first the TRANSFER ( as you would press it on the phone ) and then initiate the REFER to the provided address. At the end pressing the ENTER will start the action.


  • This URL simply starts a call (send a regular INVITE) to the remote address to pick up the call:

    <Url>phone://mb_nop#action_ifc:CallInterface=make_call,remote=&lt;USERPART@USERPART;orbit=__X__&gt;</Url>