Archive for the ‘Java’ Category

Voxeo PRISM supports wideband VoIP now

Monday, May 9th, 2011

Voxeo PRISM 10.1 is available at www.voxeo.com/prism for download now.

One of the biggest changes in Voxeo PRISM 10.1 is to support some of wideband VoIP codecs. These wideband, sometimes referred as HD, codecs offer much better sound quality than the traditional codecs.

Here are the codecs Voxeo PRISM 10.1 can set up with the phones.

CODEC NAME SAMPLING RATE DESCRIPTION LICENSE
PCMA 8KHz G.711 alaw INCLUDED
PCMU 8KHz G.711 ulaw INCLUDED
G722 16KHz G.722 INCLUDED
G726-32 8KHz G.726 at 32Kbit/s INCLUDED
GSM 8KHz GSM 6.10 INCLUDED
L16 8/16KHz 16-bit Linear PCM INCLUDED
G729 8KHz G.729 ADDITIONAL
G729 8KHz G.729 Annex B ADDITIONAL
SPEEX 8/16/32KHz Speex INCLUDED
AMR 8KHz AMR-NB ADDITIONAL
AMR-WB 16KHz AMR-WB ADDITIONAL
telephone-event RFC 2833 INCLUDED

Voxeo PRISM 10.1 also supports the following file formats and codecs in playback and recording.

FILE NAME EXTENSION MIME TYPE SUPPORTED CODEC
.wav audio/wav G.711 alaw/ulaw
8/16-bit Linear PCM
Microsoft GSM
.ulaw audio/ulaw G.711 ulaw
.alaw audio/alaw G.711 alaw
.pcm audio/pcm 16 bit Linear PCM
.gsm audio/gsm GSM 6.10
.au audio/au G.711 alaw/ulaw
8/16-bit Linear PCM
.mp3 audio/mpeg MP3
.ogg audio/ogg Vorbis
Speex
.spx audio/ogg Speex
.amr audio/amr AMR
.awb audio/amr-wb AMR-WB


Want to learn how Voxeo can help unlock your communications and deliver a better customer experience? Please contact us!

If you found this post interesting or helpful, please consider either subscribing via RSS, becoming a fan on Facebook, or following us on Twitter.


How to make Voxeo Prism to talk to PSTN?

Thursday, March 24th, 2011

If you have tried Click-To-Dial example, you might wonder if it is possible to call your home phone or cellular phone, besides the SIP phones. It is definitely possible with Voxeo Prism.

In SIP Servlet, a PSTN phone number is represented by a TelURL object based on RFC 3966. For example, here is the code snippet to generate a TelURL object for 407-555-1212.

  URI target = sipFactory.createURI("tel:+1-407-555-1212");

Once you have a TelURL, you can use it the same way as a SipURI, both of which are URI. When Voxeo Prism tries to send a SIP message to a TelURL, it will try to map the telephone number (in E.164 format) to a SIP address based on ENUM.

According to ENUM, a telephone number in E.164 format should be converted to a unique key based the following steps.

1. Remove all characters with the exception of the digits.  For
      example, given the E.164 number "+1-407-555-1212" (which would
      then have been converted into an AUS of "+14075551212"), this
      step would simply remove the leading '+', producing
      "14075551212".
2. Reverse the order of the digits.  Example: "21215557041"
3. Put dots ('.') between each digit.  Example:
      "2.1.2.1.5.5.5.7.0.4.1"
4. Append the string ".e164.arpa." to the end and interpret as a
      domain name.  Example: 2.1.2.1.5.5.5.7.0.4.1.e164.arpa.

Then the key is used to look up the corresponding SIP address in the DNS NAPTR records. E.g. the following record maps “+1-407-555-1212” to “sip:14075551212@example.com“.

$ORIGIN 2.1.2.1.5.5.5.7.0.4.1.e164.arpa.
       NAPTR 100 50 "u" "E2U+sip"             "!^(\\+14075551212)$!sip:\\1@example.com!"    .
       NAPTR 100 51 "u" "E2U+h323"            "!^\\+14075551000$!h323:operator@example.com!"    .
       NAPTR 100 52 "u" "E2U+email:mailto"    "!^.*$!mailto:info@example.com!"

