/* * IncallDTMFtransfer.java * * Copyright (c) 2004-2005 Brekeke Software, Inc. All rights reserved. * * BREKEKE JTAPI SDK Sample Program */ /******************************************************************/ /* This sample program will receive a call at a number "1234" */ /* and play an anouncement, catch DTMF, transfer the call to the */ /* DTMF number. */ /******************************************************************/ import java.util.*; import javax.telephony.*; import javax.telephony.media.*; import javax.telephony.callcontrol.*; import com.brekeke.jtapi.*; public class IncallDTMFtransfer { static Hashtable transHash = new Hashtable(); // Hashtable for saving the call transfer statuses for each call public static void main(String args[]) { Provider myprovider = null; try { JtapiPeer peer = JtapiPeerFactory.getJtapiPeer("com.brekeke.jtapi.BrPeer"); // MUST HAVE /* Set your work directory of JTAPI in the second argument */ myprovider = peer.getProvider("BrProvider; pdir=C:/JTAPI1.0/work"); /* Add this if you need to know Register is successful or not */ myprovider.addProviderListener(new IncallDTMFtransfer.MyProviderListener()); /* * Start provider and register this Provider's number (1234) to OnDO * SIP Server */ myprovider.start(); } catch (Exception excp) { System.out.println("Can't get Provider: " + excp.toString()); System.exit(0); } try { /* Choose one address from the addresses this provider has */ Terminal terminal = myprovider.getTerminal("1234"); terminal.addCallListener(new MyCallListener()); } catch (Exception excp) { System.out.println("Can't get Terminal: " + excp.toString()); System.exit(0); } } /* Listener for checking Register request result */ static class MyProviderListener implements com.brekeke.jtapi.BrProviderListener { public void eventRegistFail(BrProviderEvent event) { System.out.println("Register failed:" + event.getSourceUrl()); } public void eventRegistSuccess(BrProviderEvent event) { System.out.println("Register successful:" + event.getSourceUrl()); } public void providerInService(ProviderEvent event) { System.out.println("Provider bacame In Service"); } public void providerEventTransmissionEnded(ProviderEvent event) { } /* Not supported */ public void providerOutOfService(ProviderEvent event) { } /* Not supported */ public void providerShutdown(ProviderEvent event) { } } static class MyCallListener implements javax.telephony.TerminalConnectionListener { public void callActive(CallEvent event) { } public void callEventTransmissionEnded(CallEvent event) { } public void callInvalid(CallEvent event) { } public void multiCallMetaMergeEnded(MetaEvent event) { } /* Not supported */ public void multiCallMetaMergeStarted(MetaEvent event) { } /* Not supported */ public void multiCallMetaTransferEnded(MetaEvent event) { } /* Not supported */ public void multiCallMetaTransferStarted(MetaEvent event) { } /* Not supported */ public void singleCallMetaProgressEnded(MetaEvent event) { } /* Not supported */ public void singleCallMetaProgressStarted(MetaEvent event) { } /* Not supported */ public void singleCallMetaSnapshotEnded(MetaEvent event) { } /* Not supported */ public void singleCallMetaSnapshotStarted(MetaEvent event) { } /* Not supported */ public void connectionAlerting(ConnectionEvent event) { } public void connectionConnected(ConnectionEvent event) { Connection con = event.getConnection(); Address addr = con.getAddress(); String addr_name = addr.getName(); CallControlCall call = (CallControlCall) con.getCall(); TransferStat stat = (TransferStat) transHash.get(call); if (stat != null) { System.out.println("Status=" + stat.getStatus()); } System.out.println("Connection Connected:" + addr_name); if (addr_name.compareTo("1234") == 0) { if (stat != null) { if (stat.getStatus() <= TransferStatCode.AnsweredCall) { //If 1234 answers a call, call playCall method. try { playCall(call, false); } catch (Exception e) { System.out.println("Exception when playCall: " + e); } } } else { System.out.println("Can't find the call from transHash"); } } else { if (stat != null) { //When a phone of DTMF number receives the call, transfer String transferadd = stat.getTransferAddr(); if (transferadd != null) { if (addr_name.compareTo(transferadd) == 0) { try { stat.setStatus(TransferStatCode.Transfer); stat.setDstCall(call); CallControlCall origcall = (CallControlCall) stat.getOrigCall(); Connection connectiondst = call.getConnections()[0]; TerminalConnection[] tcs = (TerminalConnection[]) connectiondst.getTerminalConnections(); CallControlTerminalConnection tc2 = (CallControlTerminalConnection) tcs[0]; if (origcall != call) { try { origcall.setTransferController((TerminalConnection) stat.getOrigTC()); call.setTransferController(tc2); } catch (Exception excp) { System.out.println("Failed to set transfer controller:"+ excp); } System.out.println("Transfer!!!"); try { RingPlayer rp = stat.getRingPlayer(); if (rp != null) { System.out.println("Stop playing ringing sound"); rp.stop(); stat.setRingPlayer(null); } origcall.transfer(call); stat.setStatus(TransferStatCode.Transfer_done); } catch (Exception excp) { System.out.println("Failed to transfer:"+ excp); excp.printStackTrace(); try { call.drop(); origcall.drop(); } catch (Exception ex) { System.out.println("Exception when droppinng a call:"+ ex); } } } } catch (Exception ex) { ex.printStackTrace(); } } } } } } public void connectionCreated(ConnectionEvent event) { Connection con = event.getConnection(); Address addr = con.getAddress(); String addr_name = addr.getName(); System.out.println("Connection Created:" + addr_name); } public void connectionDisconnected(ConnectionEvent event) { Connection con = event.getConnection(); Address addr = con.getAddress(); String addr_name = addr.getName(); Call call = con.getCall(); System.out.println("Connection Disconnected:" + addr_name); TransferStat stat = (TransferStat) transHash.get(call); if (stat != null) { if (stat.getStatus() == TransferStatCode.Transfer_done) { transHash.remove(call); call.removeCallListener(this); } } } public void connectionFailed(ConnectionEvent event) { Connection con = event.getConnection(); Address addr = con.getAddress(); String addr_name = addr.getName(); System.out.println("Connection Failed:" + addr_name); CallControlCall call = (CallControlCall) con.getCall(); TransferStat stat = (TransferStat) transHash.get(call); if (stat == null) System.out.println("stat = null"); if (addr != null && stat != null) { System.out.println("Caller Name:" + stat.getCallerName()); System.out.println("Stat status:" + stat.getStatus()); System.out.println("call=" + call); if ((addr.getName()).compareTo(stat.getTransferAddr()) == 0) { if (stat.getStatus() == TransferStatCode.CallTransferDst) { try { CallControlCall origcall = (CallControlCall) stat.getOrigCall(); playCall(origcall, true); //Transfer retry } catch (Exception e) { e.printStackTrace(); } } if (stat.getStatus() > TransferStatCode.CallTransferDst) { if (call != null) { try { System.out.println("Disconnect original call."); CallControlCall origcall = (CallControlCall) stat.getOrigCall(); origcall.drop(); } catch (Exception e) { e.printStackTrace(); } } } } } } public void connectionInProgress(ConnectionEvent event) { } public void connectionUnknown(ConnectionEvent event) { } public void terminalConnectionActive(TerminalConnectionEvent event) { final TerminalConnection tc = event.getTerminalConnection(); Terminal term = tc.getTerminal(); System.out.println("Terminal Connection is active!! :"+ term.getName()); } public void terminalConnectionCreated(TerminalConnectionEvent event) { final TerminalConnection tc = event.getTerminalConnection(); Terminal term = tc.getTerminal(); System.out.println("Terminal Connection is created!! :" + term.getName()); } public void terminalConnectionDropped(TerminalConnectionEvent event) { TerminalConnection tc = event.getTerminalConnection(); Terminal term = tc.getTerminal(); System.out.println("Terminal Connection is dropped:" + term.getName()); Connection c = tc.getConnection(); CallControlCall call = (CallControlCall) c.getCall(); TransferStat stat = (TransferStat) transHash.get(call); if (stat == null) System.out.println("stat = null"); if (term != null && stat != null) { System.out.println("Caller Name:" + stat.getCallerName()); System.out.println("Stat status:" + stat.getStatus()); System.out.println("call=" + call); if ((term.getName()).compareTo(stat.getCallerName()) == 0 && stat.getStatus() >= TransferStatCode.CallTransferDst) { // Transfer failed and disconnect if (call != null) { try { System.out.println("Disconnect original call."); call.drop(); } catch (Exception e) { e.printStackTrace(); } } CallControlCall dstcall = (CallControlCall) stat .getDstCall(); if (dstcall != null) { try { System.out.println("Disconnect dst call."); dstcall.drop(); } catch (Exception e) { e.printStackTrace(); } } Address lastaddr = call.getLastRedirectedAddress(); if (lastaddr != null) { System.out.println("lastaddr=" + lastaddr.getName()); } } } } public void terminalConnectionPassive(TerminalConnectionEvent event) { } public void terminalConnectionRinging(TerminalConnectionEvent event) { try { final TerminalConnection tc = event.getTerminalConnection(); Terminal term = tc.getTerminal(); Call call = event.getCall(); Connection[] cons; String callerAddr = null; TransferStat stat; String transferadd; System.out.println("Terminal Connection is Ringing!! :" + term.getName()); //When 1234 receives INVITE request if (term.getName().compareTo("1234") == 0) { if (call != null) { cons = call.getConnections(); if (cons.length > 0) { for (int i = 0; i < cons.length; ++i) { callerAddr = cons[i].getAddress().getName(); if (callerAddr.compareTo("1234") != 0) break; } } } stat = new TransferStat(call, TransferStatCode.CallReceived); System.out.println("callerAddress=" + callerAddr); stat.setCallerName(callerAddr); System.out.println("Call while ringing:" + call); transHash.put(call, stat); stat.setOrigTC((CallControlTerminalConnection) tc); Runnable r = new Runnable() { public void run() { try { tc.answer(); // Answer the call } catch (Exception excp) { System.out.println("Failed to answer:" + excp); excp.printStackTrace(); } }; }; Thread T = new Thread(r); T.start(); } else { stat = (TransferStat) transHash.get(call); if ((stat != null) && ((transferadd = stat.getTransferAddr()) != null)) { // Ringing the transfer destination if (term.getName().compareTo(transferadd) == 0) { try { System.out.println("Start playing ringing sound to the caller"); RingPlayer rp = new RingPlayer(stat.getOrigCall()); rp.start(); stat.setRingPlayer(rp); } catch (Exception e) { System.out.println("Exception when playRinging: " + e); } } } } } catch (Exception excp) { System.out.println("Failed in terminalConnectionRinging"); } } public void terminalConnectionUnknown(TerminalConnectionEvent event) { } } /** * Play an anouncement, receive DTMF, call the DTMF number ** */ static void playCall(Call call, boolean retry) throws Exception { new Thread(new CallPlayer(call, retry)).start(); } static class CallPlayer extends BasicMediaService implements Runnable { static RTC[] promptRTC = { RTC.SigDet_StopPlay }; CallControlCall call = null; TransferStat transstat; boolean retry = false; CallPlayer(Call call, boolean retry) { super((MediaProvider) call.getProvider()); this.call = (CallControlCall) call; this.retry = retry; } public void run() { try { bindToCall(ConfigSpec.basicConfig, call); PlayerEvent playev = null; if (call != null) { transstat = (TransferStat) transHash.get(call); transstat.setStatus(TransferStatCode.Announce); if (retry == false) // Play greeting playev = play("/sound/exgreeting.ul", 4, promptRTC, null); else // Play retry message playev = play("/sound/exreentering.ul", 4, promptRTC, null); if (playev.getQualifier().equals(MediaConstants.q_Standard) || playev.getQualifier().equals( MediaConstants.q_Stop)) { transstat.setStatus(TransferStatCode.AnnouncePlayed); System.out.println("call=" + call); System.out.println("status=" + ((TransferStat) transHash.get(call)).getStatus()); SignalDetectorEvent sdev = null; while (true) { if (call != null) { try { transstat.setStatus(TransferStatCode.DTMFwait); //Get DTMF signals (MAX 5 signals). If // caller push #, DTMF detect will be // stopped. sdev = retrieveSignals(5, null, null, null); } catch (Exception ex) { System.out.println("Failed to retrieve signals 1:" + ex); System.exit(0); } } try { if (sdev.getQualifier().equals( SignalDetectorConstants.q_NumSignals)) { String sdtmf = sdev.getSignalString(); System.out.println("Detected DTMF =" + sdtmf); transstat.setTransferAddr(sdtmf); transstat.setStatus(TransferStatCode.DTMFreceived); playev = null; // Play the number pushed for (int i = 0; i < sdtmf.length(); ++i) { if (playev == null || playev.getQualifier().equals( MediaConstants.q_Standard)) playev = play("/sound/char/" + sdtmf.charAt(i) + ".ul", 4, null, null); else break; } if (playev.getQualifier().equals( MediaConstants.q_Standard)) { //Make a call from 1234 to the pushed // DTMF number Provider myProvider = call.getProvider(); final Call outcall = myProvider.createCall(); outcall.addCallListener(call.getCallListeners()[0]); final Address origaddr = myProvider.getAddress("1234"); Terminal[] terminals = origaddr.getTerminals(); final Terminal origterm = terminals[0]; transstat.setDstCall(outcall); System.out.println("Status=" + transstat.getStatus()); transHash.put(outcall, transstat); transstat.setStatus(TransferStatCode.CallTransferDst); Connection c[] = outcall.connect(origterm, origaddr, sdtmf); break; } } else { // If failed to receive DTMF playev = play("/sound/exreentering.ul", 4, promptRTC, null); if (playev.getQualifier().equals( MediaConstants.q_Standard) == false) { break; } // loop to try again. } } catch (Exception ex) { ex.printStackTrace(); System.out .println("Failed to retrieve signals 2:" + ex); } } } if (isBound()) try { release(); } catch (Exception ex3) { } } } catch (Exception ex) { System.err.println(ex); } } } } /* * RingPlayer.java * * Copyright (c) 2004-2005 Brekeke Software, Inc. All rights reserved. * * BREKEKE JTAPI SDK Sample Program */ import javax.telephony.Call; import javax.telephony.callcontrol.CallControlCall; import javax.telephony.media.*; /*** Plays Ringback tone to a caller while this application is ***/ /** * calling the transfer destination. ** */ public class RingPlayer extends BasicMediaService implements Runnable { CallControlCall call = null; volatile Thread thread; RingPlayer(Call call) { super((MediaProvider) call.getProvider()); this.call = (CallControlCall) call; } public void start() { thread = new Thread(this); thread.start(); } public void run() { Thread thisThread = Thread.currentThread(); try { bindToCall(ConfigSpec.basicConfig, call); PlayerEvent playev = null; while (thread == thisThread) { if (call != null) { playev = play("/sound/ring.ul", 4, null, null); if (playev.getQualifier().equals(MediaConstants.q_Standard)) { continue; } else { break; } } } if (isBound()) try { release(); } catch (Exception ex3) { } } catch (Exception ex) { System.err.println(ex); } } public void stop() { thread = null; } } /* * TransferStatCode.java * * Copyright (c) 2004-2005 Brekeke Software, Inc. All rights reserved. * * BREKEKE JTAPI SDK Sample Program */ /** Parameters of the transfer status**/ public class TransferStatCode{ public static final int CallReceived = 1; public static final int AnsweredCall = 2; public static final int Announce = 3; public static final int AnnouncePlayed = 4; public static final int DTMFwait = 5; public static final int DTMFreceived = 6; public static final int CallTransferDst = 7; public static final int TransferDstAnswered = 8; public static final int Transfer = 9; public static final int Transfer_done = 10; } /* * TransferStat.java * * Copyright (c) 2004-2005 Brekeke Software, Inc. All rights reserved. * * BREKEKE JTAPI SDK Sample Program */ /** This is for storing the transfer status of each call **/ import javax.telephony.*; import javax.telephony.callcontrol.*; public class TransferStat { private Call origcall; // Originator's call private CallControlTerminalConnection origtc; //Originator's terminal connction private int status; // Status private Call dstcall; // Call of Transfer destination private String transferadd; // Transfer destination's name (number) private RingPlayer rp; // RingPlayer for ringback tone private String callername; // Caller's name (number) public TransferStat(Call origcall, int stat){ this.origcall = origcall; this.status = stat; } public void setCallerName(String name){ callername = name; } public String getCallerName(){ return callername; } public void setOrigCall(Call origcall){ this.origcall = origcall; } public Call getOrigCall(){ return origcall; } public void setOrigTC(CallControlTerminalConnection tc){ this.origtc = tc; } public CallControlTerminalConnection getOrigTC(){ return origtc; } public void setStatus(int status){ this.status = status; } public int getStatus(){ return status; } public void setDstCall(Call dstcall){ this.dstcall = dstcall; } public Call getDstCall(){ return dstcall; } public void setTransferAddr(String addr){ this.transferadd = addr; } public String getTransferAddr(){ return transferadd; } public void setRingPlayer(RingPlayer rp){ this.rp = rp; } public RingPlayer getRingPlayer(){ return rp; } }