📄 muxprovider.java
字号:
* Delegate the call on to the appropriate sub-provider, if it registered for these calls.
*/
public boolean isMediaTerminal(String terminal) {
TelephonyProvider rp = this.getTerminalSub(terminal);
if (((RawCapabilities)this.getSubToCaps().get(rp)).allMediaTerminals)
return true; // The rawProvider guaranteed that all terminals are media terminals.
else
return rp.isMediaTerminal(terminal);
}
/**
* Determine if the given sub-provider throttles calls.
*/
private boolean isThrottled(TelephonyProvider rp) {
Properties props = (Properties)this.getSubToCaps().get(rp);
if (props != null) {
return Capabilities.resolve(props.get(Capabilities.THROTTLE));
}
return true; // Assume it does
}
/**
* Tell the remote provider to join two calls
*/
public CallId join(CallId call1, CallId call2, String address, String terminal) throws RawStateException, InvalidArgumentException, MethodNotSupportedException,
PrivilegeViolationException, ResourceUnavailableException {
MuxCallId mCall1 = (MuxCallId)call1;
MuxCallId mCall2 = (MuxCallId)call2;
// find the common callholders
CallHolder ch1 = mCall1.getLeg(address);
CallHolder ch2 = mCall2.getLeg(address);
// check that we have the same sub-provider
TelephonyProvider sub = ch1.getTpi();
if (!sub.equals(ch2.getTpi())) {
throw new InvalidArgumentException("Mux Join: No common TerminalConnection found");
}
// tell the sub-provider to join the parts
sub.join(ch1.getCall(), ch2.getCall(), address, terminal);
// update the address to CallHolder set in call1
String[] adds = mCall2.getAddsForSubCall(ch2);
int addSize = adds.length;
for (int i = 0; i < addSize; i++) {
mCall1.addLeg(adds[i], ch1);
}
// move the other calls from call23 to call1
Iterator it = mCall2.getCallHolders();
while (it.hasNext()) {
CallHolder ch = (CallHolder)it.next();
if (!ch.equals(ch2)) {
// add to mCall1
mCall1.addCall(ch);
// update the address->CallHolder table in call 1
adds = mCall2.getAddsForSubCall(ch);
addSize = adds.length;
for (int i = 0; i < addSize; i++) {
mCall1.addLeg(adds[i], ch);
}
// update the provider
this.getLowToLogicalMap().put(ch, mCall1);
}
}
// clear the old mux call
mCall2.free();
// return the call
return call1;
}
/**
* Take the values pointed to by the existing and new and return the lowest common denominator in String
* format.
* Creation date: (2000-03-14 15:20:48)
* @author: Richard Deadman
* @param existing An existing value, a String of form "txxx" or "fxxx".
* @param update A new String representation of a boolean value.
*/
private Object lcd(Object existing, Object update) {
boolean oldFlag = false;
if ((existing instanceof String && ((String)existing).length() > 0 &&
Character.toLowerCase(((String)existing).charAt(0)) != 't') ||
(existing instanceof Boolean && !((Boolean)existing).booleanValue()))
// can stop now - already false
return existing;
// test if existing true and update exists -- replace with update
if ((update instanceof String && ((String)update).length() > 0) || (update instanceof Boolean)) {
return update;
}
// existing was true and update not valid
return existing;
}
/**
* This method loads the Provider's values from a property file.
* Creation date: (2000-02-22 10:11:41)
* @author: Richard Deadman
*/
private Properties loadResources(String resName) {
// We must be able to load the properties file
Properties props = new Properties();
try {
props.load(this.getClass().getResourceAsStream("/" + resName));
} catch (IOException ioe) {
// return empty Properties
}
return props;
}
/**
* Ensure that I have a logical CallId already for the given low-level call.
* This will look for the call as an existing call, or if it doesn't exist:
* <ol>
* <li>Check if any other calls connect to this call
* <li>Create a new logical call and trace it through any sub-providers for un-reported legs.
* </ol>
* Creation date: (2000-09-24 0:45:49)
* @param subCall Low-level CallId
* @param subTpi Low-level TelephonyProvider that holds the call.
*/
MuxCallId locateCall(CallId subCall, TelephonyProvider subTpi) {
// Check for the logical CallId in the backward lookup table
MuxCallId mci = this.findCall(subCall, subTpi);
// test if the Logical CallId does not yet exist
if (mci == null) {
// first check if any other existing calls can be traced to this call
CallData cd = subTpi.getCall(subCall);
String[] remoteAddresses = cd.getRemoteAddresses();
int raSize = remoteAddresses.length;
if (raSize > 0) {
for (int i = 0; (i < raSize) && (mci == null); i++) {
Iterator it = this.getCalls().iterator();
while (it.hasNext()) {
MuxCallId testCall = (MuxCallId)it.next();
if (testCall.contains(new CallHolder(subCall, subTpi))) {
mci = testCall;
break;
}
}
}
}
if (mci == null) {
// otherwise create the call
mci = this.noteCall(subCall, subTpi);
// now trace this call through to link up other legs
this.traceCalls(mci, cd.connections, new HashSet());
}
}
return mci;
}
/**
* Ensure that a physical sub-call is properly recorded.
* Creation date: (2000-09-27 15:49:07)
*/
private void mapCall(MuxCallId call, CallData callData, TelephonyProvider sub) {
// Create and add a new CallHolder if needed
CallHolder tmpHolder = new CallHolder(callData.id, sub);
if (!call.contains(tmpHolder)) {
call.addCall(tmpHolder);
}
ConnectionData[] connData = callData.connections;
int cdSize = connData.length;
// update the address and terminal mapping
for (int i = 0; i < cdSize; i++) {
this.mapConnection(connData[i], sub);
}
}
/**
* Given a Connection, ensure it is mapped into a sub-provider
* @return true if the connection is in the sub-provider's address space
*/
private boolean mapConnection(ConnectionData cd, TelephonyProvider sub) {
// now map these to the sub-provider
if (cd.isLocal) {
Map termMap = this.getTermToMap();
// record all Addresses and Terminals
this.getAddToMap().put(cd.address, sub);
// and the Connection's Terminals
int tcSize = cd.terminalConnections.length;
for (int j = 0; j < tcSize; j++) {
TCData tcd = cd.terminalConnections[j];
termMap.put(tcd.terminal.terminal, sub);
}
}
return cd.isLocal;
}
/**
* Merge two CallData collections into one that represents the merged call.
* Creation date: (2000-10-02 14:51:36)
* @return The merged CallData representing the virtual call
* @param cd1 The first call
* @param cd2 The bridged call
*/
private CallData merge(CallData cd1, CallData cd2) {
// null value test
if (cd2 == null) {
return cd1;
}
if (cd1 == null) {
return cd2;
}
Set conns = new HashSet(); // the set of connections
Set localAddresses = new HashSet(); // set of local addresses so we can remove remote later
int i;
// Create a set of Connections
ConnectionData[] cdSet = cd1.connections;
ConnectionData cd;
for (i = 0; i < cdSet.length; i++) {
cd = cdSet[i];
conns.add(cd);
if (cd.isLocal)
localAddresses.add(cd.address);
}
cdSet = cd2.connections;
for (i = 0; i < cdSet.length; i++) {
cd = cdSet[i];
conns.add(cd);
if (cd.isLocal)
localAddresses.add(cd.address);
}
// prune remote connections that have a local twin
Iterator it = conns.iterator();
while (it.hasNext()) {
cd = (ConnectionData)it.next();
if (!cd.isLocal && (localAddresses.contains(cd.address))) {
it.remove();
}
}
// Now return the merged set of CallData
return new CallData(cd1.id, cd1.callState, (ConnectionData[])conns.toArray(new ConnectionData[conns.size()]));
}
/**
* Map an Address name from a sub-provider.
* Creation date: (2000-08-09 0:38:22)
* @author: Richard Deadman
* @param id A name of a sub-provider's Address
* @param sub The sub-provider that handles this address
*/
void noteAddress(String addressName, TelephonyProvider sub) {
this.getAddToMap().put(addressName, sub);
}
/**
* Ensure that I have a logical CallId already for the given low-level call.
* This doesn't follow links since that may or may not require the return of CallData information.
* Creation date: (2000-09-24 0:45:49)
* @param subCall Low-level CallId
* @param subTpi Low-level TelephonyProvider that holds the call.
*/
MuxCallId noteCall(CallId subCall, TelephonyProvider subTpi) {
// Check for the logical CallId in the backward lookup table
MuxCallId mci = this.findCall(subCall, subTpi);
// test if the Logical CallId does not yet exist
if (mci == null) {
CallHolder ch = new CallHolder(subCall, subTpi);
mci = new MuxCallId();
mci.addCall(ch);
this.addCall(ch, mci);
}
return mci;
}
/**
* Map a Terminal name from a sub-provider.
* Creation date: (2000-08-09 0:38:22)
* @author: Richard Deadman
* @param id A name of a sub-provider's Terminal
* @param sub The sub-provider that handles the terminal
*/
void noteTerminal(String terminalName, TelephonyProvider sub) {
this.getTermToMap().put(terminalName, sub);
}
/**
* Delegate the call onto the appropriate sub-provider
*/
public void play(String terminal, String[] streamIds, int offset, RTC[] rtcs, Dictionary optArgs) throws MediaResourceException {
this.getTerminalSub(terminal).play(terminal, streamIds, offset, rtcs, optArgs);
}
/**
* Delegate off to the appropriate sub-provider
*/
public void record(String terminal, String streamId, RTC[] rtcs, Dictionary optArgs) throws MediaResourceException {
this.getTerminalSub(terminal).record(terminal, streamId, rtcs, optArgs);
}
/**
* Create a logical CallId to handle any sub-provider muxing and register it with
* the local lookup table.
* Creation date: (2000-09-25 11:45:34)
* @return net.sourceforge.gjtapi.raw.mux.MuxCallId
* @param id net.sourceforge.gjtapi.CallId
* @param sub net.sourceforge.gjtapi.TelephonyProvider
*/
private MuxCallId registerCall(CallId id, TelephonyProvider sub) {
MuxCallId cid = new MuxCallId();
cid.addCall(id, sub);
this.getCalls().add(cid);
return cid;
}
/**
* Tell the remote provider to release an address from a call.
*/
public void release(String address, CallId call) throws PrivilegeViolationException,
ResourceUnavailableException, MethodNotSupportedException, RawStateException {
CallHolder ch = this.getSub(call, address);
if (ch != null) {
ch.getTpi().release(address, ch.getCall());
}
}
/**
* Release any CallId's that I have reserved.
*/
public void releaseCallId(CallId id) {
MuxCallId mcid = (MuxCallId)id; // This better cast...
Iterator chs = mcid.getCallHolders();
while (chs.hasNext()) {
CallHolder call = (CallHolder)chs.next();
call.getTpi().releaseCallId(call.getCall());
}
this.removeCall(mcid);
}
/**
* Remove a MuxCallId and its backwards lookup holder to my call set.
* Creation date: (2000-09-26 16:13:08)
* @param mci net.sourceforge.gjtapi.raw.mux.MuxCallId
*/
boolean removeCall(MuxCallId mci) {
boolean removed = this.getCalls().remove(mci);
if (removed) { // logical call existed...
Iterator it = this.getLowToLogicalMap().entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
if (entry.getValue().equals(mci)) {
it.remove();
}
}
}
return removed;
}
/**
* Forward removeListener to remote provider.
*/
public void removeListener(TelephonyListener rl) {
Iterator it = this.getSubProviders().iterator();
while (it.hasNext()) {
TelephonyProvider rp = ((TelephonyProvider)it.next());
rp.removeListener(new MuxListener(rl, this, rp));
}
}
/**
* Delegate off to the appropriate subprovider
*/
public void reportCallsOnAddress(String address, boolean flag) throws ResourceUnavailableException, InvalidArgumentException {
TelephonyProvider rp = this.getAddressSub(address);
if (rp != null) {
if (((RawCapabilities)this.getSubToCaps().get(rp)).throttle)
rp.reportCallsOnAddress(address, flag);
} else {
// poll each raw provider - should never do this since all addresses should have been recorded.
Iterator it = this.getSubProviders().iterator();
while (it.hasNext()) {
try {
rp = (TelephonyProvider)it.next();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -