O'Reilly    
 Published on O'Reilly (http://oreilly.com/)
 See this if you're having trouble printing code examples


OpenZoep: An Open Source VoIP Engine

by Erik van Eykelen
02/03/2006

Telephony, IM, and the OpenZoep Foundation

OpenZoep (pronounced "open soup") is a client-side telephony and instant messaging (IM) communications engine. It supports computer-to-computer (peer-to-peer) VoIP calls, instant messaging, and outbound PSTN and SIP calls to free and premium SIP providers. OpenZoep is available under the GPL license, as well as a commercial license for companies that do not wish to publish the source code of their commercial products based on OpenZoep.

OpenZoep was developed by Voipster, a technology and VoIP service provider based in Amsterdam. In late 2005, Voipster donated its client-side technology assets to the OpenZoep Foundation. A team of enthusiastic developers in Estonia and the Netherlands is continually adding new features. Like any new open source project, OpenZoep is actively seeking the support from software developers and people with writing and testing skills to improve OpenZoep.

OpenZoep is completely "open for business" to any service provider, and hopes to attract multiple providers of PSTN and voicemail services. Having multiple competing providers offers users a choice, and competition sparks innovation and quality improvements.

By using open VoIP technology, users can rest assured that they will be able to make VoIP calls to any other user. The services available may not be the same to all users (some users may purchase additional services like voicemail, SMS, or conferencing) but at least there are no artificial walls like the ones that plague interoperability in the instant messaging world. Unfortunately, the VoIP market knows walled gardens, too, but OpenZoep thinks it's not too late to turn the tide.

What Does It Do?

Related Reading

VoIP Hacks
Tips & Tools for Internet Telephony
By Ted Wallingford

What can you do with OpenZoep? Well, for one, it allows anyone to embed telephony functions into their desktop applications. The OpenZoep API makes it really easy to pick a sound-in device (microphone or handset) and a sound-out device (speaker or headset), dial a phone number or "dial by username" (more on this later), and presto, a phone call is made.

Another interesting feature is OpenZoep's instant messaging (IM, or chat) capability. OpenZoep uses Jabber to perform its IM tricks. Moreover, the XMPP protocol is used throughout OpenZoep, so when you've mastered XMPP to make a phone call, you'll also then know how to obtain the server-side phonebook, initiate a chat, or answer a call.

The OpenZoep Application Programming Interface

To quote Ben Stein, let's "jump into the middle, get your hands dirty, fall flat on your face, and then reach for the stars."

Because you have to speak XMPP to the OpenZoep API, the API itself is very simple. It has only four methods:

Note the C-language-style notation. This is not a coincidence; OpenZoep itself is entirely written in C++. The C/C++ API enables easy binding to other languages like Perl, Ruby, C#, or Visual Basic. As of January 2006, it is available for the Windows OS. Porting to OS X and Linux is underway, but OpenZoep can use your help here. There is also an XPCOM wrapper available that allows you to access the OpenZoep API from Mozilla applications such as Firefox and Thunderbird.

The api_register_account() method returns a session ID that must be passed to subsequent function calls. Once a session is opened, it must be closed using api_unregister_account() to free up system resources and internal data structures.

The api_send_buf() and api_get_response() methods work in an asynchronous request/response fashion, meaning you can fire multiple, different requests using api_send_buf() and you should be prepared to get back and process responses in random order.

The data you send to api_send_buf() and retrieve using api_get_response() must be valid XML and be UTF-8-encoded. In Jabber parlance, the XML stream consists entirely of "stanzas." Don't let this term fool you; a stanza is nothing more than a snippet of XML that is properly structured and encoded and ready to be injected into the Jabber stream, or (when it returns to you) be picked up from the stream, ready for parsing. As a rule of thumb, you should call api_get_response() every 1000 milliseconds. Every call can return zero, one, or more responses. Note that the api_get_response() function returns the number of bytes actually read, so if this number matches the size of your buffer, more data is waiting.

Jabber Streams

Now that you've mastered OpenZoep's basic methods, it's time to open the stream and make a phone call.

To open the stream, the following stanza should be sent:

  <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
      <stream:stream to='jabber.voipster.com' xmlns='jabber:client'
      xmlns:stream='http://etherx.jabber.org/streams'>

There are two things to notice here. The first is the mandatory UTF-8 encoding, and the second is the host name of the Jabber server. Just replace jabber.voipster.com with your own Jabber server.

The following steps outline the lifecycle of a Jabber stream:

  1. Start a session by calling api_register_account().
  2. Set up the stream as described above.
  3. Inform the OpenZoep engine about your configuration settings by sending the configuration:iq stanza (see trac.web1.openzoep.org/main/wiki/MoipApiSubsystemPresence3 for details).
  4. Request the authorization method (see www.openzoep.org/docs/api/primer/311.htm).
  5. Log in (see www.openzoep.org/docs/api/primer/312.htm).
  6. Send a presence notification (see www.openzoep.org/docs/api/primer/314.htm).
  7. (Recurring) Send and receive messages during the lifetime of the application.
  8. Log out (see www.openzoep.org/docs/api/primer/313.htm).
  9. Close the stream (see www.openzoep.org/docs/api/primer/310.htm).
  10. Close the session by calling api_unregister_account().

The action happens in step 7. Here are some examples of stanzas (XML messages) you can send during step 7.

Making Phone Calls

The OpenZoep client-side engine can be instructed to establish a peer-to-peer phone call to Joe by sending this stanza:

   <voice id="phonecall_3cb5c86c-b40c-4e89-956b-f07d80650109"
      to="joe@jabber.voipster.com/Zoep" type="join">
      <call_id>show</call_id>
      <private>yes</private>
   </voice>

The id attribute of the voice element should contain a globally unique ID (most programming languages offer a library for generating a GUID). The to attribute contains the address of the Jabber contact you want to talk to. The call_id and private attributes are defined by XMPP but are not used by OpenZoep.

Making a call to a "normal" phone (land line or mobile) goes as follows:

   <voice id="phonecall_93a7ba89-4a99-45da-ac82-62f0ee6b4cad"
      to="unknown/#003110123456" type="join">
      <call_id>show</call_id>
      <private>yes</private>
   </voice>

Notice that the Jabber ID should be set to unknown and the number you wish to dial should be preceded by a hash sign (#) and a fully qualified international number. You also need to establish a call credit account with an OpenZoep PSTN provider in order to make phone calls to PSTN numbers (currently the only provider is zoep.com).

Answering Phone Calls

Answering an incoming call from Suzan is just as easy:

   <voice from='suzan@jabber.voipster.com/Zoep'
      id='phonecall_3cb5c86c-b40c-4e89-956b-f07d80650109'
      to='erik@jabber.voipster.com/Zoep' type='join'>
   </voice>

Send a message with the type attribute set to joined to accept the call. The to attribute specifies the Jabber ID of the callee:

   <voice id="phonecall_3cb5c86c-b40c-4e89-956b-f07d80650109"
      to="suzan@jabber.voipster.com/Zoep" type="joined"/>

After sending this message, you get the following response from Suzan:

   <voice from='suzan@jabber.voipster.com/Zoep'
      id='phonecall_3cb5c86c-b40c-4e89-956b-f07d80650109'
      to='erik@jabber.voipster.com/Zoep' type='joined'>
   </voice>

Suzan receives a similar message, only with the from and to attributes reversed:

   <voice from='erik@jabber.voipster.com/Zoep'
      id='phonecall_3cb5c86c-b40c-4e89-956b-f07d80650109'
      to='suzan@jabber.voipster.com/Zoep' type='joined'>
   </voice>

By the way, the join and joined terms originate from the fact that OpenZoep is fully prepared to handle multi-person conferences. Although technically not implemented yet, internally even two-person calls are handled as conferences.

Multiple PSTN Providers

OpenZoep believes that its technology can only proliferate when it is reliable, secure, and open for others to innovate. Part of this mission involves opening up OpenZoep for multiple service providers.

OpenZoep has outlined the following roadmap (still in flux!):

Provider independence: When an OpenZoep user wants to access premium services like making PSTN calls to a regular (mobile) phone, this obviously costs money. Providers of PSTN-in, out, voicemail, etc., can make their services available through OpenZoep.

Soon, OpenZoep will document how providers can integrate their services with OpenZoep. The documentation will outline the following details:

Global phone book: OpenZoep will strive for a global, federated phone book that enables users to find other users who wish to be found. OpenZoep will pursue a cooperation with the IM Federation.

Codec independence: OpenZoep has a pluggable codec architecture. New and emerging codecs will be added as soon as they are available. Service providers are free to offer commercial codecs to their customers as long as they also provide the standard codecs included with OpenZoep. Calls should gracefully degrade to a codec available on both sides.

Secure calls: OpenZoep strives to be the most secure phone on the planet. A possible avenue would be to integrate PGP crypto into OpenZoep.

Device independence: the OpenZoep client engine should be available for a broad range of computers, PDAs, and mobile phones.

Use Cases

OpenZoep can be used for almost any type of application. Here are some ideas that are either in development by OpenZoep users or licensees or that might spark your imagination. (Note that we don't claim that all of these ideas are original; most, if not all, have been implemented before using different technologies):

figure 1

The OpenZoep Firefox plugin

Web browser: On January 30, 2006, Voipster announced an OpenZoep-based phone and IM client for Firefox. See Zoep: Firefox Extension for details.

Productivity software: Office suites like OpenOffice can be outfitted with a call button. The same applies to email clients and CRM applications. (Call to action: OpenZoep will actively assist developers who wish to help make an OpenOffice plugin!)

Games: OpenZoep offers game developers the means to integrate VoIP into their games. OpenZoep is written in C++, so it can be ported to any imaginable runtime platform.

Google Libjingle

OK, we'll give a full disclosure here. OpenZoep does not use Google's Libjingle. The reason, quite simply, is that Libjingle was not available when OpenZoep was developed during the course of 2005.

This is not say OpenZoep won't consider implementing Libjingle--provided some issues are resolved with Libjingle. The biggest issue we currently see with Libjingle is the translation from the Jingle protocol to SIP. The Jabber mailing list contains a thread on this topic.

OpenZoep is in the process of writing a Jabber Enhancement Proposal (JEP) that addresses the issues we see with Libjingle. This JEP addresses the following topics:

The JEP draft is available at www.openzoep.org/docs/jabber/jep-0xxx.html.

Resources

Erik van Eykelen is a senior technology advisor for Voipster BV, a VoIP technology and service provider based in Amsterdam, The Netherlands.


Return to O'Reilly Emerging Telephony

Copyright © 2009 O'Reilly Media, Inc.