我的第一个控制CTIPort的Jtapi程序,功能是控制一个CTI Port执行外拨,实现了电话信令的控制,但还没有涉及语音传输。实现的过程中遇到并克服了如下困难:
1 在CallManager中必须正确配置CTI Port并添加End User或者Application User并与该CTI Port关联,关键的是
必须把此用户添加到CTI Enable和CTI Control of All Devices
2 Jtapi一书中的示例代码只对Call 对象添加了Observer,并没有对Address和Terminal添加Observer,Address和
Terminal对象只有添加了Observer,才能监控Address和Terminal的状态并使用Observer处理Address和Terminal的Events
3 我使用3个Condition来判断Provider、Address和Terminal是否是InService状态,并在它们添加完Observer后waitTrue(),但运行程序后没有反应,后来Debug发现程序阻塞到AddressInService这个Condition的waitTrue(),因此想到Address没有InService,而我前一个Jtapi程序控制Cisco IP Comunicator就没问题,分析感觉是CTI Port没有注册的原因,去看别人代码,发现了别人使用了register()函数来注册,于是我改写了程序,先去注册Terminal再waitTrue() AddressInService和TerminalInService
/**************************************************************************************
* Outcall.java *
**************************************************************************************/
import javax.telephony.*;
import javax.telephony.events.*;
import com.cisco.cti.util.Condition;
import com.cisco.jtapi.extensions.*;
import org.apache.log4j.Logger;
/*
* Places a telephone call from 476111 to 5551212
*/
public class Outcall implements ProviderObserver, AddressObserver,
CiscoTerminalObserver {
Condition conditionInService = new Condition();
Condition addressInService = new Condition();
Condition terminalInService = new Condition();
static Logger logger = Logger.getLogger(Outcall.class.getName());
public Outcall() {
/*
* Create a provider by first obtaining the default implementation of
* JTAPI and then the default provider of that implementation.
*/
Provider myprovider = null;
String providerName = "10.104.4.28";
String login = "gzy";
String passwd = "gzy123";
String src = null;
String dest = null;
logger.info("hi, this is a logger!");
String providerString = providerName + ";login=" + login + ";passwd="
+ passwd;
System.out.println("Opening " + providerString + ".../n");
try {
JtapiPeer peer = JtapiPeerFactory.getJtapiPeer(null);
System.out.println(peer);
myprovider = peer.getProvider(providerString);
myprovider.addObserver(this);
conditionInService.waitTrue();
} catch (Exception excp) {
System.out.println("Can’t get Provider: " + excp.toString());
System.exit(0);
}
/*
* We need to get the appropriate objects associated with the
* originating side of the telephone call. We ask the Address for a list
* of Terminals on it and arbitrarily choose one.
*/
Address origaddr = null;
Terminal term1 = null;
CiscoMediaTerminal observedTerminal = null;
try {
origaddr = myprovider.getAddress("3001");
//origaddr.addObserver(this);
// addressInService.waitTrue();
/* Just get some Terminal on this Address */
Terminal[] terminals = myprovider.getTerminals();
if (terminals == null) {
System.out.println("No Terminals on Address.");
System.exit(0);
}
for (int i = 0; i < terminals.length; i++) {
term1 = terminals[i];
try {
if (term1 instanceof CiscoMediaTerminal) {
observedTerminal = (CiscoMediaTerminal) term1;
System.out.println(term1.getName());
if (observedTerminal != null
&& observedTerminal.isRegistered() == true)
observedTerminal.unregister();
observedTerminal
.register(new CiscoMediaCapability[] { CiscoMediaCapability.G711_64K_30_MILLISECONDS });
}
} catch (Exception e) {
e.printStackTrace();
}
}
origaddr.addObserver(this);
//addressInService.waitTrue();
observedTerminal.addObserver(this);
terminalInService.waitTrue();
} catch (Exception excp) {
// Handle exceptions;
excp.printStackTrace();
}
/*
* Create the telephone call object and add an observer.
*/
Call mycall = null;
try {
mycall = myprovider.createCall();
mycall.addObserver(new MyOutCallObserver());
} catch (Exception excp) {
// Handle exceptions
excp.printStackTrace();
}
/*
* Place the telephone call.
*/
try {
System.out.println("Now,place the telephone call.");
Connection c[] = mycall.connect(observedTerminal, origaddr, "1002");
} catch (Exception excp) {
// Handle all Exceptions
excp.printStackTrace();
}
}
public static void main(String[] args) {
//PropertyConfigurator.configure("Log4j.properties");
new Outcall();
//System.out.println("Input a char to quit!");
//try {
// System.out.println(System.in.read());
//} catch (Exception e) {
//}
}
public void providerChangedEvent(ProvEv[] evenList) {
if (evenList != null) {
for (int i = 0; i < evenList.length; i++) {
if (evenList[i] instanceof ProvInServiceEv) {
conditionInService.set();
}
}
}
}
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:
System.out.println("Received " + events[i] + " for " + address.getName());
addressInService.set();
break;
case CiscoAddrOutOfServiceEv.ID:
System.out.println("Received " + events[i] + " for " + address.getName());
break;
}
}
}
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:
System.out.println("Received " + events[i] + " for "
+ terminal.getName());
terminalInService.set();
break;
case CiscoTermOutOfServiceEv.ID:
System.out.println("Received " + events[i] + " for "
+ terminal.getName());
break;
}
}
}
}
/**************************************************************************************
* MyOutCallObserver.java *
**************************************************************************************/
import javax.telephony.*;
import javax.telephony.events.*;
/*
* The MyOutCallObserver class implements the CallObserver
* interface and receives all events associated with the Call.
*/
public class MyOutCallObserver implements CallObserver {
public void callChangedEvent(CallEv[] evlist) {
for (int i = 0; i < evlist.length; i++) {
if (evlist[i] instanceof ConnEv) {
String name = null;
try {
Connection connection = ((ConnEv) evlist[i])
.getConnection();
Address addr = connection.getAddress();
name = addr.getName();
} catch (Exception excp) {
// Handle Exceptions
excp.printStackTrace();
}
String msg = "Connection to Address: " + name + " is ";
if (evlist[i].getID() == ConnAlertingEv.ID) {
System.out.println(msg + "ALERTING");
} else if (evlist[i].getID() == ConnInProgressEv.ID) {
System.out.println(msg + "INPROGRESS");
} else if (evlist[i].getID() == ConnConnectedEv.ID) {
System.out.println(msg + "CONNECTED");
} else if (evlist[i].getID() == ConnDisconnectedEv.ID) {
System.out.println(msg + "DISCONNECTED");
}
}
}
}
}