SIMPLE and XMPP client interface for SECE

 

Jaya L Allamsetty

Columbia University

500 West 120th Street

New York, NY 10027

jla2164@columbia.edu

 

Abstract

 

The aim of this project is to integrate the Mobicents Sip Presence Server (MSPS) in the Sense Everything Control Everything (SECE) architecture and to provide an interface for SECE to subscribe to presence notifications of different entities. The library developed as part of this project is a Java based library which can be embedded into any applications to create an XMPP or SIMPLE client. It enables SECE to listen for the interesting events and then trigger action scripts based on the rules added by the users of SECE. SECE is an event-driven system that uses a natural-English-like language to trigger action scripts. The Java library has support for rich presence and geo-location presence as well. As SECE has to communicate with several third-party applications like presence servers and Google services due to its integrative nature, the library plays an important role of acting as a connecting agent.

 

Introduction

 

The latest release (BETA6) of a Mobicents SIP Presence server (MSPS) has been deployed on lagrange.cs.columbia.edu and has been configured to authenticate HTTP and SIP requests coming from users in the the same domain. It provides presence functionalities to SIP-based networks using standards developed by IETF. A client interface (approx. 5000 lines of code) has been developed using the JAIN SIP and Smack Jabber API’s that support SIP methods like SUBSCRIBE, NOTIFY, PUBLISH, REGISTER and MESSAGE and also the XMPP protocol for instance messaging and presence. The SIMPLE client is capable of generating RPID’s for rich presence and can include geo-location information as well.  It also stores the contact information or the buddy lists of the users on the Mobicents XML Document Management Server (XDMS) as against having them on the client machine which facilitates centralized resource-list management.

 

In related work [1], I discuss about the available open-source SIP clients that have been examined and why they do not fit in with the requirements of SECE. Section [2], briefly discusses about the architecture of the client interface and the flow of SIP and XMPP messages between the entities involved. Section [3] provides an overview of the MSPS, installation instructions and modifications to be made in its default configuration for it to work with the SECE system. Section [4] covers the library documentation by describing the overall architecture of the client interface, different modules and about the underlying API's and functionality provided by each of those. Section [5] discusses about the JAIN SIP and Smack API's used for developing the client library. Section [6] is acknowledgements and is followed by the references section [7].

 

Related work

 

Many of the available Open source SIP clients that I have explored do not support Rich presence and Location presence information. Sip Communicator (called JITSI now) is a Java based VoIP and Instant Messaging client that supports some of the most popular VoIP and instant messaging protocols such as SIP, Jabber, AIM/ICQ, MSN, Yahoo! Messenger, Bonjour and has a whole lot of other useful features. However, the support for Rich presence and Location presence is very limited and did not meet the project requirements. Also, JITSI stores the contact information locally on the machine where the application is running instead of storing them on a Resource List Server. There is no means of extracting the contacts information when using clients like JITSI, X-Lite, Mercuro, etc.

 

Architecture

 

 

 

The library can be used by a client application for communicating with Presence servers and XMPP servers.

The XMPP user agent implementation can perform real-time communications like instant messaging and lets you keep track of the availability ("presence") of other users. It also allows you to organize users into groups such as "Friends" and "Co-workers". XMPP (eXtensible Messaging and Presence Protocol) is an open protocol standardized by the IETF is supported by the XMPP Standards Foundation. There are ten of thousands of XMPP services deployed on the internet including Google Talk, Live Journal Talk, Ovi, etc.

 

The SIMPLE implementation of the library allows you to manage subscriptions from watchers to presence information and generate notifications about presence information state changes, retrieving the presence authorization rules from the XDM server.

 

These methods are implemented for the Presence types SIMPLE and XMPP in classes SIMPLEPresenceIMService and XMPPPresenceIMService respectively.

 

The factory design technique is used for creating an instance of SIMPE or XMPP client based on the parameter PresenceType passed to the getInstance() method.

