📄 xtapiprovider.java
字号:
* <li><B>XtapiSp</B> The name of the IXTapi implementation class, or a known alias.
* </ul>
* @see CoreTpi#initialize(Map)
*/
public void initialize(Map props) throws ProviderUnavailableException {
// see if the propery is set
String xtapiProvName = TAPI_SP;
Object value = props.get(IXTAPI_KEY);
if (value instanceof String && value != null) {
xtapiProvName = (String)value;
}
// now check if we should use an alias
if (xtapiProvName.toLowerCase().equals("tapi"))
xtapiProvName = TAPI_SP;
else if (xtapiProvName.toLowerCase().equals("serial"))
xtapiProvName = COMM_SP;
// try to instantiate xtapi provider
try {
realProvider = (IXTapi)Class.forName(xtapiProvName).newInstance();
} catch (Exception ex) {
throw new ProviderUnavailableException(ex.getMessage());
}
// Now hook it up and get the number of lines
numLines = realProvider.XTinit(this);
// populate the Address and Terminal information
for (int i = 0; i < numLines; i++) {
// Get Address information for each line
StringBuffer termName = new StringBuffer();
try {
int handle = realProvider.XTOpenLine(i, termName);
// populate the Address and Terminal information
/*
* If TAPI does not store line information for
* several lines, then we have multiple "" terminals
* that cause incorrect terminal-address mapping.
* The solution is to prepend the terminal name
* with its line number.
*/
String term = ADDR_PREFIX + i + ":" + termName.toString();
AddressInfo addInfo = new AddressInfo(i, term, handle);
this.addInfoMap.put(ADDR_PREFIX + i, addInfo);
this.termToAddr.put(term, addInfo);
this.lineToAddr.put(new Integer(handle), addInfo);
} catch (InvalidStateException ise) {
// try the next line
} catch (ResourceUnavailableException rue) {
// try the next line
}
}
}
/**
* The GJTAPI Framework is done with the Call and is releasing the CallId.
* @see CoreTpi#releaseCallId(CallId)
*/
public void releaseCallId(CallId id) {
try {
this.realProvider.XTDropCall(((XtapiCallId)id).getCallNum());
} catch (ResourceUnavailableException rue) {
// ignore
} catch (InvalidStateException ise) {
// ignore
}
}
/**
* I don't really need to do this, but it is here for completeness
* @see CoreTpi#removeListener(TelephonyListener)
*/
public void removeListener(TelephonyListener ro) {
if (this.gjListener.equals(ro))
this.gjListener = null;
}
/**
* Get a CallId object for later connection.
* The address parameter is ignoted.
* @see CoreTpi#reserveCallId(String)
*/
public CallId reserveCallId(String address) throws InvalidArgumentException {
return new XtapiCallId();
}
/**
* @see CoreTpi#shutdown()
*/
public void shutdown() {
try {
this.realProvider.XTShutdown();
} catch (InvalidStateException ise) {
// ignore
}
}
// Media calls
/**
* Allocate media resources.
* This is a NO-OP, since XTAPI doesn't need this.
* @see MediaTpi#allocateMedia(String, int, Dictionary)
*/
public boolean allocateMedia(
String terminal,
int type,
Dictionary resourceArgs) {
return true;
}
/**
* Free media resources.
* @see MediaTpi#freeMedia(String, int)
*/
public boolean freeMedia(String terminal, int type) {
// clear out the digit bucket for the terminal.
this.retrieveSignals(terminal);
return true;
}
/**
* All known terminals support media
* @see MediaTpi#isMediaTerminal(String)
*/
public boolean isMediaTerminal(String terminal) {
if (this.termToAddr.containsKey(terminal))
return true;
return false;
}
/**
* @see MediaTpi#play(String, String[], int, RTC[], Dictionary)
*/
public void play(
String terminal,
String[] streamIds,
int offset,
RTC[] rtcs,
Dictionary optArgs)
throws MediaResourceException {
// look up the id for the terminal
int id = this.getLineId(terminal);
int size = streamIds.length;
try {
// play each id on the found line
for (int i = 0; i < size; i++)
this.realProvider.XTPlaySound(streamIds[i], id);
} catch (InvalidStateException ise) {
throw new MediaResourceException(ise.toString());
} catch (MethodNotSupportedException mnse) {
throw new MediaResourceException(mnse.toString());
} catch (ResourceUnavailableException rue) {
throw new MediaResourceException(rue.toString());
}
}
/**
* @see MediaTpi#record(String, String, RTC[], Dictionary)
*/
public void record(
String terminal,
String streamId,
RTC[] rtcs,
Dictionary optArgs)
throws MediaResourceException {
try {
// look up the id for the terminal
int id = this.getLineId(terminal);
this.realProvider.XTRecordSound(streamId, id);
} catch (InvalidStateException ise) {
throw new MediaResourceException(ise.toString());
} catch (MethodNotSupportedException mnse) {
throw new MediaResourceException(mnse.toString());
} catch (ResourceUnavailableException rue) {
throw new MediaResourceException(rue.toString());
}
}
/**
* @see MediaTpi#retrieveSignals(String, int, Symbol[], RTC[], Dictionary)
*/
public RawSigDetectEvent retrieveSignals(
String terminal,
int num,
Symbol[] patterns,
RTC[] rtcs,
Dictionary optArgs)
throws MediaResourceException {
// look up the id for the terminal
int id = this.getCallId(terminal);
try {
this.realProvider.XTMonitorDigits(id, true);
} catch (InvalidStateException ise) {
throw new MediaResourceException(ise.toString());
} catch (MethodNotSupportedException mnse) {
throw new MediaResourceException(mnse.toString());
} catch (ResourceUnavailableException rue) {
throw new MediaResourceException(rue.toString());
}
// wait for signals to come in
//---------------------------------------------------------------------------
// Get the local p_Duration (if any).
//---------------------------------------------------------------------------
Object timeoutVal = null;
if (optArgs != null) {
timeoutVal = optArgs.get(SignalDetectorConstants.p_Duration);
}
boolean timed = (timeoutVal != null);
int timeout = (timed ? ((Integer) timeoutVal).intValue() : 0);
int timeSoFar = 0;
StringBuffer sb = this.getSignalBuffer(terminal);
synchronized (sb) {
if (sb.length() >= num) {
return RawSigDetectEvent.maxDetected(terminal, SymbolConvertor.convert(sb.toString()));
} else {
// should add support for timeout as well
while ((sb.length() < num) &&
((!timed) || (timeSoFar < timeout))) {
try {
sb.wait(100); // wait until another signal comes in
} catch (InterruptedException ie) {
// keep going...
}
timeSoFar += 100;
}
if (sb.length() >= num) {
return RawSigDetectEvent.maxDetected(terminal, SymbolConvertor.convert(sb.toString()));
} else {
return RawSigDetectEvent.timeout(terminal, SymbolConvertor.convert(sb.toString()));
}
}
}
}
/**
* This should wait until the signals have all been sent.
* @see MediaTpi#sendSignals(String, Symbol[], RTC[], Dictionary)
*/
public void sendSignals(
String terminal,
Symbol[] syms,
RTC[] rtcs,
Dictionary optArgs)
throws MediaResourceException {
// look up the id for the terminal
int id = this.getCallId(terminal);
try {
this.realProvider.XTSendDigits(id, SymbolConvertor.convert(syms));
} catch (InvalidStateException ise) {
throw new MediaResourceException(ise.toString());
} catch (MethodNotSupportedException mnse) {
throw new MediaResourceException(mnse.toString());
} catch (ResourceUnavailableException rue) {
throw new MediaResourceException(rue.toString());
}
}
/**
* @see MediaTpi#stop(String)
*/
public void stop(String terminal) {
// look up the id for the terminal
int id = this.getLineId(terminal);
this.realProvider.XTStopPlaying(id);
this.realProvider.XTStopRecording(id);
int callId = this.getCallId(terminal);
try {
this.realProvider.XTMonitorDigits(callId, false);
} catch (InvalidStateException ise) {
// ignore
} catch (MethodNotSupportedException mnse) {
// ignore
} catch (ResourceUnavailableException rue) {
// ignore
}
}
/**
* RTCs are not supported by XTAPI, but we do support stopping
* @see MediaTpi#triggerRTC(String, Symbol)
*/
public void triggerRTC(String terminal, Symbol action) {
// look up the id for the terminal
int id = this.getCallId(terminal);
if (action.equals(PlayerConstants.rtca_Stop))
this.realProvider.XTStopPlaying(id);
if (action.equals(RecorderConstants.rtca_Stop))
this.realProvider.XTStopRecording(id);
if (action.equals(SignalDetectorConstants.rtca_Stop)) {
int callId = this.getCallId(terminal);
try {
this.realProvider.XTMonitorDigits(callId, false);
} catch (InvalidStateException ise) {
// we tried to stop it...
} catch (MethodNotSupportedException mnse) {
// ignore
} catch (ResourceUnavailableException rue) {
// ignore
}
}
}
// Callback interface
/**
* Receive the XTAPI service provider callback events and transform them
* into JTAPI TelephonyListener events.
* The delegation method also stores transformation information that is needed
* for other delegation methods, such as media action termination.
* @see IXTapiCallBack#callback(int, int, int, int, int, int)
*/
public void callback(
int dwDevice,
int dwMessage,
int dwInstance,
int dwParam1,
int dwParam2,
int dwParam3) {
try {
switch (dwMessage) {
case LINE_ADDRESSSTATE:
break;
case LINE_CALLINFO:
try {
// we don't have a callId yet, so we store the remote
// name and number until we get an OFFERING event
String[] s = this.realProvider.XTGetCallInfo(dwDevice);
if(null != s) {
// We got caller id info
// An array of two strings 1. Name 2. Number
// Set the remote terminal name == name
// Set the remote address name == number
this.remoteName = s[0];
this.remoteNumber = s[1];
}
} catch(Exception e) {
System.out.println("Exception " + e.toString() + " in callback()");
}
break;
case LINE_CALLSTATE:
lineCallState(dwDevice,dwInstance,dwParam1,dwParam2,dwParam3);
break;
case LINE_CLOSE:
break;
case LINE_DEVSPECIFIC:
break;
case LINE_DEVSPECIFICFEATURE:
break;
case LINE_GATHERDIGITS:
break;
case LINE_GENERATE:
/*
* We have been notified that we have generated digits. But we should already know this.
*/
break;
case LINE_MONITORDIGITS:
/*
debugString(5,"dwDevice -> " + dwDevice + " dwInstance -> " + dwInstance +
" dwParam1 -> " + dwParam1 + " dwParam2 -> " + dwParam2 +
" dwParam3 -> " + dwParam3);
*/
//System.out.println("Monitoring digits");
//System.out.println("dwDevice -> " + dwDevice + " dwInstance (line) -> " + dwInstance +
//" dwParam1 -> " + dwParam1 + " dwParam2 -> " + dwParam2 +
//" dwParam3 -> " + dwParam3);
XtapiCallId cid = (XtapiCallId)this.callNumToCalls.get(new Integer(dwDevice));
String address = null;
AddressInfo ai = null;
if (cid != null) {
address = cid.getLocalAddress();
}
if (address != null)
ai = (AddressInfo)this.addInfoMap.get(address);
//(AddressInfo)this.lineToAddr.get(new Integer(dwInstance));
if (ai != null) {
String terminal = ai.terminal;
char[] detectedChars = { (char)dwParam1 };
Symbol[] syms = SymbolConvertor.convert(new String(detectedChars));
this.gjListener.mediaSignalDetectorDetected(terminal, syms);
// now drop the digits into the digit bucket
this.storeSignals(terminal, detectedChars);
}
break;
case LINE_LINEDEVSTATE:
lineDevState(dwDevice,dwInstance,dwParam1,dwParam2,dwParam3);
break;
case LINE_MONITORMEDIA:
break;
case LINE_MONITORTONE:
break;
case LINE_REPLY:
//m_reply = dwParam2;
//m_device = dwInstance;
/*
TODO: Check LINE_REPLY Data for success
Switch on current state, maybe connecting or
disconnecting.
*/
/*
evt = new XCallActiveEv(m_Call,CallActiveEv.ID,
Ev.CAUSE_NEW_CALL,0,false);
evlist[0] = evt;
publishEvent(evlist);
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -