GRUU – Globally Routable User-Agent URI

GRUU is a type of SIP (Session Initiation Protocol) URI (Uniform Resource Identifier) that is used to identify and route communications sessions in a VoIP network. It enables a user to be reached at a specific device or location, even if the user has multiple devices or locations.

In traditional telephone networks, a user’s telephone number is a unique identifier that can be used to reach that user at a specific device or location. However, in a SIP network, where users can have multiple devices using a single AOR (address of record) such as alice@example.org. GRUU addresses this issue by providing a way for users to be reached at a specific device or location, even if their IP address or network location changes.

There are some cases when it is required to identify a single instance of a SIP user. Let’s suppose you are making a transfer and the user has more than one device with the same AOR, in the target it is better to use a SIP instance identifier than the IP address. IP addresses are not so NAT friendly.  Also, in the REFER rather than forking the next INVITE to all registered devices it is possible to route to an specific device specifying the temporary or permanent GRUU.

Lab – Using GRUU with OpenSIPS and Blink

The free softphone Blink (www.icanblink.com) supports GRUU.
OpenSIPS also supports GRUU.

To activate, change the module parameter.

modparam("registrar", "disable_gruu", 0)

After changing this module parameter you will see in he 200OK of the register the temporary GRUU (temp-gruu=”sip:tgruu….) and the public gruu (pub-gruu=”sip…). Now you can route by the new URIs.

2023/01/27 13:56:38.821684 192.168.15.93:5060 -> 192.168.15.31:63523
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.15.31:63523;received=192.168.15.31;rport=63523;branch=z9hG4bKPjfc5e9377637a4af7a2c0276486bf89ac
To: "Flavio Goncalves" <sip:alice@domaina.com>;tag=a067.ad68745297904767ba5e92957a0613ae
From: "Flavio Goncalves" <sip:alice@domaina.com>;tag=e1794c2b31b04c83a78a03de9e8f0878
Call-ID: f31c9b20962143399f52f20ccbeaafaf
CSeq: 2 REGISTER
Contact: <sip:alice@192.168.15.31:54043;ob>;expires=12, <sip:14297635@192.168.15.31:63523>;expires=600;pub-gruu="sip:alice@domaina.com;gr=urn:uuid:fbd61308-0
b-4f37-bc8c-0be1cd33cd8f";temp-gruu="sip:tgruu.AUYEWmsFRWQJSBMPP1gTNnAUXAMyWB4yHhNcA3NEAj0KBUYHNwsWMVRGAl1jCV1jARRRQ2dXQ2QdElBWMBxAMVVBUApgAhM3CBYTCGAAE2pSQg
ZQNBZwNDClc1BEI1AkBQDTFUETJWEVU=@192.168.15.93:5060;gr";+sip.instance="urn:uuid:fbd61308-01db-4f37-bc8c-0be1cd33cd8f"
Server: OpenSIPS (3.2.10 (x86_64/linux))
Content-Length: 0

For sequential requests it is important now that you can route properly. Looking at the ACK below you will notice that the address in the RURI is not the final address, but the GRUU.

2023/01/27 14:15:47.520837 192.168.15.31:5080 -> 192.168.15.93:5060
ACK sip:alice@domaina.com;gr=urn:uuid:fbd61308-01db-4f37-bc8c-0be1cd33cd8f SIP/2.0
Via: SIP/2.0/UDP 192.168.15.31:5080;rport;branch=z9hG4bKPj762eec6221574c13a201e4b55717e1b8
Max-Forwards: 70
From: "bob" <sip:bob@domaina.com>;tag=c72cfe7516434b8d864918366a4bdc69
To: <sip:alice@domaina.com>;tag=2b45621a6a35482e97a16046c2e0ef74
Call-ID: 7457248f27d4475fbf5d062106e4af1d
CSeq: 24702 ACK
Route: <sip:192.168.15.93;lr;did=7ca.7d91344>
Content-Length: 0

So, for sequential requests with GRUU support, you need to do a lookup before sending.

if (has_totag()) {
  if($(ru{uri.param,gr})!=null) {
    lookup("location");
  }
  ...

In the snippet above, we are checking for the presence of the parameter gr in the request URI. If gr is present we do a lookup to find the IP address of the specific instance.

In conclusion, GRUU is a powerful solution for maintaining reliable and consistent communication in a VoIP network. It allows users to be reached at a specific device or location, regardless of their IP address or network location. It is essential in some advanced scenarios such as transfers. Implementing GRUU in a VoIP network can be easily done using open-source SIP servers, and is an excellent choice for businesses and individuals looking for a cost-effective and flexible communication solution.

Paging and Intercom

Paging was immortalized in the “Charlie’s Angel television series. It is not difficult to do it in your own IP phone.  This is useful when you want to make a call directly to the speaker of the callee on the other phone. The destination phone auto-answers the call and enable the speaker. 

The experiments show that these features are highly dependent on the phone and they are implemented in slightly different ways depending on the device’s vendor. Many phones simply don’t support them or have to be configured. Zoiper Free is an example of phone not supporting the Call-info header, but the setting to support is available in the paid version. Microsip supports it and most good phones supports, but have to be configured. 

Most implementations use the Call-Info header. Below is a quick table for the most popular phones.

Vendor Implementation
Grandstream Call-info: answer-after=0
Yealink Call-info: answer-after=0
Alert-info: alert-autoanswer
Alert-info: answer-after=0
Polycom Alert-info:  Ring-Answer

Please, check the documentation of your device to  verify which header it supports. Some phones also support Intercom using a request uri parameter called intercom=true.

Example:

INVITE sip:alice@domain.com;intercom=true SIP/2.0

Most phones will require a previous configuration authorizing the auto-answer. Enabling intercom on your phones pose a security risk because many people will not be aware  of the Intercom feature and may leave the phone open. This allows an attacker to eavesdrop the sound of the destination room.  

To implement is very simple, create a feature code. As an example *6. After typing *6 + the number, strip the prefix and add the header.

Example for OpenSIPS:

if($rU=~"^*6"") {
    strip(2);
    append_hf("Call-info: ;answer-after=0\r\n") ;
}

Example for FreeSwitch. With the variable sip_auto_answer, FS inserts the appropriate headers. You could also add a header using:

<extension name="intercom">
  <condition field="destination_number" expression="^\*6(.*)$">
    <action application="set" data="dialed_extension=$1"/>
    <action application="export" data="sip_auto_answer=true"/>
    <action application="bridge" data="user/${dialed_extension}@${domain_name}"/>
  </condition>
</extension>

For Asterisk:

[intercom]
exten=> _*6.,1,Set(PJSIP_HEADER(add,Call-Info)=;answer-after=0)
same => Dial(PJSIP/{EXTEN:2})

I have tested the first example and worked quite well.

This article generated a new chapter on the training “SIP Training for Professionals” and a new feature in the WeHostVoIP Cloud PBX.

I hope you enjoy!