VoIP in ECF, GSoC07 DevLog
This page will be updated regularly with status reports on the development progress of the VoIP implementation via Jingle in the ECF.
Trying to identify the usage points of the jmf in the Smack API. The intention is to take control of the media framework via the call api. In detail this constitutes the audio with bitrate, samplerate, mono/stereo as well as the current status of the media playback and recording. Additionally it is intended to set the current playback parameters like volume or pan. As it seams, the usage is pretty interwoven with the Smack API itself. Therefore it is not as easy as intended to access the necessary jmf infrastructure. The key jmf classes required are:
|Required JMF class||Location in the Smack API||Intended Usage|
|javax.media.Player||org.jivesoftware.smackx.jingle.mediaimpl.jmf.AudioReceiver||The Player class and its base class the Controller can be used to get timing information about the data stream.|
|javax.media.Processor||org.jivesoftware.smackx.jingle.mediaimpl.jmf.AudioChannel||The Processor (extending Player) in the AudioChannel class is running the audio conversion. It is also able to provide the required javax.media.GainControl. This GainControl is able to modify the volume, pan etc.|
As it seams the AudioReceiver is not able to handle payload (encoding details of the stream) changes on runtime. As the possible payload types are preconfigured (hard coded) in the Smack API, those predefined values would need to be changed before establishing a connection. Possibly be removing higher quality payloads to use less bandwidth.
The currently supported Payloads are: gsm, g723 and PCMU at 16000 bits. There configuration takes place in org.jivesoftware.smackx.jingle.mediaimpl.jmf.JmfMediaManager. According to the api docs those codecs work on Windows and Mac only.
Posted several issues in the SmackAPI forum. Tried to contact Thiago Camargo, the author of the SmackAPI, with several issues described in the previous posting.
Additionally created a figure to describe the architecture of the Jingle Provider in the context of the ECF. It can be seen here.
Progress can be reported with the SmackAPI. Although no concrete voice is transmitted yet, after various connection configuration attempts it turned out, that the current TransportManager is not well suited. Instead of using an ICETransportManager a STUNTransportManager is used now. It is able to handle NAT based connection issues and does not rely on an intermediator like the ICETransportManager. As a result the current configuration is able to negotiate the connection details such as ports to use for the connection and what codecs to use. In the logs this manfiests as:
... Track 0 is set to transmit as: gsm/rtp, 8000.0 Hz, Mono, FrameSize=264 bits Created RTP session at 19028 to: 188.8.131.52 12568 ....
Although the setup seams to be up and running, there is still no voice to be heard. I have posted this development to the ignite forum.
Further researched the ECF call api trying to figure out what extensions need to be implemented for the jingle implementation.
Spend more time working on the jingle demo application. One issue has been solved but there is still no voice for the voiceless. The discussion continues in the ignite forum. As it seams my network setup is not the main problem. I have tested the Spark XMPP client which uses the SmackAPI. Spark is able to provide computer-to-computer voice communication with the very same jingle api.
Implemented the adapter facilities of the call api. The goal is to create a custom IAdapterFactory to extend the XMPPContainer. The adapter type provided here is an ICallSessionContainerAdapter. To understand the adapter approach it is advised to consult this resource: http://www.eclipsezone.com/articles/what-is-iadaptable/
Created some graphics describing the IAdapater pattern in the Eclipse Communication Framework. The image describes the implementation in the Jingle provider. Additionally further work has been done on the SmackAPI demo.
Image: Adapter pattern in the ECF (549x680, 116 KB)
Managed to implement a first demo version of a jingle call via the SmackAPI. Earlier problems seamed to have resulted in a faulty build process of the SmackAPI.
Started to integrate the Jingle functionality of the SmackAPI into the ECF call api.
It was possible to make a first Smack demo application running from within eclipse. It is not based in the call api yet, but the process of loading and executing is plugin/bundle based. The assumption, that the earlier problems were Smack related turned out to be wrong. It was classpath problem which had its origin in the bundle classloading. Additionally i was able to make my first contribution to improve the call api itself. Some more enhancements are going to take place over the next few days.
Added a new namespace for the jingle protocol via the ecf extension point "org.eclipse.ecf.identity.namespace". It is used to identify Jingle call sessions via a JingleID. I also introduced the logging facilities provided by the osgi framework. It is used for every logging operation in the jingle plugin. Additional work has been done to incorporate the smack api into the call api. This includes creating an uml diagram of the jingle plugin using the call api, which can be found here . It is created using the free version of omondo.
A new unit test project has been created. The required infrastructure to run the test cases has been setup as well as some first test cases. The initialization of the test environment is quite complex and some more abstracting will be done in that area over the next few days. Also several code cleanups have been performed with custom formating and some stricter compiler rules. Additionally added javadoc comments wherever appropriated.
To run the initial test cases it is required to have the bundles of the ECF available. This caused some problems since the XMPP provider (on which the jingle provider is footed) uses the SmackAPI in version 2 whereas the Jingle provider needs version 3. Therefore it was required to upgrade the XMPP provider to make it Smack3 compatible. A patch has been created to upgrade the XMPP provider. It has been send to the responsible commiter (scott lewis) for review and incorporation.
Test, Test... Test case. :) A lot of test cases have been written for the jingle provider. Some problems arose do to the networked nature of the entire project. In the current setup it is necessary to have a remote jingle client running which answers or creates calls. In an ideal world those actions would be initiated from within the test cases by invoking the remote jingle client directly.
I have created a new project for the jingle provider user interface. It is based on the infrastructure provided in org.eclipse.ecf.telephony.call.ui and has the main component of an Action. This Action provides the possibility to start a phone call to a remote user by right clicking on the user and selecting "Call via Jingle" (see screenshot). This procedure works and voice communication is possible. A problem arises here. It only works when calling the little demo application i have written. The demo application can't call the ECF. ECF to ECF doesn't work either. The call is canceled immediately stating that the service is not available. So some more work is required here.
The call feature is finally working inside the ECF by utilizing the Call api. To make that possible, it was required to alter the XMPP provider slightly. It is required to initialize the ICallSessionContainerAdapter which ties the Jingle features to an existing and connected XMPPConnection. With a working implementation up and running it is required to do some more testing to ensure integrity. If robustness can be assured, it is intended to focus on the call ui features. Currently it is not possible to accept an incoming call via a user interaction, nor is it possible to hangup a call.
Created two gui elements to interact with the call api. One is a popup windows which informs of incoming calls. The other is a view which lets the user accept/reject/cancel incoming calls as well as to see some session details. He is also able to adjust the output volume as well as his own microphone input volume.
After some time off (exams) the work on the ECF call api continued. After some discussion with Scott Lewis, we decided to extend the container infrastructure of the ECF with some additional facilities. The idea is to be able to act as a listener on the container creation process. This is required in order to set up appropriate listeners on the call api. So when a container is created, which is able to provide an ICallSessionContainerAdapter (the adapter which supports a voice protocol), a listener can be registered to present gui elements on incoming calls.
Some more modifications on the call api have been introduced to notify facilities of connection events on an IContainer. For that purpose the two parameter classes IContainerConnectingEvent and IContainerConnectedEvent have been introduced in the handleEvent(IContainerEvent) method of the IContainer.
Apparently the Smack library, which provides the jingle support, is not Windows Vista compatible. This is due to the fact, that it relies on the Java Media Framework (JMF) which is not Windows Vista compatible. The JMF has not been under active development for several years now and the company behind the Smack api (ignitesoftware) is planning on replacing the dependency to the JMF with a custom solution (at some point in the future).
Several problems have been solved now. For one, the jingle call provider can now have any name for its client type. Previously the name had to be "Smack". More important is the usage of the ECFStart extension point. It is used for the jingle provider as well as for the call.ui. They both register themselves on the ContainerManager to get informed of newly created XMPPContainers. They can then leverage the newly created XMPPContainer to get notified of connection events (Jingle provider) or to register them selfs as a listener on the jingle provider (call.ui). With this in place it is now possible to use the call.ui to accept or reject calls.
Additionally i have posted an enhancement request to gather some more ideas about the user interface. See here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=200078