These classes use a multiton design pattern for creating a unique instance of the class using a combination of the passed parameters to create a key. Only one instance is maintained per combination which is returned by the getInstance() method.

 

A listener interface has been designed which will have the methods that will be invoked when when any interesting events like a NOTIFY message or an IM is received. The application can have different implements of this interface and define different ways of handling such events.

 

Other important classes included in the client library are

PresenceRules - for defining presence authorization rules for a user. These rules are used to determine which elements in a presentity's PIDF can be shared with which watchers.

ResourceList - for creating and uploading resource-lists to the XDM server. This allows a single SUBSCRIBE message being sent to the server instead of sending individual subscriptions to each of the contacts.

RichPresence - for creating a RPID for publishing a user's state

Register - for creating headers for a REGISTER method and for sending it to the registrar

Subscribe - for creating headers for a SUBSCRIBE method and for sending it to the presence server

Publish - for creating headers for a PUBLISH method and for sending it to the presence server

StateChangedEvent - for parsing the PIDF document to retrieve information from the XML document

MessageEvent - for retrieving the information from a MESSAGE request

SipIM  - for sending an IM to another user using MESSAGE method

 

 

Mobicents Documentation

 

3.1    Mobicents Presence Server

 

    3.1.1    Introduction to Mobicents SIP Presence Service

    3.1.2    Installing, configuring and running Mobicents

    3.1.3    Changes to be made for running Mobicents on lagrange

    3.1.4    User profile provisioning on Mobicents

    3.1.5    Console logging for Mobicents

    3.1.6    Authentication of users

    3.1.7    Authorization - pres rules document

    3.1.8    Resource List document

    3.1.9    RLS services document

    3.1.10  Mobicents XCAP API's

 

Client Library Documentation

 

JAIN SIP API's

 

The SIP client library is written in Java using JAIN SIP API's which is a low level Java API specification for SIP signaling.

 

 

JAIN SIP defines four different factories each with respective responsibilities, namely:

Information about the latest releases and other release information can be found at https://jain-sip.dev.java.net.Download the JAIN-SIP package and follow the installation instructions. The following files have to be in the .classpath while executing the client application:

jain-sip-ri-1.2.152.jar

jain-sip-api-1.2.jar

 

*Please note that JAIN SIP appends the port information in the Request URI while sending a SUBSCRIBE message to the Mobicents Presence server. The port number should not be appended for the Mobicents to handle it correctly. This needs to be modified in the JAIN SIP library and the library should be re-compiled after the changes are done. A compiled version of the modified JAIN SIP libraries has been submitted.

 

Smack API's

Smack is an Open Source XMPP (Jabber) client library for instant messaging and presence. A pure Java library, it can be embedded into applications to create anything from a full XMPP client to simple XMPP integrations such as sending notification messages and presence-enabling devices. Smack is meant to be easily embedded into any existing JDK 1.5 or later Java application. It has no external dependencies (except for the Jingle voice chat functionality) and is optimized to be as small as possible. The library ships as several JAR files to provide more flexibility over which features applications require:

Smack provides two ways to read incoming packets: PacketListener, and PacketCollector. Both use PacketFilter instances to determine which packets should be processed. A packet listener is used for event style programming, while a packet collector has a result queue of packets that you can do polling and blocking operations on. So, a packet listener is useful when you want to take some action whenever a packet happens to come in, while a packet collector is useful when you want to wait for a specific packet to arrive. Packet collectors and listeners can be created using an Connection instance.

Acknowledgements

 

I would like to thank Prof. Henning Schulzrinne and Omer Boyaci for their valuable guidance throughout the project. This has been a great learning experience for me. I have had the opportunity to learn and implement some good Object Oriented design concepts during application development through Omer. He has been a very good mentor and always made time to review my progress periodically. I would also like to thank Jan Janak for helping me with configuration issues on SER and Mobicents and Victoria Beltran for her mentorship in the initial stages of the project.

 

