Version

Back-to-Back User Agent (B2BUA)

The Back-to-Back User Agent (B2BUA) is a critical SIP element that acts as an intermediary between two or more SIP dialogs, functioning as an endpoint for each dialog and forwarding requests and responses between them. This unique capability makes B2BUAs one of the most frequently used application types in SIP-based communication services.

Despite their versatility, B2BUAs can sometimes be viewed as problematic due to their potential to disrupt end-to-end services. By mediating signaling between endpoints, a B2BUA may unintentionally interfere with services it is not explicitly designed to support. However, when properly implemented, B2BUAs offer a powerful toolset for developers to enable advanced SIP application functionality.

The SIP Servlet API fully supports the B2BUA pattern, providing new helper classes and methods that simplify its implementation. B2BUAs play a key role in advanced use cases such as call recording, bridging multiple call legs, and exerting fine-grained control over SIP sessions.

The B2buaHelper interface provides utility methods to support B2BUA applications in SIP servlet environments. A B2BUA is an intermediary in SIP communication that maintains complete control over both sides of the session, creating two independent SIP dialogs and bridging them.

An instance of this interface can be retrieved by calling the getB2buaHelper() method on a SipServletRequest. This helper class simplifies the management of SIP dialogs, requests, and responses in B2BUA applications, allowing you to focus on application-specific logic while abstracting much of the underlying complexity.
The B2buaHelper is important for applications that need to manipulate or control SIP dialogs on both sides of the B2BUA, such as call bridging, protocol translation, or advanced routing.

Methods:

createRequest

SipServletRequest createRequest(SipServletRequest origRequest,
                                boolean linked,
                                java.util.Map<java.lang.String,java.util.List<java.lang.String>> headerMap)
                                throws java.lang.IllegalArgumentException,
                                       TooManyHopsException

The method creates a new request object belonging to a new SipSession. The method allows for constructing a new request based on the provided origRequest, with most header fields copied to the new request. Additionally, the headerMap can override specific headers in the new request, including From, To, Contact, and Route. The new SipSession shares the same SipApplicationSession as the original request. Generates a new From header with a tag chosen by the container. Tags specified in the headerMap are ignored. The To header in the new request will not include a tag. Excludes Record-Route and Via headers from copying; the container adds its own Via header during transmission. For non-REGISTER requests, the Contact header is populated by the container unless specified in the headerMap.

This method is designed for initial requests in B2BUA applications, providing flexibility to override headers. Subsequent requests in a dialog should use SipSession.createRequest(String) or this method's overload variant.
If the Max-Forwards header in the original request is 0, a TooManyHopsException is thrown, and a 483 (Too many hops) response is sent. Otherwise, the Max-Forwards value in the new request is decremented by 1.

Parameters:

origRequest: The request to be copied.

linked: Boolean indicating whether the new session should be linked to the original session.

headerMap: A map of header names and their values to override in the new request. Multi-valued headers can use a java.util.List to specify multiple values.

Returns:

A new SipServletRequest object based on the original request with modifications as specified.

Throws:

IllegalArgumentException: If the headerMap includes unsupported system headers, irrelevant headers for the context, or if the original request/session is improperly linked and linked is true, or if origRequest is not an initial request.
NullPointerException: If the origRequest is null.

TooManyHopsException: If the Max-Forwards header in the original request is 0.

 

createRequest

SipServletRequest createRequest(SipServletRequest origRequest)

The method creates a new SipServletRequest object belonging to a new SipSession. The new request is modeled after the specified origRequest, with the method and most header fields copied to the new request. The SipSession associated with the new request shares the same SipApplicationSession as the original request. This method provides a way to construct a new "leg" of a B2BUA application for initial requests. Subsequent requests in a dialog must be created using either SipSession.createRequest(String) or the overloaded variants of createRequest.

Rules the Method Must Satisfy:

  • From Header: The From header in the new request is assigned a new tag, determined by the container.
  • To Header: The To header in the new request does not include a tag.
  • Call-ID: The new request and its corresponding SipSession are assigned a new Call-ID.
  • Excluded Headers: Record-Route and Via headers are not copied. The container automatically adds its own Via header when the request is sent outside the application server.
  • Contact Header: For non-REGISTER requests, the Contact header is not copied but is populated by the container.

Parameters:

origRequest: The original request to be copied.

Returns:

A new SipServletRequest object based on the original request.

 

createRequest

SipServletRequest createRequest(SipSession session,
                                SipServletRequest origRequest,
                                java.util.Map<java.lang.String,java.util.List<java.lang.String>> headerMap)
                                throws java.lang.IllegalArgumentException

This method creates a new subsequent request based on the provided original request, while linking the specified SipSession and SipServletRequest. It is designed for subsequent requests in scenarios where a (B2BUA) application requires them.

Unlike factory methods used for initial requests, this method focuses on creating requests that:

  • Copy non-system headers from the original request.
  • Generate system headers based on the provided session.
  • Set the route headers according to the session route set.

If the headerMap includes Contact, From, or To headers, their respective parts are used in compliance with sections 4.1.2 and 4.1.3 of the SIP Servlet specification.

Notes:

Linking: The method ensures that the new request and session are automatically linked to the original ones, if not already linked.

Header Handling: Non-system headers are copied from origRequest, while system headers (Contact, From, To) follow the specifications for their respective parameters.

Parameters:

session: The SipSession on which the new request is created.

origRequest: The original request to base the new request on.

headerMap: A map containing header names and their values to override or replace in the new request. It can include Contact, From, and To headers with specific constraints.

