📄 r2caschannel.java
字号:
// local.dialogic.R2CASChannel
// $Id: R2CASChannel.java,v 1.15 2003/11/13 11:51:47 cgm8 Exp $
/*
* Copyright (c) 1999 Carlos G Mendioroz.
*
* This file is part of D4J.
*
* D4J is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* D4J is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Report problems and direct all questions to:
*
* tron@acm.org
*/
package local.dialogic;
public class R2CASChannel extends Channel implements Runnable {
// Constantes
private static final int INIT = -1;
private static final int RESET = 0;
private static final int IDLE = 1;
private static final int RSEIZED = 2;
private static final int ICALL = 3;
private static final int RINGS = 4;
private static final int IN = 5;
private static final int OFFH = 6;
private static final int DIAL = 7;
private static final int DIALOK = 8;
private static final int OUT = 9;
private static final int ERROR = 10;
// Handy constants
private static final int A = Dialogic.DTB_ABIT;
private static final int B = Dialogic.DTB_BBIT;
private static final int C = Dialogic.DTB_CBIT;
private static final int D = Dialogic.DTB_DBIT;
private static final int CA = Dialogic.DTC_ABIT;
private static final int CB = Dialogic.DTC_BBIT;
private static final int CC = Dialogic.DTC_CBIT;
private static final int CD = Dialogic.DTC_DBIT;
private static final int WINK = Dialogic.DTMM_WINK;
// Protocol constants
private static final int R2Idle = 200; // Lapse in IDLE
private static final int R2InterDigit = 15000;// timeout
private static final int R2OHDelay = 1000; // Wait for seizure conf
private static final int R2SimSeizureDelay = 200; // Keep signaled
private static final int R2ImpulseGuard = 300;// Do not pay att. to fsig
private static final int R2ConnDelayOut = 60; // Delay before connection
private static final int R2ConnDelayIn = 75; // Delay before connection
// reject reasons
public static final int CONGESTION = 0;
public static final int BUSY = 1;
public static final int BADNUMBER = 2;
public static final int NOTINSERVICE = 3;
// Variables
Voice voiceDev = null;
DTI dtiDev = null;
boolean ra = false, rb = false;
boolean xa = false, xb = false;
private int linestate = -1;
private int pulses = 0;
private String ani = null;
private int r2tone = 0;
private int ringsSent = 0;
private boolean ringPhase = true;
private int inDnisLength = 4;
private String dnisPref = "";
private boolean freeAccept = false;
private boolean A3B6Accept = false;
public R2CASChannel(String dtiName, String voiceName) {
this (dtiName, voiceName, "");
}
public R2CASChannel(String dtiName, String voiceName, String dnisPreffix) {
super();
dtiDev = new DTI(this, dtiName);
voiceDev = new Voice(this, voiceName);
// link
dtiDev.listen(voiceDev);
voiceDev.listen(dtiDev);
//
linestate = INIT;
dnisPref = dnisPreffix;
ra = dtiDev.getA();
rb = dtiDev.getB();
dtiDev.setsig(xa = true, xb = true);
voiceDev.r2_creasig();
group = new ThreadGroup(dtiName + "/" + voiceName + " group");
serviceThread = new Thread(group, this, dtiName + "/" + voiceName + " service");
serviceThread.start();
}
public void close()
{
super.clear();
if (serviceThread != null) {
Channel.stopGroup(this);
serviceThread.interrupt();
try {
serviceThread.join(500);
}
catch (InterruptedException ie) {};
serviceThread = null;
}
if (dtiDev != null) {
dtiDev.close();
dtiDev = null;
}
if (voiceDev != null) {
voiceDev.close();
voiceDev = null;
}
}
public Voice getVoice() {
return voiceDev;
}
public Device getNetwork() {
return dtiDev;
}
public void run() {
int dnisl;
StringBuffer dnis = new StringBuffer(dnisPref);
EVT evt;
service:
while(true) try {
dnis.setLength(dnisPref.length());
dnisl = 0;
clear();
beginService();
// Stay in reset...
do {
evt = serviceWaitEvent(R2Idle);
// Just in case we are resetting from OFFH timeout...
/* Longer description: We are always xa && !xb here,
* but for the case that we give up waiting for line, in which
* case we are !xa && !xb, and should wait forever until rb,
* then go xa && !xb */
if (!xa && !xb && rb)
dtiDev.setsig(xa = true, xb = false);
/* evt is null only when timeout, but AOFF events are filtered by service.
* we stay here until we either see idle for some time or get an event
*/
} while (!(xa && !rb) || (evt == null && !(ra && !rb)));
if (evt == null) {
// We are ok for dial out
linestate = IDLE;
setState(FREE);
try {
evt = serviceWaitEvent();
} catch (ChannelException ie) {
// Somebody is asking me to leave, outdial ?
if (linestate != OFFH)
setState(OOS); // This should not happen...
return;
}
}
// event should be AOFF, and state RSEIZED
if (linestate != RSEIZED) {
System.err.println("Ignoring " + evt);
continue service;
}
voiceDev.r2_fenable();
call = new Call(R2CASChannel.this);
ani = null;
getDnis:
while (true) {
evt = serviceWaitEvent(R2InterDigit);
if (evt == null) {
// Timeout in incomming dial
abortRings("InterDigit timeout");
continue service;
}
if (evt.type == EVT.TDX_CST
&& evt.cstevt == EVT.DE_TONEON) {
r2tone = evt.cstdata;
dnisl++;
switch(r2tone) {
case Voice.SIGI_1:
dnis.append('1');
break;
case Voice.SIGI_2:
dnis.append('2');
break;
case Voice.SIGI_3:
dnis.append('3');
break;
case Voice.SIGI_4:
dnis.append('4');
break;
case Voice.SIGI_5:
dnis.append('5');
break;
case Voice.SIGI_6:
dnis.append('6');
break;
case Voice.SIGI_7:
dnis.append('7');
break;
case Voice.SIGI_8:
dnis.append('8');
break;
case Voice.SIGI_9:
dnis.append('9');
break;
case Voice.SIGI_10:
dnis.append('0');
break;
case Voice.SIGI_15:
break getDnis;
default:
// Unexpected forward signal
abortRings("Unexpected forward" + evt);
continue service;
}
if (dnisl < inDnisLength) {
voiceDev.r2_sendb(Voice.SIGA_1, r2tone);
} else {
break;
}
} else if (evt.type == EVT.TDX_CST &&
evt.cstevt == EVT.DE_TONEOFF) {
// Ignore, forward off
} else if (evt.type == EVT.TDX_PLAYTONE) {
// Ignore, backward completed
} else {
abortRings("Unexpected " + evt);
continue service;
}
}
call.dnis = dnis.toString();
linestate = ICALL;
if (handler != null) {
endService();
handler.handleCall(call);
} else {
// Reject with congestion
voiceDev.r2_sendb(Voice.SIGB_4, r2tone);
do {
evt = serviceWaitEvent();
} while (evt.type != EVT.TDX_PLAYTONE);
}
}
catch (ChannelException ce) {}
finally {
endService();
}
}
// abort incomming due to protocol error
private void abortRings(String error) {
EVT evt;
System.err.println("Rings: " + error);
setState(OOS);
voiceDev.stop();
voiceDev.r2_fdisable();
voiceDev.r2_sendbp(Voice.SIGA_4);
do {
evt = serviceWaitEvent();
} while (!ra && evt.type != EVT.TDX_PLAYTONE);
if (call != null) call.drop();
}
public String toString() {
return "R2CASChannel on " + dtiDev + "/" + voiceDev;
}
public void setFree(boolean x) {
freeAccept = x;
}
public void setA3B6(boolean x) {
A3B6Accept = x;
}
public void setDnisLength(int n) {
inDnisLength = n;
}
static TNGEN ringLead = new TNGEN(200, -40, 20) ;
static TNGEN ring = new TNGEN(440, -10, 100) ;
static TNGEN ringSilence = new TNGEN(200, -40, 200);
static TPT stdTPT = new TPT();
static Thread ringer = null;
static EVT ringerEvt = null;
void accept() {
if (linestate != ICALL)
throw new ChannelException("accept(): wrong state");
try {
EVT evt = null;
boolean acceptOne = false;
if (freeAccept || A3B6Accept){
voiceDev.r2_sendb(Voice.SIGA_3, r2tone);
while (true) {
evt = serviceWaitEvent(R2InterDigit);
if (evt == null) {
// Timeout in incomming dial
abortIcall("InterDigit timeout");
}
if (evt.type == EVT.TDX_CST
&& evt.cstevt == EVT.DE_TONEON) {
r2tone = evt.cstdata; // category
if (freeAccept)
voiceDev.r2_sendb(Voice.SIGB_7, r2tone);
else
voiceDev.r2_sendb(Voice.SIGB_6, r2tone);
break;
} else if (evt.type == EVT.TDX_CST &&
evt.cstevt == EVT.DE_TONEOFF) {
// Ignore, forward off
} else if (evt.type == EVT.TDX_PLAYTONE) {
// Ignore, backward completed
} else {
abortIcall("Unexpected " + evt);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -