by David Sugar email@example.com, http://www.gnu.org/software/bayonne
Even without considering all the various reasons of why we must have Free Software as part of the telecommunications infrastructure, it is important to consider what the goals and platform needs are for a telephony platform. Historically, telephony services platforms had been the domain of realtime operating systems. Recent advances in CTI hardware has made it possible to offload much of this requirement to hardware making it practical for even low performance systems running efficient kernels to provide such services for many concurrent users.
Telephony services are usually housed in phone closets or other closed and isolated areas. As such, remote maintainability, and high reliability are both important platform requirements as well. The ability to integrate with and use standard networking protocols is also becoming very important in traditional telephony, and certainly is a key requirement for next generation platforms.
So we can summarize; low latency/high performance kernels, remote manageability without the need for a desktop environment, high reliability, and open networking protocols. This sounds like an ideal match for a GNU/Linux system. For these reason, and with the abundance of computer telephony drivers available for it, we choose to build telephony services such as GNU Bayonne primarily under GNU/Linux.
Our initial goal for GNU Bayonne 1.0 is primarily to make telephony services as easy to program and deploy as a web server is today. We choose to make this server easily programmable thru server scripting. We also desired to have it highly portable, and allow it to integrate with existing application scripting tools so that one could leverage not just the core server but the entire platform to deliver telephony functionality and integrate with other resources like databases.
GNU Bayonne, as a telephony server, also imposes some very real and unique design constraints. For example, we must provide interactive voice response in real-time. ``realtime'' in this case may mean what a person might tolerate, or delay of 1/10th of a second, rather than what one might measure in milliseconds in other kinds of real-time applications. However, this still means that the service cannot block, for, after all, you cannot flow control people speaking.
Since each vendor of telephony hardware has chosen to create their own unique and substantial application library interface, we needed GNU Bayonne to sit above these and be able to abstract them. Ultimately we choose to create a driver plugin architecture to do this. What this means is that you can get a card and api from Aculab, for example, write your
application in GNU Bayonne using it, and later choose, say, to use Intel telephony hardware, and still have your application run, unmodified. This has never been done in the industry widely because many of these same
telephony hardware manufacturers like to produce their own middleware solutions that lock users into their products.
TGI support and plugins
To create GNU Bayonne we needed a portable foundation written in C++. I wanted to use C++ for several reasons. First, the highly abstract nature of the driver interfaces seemed very natural to use class encapsulation. Second, I found I personally could write C++ code faster and more bug free than I could write C code.
Why we choose not to use an existing class framework is also simple to explain. We knew we needed threading, and socket support, and a few other
things. There were only a couple of existing framework that did most of these things and were available in any form of free software license, but
were very large and complex which did far more than we needed. We wanted a small footprint for Bayonne, and the most adaptable framework that we found at the time, ACE, typically added several megs of core image just for their runtime environment.
GNU Common C++ (originally APE) was created to provide a very easy to comprehend and portable class abstraction for threads, sockets, semaphores, exceptions, etc. This has since grown into it's own and is now used as a foundation of a number of projects as well as being a part of GNU. In addition to having portable C++ threading, we needed a scripting engine. This scripting system had to operate in conjunction with a non-blocking state-transition call processing system. It also had to offer immediate call response, and support several hundred to a thousand instances running concurrently in one server image.
Many extension languages assume a separate execution instance (thread or process) for each interpreter instance. These were unsuitable. Many extension languages assume expression parsing with non-deterministic run time. An expression could invoke recursive functions or entire subprograms for example. Again, since we wanted not to have a separate execution instance for each interpreter instance, and have each instance respond to the leading edge of an event callback from the telephony driver
as it steps thru a state machine, none of the existing common solutions like tcl, perl, guile, etc, would immediately work for us. Instead, we created a non-blocking and deterministic scripting engine, GNU ccScript.
GNU ccScript is unique in several ways. It is step executed, and is non-blocking. Statements either execute and return immediately, or they schedule their completion for a later time with the executive. A given "step" is executed, rather than linearly. This allows a single thread to invoke and manage multiple interpreter instances. While GNU Bayonne can support interacting with hundreds of simultaneous telephone callers on high density carrier scale hardware, we do not require hundreds of native "thread" instances running in the server, and we have a very modest cpu load. \\
Another way GNU ccScript is unique is in support for memory loaded scripts. To avoid delay or blocking while loading scripts, all scripts are loaded and parsed into a virtual machine structure in memory. When we wish to change scripts, a brand new virtual machine instance is created to contain these scripts. Calls currently in progress continue under the old vm and new callers are offered the new vm. When the last old call terminates, the entire old vm is then disposed of. This allows for 100% uptime even while services are modified.
Finally, GNU ccScript allows direct class extension of the script interpreter. This allows one to easily create a derived dialect specific to a given application, or even specific to a given GNU Bayonne driver, simply by deriving it from the core language thru standard C++ class extension.
To be able to create useful applications, it is necessary to have more than just a scripting language. It requires a means to be extended so that it can incorporate things like database access libraries or other functions that fall outside of the scope of the scripting language itself. These extensions should be loaded on demand only when used, and should be specified at runtime so that new ones can easily be added without the need to recompile the entire server.
To support scripting extensions we have the ability to create direct command extensions to the native GNU Bayonne scripting languages. These command extensions can be processed thru plugin modules which can be loaded at runtime, and offer both scripting language visible interface extensions, and, within the plugin, the logic necessary to support the operation being represented to the scripting system. These are much more tightly coupled to the internal virtual machine environment and a well written plugin could make use of thread pools or other resources in a very efficient manner for high port capacity applications.
When writing command extensions, it is necessary to consider the need for non-blocking operations. GNU Bayonne uses ccScript principally to assure non-blocking scripting, and so any plugin must be written so that if it must block, it does so by scheduling a state operation such as "sleep" and performs potentially blocking operations in separate threads. This makes it both hard and complex to correctly create script extensions in this manner. While GNU Bayonne's server scripting can support the creation of complete telephony applications, it was not designed to be a general purpose programming language or to integrate with external libraries the way traditional languages do. The requirement for non-blocking requires any module extensions created for GNU Bayonne are written highly custom. We wanted a more general purpose way to create script extensions that could interact with databases or other system resources, and we choose a model essentially similar to how a web server does this.
The TGI model for GNU Bayonne is very similar to how CGI works for a web server. In TGI, a separate process is started, and it is passed information on the phone caller thru environment variables. Environment variables are used rather than command line arguments to prevent snooping of transactions that might include things like credit card information and which might be visible to a simple ``ps'' command. The TGI process is tethered to GNU Bayonne thru stdout and any output the TGI application generates is used to invoke server commands. These commands can do things like set return values, such as the result of a database lookup, or they can do things like invoke new sessions to perform outbound dialing. A ``pool'' of available processes are maintained for TGI gateways so that it can be treated as a restricted resource, rather than creating a gateway for each concurrent call session. It is assumed gateway execution time represents a small percentage of total call time, so it is efficient to maintain a small process pool always available for quick TGI startup and desirable to prevent stampeding if say all the callers hit a TGI at the exact same moment.
As can be seen, we bring all these elements we described earlier together into a GNU Bayonne server, which then executes as a single core image. The server itself exports a series of base classes which are then derived in plugins. In this way, the core server itself acts as a ``library'' as well as a system image. One advantage of this scheme is that, unlike a true library, the loaded modules and core server do not need to be relocatable, since only one instance is instantiated in a specific form that is not shared over arbitrary processes. When the server comes up, it creates gateways and loads plugins. Theplugins themselves use base classes found in the server and derived objects that are defined for static storage. This means when the plugin object is mapped thru dload, it's constructor is immediately executed, and the object's base class found in the server image registers the object with the rest of GNU Bayonne. Using this method, plugins in effect automatically register themselves thru the server as they are loaded, rather than thru a separate runtime operation. The server itself also instantiates some objects at startup even before main() runs. These are typically objects related to plugin registration or parsing of the config file.
Since GNU Bayonne has to interact with telephone users over the public telephone network or private branch exchange, there must be hardware used to interconnect GNU Bayonne to the telephone network. There are many vendors that supply this kind of hardware and often as PC add-on cards. Some of these cards are single line telephony devices such as the Quicknet LineJack card, and others might support multiple T1 spans. Some of these cards have extensive on-board DSP resources and TDM busses to allow interconnection and switching. GNU Bayonne tries to abstract the hardware as much as possible and supports a very broad range of hardware already. GNU Bayonne offers support for /dev/phone Linux kernel telephony cards such as the Quicknet LineJack, for multiport analog DSP cards from VoiceTronix and Dialogic, and digital telephony cards including CAPI 2.0 (CAPI4Linux) compliant cards, and digital span cards from Intel/Dialogic and Aculab. We are always looking to broaden this range of card support. At present both voice modem and OpenH323 support is being worked on. Voice modem support will allow one to use generic low cost voice modems as a GNU Bayonne telephony resource. The openh323 driver will actually require no hardware but will enable GNU Bayonne to be used as an application server for telephone networks and softswitch equipment built around the h323 protocol family. At the time of this writing I am not sure if either or both of these will be completed in time for the 1.0 release or will wait until 1.1.
GNU Bayonne and XML Scripting
Some people have chosen to create telephony services thru web scripting, which is an admirable ambition. To do this, several XML dialects have been created, but the idea is essentially the same. A query is made, typically to a web server, which then does some local processing and spits back a well formed XML document, which can then be used as a script to interact with the telephone user. These make use of XML to generate application logic and control much like a scripting language, and, perhaps, is an inappropriate use of XML, which really is designed for document presentation and inter- exchange rather than as a scripting tool. However, given the popularity of creating services in this manner, we do support them in GNU Bayonne.
GNU Bayonne did not choose to be designed with a single or specific XML dialect in mind, and as such it uses a plugin. The design is implemented by dynamically transcoding an XML document that has been fetched into the internal ccScript virtual machine instructions, and we then execute the transcoded script as if it were a native ccScript application. This allows us to transcode different XML dialects and run them on GNU Bayonne, or even support multiple dialects at once.
Since we now learn that several companies are trying to force thru XML voice browsing standards which they have patent claims in, it seems fortunate that we neither depend on XML scripting nor are restricted to a specific dialect at this time. My main concern is if the W3C will standardize voice browsing itself only to later find out that the very process of presenting a document in XML encoded scripting to a telephone user may turn out to have a submarine patent, rather than just the specific attempts to patent parts of the existing W3C voice browsing standard efforts. \\
Current plans are to distribute the 1.0 "rc1" release of GNU Bayonne during the opening of this year's Libre Software Meeting in Bordeaux, France, July 9. This release represents several years of active development. We are doing some final work on standardizing how Bayonne operates and how it is deployed. GNU Bayonne does not exist alone but is part of a larger meta-project, ``GNUCOMM''. The goals of GNUCOMM is to provide telephony services for both current and next generation telephone networks using freely licensed software. These services could be defined as services that interact with desktop users such as address books that can dial phones and softphone applications, services for telephone switching such as the IPSwitch GNU softswitch project and GNU oSIP proxy registrar, services for gateways between current and next generation telephone networks such as troll and proxies between firewalled telephone networks such as Ogre, realtime database transaction systems like preViking Infotel and BayonneDB, and voice application services such as those delivered thru GNU Bayonne. While much work is being done to finalize the current implementation of GNU Bayonne, work is also moving forward in defining what GNU Bayonne will become. We envision several key areas for future development; native switching, web services, IP voice services, and carrier grade linux support. \\
In native switching, I do mean where Bayonne alone acts as the primary office telephone switch on it's own. One would then plug office telephones directly into a Bayonne server for internal dialtone, and outside lines for interconnection with the public telephone network. The functionality of a Bayonne switch, as well as the features offered to station users and the operation and behavior of the switch as a whole would be completely programmable thru scripting. To support the Bayonne small office phone switch (PABX), we need to support hardware that offers both POTS and PSTN termination. We are initially looking at the new 12 port Voicetronix card, as they will offer such capabilities, and do so on a card with a driver under the GPL. We are open to working with other products as well for this purpose.
For web services, we already support the ability to have Bayonne parse XML content from foreign servers. We are looking to make it possible for other web services to also invoke Bayonne services and functionality directly, such as thru XMLRPC.
In IP voice, conversations are carried as packets directly over ethernet rather than thru circuit switched telephone lines. For IP voice, we are looking to using both the new openh323 driver development and, in particular the openh323 related OPAL library. This library would allow us to use either H323 or SIP for end-point control and allow GNU Bayonne to integrate into any IP voice environment today. When used for IP voice, Bayonne requires no physical hardware as it operates purely over a network stack, and hence, some of the more obscure ports, such as the recent s/360 port of GNU Bayonne, start actually having some value.
The carrier grade linux project offers the ability to support hotswap hardware dynamically on a cPCI bus. This would allow telephony cards to be swapped in and out on a live machine. It would also allow high speed switchovers where one can have active and standby cpu's each running a linux kernel instance. Finally, it looks to address start and stop time of the kernel to make it very quick. All of these have the goal of achieving carrier grade systems that offer 6'9's reliability, or, a maximum of 2-5 seconds of downtime per year.
Since GNU Bayonne is already being deployed by commercial telephone carriers, we are interested in this. There have also been some experimenting with GNU Bayonne as a tandum switch in a public telephone network setting. These applications typically expect and require such level of reliability. Support for carrier grade linux from the application server is actually easy to achieve. Assuming we can receive notification of cards being inserted and removed, all we need to do is activate or deactivate running card resources. This type of operation is very easy to resolve in the Bayonne driver abstraction environment. Our next immediate goal after the 1.0 release is development in this area, and we hope some if not all of these things can be achieved by the 1.1 release.
There are a number of contributors to GNU Bayonne. These include:
Matthias Ivers who has provided a lot of good bug fixes and new scheduler code.
Matt Benjamin has provided a new and improved tgi tokeniser and worked on Pika outbound dialing code. Wilane Ousmane helped with the French phrasebook rulesets and French language audio prompts.
Henry Molina helped with the Spanish phrasebook rulesets and Spanish language audio prompts.
Kai Germanschewski wrote the CAPI 2.0 driver for GNU Bayonne.
David Kerry contributed the entire Aculab driver tree. Mark Lipscombe worked extensivily on the Dialogic driver tree.
There have been many additional people who have contributed to and participated in related projects like GNU Common C++ or who have helped in other ways.