Table Of Contents
Cisco Unified JTAPI Examples
MakeCall.java
Actor.java
Originator.java
Receiver.java
StopSignal.java
Trace.java
TraceWindow.java
Running makecall
Cisco Unified JTAPI Examples
This chapter provides the source code for makecall, the Cisco Unified JTAPI program that is used to test the JTAPI installation. The makecall program comprises a series of programs that were written in Java by using the Cisco Unified JTAPI implementation.
This chapter contains the following sections:
•
MakeCall.java
•
Actor.java
•
Originator.java
•
Receiver.java
•
StopSignal.java
•
Trace.java
•
TraceWindow.java
This chapter also provides instructions on how to invoke makecall:
•
Running makecall
MakeCall.java
* Copyright Cisco Systems, Inc.
* Performance-testing application (first pass) for Cisco JTAPI
* Due to synchronization problems between Actors, calls may
* not be cleared when this application shuts down.
//import com.ms.wfc.app.*;
import javax.telephony.*;
import javax.telephony.events.*;
import com.cisco.cti.util.Condition;
public class makecall extends TraceWindow implements ProviderObserver
Vector actors = new Vector ();
Condition conditionInService = new Condition ();
public makecall ( String [] args ) {
super ( "makecall" + ": "+ new CiscoJtapiVersion());
println ( "Initializing Jtapi" );
String providerName = args[curArg++];
String login = args[curArg++];
String passwd = args[curArg++];
int actionDelayMillis = Integer.parseInt ( args[curArg++] );
JtapiPeer peer = JtapiPeerFactory.getJtapiPeer ( null );
if ( curArg < args.length ) {
String providerString = providerName + ";login=" + login + ";passwd=" + passwd;
println ( "Opening " + providerString + "...\n" );
provider = peer.getProvider ( providerString );
provider.addObserver ( this );
conditionInService.waitTrue ();
println ( "Constructing actors" );
for ( ; curArg < args.length; curArg++ ) {
Originator originator = new Originator ( provider.getAddress ( src ), dest, this,
actionDelayMillis );
actors.addElement ( originator );
new Receiver ( provider.getAddress ( dest ), this, actionDelayMillis, originator )
println ( "Skipping last originating address \"" + src + "\"; no destination specified" );
Enumeration e = actors.elements ();
while ( e.hasMoreElements () ) {
Actor actor = (Actor) e.nextElement ();
Enumeration en = actors.elements ();
while ( en.hasMoreElements () ) {
Actor actor = (Actor) en.nextElement ();
println ( "Caught exception " + e );
println ( "Stopping actors" );
Enumeration e = actors.elements ();
while ( e.hasMoreElements () ) {
Actor actor = (Actor) e.nextElement ();
public static void main ( String [] args )
System.out.println ( "Usage: makecall <server> <login> <password> <delay> <origin> <destination>
..." );
public void providerChangedEvent ( ProvEv [] eventList ) {
if ( eventList != null ) {
for ( int i = 0; i < eventList.length; i++ )
if ( eventList[i] instanceof ProvInServiceEv ) {
conditionInService.set ();
Actor.java
* Copyright Cisco Systems, Inc.
import javax.telephony.*;
import javax.telephony.events.*;
import javax.telephony.callcontrol.*;
import javax.telephony.callcontrol.events.*;
import com.cisco.jtapi.extensions.*;
public abstract class Actor implements AddressObserver, TerminalObserver, CallControlCallObserver, Trace
public static final int ACTOR_OUT_OF_SERVICE = 0;
public static final int ACTOR_IN_SERVICE =1;
protected int actionDelayMillis;
private Address observedAddress;
private Terminal observedTerminal;
private boolean addressInService;
private boolean terminalInService;
protected int state = Actor.ACTOR_OUT_OF_SERVICE;
public Actor ( Trace trace, Address observed, int actionDelayMillis ) {
this.observedAddress = observed;
this.observedTerminal = observed.getTerminals ()[0];
this.actionDelayMillis = actionDelayMillis;
public void initialize () {
if ( observedAddress != null ) {
"Adding Call observer to address "
+ observedAddress.getName ()
observedAddress.addCallObserver ( this );
//Now add observer on Address and Terminal
"Adding Adddress Observer to address "
+ observedAddress.getName ()
observedAddress.addObserver ( this );
"Adding Terminal Observer to Terminal"
+ observedTerminal.getName ()
observedTerminal.addObserver ( this );
public final void start () {
public final void dispose () {
if ( observedAddress != null ) {
"Removing observer from Address "
+ observedAddress.getName ()
observedAddress.removeObserver ( this );
"Removing call observer from Address "
+ observedAddress.getName ()
observedAddress.removeCallObserver ( this );
if ( observedTerminal != null ){
"Removing observer from terminal "
+ observedTerminal.getName ()
observedTerminal.removeObserver ( this );
println ( "Caught exception " + e );
public final void stop () {
public final void callChangedEvent ( CallEv [] events ) {
// for now, all metaevents are delivered in the
public void addressChangedEvent ( AddrEv [] events ) {
for ( int i=0; i<events.length; i++ ) {
Address address = events[i].getAddress ();
switch ( events[i].getID () ) {
case CiscoAddrInServiceEv.ID:
bufPrintln ( "Received " + events[i] + "for "+ address.getName ());
if ( terminalInService ) {
if ( state != Actor.ACTOR_IN_SERVICE ) {
state = Actor.ACTOR_IN_SERVICE ;
case CiscoAddrOutOfServiceEv.ID:
bufPrintln ( "Received " + events[i] + "for "+ address.getName ());
addressInService = false;
if ( state != Actor.ACTOR_OUT_OF_SERVICE ) {
state = Actor.ACTOR_OUT_OF_SERVICE; // you only want to notify when you had notified
earlier that you are IN_SERVICE
public void terminalChangedEvent ( TermEv [] events ) {
for ( int i=0; i<events.length; i++ ) {
Terminal terminal = events[i].getTerminal ();
switch ( events[i].getID () ) {
case CiscoTermInServiceEv.ID:
bufPrintln ( "Received " + events[i] + "for " + terminal.getName ());
terminalInService = true;
if ( addressInService ) {
if ( state != Actor.ACTOR_IN_SERVICE ) {
state = Actor.ACTOR_IN_SERVICE;
case CiscoTermOutOfServiceEv.ID:
bufPrintln ( "Received " + events[i] + "for " + terminal.getName () );
terminalInService = false;
if ( state != Actor.ACTOR_OUT_OF_SERVICE ) { // you only want to notify when you had
notified earlier that you are IN_SERVICE
state = Actor.ACTOR_OUT_OF_SERVICE;
final void delay ( String action ) {
if ( actionDelayMillis != 0 ) {
println ( "Pausing " + actionDelayMillis + " milliseconds before " + action );
Thread.sleep ( actionDelayMillis );
catch ( InterruptedException e ) {}
protected abstract void metaEvent ( CallEv [] events );
protected abstract void onStart ();
protected abstract void onStop ();
protected abstract void fireStateChanged ();
public final void bufPrint ( String string ) {
trace.bufPrint ( string );
public final void bufPrintln ( String string ) {
trace.bufPrint ( string );
public final void print ( String string ) {
public final void print ( char character ) {
trace.print ( character );
public final void print ( int integer ) {
public final void println ( String string ) {
trace.println ( string );
public final void println ( char character ) {
trace.println ( character );
public final void println ( int integer ) {
trace.println ( integer );
public final void flush () {
Originator.java
* Copyright Cisco Systems, Inc.
import javax.telephony.*;
import javax.telephony.events.*;
import javax.telephony.callcontrol.*;
import javax.telephony.callcontrol.events.*;
import com.cisco.jtapi.extensions.*;
public class Originator extends Actor
int receiverState = Actor.ACTOR_OUT_OF_SERVICE;
boolean callInIdle = true;
public Originator ( Address srcAddress, String destAddress, Trace trace, int actionDelayMillis ) {
super ( trace, srcAddress, actionDelayMillis ); // observe srcAddress
this.srcAddress = srcAddress;
this.destAddress = destAddress;
protected final void metaEvent ( CallEv [] eventList ) {
for ( int i = 0; i < eventList.length; i++ ) {
CallEv curEv = eventList[i];
if ( curEv instanceof CallCtlTermConnTalkingEv ) {
TerminalConnection tc = ((CallCtlTermConnTalkingEv)curEv).getTerminalConnection ();
Connection conn = tc.getConnection ();
if ( conn.getAddress ().getName ().equals ( destAddress ) ) {
delay ( "disconnecting" );
bufPrintln ( "Disconnecting Connection " + conn );
else if ( curEv instanceof CallCtlConnDisconnectedEv ) {
Connection conn = ((CallCtlConnDisconnectedEv)curEv).getConnection ();
if ( conn.getAddress ().equals ( srcAddress ) ) {
setCallProgressState ( true );
println ( "Caught exception " + e );
protected void makecall ()
throws ResourceUnavailableException, InvalidStateException,
PrivilegeViolationException, MethodNotSupportedException,
InvalidPartyException, InvalidArgumentException {
println ( "Making call #" + ++iteration + " from " + srcAddress + " to " + destAddress + " " +
Thread.currentThread ().getName () );
Call call = srcAddress.getProvider ().createCall ();
call.connect ( srcAddress.getTerminals ()[0], srcAddress, destAddress );
setCallProgressState ( false );
println ( "Done making call" );
protected final void onStart () {
stopSignal = new StopSignal ();
new ActionThread ().start ();
protected final void fireStateChanged () {
protected final void onStop () {
Connection[] connections = srcAddress.getConnections ();
if ( connections != null ) {
for (int i=0; i< connections.length; i++ ) {
connections[i].disconnect ();
println (" Caught Exception " + e);
public int getReceiverState () {
public void setReceiverState ( int state ) {
if ( receiverState != state ){
public synchronized void checkReadyState () {
if ( receiverState == Actor.ACTOR_IN_SERVICE && state == Actor.ACTOR_IN_SERVICE ) {
public synchronized void setCallProgressState ( boolean isCallInIdle ) {
callInIdle = isCallInIdle;
public synchronized void doAction () {
if ( !ready || !callInIdle ) {
println (" Caught Exception from wait state" + e );
if ( actionDelayMillis != 0 ) {
println ( "Pausing " + actionDelayMillis + " milliseconds before making call " );
wait ( actionDelayMillis );
catch ( Exception ex ) {}
//make call after waking up, recheck the flags before making the call
if ( ready && callInIdle ) {
println (" Caught Exception in MakeCall " + e + " Thread =" + Thread.currentThread
().getName ());
class ActionThread extends Thread {
Receiver.java
* Copyright Cisco Systems, Inc.
import javax.telephony.*;
import javax.telephony.events.*;
import javax.telephony.callcontrol.*;
import javax.telephony.callcontrol.events.*;
public class Receiver extends Actor
public Receiver ( Address address, Trace trace, int actionDelayMillis, Originator originator ) {
super ( trace, address, actionDelayMillis );
this.originator = originator;
protected final void metaEvent ( CallEv [] eventList ) {
for ( int i = 0; i < eventList.length; i++ ) {
TerminalConnection tc = null;
CallEv curEv = eventList[i];
if ( curEv instanceof CallCtlTermConnRingingEv ) {
tc = ((CallCtlTermConnRingingEv)curEv).getTerminalConnection ();
bufPrintln ( "Answering TerminalConnection " + tc );
bufPrintln ( "Caught exception " + e );
bufPrintln ( "tc = " + tc );
protected final void onStart () {
stopSignal = new StopSignal ();
protected final void onStop () {
Connection[] connections = address.getConnections ();
if ( connections != null ) {
for (int i=0; i< connections.length; i++ ) {
connections[i].disconnect ();
println (" Caught Exception " + e);
protected final void fireStateChanged () {
originator.setReceiverState ( state );
StopSignal.java
* Copyright Cisco Systems, Inc.
boolean stopping = false;
synchronized boolean isStopped () {
synchronized boolean isStopping () {
synchronized void stop () {
catch ( InterruptedException e ) {}
synchronized void canStop () {
Trace.java
* Copyright Cisco Systems, Inc.
* bufPrint (str) puts str in buffer only.
public void bufPrint ( String string );
* print () println () bufPrint and invoke flush ();
public void print ( String string );
public void print ( char character );
public void print ( int integer );
public void println ( String string );
public void println ( char character );
public void println ( int integer );
TraceWindow.java
* Copyright Cisco Systems, Inc.
public class TraceWindow extends Frame implements Trace
boolean traceEnabled = true;
StringBuffer buffer = new StringBuffer ();
public TraceWindow (String name ) {
private void initWindow() {
this.addWindowListener(new WindowAdapter () {
public void windowClosing(WindowEvent e){
textArea = new TextArea();
public final void bufPrint ( String str ) {
public final void print ( String str ) {
public final void print ( char character ) {
buffer.append ( character );
public final void print ( int integer ) {
buffer.append ( integer );
public final void println ( String str ) {
public final void println ( char character ) {
public final void println ( int integer ) {
public final void setTrace ( boolean traceEnabled ) {
this.traceEnabled = traceEnabled;
public final void flush () {
textArea.append ( buffer.toString());
buffer = new StringBuffer ();
public final void clear () {
Running makecall
To Invoke makecall on the client workstation, from the Windows NT command line, navigate to the makecall directory where JTAPI Tools directory was installed and execute the following command:
jview makecall <server name> <login> <password> 1000 <device 1> <device2>
<server name> specifies the hostname or IP address of your Cisco Unified Communications Manager and <device1> <device2> are directory numbers of IP phones. Make sure that the phones are part of the associated devices of a given user as administered in the Cisco Unified Communications Manager's directory administration. The <logic> and <password> apply similarly as administered in the directory. This will test that you have installed and configured everything correctly. The application will make calls between the two devices with an action delay of 1000 msecs until terminated.