References

1. Omer Boyaci, Victoria Beltran and Henning Schulzhrinne "Bridging communications and physical world: Sense Everything, Control Everything"  IEEE Globecom 2010 Workshop on Ubiquitous Computing and Networks.

2. Smack API's http://www.igniterealtime.org/projects/smack/index.jsp

3. Mobicents SIP Presence Server user guide http://hudson.jboss.org/hudson/job/MobicentsBooks/lastSuccessfulBuild/artifact/sip-presence/index.html

4. JAIN SIP API's http://jcp.org/en/jsr/detail?id=32

 

Appendix

 

Interface IPresenceIM

 

package edu.columbia.cs.sece.presenceAgent;

import java.util.Collection;
import org.jivesoftware.smack.packet.Presence;

public interface IPresenceIM {

/**
* This method attaches the specified seceListeners to the
* client. The appropriate methods implemented by the listener are invoked
* by the client if it is in the listening mode. Implemented for both XMPP
* and SIMPLE clients
* @param seceListeners
* - List of the listeners to be attached to the client
* @throws ConnectionIssueException
* - exception is thrown if there are any protocol or connection issues
* @author Jaya Allamsetty
*/
public void addSECEListener(SECEListener seceListener)
throws ConnectionIssueException;

/**
* This method detaches the specified seceListener from the client
* Implemented for both XMPP and SIMPLE clients
* @param seceListener - seceListener to be removed
* @throws ConnectionIssueException
* - exception is thrown if there are any protocol or connection issues
* @author Jaya Allamsetty
*/
public void removeSECEListener(SECEListener seceListener)
throws ConnectionIssueException;

/**
* This method changes the mode of the client to Listening. The appropriate
* methods implemented by the attached listeners are invoked by the client
* upon receipt of interesting events from the server or from other users
* Implemented for both XMPP and SIMPLE clients
* @author Jaya Allamsetty
*/
public void startListening();

/**
* This method changes the mode of the client to not listening. Methods of
* the attached listeners are not invoked upon receipt of interesting
* events. This is the default mode of operation for both the XMPP and SIMPLE
* clients.
* Implemented for both XMPP and SIMPLE clients
* @author Jaya Allamsetty
*/
public void stopListening();

/**
* This method sends an IM to the destination user. A single IM is sent
* depending on the implementation of the user agent client Implemented for
* both XMPP and SIMPLE clients
* @param username
* - destination user
* @param message
* - text message to be sent
* @throws ConnectionIssueException
* - exception is thrown if there are any protocol or connection issues
* @author Jaya Allamsetty
*/
public void sendMessage(String username, String message)
throws ConnectionIssueException;

/**
* This method sends an IM to a group of users This method is currently
* implemented for XMPP clients only. Implemented for only XMPP clients
*
* @param group
* - a string array of group names
* @param message
* - text message to be sent
* @throws MethodNotImplementedException
* - exception is thrown if this method is not implemented by the client
* @throws ConnectionIssueException
* - exception is thrown if there are any protocol or connection issues
* @author Jaya Allamsetty
*/
public void sendMessage(Collection<String> group, String message)
throws MethodNotImplementedException, ConnectionIssueException;

/**
* This method publishes the presence information to the server that the
* user is registered to. for XMPP - user status and mode is published to
* the users in its Roster or contact list for SIMPLE - user information is
* sent via a PUBLISH to the presence server Implemented for both XMPP and
* SIMPLE clients
*
* @param presence
* - Presence object
* @throws ConnectionIssueException
* - exception is thrown if there are any protocol or connection issues
* @throws MethodNotImplementedException
* - exception is thrown if this method is not implemented by the client
* @author Jaya Allamsetty
*/
public void setPresence(Presence presence) throws ConnectionIssueException,
MethodNotImplementedException;

/**
* This method publishes the Rich Presence information to the presence
* server using PUBLISH This method is currently implemented for SIMPLE
* client only Implemented only for SIMPLE clients
*
* @param presence
* - Rich Presence object
* @throws ConnectionIssueException
* - exception is thrown if there are any protocol or connection issues
* @throws MethodNotImplementedException
* - exception is thrown if this method is not implemented by the client
* @author Jaya Allamsetty
*/
public void setPresence(RichPresence presence)
throws ConnectionIssueException, MethodNotImplementedException;

/**
* This method retrieves the presence information of a particular user if
* the target user is in the contact list of the user on whom this method is
* invoked. This is currently implemented for XMPP clients only
* @param username
* of user whose status is to be retrieved
* @return - presence if the information is available - unavailable if the
* information is unknown or if the user is offline
* @throws MethodNotImplementedException
* - exception is thrown if this method is not implemented by the client
* @throws ConnectionIssueException
* - exception is thrown if there are any protocol or connection issues
* @author Jaya Allamsetty
*/
public Presence getPresence(String username)
throws MethodNotImplementedException, ConnectionIssueException;

/**
* This method adds the contact to the specified group For XMPP - adds an
* entry in the Roster of the user For SIMPLE - this method creates a
* ResourceList with the user as the entry, uploads the list to the XDM
* server and sends a Subscribe to the Presence Server so that the user is
* notified of any changes of state Implemented for both XMPP and SIMPLE
* clients
* @param username
* - user to be added to the group
* @param group
* - name of the group
* @throws ConnectionIssueException
* - exception is thrown if there are any protocol or connection issues
* @author Jaya Allamsetty
*/
public void addContact(String username, String group)
throws ConnectionIssueException;

/**
* This method adds a contact to the user For XMPP - adds an entry in the
* roster associated with the user
* For SIMPLE - creates a ResourceList with
* the default name, uploads the list to the XDM server and sends a
* Subscribe to the presence server so that the user is notified of changes
* of state Implemented for both XMPP and SIMPLE clients
* @param username - contact to be added
* @throws MethodNotImplementedException
* - exception is thrown if this method is not implemented by the client
* @throws ConnectionIssueException
* - exception is thrown if there are any protocol or connection issues
* @author Jaya Allamsetty
*/
public void addContact(String username)
throws MethodNotImplementedException, ConnectionIssueException;

/**
* This method retrieves the list of contacts in the roster of the user. It
* is currently implemented only for XMPP
* @return - list of the contacts in the contact list of the user
* @throws MethodNotImplementedException
* - exception is thrown if this method is not implemented by the client
* @author Jaya Allamsetty
*/
public Collection<String[]> getContacts()
throws MethodNotImplementedException;

/**
* Send a SUBSCRIBE to the user for getting the status change notifications
* Implemented for both XMPP and SIMPLE clients
* @param username
* @throws ConnectionIssueException
* - exception is thrown if there are any protocol or connection issues
* @author Jaya Allamsetty
*/
public void subscribe(String username) throws ConnectionIssueException,
MethodNotImplementedException;

/**
* This method sends a SUBSCRIBE to each of the users in the group specified
* Implemented only for SIMPLE clients
* @param group
* @throws ConnectionIssueException
* - exception is thrown if there are any protocol or connection issues
* @throws MethodNotImplementedException
* - exception is thrown if this method is not implemented by the client
* @author Jaya Allamsetty
*/
public void subscribe(Collection<String> group)
throws ConnectionIssueException, MethodNotImplementedException;

}

 

Interface SECEListener

 

package edu.columbia.cs.sece.presenceAgent;

import java.util.Collection;

public interface SECEListener {

/**
* This method defines how the message event has to be handled
* @param event
*/
public void processMessageEvent(MessageEvent event);

/**
* This method defines how a presence state change event has to be handled
* @param list of the events
*/
public void processStateChangeEvent(Collection<StateChangedEvent> list);

/**
* This method defines how a document change event has to be handled
* @param event
*/
public void processDocChangeEvent(DocChangedEvent event);

}