By default, Voxeo Prism uses the default DNS server configured on the system to perform the ENUM lookup. However, it is possible to specify a specific DNS server for the ENUM lookup. You can even specify a different domain suffix instead of the default “e164.arpa“. Please see Voxeo Prism User Guide for more information on how to configure that.

While ENUM gives you complete control on how to map individual telephone number to different SIP address, another popular way to connect Voxeo Prism to PSTN is through a VoIP (SIP trunking) provider.

Voxeo Prism always looks up ENUM first. If no mapping is found in ENUM and a VoIP provider is configured, the SIP messages will sent to the VoIP provider. The following picture shows where you can configure the VoIP provider’s gateway information.

Obviously, Gateway’s Host, Port, and Protocol specify where the gateway is. If the gateway requires SIP registration, you further configure the Registration section. The registrar’s Host and Port is the same as gateway’s, unless specified differently. The User and Domain allows you to specify the Address-of-Record (AOR) for registration. The Auth User and Password allows you to specify credentials in case the registrar requires authentication.  For more information on specific fields, please refer to Voxeo Prism User Guide.


Want to learn how Voxeo can help unlock your communications and deliver a better customer experience? Please contact us!

If you found this post interesting or helpful, please consider either subscribing via RSS, becoming a fan on Facebook, or following us on Twitter.


Click To Dial: a converged application on Voxeo Prism

Saturday, March 19th, 2011

Voxeo Prism is a converged application platform where you can mingle Web (HTTP) functionality with real-time communication (SIP or XMPP) functionality in a single programming model and application.

A classic example of converged application is Click-To-Dial, where the user can enter two telephone numbers in a web page and the web application calls each phone and connect them together.

In this blog, I will show how to build a simple Click-To-Dial application on Voxeo Prism that can connect two SIP softphones together.

Voxeo Prism supports both Java Servlet 2.5 API and JSP 2.1. It also supports SIP Servlet 1.1 API. So I built this application using JSP and SIP Servlet. Here is how the application, a.k.a. WAR, looks like.

Tutorial.4
   |-- WEB-INF
   |         |-- sip.xml
   |         |-- web.xml
   |         |-- xmpp.xml
   |         |-- sipmethod-application.xml
   |         |-- classes
   |                  |-- com/voxeo/prism/tutorial/four/Call.class
   |                  |-- com/voxeo/prism/tutorial/four/ClickToDialServlet.class
   |-- call.jsp
   |-- index.jsp
   |-- status.jsp
   |-- terminate.jsp
   |-- phone.jpg

Once the application is deployed on Voxeo Prism, go to http://localhost:8080/Tutorial.4 to open home page (index.jsp). It will look like the following.

Once you enter two reachable SIP addresses, e.g. sip:john@somedomain.com and sip:doe@otherdomain.com, and click the Call button. The call.jsp will be invoked to make the call to sip:john@somedomain.com and sip:doe@otherdomain.com respectively and join them together when both have answered.

The following diagram shows how the JSPs, Java objects, and SIP servlet interact with each other.

The logic of making outbound calls  are in the Call.call() method, as shown below. “_factory” is the SipFactory object. “_left” and “_right” are the URIs submitted from the index.jsp. “_servlet” is the name of the ClickToDialServlet defined in its annotation or deployment descriptor. By setting the servlet as  the handler of the session, the servlet will receive all messages for that session.

      _inviteL = _factory.createRequest(_session, "INVITE", _left, _right);
      _inviteR = _factory.createRequest(_session, "INVITE", _right, _left);
      _inviteL.setRequestURI(_right);
      _inviteR.setRequestURI(_left);
      _inviteL.getSession().setHandler(_servlet);
      _inviteL.getSession().setAttribute(Call.class.getName(), this);
      _inviteR.getSession().setHandler(_servlet);
      _inviteR.getSession().setAttribute(Call.class.getName(), this);
      _inviteL.send();
      _inviteR.send();

