Driving a Cantata Media Server with WebLogic SIP Server and WebLogic Workshop
Pages: 1, 2, 3

Conferencing application

The conferencing folder contains the com.bea.appserver.conference package, which is the business logic behind the conference itself, including the call flow logic implemented by SIP servlets to accept calls joining the conference, and state control classes for managing the call flows. The class com.bea.appserver.conferencing.ConferenceManager serves as the interface point for the HTTP UI.

An event listener design pattern is utilized to trigger SIP actions from the HTTP side. When a user is disconnected, for example, a SIP INFO message containing an MSCML payload is sent to disconnect the user.

SIP dialog details are handled by the DialogHandler interface, and two implementations of the interface are provided for SIP client and SIP server. By encapsulating SIP dialog state as a finite state machine in separate business logic, the SIP servlet programming is greatly simplified. This brings back memories of the HTTP servlet world before the advent of MVC-based technologies such as Struts and JPF. In the near future one can imagine industry leaders driving extensions to JSP, Struts, and JPF to include SIP-based presentation layers. Until then, it's important to properly manage this in your SIP servlet application.

Figure 2 shows a simple object diagram for the confapp section of the application:

Figure 2
Figure 2. Object diagram of the confapp application (click the image for a full-size screen shot)

Note that SIP call flow logic is abstracted away from the business logic of managing a conference. SIP dialogs that are initiated by the UI are signaled by calling a method on the conferee, which makes a call to a DialogHandler as part of its state change logic. Likewise, SIP dialogs that are initiated by an incoming request to the com.bea.appserver.conferencing.ConferenceServlet class also go through the state mechanism implemented in the DialogHandler. By maintaining their own internal state, the DialogHandlers are able to easily implement SIP call flows.

Driving the media server

The rich features of the Snowshore IP Media Server, such as playing an announcement and controlling a conference, are driven through MSCML, an XML-based protocol delivered in the body of SIP messages. This application forms MSCML to play announcements, and to set up and tear down conferences. It also parses MSCML from the media server to collect DTMF digits that serve as conference IDs and PINs. While this application is MSCML-specific, I'll be writing further articles on how to follow with other media server standards, and how to interoperate with media servers in a more abstract, cross-platform way.

If you're under a time constraint, then the simplest and least elegant approach is to provide template XML in a Java String object for each discrete media server operation performed by the application. At run-time, the application simply performs keyword substitution in order to dynamically configure the operation:

public void announceConferee(Conferee user) {
 // Here we will not change the state of the conference
 // We will simply instruct the conference server to play the prompt
 String command = "<mediaservercontrol version="1.0">";
 command += "<request>";
 command += "<play>";
 command += "<prompt>";
 command += "<audio url="" + Conferee.baseDir + user.getRecordedName()
+ "">";
 command += "<audio url="" + Conferee.JOIN_PROMPT + "">";
 command += "</audio>";
 command += "</audio>";
 command += "</prompt>";
 command += "</play>";
 command += "</request></mediaservercontrol>";
 SipServletRequest req = dialogHandler.session.createRequest("INFO");
 try {
 req.setContent(command.getBytes(), "application/mediaservercontrol+xml");
 req.send();
 } catch (Exception e) {
 e.printStackTrace();
 }
}

As media operations get more complex and parsing MSCML messages from the media server is required, it becomes necessary to expand our toolset and to provide an abstraction layer for media server control. A good start is to use an XML binding framework such as XMLBeans, leveraging the publicly available XML schema files for the media server control language in question. In this example, MSCML is used, and the XML schema is available here. When the XML control language is encompassed in XMLBeans, more complex tasks such as parsing a SIP INFO message with an XML payload attached become manageable. This code uses the classes generated by XMLBeans to parse the DTMF digits returned from the media server to the application server:

// Now get the content
try {
 String content = new String((byte[]) req.getContent());
 // First parse the MSCML response
 MediaServerControlDocument doc =
 MediaServerControlDocument.Factory.parse(content);
 MediaServerControl control = doc.getMediaServerControl();
 ResponseType resp = control.getResponse();
 String digits = resp.getDigits();
 myState = new Connected();
 notifyListeners(DialogHandler.AUTHORIZATION_EVENT, digits);
 return myState;
} catch (Exception e) {
 e.printStackTrace();
}

Now that the XML layer is abstracted, you can create a control API for generic media server control. Stay tuned for future articles on this topic.

Pages: 1, 2, 3

Next Page ยป