3 SIP Protocol Programming

This chapter describes programming SIP applications and contains the following sections:

3.1 Using Compact and Long Header Formats for SIP Messages

This section describes how to use the Oracle WebLogic Server SIP Container SipServletMessage interface and configuration parameters to control SIP message header formats.

3.1.1 Overview of Header Format APIs and Configuration

Applications that operate on wireless networks may want to limit the size of SIP headers to reduce the size of messages and conserve bandwidth. JSR 289 provides the SipServletMessage.setHeaderForm() method, which enables application developers to set a long or compact format for the value of a given header.

One feature of the SipServletMessage API provided in JSR 289 is the ability to set long or compact header formats for the entire SIP message using the setHeaderForm method.

In addition to SipServletMessage, Oracle WebLogic Server SIP Container provides a container-wide configuration parameter that can control SIP header formats for all system-generated headers. This system-wide parameter can be used along with SipServletMessage.setHeaderForm and SipServletMessage.setHeader to further customize header formats.

3.1.2 Summary of Compact Headers

Table 3-1 defines the compact header abbreviations described in the SIP specification (http://www.ietf.org/rfc/rfc3261.txt). Specifications that introduce additional headers may also include compact header abbreviations.

Table 3-1 Compact Header Abbreviations

Header Name (Long Format) Compact Format

Call-ID

i

Contact

m

Content-Encoding

e

Content-Length

l

Content-Type

c

From

f

Subject

s

Supported

k

To

t

Via

v


3.1.3 Assigning Header Formats with WlssSipServletMessage

A pair of getter/setter methods, setHeaderForm and getHeaderForm, are used to assign or retrieve the header formats used in the message. These methods assign or return a HeaderForm object, which is a simple Enumeration that describes the header format:

  • COMPACT—Forces all headers in the message to use compact format. This behavior is similar to the container-wide configuration value of "force compact," as described in use-compact-form in the Configuration Reference Manual.

  • LONG—Forces all headers in the message to use long format. This behavior is similar to the container-wide configuration value of "force long," as described in use-compact-form in the Configuration Reference Manual.

  • DEFAULT—Defers the header format to the container-wide configuration value set in use-compact-form.

SipServletResponse.setHeaderForm can be used in combination with SipServletMessage.setHeader and the container-level configuration parameter, use-compact-form.

3.1.4 Summary of API and Configuration Behavior

Header formats can be specified at the header, message, and SIP Servlet container levels. Table 3-1 shows the header format that results when adding a new header with SipServletMessage.setHeader, given different container configurations and message-level settings with SipServletMessage.setHeaderForm.

Table 3-2 API Behavior when Adding Headers

SIP Servlet Container Header Configuration (use-compact-form Setting)

.SIPServletMessage

setHeaderForm Setting

SipServletMessage.

setHeader Value

Resulting Header

COMPACT

DEFAULT

"Content-Type"

"Content-Type"

COMPACT

DEFAULT

"c"

"c"

COMPACT

COMPACT

"Content-Type"

"c"

COMPACT

COMPACT

"c"

"c"

COMPACT

LONG

"Content-Type"

"Content-Type"

COMPACT

LONG

"c"

"Content-Type"

LONG

DEFAULT

"Content-Type"

"Content-Type"

LONG

DEFAULT

"c"

"c"

LONG

COMPACT

"Content-Type"

"c"

LONG

COMPACT

"c"

"c"

LONG

LONG

"Content-Type"

"Content-Type"

LONG

LONG

"c"

"Content-Type"

FORCE_COMPACT

DEFAULT

"Content-Type"

"c"

FORCE_COMPACT

DEFAULT

"c"

"c"

FORCE_COMPACT

COMPACT

"Content-Type"

"c"

FORCE_COMPACT

COMPACT

"c"

"c"

FORCE_COMPACT

LONG

"Content-Type"

"Content-Type"

FORCE_COMPACT

LONG

"c"

"Content-Type"

FORCE_LONG

DEFAULT

"Content-Type"

"Content-Type"

FORCE_LONG

DEFAULT

"c"

"Content-Type"

FORCE_LONG

COMPACT

"Content-Type"

"c"

FORCE_LONG

COMPACT

"c"

"c"

FORCE_LONG

LONG

"Content-Type"

"Content-Type"

FORCE_LONG

LONG

"c"

"Content-Type"


Table 3-1 shows the system header format that results when setting the header format with WlssSipServletResponse.setUseHeaderForm given different container configuration values.

Table 3-3 API Behavior for System Headers

SIP Servlet Container Header Configuration (use-compact-form Setting)

SipServletMessage.

setHeaderForm Setting

Resulting Contact Header

COMPACT

DEFAULT

"m"

COMPACT

COMPACT

"m"

COMPACT

LONG

"Contact"

LONG

DEFAULT

"Contact"

LONG

COMPACT

"m"

LONG

LONG

"Contact"

FORCE_COMPACT

DEFAULT

"m"

FORCE_COMPACT

COMPACT

"m"

FORCE_COMPACT

LONG

"Contact"

FORCE_LONG

DEFAULT

"Contact"

FORCE_LONG

COMPACT

"m"

FORCE_LONG

LONG

"Contact"


3.2 Using Content Indirection in SIP Servlets

This section describes how to develop SIP Servlets that work with indirect content specified in the SIP message body.

3.2.1 Overview of Content Indirection

Data provided by the body of a SIP message can be included either directly in the SIP message body, or indirectly by specifying an HTTP URL and metadata that describes the URL content. Indirectly specifying the content of the message body is used primarily in the following scenarios:

  • When the message bodies include large volumes of data. In this case, content indirection can be used to transfer the data outside of the SIP network (using a separate connection or protocol).

  • For bandwidth-limited applications. In this case, content indirection provides enough metadata for the application to determine whether or not it must retrieve the message body (potentially degrading performance or response time).

Oracle WebLogic Server SIP Container provides a simple API that you can use to work with indirect content specified in SIP messages.

3.2.2 Using the Content Indirection API

The content indirection API provided by Oracle WebLogic Server SIP Container helps you quickly determine if a SIP message uses content indirection, and to easily retrieve all metadata associated with the indirect content. The basic API consists of a utility class, com.bea.wcp.sip.util.ContentIndirectionUtil, and an interface for accessing content metadata, com.bea.wcp.sip.util.

SIP Servlets can use the utility class to identify SIP messages having indirect content, and to retrieve an ICParsedData object representing the content metadata. The ICParsedData object has simple "getter" methods that return metadata attributes.

3.2.3 Additional Information

Complete details about content indirection are available in RFC 4483.

See Oracle Fusion Middleware WebLogic Server API Reference for additional documentation about the content indirection API.

3.3 Generating SNMP Traps from Application Code

This section describes how to use the Oracle WebLogic Server SIP Container SipServletSnmpTrapRuntimeMBean to generate SNMP traps from within a SIP Servlet.

3.3.1 Overview

Oracle WebLogic Server SIP Container includes a runtime MBean, SipServletSnmpTrapRuntimeMBean, that enables applications to easily generate SNMP traps. The Oracle WebLogic Server SIP Container MIB contains seven new OIDs that are reserved for traps generated by an application. Each OID corresponds to a severity level that the application can assign to a trap, in order from the least severe to the most severe:

  • Info

  • Notice

  • Warning

  • Error

  • Critical

  • Alert

  • Emergency

To generate a trap, an application simply obtains an instance of the SipServletSnmpTrapRuntimeMBean and then executes a method that corresponds to the desired trap severity level (sendInfoTrap(), sendWarningTrap(), sendErrorTrap(), sendNoticeTrap(), sendCriticalTrap(), sendAlertTrap(), and sendEmergencyTrap()). Each method takes a single parameter—the String value of the trap message to generate.

For each SNMP trap generated in this manner, Oracle WebLogic Server SIP Container also automatically transmits the Servlet name, application name, and Oracle WebLogic Server SIP Container instance name associated with the calling Servlet.

3.3.2 Requirement for Accessing SipServletSnmpTrapRuntimeMBean

In order to obtain a SipServletSnmpTrapRuntimeMBean, the calling SIP Servlet must be able to perform MBean lookups from the Servlet context. To enable this functionality, you must assign a Oracle WebLogic Server SIP Container administrator role-name entry to the security-role and run-as role elements in the sip.xml deployment descriptor. Example 3-1 shows a sample sip.xml file with the required role elements highlighted.

Example 3-1 Sample Role Requirement in sip.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sip-app
   PUBLIC "-//Java Community Process//DTD SIP Application 1.0//EN"
   "http://www.jcp.org/dtd/sip-app_1_0.dtd">
<sip-app>
  <display-name>My SIP Servlet</display-name>
  <distributable/>
  <servlet>
    <servlet-name>myservlet</servlet-name>
    <servlet-class>com.mycompany.MyServlet</servlet-class>
    <run-as>
      <role-name>weblogic</role-name>
    </run-as>
  </servlet>
  <servlet-mapping>
    <servlet-name>myservlet</servlet-name>
    <pattern>
      <equal>
        <var>request.method</var>
        <value>INVITE</value>
      </equal>
    </pattern>
  </servlet-mapping>
  <security-role>
    <role-name>weblogic</role-name>
  </security-role>
</sip-app>

3.3.3 Obtaining a Reference to SipServletSnmpTrapRuntimeMBean

Any SIP Servlet that generates SNMP traps must first obtain a reference to the SipServletSnmpTrapRuntimeMBean. Example 3-2 shows the sample code for a method to obtain the MBean.

Example 3-2 Sample Method for Accessing SipServletSnmpTrapRuntimeMBean

public SipServletSnmpTrapRuntimeMBean getServletSnmpTrapRuntimeMBean() {
    MBeanHome localHomeB = null;
    SipServletSnmpTrapRuntimeMBean ssTrapMB = null;

    try
    {
      Context ctx = new InitialContext();
      localHomeB = (MBeanHome)ctx.lookup(MBeanHome.LOCAL_JNDI_NAME);
      ctx.close();
    } catch (NamingException ne){
      ne.printStackTrace();
    }

    Set set = localHomeB.getMBeansByType("SipServletSnmpTrapRuntime");
    if (set == null || set.isEmpty()) {
      try {
        throw new ServletException("Unable to lookup type 'SipServletSnmpTrapRuntime'");
      } catch (ServletException e) {
        e.printStackTrace();
      }
    }
    ssTrapMB = (SipServletSnmpTrapRuntimeMBean) set.iterator().next();
    return ssTrapMB;
}

3.3.4 Generating an SNMP Trap

In combination with the method shown in Example 3-2, Example 3-3 demonstrates how a SIP Servlet would use the MBean instance to generate an SNMP trap in response to a SIP INVITE.

Example 3-3 Generating a SNMP Trap

public class MyServlet extends SipServlet {
  private SipServletSnmpTrapRuntimeMBean sipServletSnmpTrapMb = null;

  public MyServlet () {
  }

  public void init (ServletConfig sc) throws ServletException {
    super.init (sc);
    sipServletSnmpTrapMb = getServletSnmpTrapRuntimeMBean();
  }

  protected void doInvite(SipServletRequest req) throws IOException {
    sipServletSnmpTrapMb.sendInfoTrap("Rx Invite from " + req.getRemoteAddr() + "with call id" + req.getCallId());
  }
}