Once both phones have responded with 2xx answers, Call.connect() will generate ACK for each phone with the SDP from the other phone. If one of the phones returns an error response, the call is terminated. Here is the logic in Call.connect() method.

  synchronized void connect(SipServletResponse response) {
    SipServletResponse otherResponse = null;
    int code = response.getStatus();

    if (code < 200) {
      return;
    }

    if (_inviteL.getSession().equals(response.getSession())) {
      _responseL = response;
      otherResponse = _responseR;
    }
    else if (_inviteR.getSession().equals(response.getSession())) {
      _responseR = response;
      otherResponse = _responseL;
    }

    //TODO: handle 3xx for redirection
    if(code >= 300) {
      terminate();
      return;
    }

    if (otherResponse != null) {
      try {
        if (response.getStatus() >= 200 && response.getStatus() < 300 && otherResponse.getStatus() >= 200 && otherResponse.getStatus() < 300) {
          SipServletRequest ack = response.createAck();
          ack.setContent(otherResponse.getRawContent(), otherResponse.getContentType());
          SipServletRequest otherAck = otherResponse.createAck();
          otherAck.setContent(response.getRawContent(), response.getContentType());
          ack.send();
          otherAck.send();
          _state = State.CONNECTED;
        }
        // container automatically sends ACK in other cases.
      }
      catch (Exception e) {
        terminate();
      }
    }
  }

When the call is terminated, we have to send either CANCEL or BYE to each telephone. Based on RFC 3261, CANCEL should be sent before receiving the final response. The follow is the code to terminate the call to one telephone.

  private void terminate(SipServletRequest invite, SipServletResponse response) {
    try {
      if (invite != null) {
        if (invite.isCommitted()) {
          if (response == null) {
            invite.createCancel().send();
          }
          else {
            invite.getSession().createRequest("BYE").send();
          }
        }
      }
    }
    catch (Exception e) {
      // nothing we can do at this point
    }
  }

To try it out, download and deploy the application to <prism>/apps. Open the home page at http://localhost:8080/Tutorial.4. Make sure you type in valid and reachable SIP addresses. By default, PSTN telephone number won’t work unless VoIP gateway or ENUM are configured, which I will show you in the future blog.


Want to learn how Voxeo can help unlock your communications and deliver a better customer experience? Please contact us!

If you found this post interesting or helpful, please consider either subscribing via RSS, becoming a fan on Facebook, or following us on Twitter.


How to Find Me or Follow Me?

Friday, January 7th, 2011

Virtual number with Find-Me and Follow-Me service is getting popular. The idea is you can give your friends and family a virtual number. Then you can register multiple phones, such as your cellphone, home phone, and work phone, to that virtual number. When people call your virtual number, the virtual number can ring your registered phones either one by one — Follow Me — or all at the same time — Find Me — until you pick up one of them.

In SIP world, your SIP address, e.g. sip:wchen@voxeo.com, essentially is the virtual number. You can register multiple SIP phones to your SIP address. To Find Me, simply proxy the call to all the registered addresses in parallel. To Follow Me, simply proxy the call to all the registered addresses sequentially.

In the Using SIP Servlet to implement SIP Registrar and Proxy Server blog, I described how registration and proxy works. With SIP Servlet, adding Find-Me and Follow-Me is trivial.