Returns:

A SipServletRequest object representing the new subsequent request.

Throws:

java.lang.IllegalArgumentException:

  • If the headerMap contains invalid system headers (other than Contact, From, or To), or headers irrelevant in the context.
  • If the session does not belong to the same SipApplicationSession as origRequest.
  • If the origRequest or session is already linked to another request or session.
  • If the origRequest is not an initial request.

java.lang.NullPointerException:

  • If the origRequest or session is null.

 

createCancel

SipServletRequest createCancel(SipSession session) 

Creates a new CANCEL request intended to cancel the initial request sent on the other leg of a B2BUA operation. The container generates the CANCEL request based on the initial request associated with the specified SipSession.

The CANCEL request is derived from the initial request stored in the session linked to the other leg of the transaction.

This method simplifies canceling operations in B2BUA applications by leveraging the session's stored request data.

Parameters:

session: The SipSession whose initial request is targeted for cancellation.

Returns:

A new SipServletRequest object representing the CANCEL request to be sent on the other leg.

Throws:

java.lang.NullPointerException if the provided session is null.

 

createResponseToOriginalRequest

SipServletResponse createResponseToOriginalRequest(SipSession session,
                                                   int status,
                                                   java.lang.String reasonPhrase)

The method generates a response to the original request that created the specified SipSession. This is useful if a B2BUA application needs to send multiple responses to an initial request. For example, when a downstream proxy forks, multiple successful responses may need to be forwarded upstream. This method applies only to initial requests. The generated response must have a unique To tag compared to previously sent responses for the same request. The resulting response creates a new SipSession as part of a new dialog. The container handles cloning the original SipSession to establish subsequent dialogs. Cloned sessions retain the same application data but are specific to their corresponding To tags.

Parameters:

session: The SipSession associated with the original request.

status: The status code for the response (e.g., 200, 400).

reasonPhrase: A custom reason phrase for the response, or null to use the default.

Returns:

A SipServletResponse object representing the created response.

Throws:

java.lang.IllegalStateException If sending the new response would result in inconsistency, such as sending a 400 Bad Request after a 200 OK for the same original request.

java.lang.IllegalArgumentException If the provided SipSession is invalid.

 

getLinkedSession

SipSession getLinkedSession(SipSession session)

The getLinkedSession method retrieves the SipSession linked to the specified SipSession. This linking may occur through an explicit call to linkSipSessions(SipSession, SipSession) or during the invocation of createRequest(SipServletRequest, boolean, java.util.Map). A linked session represents an association between two SIP sessions, often used in B2BUA scenarios. If no association exists, the method returns null.

Parameters:

session: the SipSession whose linked session is to be retrieved.

Returns:

The SipSession linked to the specified session, or null if no linked session exists.

Throws:

java.lang.IllegalArgumentException if the provided session is invalid.

 

getLinkedSipServletRequest

SipServletRequest getLinkedSipServletRequest(SipServletRequest req)

The method retrieves the request that is linked to the specified request. If a new request is created with the link argument set to true using methods such as createRequest(SipServletRequest, boolean, java.util.Map) or createRequest(SipSession, SipServletRequest, java.util.Map), the new request becomes implicitly linked with the original request. This method allows applications to recieve the linked request. While there is no explicit mechanism to link or unlink requests, unlinking associated sessions will also result in the requests being unlinked.

Parameters:

req: The SipServletRequest for which the linked request is to be retrieved.

Returns:

The SipServletRequest that is linked to the specified request, or null if no linked request exists.

 

getPendingMessages

java.util.List<SipServletMessage> getPendingMessages(SipSession session,
                                                     UAMode mode)

This method retrieves a list of all uncommitted messages associated with the specified SipSession, ordered by increasing CSeq number for the given user agent mode (UAC or UAS). If no pending messages exist for the session in the specified mode, the method returns an empty list.

Parameters:

session: The SipSession to inspect for pending messages.

mode: The UAMode (UAC or UAS) for which pending messages are requested.

Returns:

A list of SipServletMessage objects representing the pending messages for the session, or an empty list if there are no pending messages.

Throws:

java.lang.IllegalArgumentException if the provided session is invalid.

 

linkSipSessions

void linkSipSessions(SipSession session1,
                     SipSession session2)

This method establishes a 1-to-1 association between the specified SipSession objects, enabling each session to retrieve the other through getLinkedSession(javax.servlet.sip.SipSession). A SipSession can be linked to only one other session at a time, and both sessions must belong to the same SipApplicationSession. Attempting to link sessions already linked to other sessions will throw an exception. If the specified sessions are already linked to each other, the method performs no action and silently ignores the call.

Parameters:

session1: The first SipSession to link.

session2: The second SipSession to link.

Throws:

java.lang.IllegalArgumentException if either session has been terminated, the sessions do not belong to the same SipApplicationSession, or one or both sessions are already linked to other sessions.

java.lang.NullPointerException if either of the specified SipSession objects is null.

 

unlinkSipSessions

void unlinkSipSessions(SipSession session)

This method removes the association between the specified SipSession and the session it is linked to, if any. Additionally, the method unlinks any implicit linkage at the request level between the two sessions.

Parameters:

session: The SipSession to be unlinked.

Throws:

java.lang.IllegalArgumentException if the specified SipSession is not currently linked to another session or if it has been terminated.

Start innovating with Mobius

What's next? Let's talk!

Mobius Software

As a company you'll get:

  • Get started quickly

  • Support any business model

  • Join millions of businesses

Questions? websupport@mobius.com