/* * TSTest application * Version 1.1 8/97 * * This program may be executed as an applet or stand-alone application. * It uses Lucent's implementation of JTAPI to make a call. The application * does the following for every call made: * * 1) Create Provider object * 2) Create Address object for Calling Device * 3) Create Terminal object for Calling Device * 4) Create CallObserver object * 5) Estalish a CallObserver for the Calling Device * 6) Create a Call object * 7) Make call using the Call.connect method * 8) Change button labels according to call state ("Hang up" vs. "Make Call") * 9) When "Hang-up" is requested, drop call using Connection.disconnect() method * 10) Shutdown the provider * * The JtapiPeer object is created once upon initialization of the application. * When the option "Show Trace" is enabled, all tracing messages and events * are printed on a separate window. * * Parameters required: * Tlink Name name for PBX driver as advertised by Tserver * Jtapi Server hostname or IP address of machine running the Jtapi server * Login login as administered on the NT domain * Password password administered for login * Calling Device device that will originate the call * Called Device destination number */ import java.awt.*; import java.applet.*; import javax.telephony.*; import javax.telephony.events.*; import javax.telephony.callcontrol.*; //import symantec.itools.awt.*; public class TSTest extends Applet { void makeCallButton_Clicked( Event event ) { //create Provider before making a call login(); if ( provider != null ) { makeCall(); } else { trace.appendText( "Call may not be completed until properly logged-in\n" ); } } /* redirectButton_Clicked() * when redirect button clicked it redirects the current call connection to * 45515 */ void redirectButton_Clicked(Event event) { if (myConnection != null) { CallControlConnection ccconn = (CallControlConnection)destConnection; try { ccconn.redirect("45515"); System.out.println("Call Forwarded"); } catch (Exception e ) { System.out.println("Cannot forward " + e ); } } } void hangUpButton_Clicked(Event event) { //user wants to disconnect existing call if (myConnection != null) { hangup(); } } void cancelButton_Clicked(Event event) { stop(); trace.hide(); trace.dispose(); hide(); System.exit(0); } public void init() { super.init(); String[] services = null; String tlink = null; String user = null; String password = null; String phone = null; String destination = null; // get tlink parameter from html file tlink = getParameter("TLINK"); if (tlink != null) { tlink.toUpperCase(); System.out.println( tlink ); } // get user parameter from html file user = getParameter("USER"); // get user password from html file password = getParameter("PASSWORD"); // get calling device from html file phone = getParameter("PHONE"); // get dest parameter from html file destination = getParameter("DESTINATION"); // user interface defined here //{{INIT_CONTROLS setLayout(null); resize(368,325); setFont(new Font("Helvetica", Font.PLAIN, 11)); setBackground(new Color(12632256)); mainPanel = new java.awt.Panel(); mainPanel.setLayout(null); mainPanel.reshape(2,2,366,320); mainPanel.setFont(new Font("Helvetica", Font.PLAIN, 11)); mainPanel.setBackground(new Color(12632256)); add(mainPanel); borderPanel1 = new symantec.itools.awt.BorderPanel(); borderPanel1.setLayout(null); borderPanel1.reshape(0,0,347,164); mainPanel.add(borderPanel1); try { borderPanel1.setLabel("Tserver Information"); borderPanel1.setAlignStyle(symantec.itools.awt.BorderPanel.ALIGN_LEFT); borderPanel1.setBorderColor(new Color(16777215)); } catch (java.beans.PropertyVetoException e) {}; TserverInfoPanel = new java.awt.Panel(); TserverInfoPanel.setLayout(null); TserverInfoPanel.reshape(0,0,353,150); TserverInfoPanel.setFont(new Font("Helvetica", Font.PLAIN, 11)); TserverInfoPanel.setBackground(new Color(12632256)); borderPanel1.add(TserverInfoPanel); pwdButton = new symantec.itools.awt.LabelButton(); pwdButton.reshape(51,103,70,20); TserverInfoPanel.add(pwdButton); try { pwdButton.setText("Password:"); pwdButton.setBevelStyle(symantec.itools.awt.LabelButton.BEVEL_NONE); pwdButton.setAlignStyle(symantec.itools.awt.LabelButton.ALIGN_LEFT); } catch (java.beans.PropertyVetoException e) {}; serviceButton = new symantec.itools.awt.LabelButton(); serviceButton.reshape(53,31,69,20); TserverInfoPanel.add(serviceButton); try { serviceButton.setText("Service ID:"); serviceButton.setBevelStyle(symantec.itools.awt.LabelButton.BEVEL_NONE); serviceButton.setAlignStyle(symantec.itools.awt.LabelButton.ALIGN_LEFT); } catch (java.beans.PropertyVetoException e) {}; loginButton = new symantec.itools.awt.LabelButton(); loginButton.reshape(77,69,45,20); TserverInfoPanel.add(loginButton); try { loginButton.setText("Login:"); loginButton.setBevelStyle(symantec.itools.awt.LabelButton.BEVEL_NONE); loginButton.setAlignStyle(symantec.itools.awt.LabelButton.ALIGN_LEFT); } catch (java.beans.PropertyVetoException e) {}; serviceIDChoice = new java.awt.Choice(); serviceIDChoice.reshape(141,31,175,20); TserverInfoPanel.add(serviceIDChoice); loginTextfield = new java.awt.TextField(); loginTextfield.reshape(141,67,106,20); TserverInfoPanel.add(loginTextfield); passwordTextfield = new java.awt.TextField(); passwordTextfield.setEchoCharacter('*'); passwordTextfield.reshape(141,100,106,20); TserverInfoPanel.add(passwordTextfield); borderPanel2 = new symantec.itools.awt.BorderPanel(); borderPanel2.setLayout(null); borderPanel2.reshape(0,159,345,107); mainPanel.add(borderPanel2); try { borderPanel2.setLabel("Make Call"); borderPanel2.setAlignStyle(symantec.itools.awt.BorderPanel.ALIGN_LEFT); borderPanel2.setBorderColor(new Color(16777215)); } catch (java.beans.PropertyVetoException e) {}; MakecallInfoPanel = new java.awt.Panel(); MakecallInfoPanel.setLayout(null); MakecallInfoPanel.reshape(0,0,353,104); MakecallInfoPanel.setBackground(new Color(12632256)); borderPanel2.add(MakecallInfoPanel); callingButton = new symantec.itools.awt.LabelButton(); callingButton.reshape(74,17,43,20); callingButton.setFont(new Font("Helvetica", Font.PLAIN, 11)); MakecallInfoPanel.add(callingButton); try { callingButton.setText("From:"); callingButton.setBevelStyle(symantec.itools.awt.LabelButton.BEVEL_NONE); callingButton.setAlignStyle(symantec.itools.awt.LabelButton.ALIGN_LEFT); } catch (java.beans.PropertyVetoException e) {}; calledButton = new symantec.itools.awt.LabelButton(); calledButton.reshape(86,45,28,20); calledButton.setFont(new Font("Helvetica", Font.PLAIN, 11)); MakecallInfoPanel.add(calledButton); try { calledButton.setText("To:"); calledButton.setBevelStyle(symantec.itools.awt.LabelButton.BEVEL_NONE); calledButton.setAlignStyle(symantec.itools.awt.LabelButton.ALIGN_LEFT); } catch (java.beans.PropertyVetoException e) {}; callingExtTextfield = new java.awt.TextField(); callingExtTextfield.reshape(142,16,106,20); MakecallInfoPanel.add(callingExtTextfield); calledExtTextfield = new java.awt.TextField(); calledExtTextfield.reshape(142,46,106,20); MakecallInfoPanel.add(calledExtTextfield); tracingCheckbox = new java.awt.Checkbox("Show Tracing"); tracingCheckbox.reshape(19,280,88,20); mainPanel.add(tracingCheckbox); cancelButton = new java.awt.Button("Close"); cancelButton.reshape(140,279,60,20); mainPanel.add(cancelButton); makeCallButton = new java.awt.Button("Make Call"); makeCallButton.reshape(210,279,60,20); mainPanel.add(makeCallButton); redirectButton = new java.awt.Button("Redirect"); redirectButton.reshape(280,279,60,20); mainPanel.add(redirectButton); trace = new TraceFrame(tracingCheckbox); //}} if ( !initJtapi() ) { trace.appendText( "Error: JtapiPeer could not be created. Verify your Jtapi client install.\n\n"); return; } // get tlinks administered try { System.out.println("Get Services"); services = jtapiPeer.getServices(); System.out.println("Got Services"); } catch (PlatformException e) { trace.appendText( "JtapiPeer.getServices(): caught PlatformException\n\n" ); } //populate serviceID choice component with administered tlinks if (services != null) { for ( int i=0; i < services.length; i++ ) { System.out.println( services[i] ); serviceIDChoice.addItem( services[i] ); } } else { System.out.println("No services!"); } System.out.println("Services setup"); // Set-up defaults read in html file serviceIDChoice.select(tlink); loginTextfield.setText(user); passwordTextfield.setText(password); callingExtTextfield.setText(phone); calledExtTextfield.setText(destination); } /* * handleEvent() * This method handles button interactions. */ public boolean handleEvent(Event event) { if(event.id == Event.WINDOW_DESTROY) { cancelButton_Clicked( event ); return true; } if ( event.id == Event.ACTION_EVENT ) { if ( event.target == cancelButton ) { cancelButton_Clicked( event ); return true; } if (event.target == makeCallButton ) { if ( "Make Call".equals( makeCallButton.getLabel() ) ) { makeCallButton_Clicked(event); } else { hangUpButton_Clicked(event); } return true; } // handling redirection of call if (event.target == redirectButton ) { redirectButton_Clicked(event); return true; } if (event.target == tracingCheckbox ) { if ( ((Boolean)event.arg).booleanValue() == true ) { if ( trace == null ) { trace = new TraceFrame(tracingCheckbox); } trace.show(); } else { if ( trace != null ) { trace.hide(); } } return true; } if ( event.target == serviceButton ) { trace.appendText("ServiceID: this field represents the tlink name that represents the CTI link.\n" + "Example: LUCENT#G3_SWITCH#CSTA#MYSERVER\n\n"); return true; } if ( event.target == loginButton ) { trace.appendText("Login: this field represents the login administered in the Tserver.\n\n"); return true; } if ( event.target == pwdButton ) { trace.appendText("Password: this field represents the password for the login entered in the previous field.\n\n"); return true; } if ( event.target == callingButton ) { trace.appendText("From: this field represents the extension from which the call will be originated.\n\n"); return true; } if ( event.target == calledButton ) { trace.appendText("To: this field represents the destination number for the call.\n\n"); return true; } } else if ( event.id == Event.GOT_FOCUS ) { if ( event.target instanceof TextField) { ((TextField) event.target).selectAll(); } } else if ( event.id == Event.LOST_FOCUS ) { if ( event.target instanceof TextField) { ((TextField) event.target).select(0, 0); } } return super.handleEvent(event); } /* * keyDown() * This method handles the Return and ESC keys being pressed. */ public boolean keyDown(Event event, int key) { if ((event.id == Event.KEY_PRESS)) { switch ((char)key) { case '\n': if ( "Make Call".equals( makeCallButton.getLabel() ) ) { makeCallButton_Clicked( event ); } else { hangUpButton_Clicked( event ); } return true; case '\033': cancelButton_Clicked(event); return true; default: break; } } return false; } /* * initJtapi() * This method creates the JtapiPeer */ public boolean initJtapi() { // 1) create JtapiPeer object try { // get Lucent's implementation of the JtapiPeer object jtapiPeer = JtapiPeerFactory.getJtapiPeer( "com.lucent.jtapi.tsapi.TsapiPeer" ); } catch (JtapiPeerUnavailableException e) { trace.appendText( "JtapiPeerFactory.getJtapiPeer: caught JtapiPeerUnavailableException\n\n"); } if ( jtapiPeer == null ) { trace.appendText("Error: JtapiPeer could not be created\n\n"); return false; } else { trace.appendText("JtapiPeer created successfully\n\n"); } return true; } /* * login() * This method creates the JtapiPeer and the Provider */ public void login() { String serviceID; String login; String password; String hostname; String callingExt; String calledExt; String providerString; serviceID = serviceIDChoice.getSelectedItem(); login = loginTextfield.getText(); password = passwordTextfield.getText(); provider = null; providerString = serviceID + ";login=" + login + ";passwd=" + password + ";"; System.out.println(providerString); try { // create provider if ( jtapiPeer != null ) { System.out.println("get provider"); provider = jtapiPeer.getProvider(providerString); System.out.println("got provider"); } else { System.out.println("Error: No provider\n"); trace.appendText("Error: JtapiPeer could not be created\n\n"); return; } if (provider != null) { System.out.println("Provider Ready\n"); trace.appendText("Provider created successfully\n\n"); trace.appendText("Verifying that the provider is in service"); while (provider.getState() != Provider.IN_SERVICE) { Thread.sleep(3000); trace.appendText("."); } trace.appendText("\nProvider is in service\n\n"); } else { trace.appendText("Error: Provider could not be created\n\n"); return; } } catch (PlatformException e) { trace.appendText("JtapiPeer.createProvider(): caught PlatformException\n\n"); } catch (Exception e) { trace.appendText("JtapiPeer.createProvider(): caught PlatformException\n\n"); e.printStackTrace(); } } /* * makeCall() * This method creates Terminal, Address and Call objects. It adds a callObserver * to the originating terminal, and calls the connect() method of the Call object */ public void makeCall() { String callingExt; String calledExt; Address address = null; Call call = null; Connection[] connections = null; MyCallObserver myCallObserver; callingExt = callingExtTextfield.getText(); calledExt = calledExtTextfield.getText(); if ( provider != null ) { // create Address try { address = provider.getAddress( callingExt ); } catch (InvalidArgumentException e) { trace.appendText("Provider.getAddress(): caught InvalidArgumentException\n\n"); } catch (PlatformException e) { trace.appendText("Provider.getAddress(): caught PlatformException\n\n"); } if ( address != null ) { trace.appendText("Address " + callingExt + " created successfully\n\n"); } else { trace.appendText("Address " + callingExt + " could not be created\n\n"); return; } // create Terminal try { terminal = provider.getTerminal(callingExt); } catch (InvalidArgumentException e) { trace.appendText("Provider.getAddress(): caught InvalidArgumentException\n\n"); } catch (PlatformException e) { trace.appendText("Provider.getAddress(): caught PlatformException\n\n"); } if ( terminal != null ) { trace.appendText("Terminal " + callingExt + " created successfully\n\n"); } else { trace.appendText("Terminal " + callingExt + " could not be created\n\n"); return; } // create CallObserver myCallObserver = new MyCallObserver(this); trace.appendText("Adding callObserver to terminal\n\n"); try { // add callObserver to terminal terminal.addCallObserver( myCallObserver ); } catch (ResourceUnavailableException e) { trace.appendText ( "Terminal.addCallObserver(): caught ResourceUnavailableException\n\n" ); } catch (PlatformException e) { trace.appendText ( "Terminal.addCallObserver(): caught PlatformException\n\n" ); } try { // create Call call = provider.createCall(); } catch (InvalidStateException e) { trace.appendText("Provider.createCall(): caught InvalidStateException\n\n"); } catch (MethodNotSupportedException e) { trace.appendText("Provider.createCall(): caught MethodNotSupportedException\n\n"); } catch (ResourceUnavailableException e) { trace.appendText("Provider.createCall(): caught ResourceUnavailableException\n\n"); } catch (PlatformException e) { trace.appendText("Provider.createCall(): caught PlatformException\n\n"); } catch (PrivilegeViolationException e) { trace.appendText("Provider.createCall(): caught PrivilegeViolationException\n\n"); } if (call != null) { trace.appendText("Call created successfully\n\n"); } else { trace.appendText("Error: Call could not be created\n\n"); logout(); return; } try { // makecall by using the connect method of the Call object trace.appendText("Making Call from " + callingExt + " to " + calledExt + "...\n\n"); connections = call.connect(terminal, address, calledExt); } catch ( InvalidStateException e ) { trace.appendText ( "Call.connect: caught InvalidStateException\n\n" ); logout(); } catch ( MethodNotSupportedException e ) { trace.appendText ( "Call.connect: caught MethodNotSupportedException\n\n" ); logout(); } catch ( InvalidArgumentException e ) { trace.appendText ( "Call.connect: caught InvalidArgumentException\n\n" ); logout(); } catch ( ResourceUnavailableException e ) { trace.appendText ( "Call.connect: caught ResourceUnavailableException\n\n" ); logout(); } catch ( PlatformException e ) { trace.appendText ( "Call.connect: caught PlatformException\n\n" ); logout(); } catch ( PrivilegeViolationException e ) { trace.appendText ( "Call.connect: caught PrivilegeViolationException\n\n" ); logout(); } catch ( InvalidPartyException e ) { trace.appendText ( "Call.connect: caught InvalidPartyException\n\n" ); logout(); } // the first connection created represents the originating end of the call // the second connection created represents the destination end of the call if (connections != null) { myConnection = connections[0]; destConnection = connections[1]; } } } /* * hangup() * This method calls the disconnect() method of the Connection object * to end the call. Also, it removes the callObserver on the terminal */ public void hangup() { // drop my connection try { trace.appendText("\nDropping connection...\n\n"); if ( myConnection != null ) { myConnection.disconnect(); } } catch (PrivilegeViolationException e) { trace.appendText ( "Connection.disconnect(): caught PrivilegeViolationException\n\n" ); } catch (ResourceUnavailableException e) { trace.appendText ( "Connection.disconnect(): caught ResourceUnavailableException\n\n" ); } catch (MethodNotSupportedException e) { trace.appendText ( "Connection.disconnect(): caught MethodNotSupportedException\n\n" ); } catch (InvalidStateException e) { trace.appendText ( "Connection.disconnect(): caught InvalidStateException\n\n" ); } catch (PlatformException e) { trace.appendText ( "Connection.disconnect(): caught PlatformException\n\n" ); } } public void logout() { if (provider != null ) { if ( provider.getState() == Provider.IN_SERVICE ) { try { Thread.sleep(2000); } catch ( InterruptedException e ) { trace.appendText ( "Thread.sleep(): caught InterruptedException\n\n" ); } trace.appendText("Shutting down provider...\n\n"); try { provider.shutdown(); } catch ( PlatformException e ) { trace.appendText ( "ProviderFrame.shutdown(): caught PlatformException\n\n" ); } finally { provider = null; } } } } /* * handleConnActive() * When there is a connection active, enable the "Send DTMF" and the "Disconnect" menu * items; disable the "Make Call with UUI" menu item */ public void handleConnActive() { makeCallButton.setLabel("Hang Up"); } /* * handleConnDropped() * When a connection has gone away, disable the "Send DTMF" and the "Disconnect" menu * items; enable the "Make Call with UUI" menu item */ public void handleConnDropped() { makeCallButton.setLabel("Make Call"); } public void stop() { // before terminating application, we should shutdown provider logout(); } public static void main(String[] args) { Applet applet = new TSTest(); Frame frame = new AppletFrame("Jtapi TSTest", applet, 370, 335); } //{{DECLARE_CONTROLS java.awt.Panel mainPanel; java.awt.Panel MakecallInfoPanel; symantec.itools.awt.BorderPanel borderPanel1; symantec.itools.awt.BorderPanel borderPanel2; symantec.itools.awt.LabelButton callingButton; symantec.itools.awt.LabelButton calledButton; java.awt.TextField calledExtTextfield; java.awt.TextField callingExtTextfield; java.awt.Panel TserverInfoPanel; symantec.itools.awt.LabelButton pwdButton; symantec.itools.awt.LabelButton serviceButton; symantec.itools.awt.LabelButton loginButton; java.awt.Choice serviceIDChoice; java.awt.TextField javaServerTextfield; java.awt.TextField loginTextfield; java.awt.TextField passwordTextfield; java.awt.Checkbox tracingCheckbox; java.awt.Button cancelButton; java.awt.Button makeCallButton; java.awt.Button redirectButton; // redirect button added //}} JtapiPeer jtapiPeer; Provider provider; Connection myConnection; Connection destConnection; TraceFrame trace; Terminal terminal; } /* * Class: EventHandler * This class is the thread that handles the actions to be taken from events recevived * by our CallObserver and ou ProviderObserver. We should not be calling this functions * directly from our callbacks. */ class EventHandler extends Thread { public EventHandler ( Ev ev, Applet applet ) { super(); if ( applet instanceof TSTest ) { tstestApplet = (TSTest) applet; } event = ev; } public void run() { if ( tstestApplet != null ) { switch ( event.getID() ) { case TermConnActiveEv.ID: tstestApplet.handleConnActive(); break; case TermConnDroppedEv.ID: tstestApplet.handleConnDropped(); break; case CallObservationEndedEv.ID: tstestApplet.logout(); break; } } } TSTest tstestApplet; Ev event; } /* * MyCallObserver * This class implements the CallObserver interface. * The CallObserver interface reports all state changes on the Call object * as events. Use the events to change button labels from "Make Call" to "Hang up" * and viceversa. */ class MyCallObserver implements CallObserver { public MyCallObserver() { } public MyCallObserver( Applet _applet ) { this(); applet = _applet; if ( applet instanceof TSTest ) { msgTrace = ((TSTest) applet).trace; } } public void callChangedEvent(CallEv[] eventList) { int i =0; for ( i = 0; i < eventList.length; i++ ) { msgTrace.appendText("Received "); switch(eventList[i].getID()) { case CallActiveEv.ID: msgTrace.appendText("Call Active Event\n"); break; case CallInvalidEv.ID: msgTrace.appendText("Call Invalid Event\n"); break; case ConnAlertingEv.ID: msgTrace.appendText("Connection Alerting Event\n"); break; case ConnConnectedEv.ID: msgTrace.appendText("Connection Connected Event\n"); break; case ConnCreatedEv.ID: msgTrace.appendText("Connection Created Event\n"); break; case ConnDisconnectedEv.ID: msgTrace.appendText("Connection Disconnected Event\n"); break; case ConnFailedEv.ID: msgTrace.appendText("Connection Failed Event\n"); break; case ConnInProgressEv.ID: msgTrace.appendText("Connection In Progress Event\n"); break; case ConnUnknownEv.ID: msgTrace.appendText("Connection Unknown Event\n"); break; case TermConnActiveEv.ID: //when this event is received, it means we have a call active //on our terminal. Change label to "Hang up". msgTrace.appendText("TerminalConnection Active Event\n"); (new EventHandler ( eventList[i], applet )).start(); break; case TermConnCreatedEv.ID: msgTrace.appendText("TerminalConnection Created Event\n"); break; case TermConnDroppedEv.ID: msgTrace.appendText("TerminalConnection Dropped Event\n"); (new EventHandler ( eventList[i], applet )).start(); break; case TermConnPassiveEv.ID: msgTrace.appendText("TerminalConnection Passive Event\n"); break; case TermConnRingingEv.ID: msgTrace.appendText("TerminalConnection Ringing Event\n"); break; case TermConnUnknownEv.ID: msgTrace.appendText("TerminalConnection Unknown Event\n"); break; case CallObservationEndedEv.ID: //when call is terminated either manually or from the //app, shutdown the provider msgTrace.appendText("Call Observation Ended Event\n"); (new EventHandler ( eventList[i], applet )).start(); break; default: msgTrace.appendText("Unknown CallEv: " + eventList[i].getID() + "\n"); break; } } } TraceFrame msgTrace; Applet applet; } class TraceFrame extends Frame { public TraceFrame(java.awt.Checkbox button) { setLayout(null); addNotify(); resize(insets().left + insets().right + 330,insets().top + insets().bottom + 200); setBackground(new Color(16777215)); textAreaPanel = new java.awt.Panel(); textAreaPanel.setLayout(null); textAreaPanel.reshape(insets().left + 0,insets().top + 0,330,200); textAreaPanel.setFont(new Font("Helvetica", Font.PLAIN, 11)); add(textAreaPanel); textArea = new TextArea(); textArea.reshape(0,0,322,174); textAreaPanel.add(textArea); setTitle("Message Tracing"); move(400, 2); hide(); traceCheckbox = button; } public void paint(Graphics d) { Dimension size; textAreaPanel.resize(size()); size = size(); textArea.resize(size.width - 8, size.height - 26); return; } public synchronized void appendText(String str) { textArea.appendText(str); } public boolean handleEvent(Event event) { if (event.id == Event.WINDOW_DESTROY) { hide(); // hide the Frame dispose(); // free the system resources traceCheckbox.setState(false); return true; } return super.handleEvent(event); } java.awt.Panel textAreaPanel; java.awt.TextArea textArea; java.awt.Checkbox traceCheckbox; }