The following code was shown in that blog to demonstrate how SIP proxy works.

  @Override
  protected void doInvite(SipServletRequest req) throws ServletException, IOException {
    // application only has to worry about forwarding the initial request.
    // the rest is taken care by the container.
    if (req.isInitial()) {
      URI callee = req.getTo().getURI();
      Proxy proxy = req.getProxy();

      //let's see if the Location Service has bindings for this callee.
      List<URI> targets = _locator.getContacts(callee);
      if (targets.size() > 0) {
        // The Proxy Server should stay on the signaling path
        proxy.setRecordRoute(true);

        // Let the container handles all the 3xx redirect automatically
        proxy.setRecurse(true);

        // Try all the registered phones for this callee sequentially
        proxy.setParallel(false);

        //Yes, let's proxy the call to the registered phones.
        proxy.proxyTo(targets);
      }
      else {
        // Oops, no phone is registered right now. Let's do our best.
        proxy.proxyTo(callee);
      }
    }

When you have multiple phones registered, the above code essentially provides Follow-Me.

You can change one line — #19 –  to make this become Find-Me.

        proxy.setParallel(true);

What if you want to provide a PSTN virtual number and register PSTN numbers? SIP Servlet can work with either SIP URI and Telephone URL. So there is no difference as far as proxy code concerns. What you need is to connect the platform to a VoIP provider that can provide SIP-PSTN connectivity. In the future blog, I will show you how to configure Voxeo Prism to provide PSTN connectivity.


Want to learn how Voxeo can help unlock your communications and deliver a better customer experience? Please contact us!

If you found this post interesting or helpful, please consider either subscribing via RSS, becoming a fan on Facebook, or following us on Twitter.


Using SIP Servlet to implement SIP Registrar and Proxy Server

Monday, November 29th, 2010

In “SIP Servlet Programming: Basic“, I showed you how to write a simple SIP Servlet application. In this blog, I will show you a more realistic application –a simple SIP Registrar and Proxy server .

SIP Registration and Proxy

SIP Registrar and Proxy servers play a central role in routing SIP calls among SIP phones.

As illustrated in the above diagram, a SIP phone registers to Registrar with its current address. Registration essentially establishes a binding between SIP phone’s logical address (e.g. sip:wchen@voxeo.com) to its physical address (e.g. sip:wchen@192.168.1.105).  The bindings are stored in a Location Service. When john@voxeo.com calls wchen@voxeo.com, Proxy looks up the Location Service to find the physical address of wchen@voxeo.com, where Proxy forwards the call. Please note Location Service here is a logical concept and is not necessarily a separated software entity.

Application Overview

The application includes two SIP servlets, one for SIP Registrar and one for SIP Proxy. Here is the application package layout.

  |-- WEB-INF
  |     |-- classes  (where all the java classes are)
  |     |   |-- com
  |     |       |-- voxeo
  |     |           |-- prism
  |     |               |-- tutorial
  |     |                   |-- two
  |     |                       |-- ProxyServer.class
  |     |                       |-- Registrar.class
  |     |                       |-- Binding.class
  |     |                       |-- LocationService.class
  |     |                       |-- IllegalRegistrationException.class
  |     |-- lib (where all the library JARs are, if any)
  |     |-- sip.xml (SIP deployment descriptor XML)
  |     |-- web.xml (HTTP deployment descriptor XML)
  |     |-- xmpp.xml (optional XMPP deployment descriptor XML)
  |     |-- sipmethod-application.xml (optional Prism deployment descriptor XML)
  |-- index.jsp (document files)

Implement a SIP Registrar

The overall SIP registration behavior is well defined in RFC 3261, section 10. Two of the key designs in implementing a SIP Registrar are the data model for the binding and processing logic for REGISTER message.

Data Model for Binding

A binding is created when a SIP phone registers itself to Registrar by sending a SIP REGISTER request. A binding essentially is entity with the following attributes.

Address of Record Contact URI Call ID CSeq Expiration
  • Address of Record (AOR): the logical address of the SIP phone.
  • Contact URI (Contact): the physical address of the SIP phone.
  • Call ID: the Call-ID associated with the SIP REGISTER request that creates this binding.
  • CSeq: the CSeq number associated with the SIP REGISTER request that creates this binding.
  • Expiration: the expiration time for this binding.

AOR and Contact are the composite key for a binding entity.

In this blog, I used a two-level Map to store all the bindings in memory for simplicity. In real world, you might persist the bindings to a relational data store.

Map<URI, Map<URI, Binding>>
     |        |       |
    AOR    Contact Binding

The first level Map allows look-up of all bindings given an AOR. The second level Map allows look-up a binding given a specific Contact. The Binding class encapsulates the binding entity. The AOR is not encapsulated inside the Binding class since it is already the key in the map.

Registration Processing

RFC 3261, section 10.3 describes 8 steps for processing a SIP REGISTER request.  In this blog, I implemented most of the requirements in a Registrar Servlet, as illustrated in the following flow chart.

Here is the corresponding Java code in Registrar servlet.

  @Override
  protected synchronized void doRegister(SipServletRequest req) throws ServletException, IOException {
    // TODO 1: request URI format validation
    // TODO 2: domain validation
    // TODO 3: Require validation
    // TODO 4: Multiple contact headers support

    // get the Address-of-Record (AOR) for this REGISTER request.
    URI aor = req.getTo().getURI();

    // get the Contact for this REGISTER request, assuming there is at most one.
    Address contact = req.getAddressHeader("Contact");

    // get the bindings map for the AOR, if no bindings map, initialize an empty one.
    Map<URI, Binding> bindings = _registrations.get(aor);
    if (bindings == null) {
      bindings = new HashMap<URI, Binding>();
      _registrations.put(aor, bindings);
    }

    try {
      // is there a Contact in this Request? If not, this is a fetch per RFC 3261 10.2.3
      if (contact != null) {
        // calculating the Expires for this Contact
        int expires = contact.getExpires();
        if (expires < 0) {
          expires = req.getExpires();
        }
        if (expires < 0) {
          expires = DEFAULT_EXPIRES;
        }

        // is this Contact a wildcard Contact? i.e."*".
        if (!contact.isWildcard()) {
          String callID = req.getCallId();
          int seq = Integer.parseInt(new StringTokenizer(req.getHeader("CSeq").trim()).nextToken());
          URI key = contact.getURI();

          // is there a binding existed for this URI already?
          Binding current = bindings.get(key);
          if (current != null) {
            // Now we have to compare the Call ID and CSeq of the new Contact and the existed Contact
            // per RFC 3261 10.3, step 7
            if (!current.getCallID().equals(callID) || current.getSeq() < seq) {
              if (expires != 0) {
                current.update(callID, seq, expires);
              }
              else {
                bindings.remove(key);
              }
            }
            else {
              throw new IllegalRegistrationException("Registration is out of order.");
            }
          }
          else if (expires > 0) {
            // since no existing binding, let's add the new binding
            bindings.put(key, new Binding(contact, callID, seq, expires));
          }
        }
        else if (expires == 0) {
          // Wildcard Contact can only removes the bindings for an AOR, per RFC 3261 10.3, step 6
          bindings.clear();
        }
        else {
          throw new IllegalRegistrationException("In violation of RFC 3261 10.2.2.");
        }
      }

      // valid response must enumerate all the current bindings, per RFC 3261 10.3, step 8
      SipServletResponse resp = req.createResponse(SipServletResponse.SC_OK);
      for (Binding b : bindings.values()) {
        Address addr = _factory.createAddress(b.getContact());
        addr.setExpires(b.getExpires());
        resp.addAddressHeader("Contact", addr, false);
      }
      resp.send();
    }
    catch (IllegalRegistrationException e) {
      req.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, e.getMessage()).send();
    }
    finally {
      // REGISTER session should be invalidated since REGISTER request doesn't establish a SIP dialog.
      req.getApplicationSession().invalidate();
    }
  }

