Cross-dialog data accessing

There are several calling scenarios – typical Class V – where multiple SIP dialogs may be involved. And to make it work, you need, from one dialog, to access the data that belongs to another dialog. By data we mean here dialog specific data, like dialog variables, profiles or flags, and, even more, accounting data (yes, the accounting engine is so powerful that it ended be used for storing a lot of information during the calls).

Let’s take a quick look at a couple of such scenarios:

  • attended call transfer – the new call may need to import data (about the involved parties) from the old dialog;
  • call parking – the retrieving call will need to import a lot of data (again, about the parties involved and the nature of the call) from the parked call
  • call pickup – the picking up call will also have to access data from the ringing calls in order to find them, check permissions and grab one call.

Scratching the surface, before OpenSIPS 3.1

The pre 3.1 OpenSIPS versions had some limited possibilities when comes to accessing the data from other dialogs.

Historically speaking, the first attempt was the get_dialog_info() function, a quite primitive approach that allows you, using the dialog variables, to find a dialog and to retrieve from it only one dialog variable. Even so, this function served the purpose of addressing scenarios where you wanted to group dialogs around custom values – this solved the problem of a front-end OpenSIPS balancer trying to group all calls of a conf room on the same conf server, or trying to group the calls of a user on the same PBX (so call transfer will work).

But there were some limitations in terms of scalability (only one value was retrieved) and usage, on how the dialogs were referred (by dlg variables, not by the more natural call-id).

So we had the next wave of functions that addressed that issues : the get_dialog_vals(), get_dialogs_by_val() or get_dialogs_by_profile() functions. They solved somehow the problem allowing a more versatile way of referring/identifying the dialogs and allowing a bulk access to the dialog data, but still, not all dialog data was accessible and the the way the data was returned (it complex arrays or json strings) makes them difficult to use.

The true solution, with OpenSPIS 3.1

So back to the drawing board. And the correct solution to the problem (of inter dialog data accessing) come from a totally different, much simpler approach – give direct access to the dialog context, so every piece of dialog data will be accessible via the regular dialog functions/variables/profiles/flags/etc/.

So, OpenSIPS 3.1 gives you the possibility to load the context of a different dialog, so you can retrieve whatever data without the need of additional functions or special data packing or re-formatting.

Two simple functions were added, the load_dialog_ctx() and unload_dialog_ctx(). These two functions may be used to define a region in your script where “you see” a different dialog than the current one (dictated by the SIP traffic). Inside that region, all the dialog functions and variables will operate on the other dialog. Simple and very handy, right ?

To make it even better, the OpenSIPS 3.1 gives you more than only the access to another dialog context – it gives you the possibility to access the accounting context of another call. Shortly, you can access the accounting variables (extra data or per-leg data) of a different call – isn’t that cool ?

This can be done via the acc_load_ctx_from_dlg() and acc_unload_ctx_from_dlg() functions, in the similar way to the loading/unloading the dialog context. Inside the region defined by these new accounting function, you will “see” the accounting data of another call.

Example

Let’s take the example of an attended transfer, when handling the transferring call. This snippet will show we can get access to various dialog and accounting data from the transferred dialog , while handling the transferring dialog.

# is it an INVITE carrying a Refer-To with Replaces ? 
if ($rm=="INVITE" && $hdr(Refer-To) != NULL && $hdr(Refer-To) =~ "Replaces=") {

   # extract the dialog coordinates from "Replaces" parameter
   $var(params_offset) = $(var(refer_uri){s.index,?Replaces=});
   $var(params) = $(var(refer_uri){s.substr,$var(params_offset),0});
   # skip '?Replaces='
   $var(dialog_data) = $(var(params){s.substr,10,0}{s.unescape.param});
   $var(callid) = $(var(dialog_data){s.select,0,;});

   # load the context of the transferred dialog by its SIP Call-ID
   if (load_dialog_ctx("$var(callid)")) {
     # we are in the context of the transferred dialog
     xlog("The dialog $var(callid) is ongoing for $DLG_lifetime seconds \n);

     # we can check the profiles of the loaded dialog
     if (is_in_profile("pstn")) {
       xlog("This is a from PSTN side\n");
       # fetch the GW ID for later usage
       $var(gw_id) = $dlg_val(gw_id);
     }
     # also we can read/write the dlg vals of the loaded dialog
     $dlg_val(is_transferred) = "yes";

     acc_load_ctx_from_dlg();
     # we got access the the accounting of the transferred dialog

     $var(caller) = $acc_extra(caller);
     $var(callee) = $acc_extra(callee);

     acc_unload_ctx_from_dlg();
     unload_dialog_ctx();
     # we are back in the context of the transferring dialog

     xlog("we are about to transfer call $var(callid) between $var(caller) and $var(callee) \n");
   }
 }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

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

Google photo

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

Twitter picture

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

Facebook photo

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

Connecting to %s