DFKS or the “Key to Synchronization”

In advanced Class 5 SIP systems, the “intelligence” is not a characteristic reserved 100% only to the SIP Server (or Application Server component). In such system, the “intelligence” – meaning the ability to control and operate the Class 5 specific features – is actually shared between all the SIP phones and the SIP Server. This means that features like Do-Not-Disturb or Call-Forwarding can be controlled (provisioned) not only from the SIP Server, but from the SIP phone as well.

This ability to control features from multiple places raises the problem of synchronizing the features’ status, as at the end of the day we want to experience an unified behavior of the feature. For example, if the SIP hardphone gives me the option to active the DND status, I want to see this status in the Application Servers (SIP Server) and vice-versa – if I enable DND from the WEB portal (of the Application Server), I want to see the DND button blinking on my SIP hardphone too. Basically, I want my SIP Server and SIP phone (or SIP phones) to share the same single DND status, regardless where I change the status from.

DFKS – the solution

Even if it is not an IETF standard, an answer to this issue is provided by the Broadsoft’s Device Feature Key Synchronization protocol (or shortly, DFKS).

DFKS is a SIP presence based protocol that allows SIP phones/end-points to fetch and set the status of same features from/to the Application Server.

As getting more Class 5 flavored, the upcoming OpenSIPS 3.1 provides support (server side) for the DFKS protocol, via the presence_dfks module. The module supports synchronization for the following features:

  • Do Not Disturb
  • Call Forwarding Always
  • Call Forwarding Busy
  • Call Forwarding No Answer

The feature’s status can be changed either from the SIP phone, as well as from the OpenSIPS Server (by running an MI command).

The module provides an interesting combination of loose versus strict approaches. On one side it is very strict and encapsulated when comes to the SIP side (handling the presence specific SIP traffic and DFKS specific XML encapsulation), making it trivial to use from the OpenSIPS script.

On the other side it is very loose and flexible when comes to how the features are provisioned on the SIP Server side – there are no two solutions alike when comes to storing and provisioning the SIP users’ profiles, so the module must provide the maximum of flexibility here. For this reason, the DFKS module, instead of encapsulating some rigid logic for provisioning the features, it uses the power of the scripting language for this purpose – shortly said, the module uses scripting routes in order to “implement” the set and get operations over the features. In this routes, you can do any necessary DB operations, SQL or NoSQL, any exec or HTTP external triggering – whatever is needed to set or get the value of the features. The linking between the data from the XML payload from the SIP side and the OpenSIPS script is done via the $dfks(field) scripting variables.

So, at the end of the day, to implement the DFKS support with OpenSIPS reduces to the single task of writing some script routes to set and get the values of the features, according to your provisioning specifics.

DFKS – OpenSIPS examples

Here is a simple example, considering that you already have the generic presence server support configured in your OpenSIPS (the “presence” modules):

loadmodule "presence_dfks.so"
modparam("presence_dfks", "get_route", "dfks_get")
modparam("presence_dfks", "set_route", "dfks_set")

Nothing more to do on the SIP side. And to SET and GET the feature’s values via scripting, here is a simple example.

route[dfks_get]
{
   xlog("DFKS: get feature <$dfks(feature)> for $dfks(presentity)\n");

   ....
   if ($dfks(feature)=="CallForwardingAlways") {
      $avp(cf_dst) := NULL;
      if (avp_db_query("select cfaw_uri from subscriber where username='$(dfks(presentity){uri.user})' and domain='$(dfks(presentity){uri.host})","$avp(cf_dst)") &&  $avp(cf_dst)!=NULL) {
         # return the value of the feature
         $dfks(value/forwardTo) = $avp(cf_dst);
         # report that the feature is set/activated
         $dfks(status) = 1;
      } else
         # the feature is not set at all
         $dfks(status) = 0;
      }
   ....
}

or for setting the feature’s value:

route[dfks_set]
{
   xlog("DFKS: set feature <$dfks(feature)> for $dfks(presentity)\n");

   ....
   if ($dfks(feature)=="CallForwardingAlways") {
      if ($dfks(status) == 1) {
         # set the value of the Call FWD
         avp_db_query("update subscriber set cfaw_uri='$dfks(value/forwardTo)' where username='$(dfks(presentity){uri.user})' and domain='$(dfks(presentity){uri.host})");
      } else {
         # reset the value of the Call FWD
         avp_db_query("update subscriber set cfaw_uri=NULL where username='$(dfks(presentity){uri.user})' and domain='$(dfks(presentity){uri.host})");
      }
   }
   .....
}

The beauty of the implementation is that the same SET and GET routes is used when DFKS traffic is received from SIP end-points, but also when the dfks_set_feature MI command is triggered from outside – yes, the module also considers the scenario when the there are also some external non-SIP entities (like Web portals or APIs) that needs to trigger the setting of a features.

Conclusions

With this DFKS approach in OpenSIPS we have not only a single unified value for the feature, but also a single piece of code that is setting the feature, even if the setting may be trigger from the SIP phone, from APIs or other components of the platform.

One thought on “DFKS or the “Key to Synchronization”

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s