Please note, at the end of doRegister() method, the session is invalidated right away. This is because a REGISTER request does not establish a SIP dialog, per RFC 3261, section 10.2.

Implement a SIP Proxy

The overall SIP proxy behavior is well defined in RFC 3261, section 16. In SIP Servlet, only stateful Proxy is supported, which is most often used. Most of the proxy logic is already built within a SIP Servlet container. So writing a SIP proxy is really simple.

The following is how the ProxyServer servlet handles SIP INVITE messages.

  @Override
  protected void doInvite(SipServletRequest req) throws ServletException, IOException {
    // application only has to worry about forwarding the initial request.
    // the rest is taken care by the container.
    if (req.isInitial()) {
      URI callee = req.getTo().getURI();
      Proxy proxy = req.getProxy();

      //let's see if the Location Service has bindings for this callee.
      List<URI> targets = _locator.getContacts(callee);
      if (targets.size() > 0) {
        // The Proxy Server should stay on the signaling path
        proxy.setRecordRoute(true);

        // Let the container handles all the 3xx redirect automatically
        proxy.setRecurse(true);

        // Try all the registered phones for this callee sequentially
        proxy.setParallel(false);

        //Yes, let's proxy the call to the registered phones.
        proxy.proxyTo(targets);
      }
      else {
        // Oops, no phone is registered right now. Let's do our best.
        proxy.proxyTo(callee);
      }
    }

Servlet Selection

Since there are two servlets in this application, how does Voxeo Prism know Registar servlet will handle SIP REGISTER messages and Proxy servlet will handle SIP INVITE messages?

The trick is to specify the matching rules in the SIP deployment descriptor.

	<servlet-selection>
		<servlet-mapping>
			<servlet-name>Registrar</servlet-name>
			<pattern>
				<equal ignore-case="false">
					<var>request.method</var>
					<value>REGISTER</value>
				</equal>
			</pattern>
		</servlet-mapping>
		<servlet-mapping>
			<servlet-name>Proxy</servlet-name>
			<pattern>
				<and>
					<not>
						<equal ignore-case="false">
							<var>request.to.uri.user</var>
							<value>prism</value>
						</equal>
					</not>
					<equal ignore-case="false">
						<var>request.method</var>
						<value>INVITE</value>
					</equal>
				</and>
			</pattern>
		</servlet-mapping>
	</servlet-selection>

The above rules basically tell Voxe Prism that Registar servlet will take any SIP REGISTER requests, and Proxy servlet will take any SIP INVITE requests if the request URI’s user portion is not “prism”. The last condition is to avoid conflicts with the pre-installed Voxeo Prism demo application.

Please note that the rules are associated with servlet names, instead of servlet class name. The association between servlet names and servlet class names are defined via @SipServlet annotations in Registar servlet and Proxy servlet respectively.

Running the Application

First step is to download and install Voxeo Prism. Then download the application and copy the WAR file to your <where_prism_is_installed>/apps directory.

Now you can configure two phones to register Voxeo Prism. Here I show you how to configure two X-Lite softphones to test the application.

Please note that Proxy address is pointing to the where Voxeo Prsim is, e.g. 192.168.1.111.

Once both phones are registered, you can view the current bindings by going to http://192.168.1.111:8080/Tutorial.2/, as shown below.

Now the two phones can call each other by entering the name. E.g. calling john from my phone will look like the following.

Summary

In this blog and the tutorial application, I showed you how to implement a SIP Registrar and Proxy using SIP Servlet APIs.

Please note that the code is written mainly for simplicity and readability, instead of performance and scalability.

As an exercise, you can try to enhance it by completing the TODO items I listed in Registrar Servlet.

Enjoy!


Want to learn how Voxeo can help unlock your communications and deliver a better customer experience? Please contact us!

If you found this post interesting or helpful, please consider either subscribing via RSS, becoming a fan on Facebook, or following us on Twitter.


Test Drive Voxeo Prism

Tuesday, November 23rd, 2010

If you have followed my last blog, you should have Voxeo Prism installed and running by now.

In this blog, I want to show you how to use a SIP phone to test drive Voxeo Prism. Voxeo Prism comes with a demo application that demonstrates the following functions:

  • SIP voice call
  • DTMF input recognition
  • SIP instant messaging (using SIMPLE)
  • Text-to-Speech
  • Recording
  • Media playback

The following video shows how you can use XLite, a free softphone with both voice and instant messaging capabilities, to test drive Voxeo Prism.

In the future blog, I will show you how this demo application looks like.


Want to learn how Voxeo can help unlock your communications and deliver a better customer experience? Please contact us!

If you found this post interesting or helpful, please consider either subscribing via RSS, becoming a fan on Facebook, or following us on Twitter.