Merge "SIP: misc fixes." into gingerbread
This commit is contained in:
committed by
Android (Google) Code Review
commit
2365b78e64
@ -520,7 +520,9 @@ public class SipManager {
|
|||||||
|
|
||||||
private String getUri(ISipSession session) {
|
private String getUri(ISipSession session) {
|
||||||
try {
|
try {
|
||||||
return session.getLocalProfile().getUriString();
|
return ((session == null)
|
||||||
|
? "no session"
|
||||||
|
: session.getLocalProfile().getUriString());
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -510,31 +510,43 @@ public final class SipService extends ISipService.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KeepAliveProcess is controlled by AutoRegistrationProcess.
|
||||||
|
// All methods will be invoked in sync with SipService.this except realRun()
|
||||||
private class KeepAliveProcess implements Runnable {
|
private class KeepAliveProcess implements Runnable {
|
||||||
private static final String TAG = "\\KEEPALIVE/";
|
private static final String TAG = "\\KEEPALIVE/";
|
||||||
private static final int INTERVAL = 10;
|
private static final int INTERVAL = 10;
|
||||||
private SipSessionGroup.SipSessionImpl mSession;
|
private SipSessionGroup.SipSessionImpl mSession;
|
||||||
|
private boolean mRunning = false;
|
||||||
|
|
||||||
public KeepAliveProcess(SipSessionGroup.SipSessionImpl session) {
|
public KeepAliveProcess(SipSessionGroup.SipSessionImpl session) {
|
||||||
mSession = session;
|
mSession = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
|
if (mRunning) return;
|
||||||
|
mRunning = true;
|
||||||
mTimer.set(INTERVAL * 1000, this);
|
mTimer.set(INTERVAL * 1000, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// timeout handler
|
||||||
public void run() {
|
public void run() {
|
||||||
|
if (!mRunning) return;
|
||||||
|
final SipSessionGroup.SipSessionImpl session = mSession;
|
||||||
|
|
||||||
// delegate to mExecutor
|
// delegate to mExecutor
|
||||||
getExecutor().addTask(new Runnable() {
|
getExecutor().addTask(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
realRun();
|
realRun(session);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void realRun() {
|
// real timeout handler
|
||||||
|
private void realRun(SipSessionGroup.SipSessionImpl session) {
|
||||||
synchronized (SipService.this) {
|
synchronized (SipService.this) {
|
||||||
SipSessionGroup.SipSessionImpl session = mSession.duplicate();
|
if (notCurrentSession(session)) return;
|
||||||
|
|
||||||
|
session = session.duplicate();
|
||||||
if (DEBUG) Log.d(TAG, "~~~ keepalive");
|
if (DEBUG) Log.d(TAG, "~~~ keepalive");
|
||||||
mTimer.cancel(this);
|
mTimer.cancel(this);
|
||||||
session.sendKeepAlive();
|
session.sendKeepAlive();
|
||||||
@ -547,8 +559,14 @@ public final class SipService extends ISipService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
|
mRunning = false;
|
||||||
|
mSession = null;
|
||||||
mTimer.cancel(this);
|
mTimer.cancel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean notCurrentSession(ISipSession session) {
|
||||||
|
return (session != mSession) || !mRunning;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AutoRegistrationProcess extends SipSessionAdapter
|
private class AutoRegistrationProcess extends SipSessionAdapter
|
||||||
@ -561,13 +579,15 @@ public final class SipService extends ISipService.Stub {
|
|||||||
private long mExpiryTime;
|
private long mExpiryTime;
|
||||||
private int mErrorCode;
|
private int mErrorCode;
|
||||||
private String mErrorMessage;
|
private String mErrorMessage;
|
||||||
|
private boolean mRunning = false;
|
||||||
|
|
||||||
private String getAction() {
|
private String getAction() {
|
||||||
return toString();
|
return toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start(SipSessionGroup group) {
|
public void start(SipSessionGroup group) {
|
||||||
if (mSession == null) {
|
if (!mRunning) {
|
||||||
|
mRunning = true;
|
||||||
mBackoff = 1;
|
mBackoff = 1;
|
||||||
mSession = (SipSessionGroup.SipSessionImpl)
|
mSession = (SipSessionGroup.SipSessionImpl)
|
||||||
group.createSession(this);
|
group.createSession(this);
|
||||||
@ -584,35 +604,24 @@ public final class SipService extends ISipService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
stop(false);
|
if (!mRunning) return;
|
||||||
}
|
mRunning = false;
|
||||||
|
mSession.setListener(null);
|
||||||
private void stopButKeepStates() {
|
|
||||||
stop(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stop(boolean keepStates) {
|
|
||||||
if (mSession == null) return;
|
|
||||||
if (mConnected && mRegistered) mSession.unregister();
|
if (mConnected && mRegistered) mSession.unregister();
|
||||||
|
|
||||||
mTimer.cancel(this);
|
mTimer.cancel(this);
|
||||||
if (mKeepAliveProcess != null) {
|
if (mKeepAliveProcess != null) {
|
||||||
mKeepAliveProcess.stop();
|
mKeepAliveProcess.stop();
|
||||||
mKeepAliveProcess = null;
|
mKeepAliveProcess = null;
|
||||||
}
|
}
|
||||||
if (!keepStates) {
|
|
||||||
mSession = null;
|
|
||||||
mRegistered = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isStopped() {
|
mRegistered = false;
|
||||||
return (mSession == null);
|
setListener(mProxy.getListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setListener(ISipSessionListener listener) {
|
public void setListener(ISipSessionListener listener) {
|
||||||
synchronized (SipService.this) {
|
synchronized (SipService.this) {
|
||||||
mProxy.setListener(listener);
|
mProxy.setListener(listener);
|
||||||
if (mSession == null) return;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int state = (mSession == null)
|
int state = (mSession == null)
|
||||||
@ -632,6 +641,18 @@ public final class SipService extends ISipService.Stub {
|
|||||||
mProxy.onRegistrationFailed(mSession, mErrorCode,
|
mProxy.onRegistrationFailed(mSession, mErrorCode,
|
||||||
mErrorMessage);
|
mErrorMessage);
|
||||||
}
|
}
|
||||||
|
} else if (!mConnected) {
|
||||||
|
mProxy.onRegistrationFailed(mSession,
|
||||||
|
SipErrorCode.DATA_CONNECTION_LOST,
|
||||||
|
"no data connection");
|
||||||
|
} else if (!mRunning) {
|
||||||
|
mProxy.onRegistrationFailed(mSession,
|
||||||
|
SipErrorCode.CLIENT_ERROR,
|
||||||
|
"registration not running");
|
||||||
|
} else {
|
||||||
|
mProxy.onRegistrationFailed(mSession,
|
||||||
|
SipErrorCode.IN_PROGRESS,
|
||||||
|
String.valueOf(state));
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
Log.w(TAG, "setListener(): " + t);
|
Log.w(TAG, "setListener(): " + t);
|
||||||
@ -643,21 +664,29 @@ public final class SipService extends ISipService.Stub {
|
|||||||
return mRegistered;
|
return mRegistered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// timeout handler
|
||||||
public void run() {
|
public void run() {
|
||||||
// delegate to mExecutor
|
synchronized (SipService.this) {
|
||||||
getExecutor().addTask(new Runnable() {
|
if (!mRunning) return;
|
||||||
public void run() {
|
final SipSessionGroup.SipSessionImpl session = mSession;
|
||||||
realRun();
|
|
||||||
}
|
// delegate to mExecutor
|
||||||
});
|
getExecutor().addTask(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
realRun(session);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void realRun() {
|
// real timeout handler
|
||||||
mErrorCode = SipErrorCode.NO_ERROR;
|
private void realRun(SipSessionGroup.SipSessionImpl session) {
|
||||||
mErrorMessage = null;
|
|
||||||
if (DEBUG) Log.d(TAG, "~~~ registering");
|
|
||||||
synchronized (SipService.this) {
|
synchronized (SipService.this) {
|
||||||
if (mConnected && !isStopped()) mSession.register(EXPIRY_TIME);
|
if (notCurrentSession(session)) return;
|
||||||
|
mErrorCode = SipErrorCode.NO_ERROR;
|
||||||
|
mErrorMessage = null;
|
||||||
|
if (DEBUG) Log.d(TAG, "~~~ registering");
|
||||||
|
if (mConnected) session.register(EXPIRY_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,22 +726,29 @@ public final class SipService extends ISipService.Stub {
|
|||||||
public void onRegistering(ISipSession session) {
|
public void onRegistering(ISipSession session) {
|
||||||
if (DEBUG) Log.d(TAG, "onRegistering(): " + session);
|
if (DEBUG) Log.d(TAG, "onRegistering(): " + session);
|
||||||
synchronized (SipService.this) {
|
synchronized (SipService.this) {
|
||||||
if (!isStopped() && (session != mSession)) return;
|
if (notCurrentSession(session)) return;
|
||||||
|
|
||||||
mRegistered = false;
|
mRegistered = false;
|
||||||
mProxy.onRegistering(session);
|
mProxy.onRegistering(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean notCurrentSession(ISipSession session) {
|
||||||
|
if (session != mSession) {
|
||||||
|
((SipSessionGroup.SipSessionImpl) session).setListener(null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !mRunning;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRegistrationDone(ISipSession session, int duration) {
|
public void onRegistrationDone(ISipSession session, int duration) {
|
||||||
if (DEBUG) Log.d(TAG, "onRegistrationDone(): " + session);
|
if (DEBUG) Log.d(TAG, "onRegistrationDone(): " + session);
|
||||||
synchronized (SipService.this) {
|
synchronized (SipService.this) {
|
||||||
if (!isStopped() && (session != mSession)) return;
|
if (notCurrentSession(session)) return;
|
||||||
|
|
||||||
mProxy.onRegistrationDone(session, duration);
|
mProxy.onRegistrationDone(session, duration);
|
||||||
|
|
||||||
if (isStopped()) return;
|
|
||||||
|
|
||||||
if (duration > 0) {
|
if (duration > 0) {
|
||||||
mSession.clearReRegisterRequired();
|
mSession.clearReRegisterRequired();
|
||||||
mExpiryTime = SystemClock.elapsedRealtime()
|
mExpiryTime = SystemClock.elapsedRealtime()
|
||||||
@ -751,17 +787,18 @@ public final class SipService extends ISipService.Stub {
|
|||||||
if (DEBUG) Log.d(TAG, "onRegistrationFailed(): " + session + ": "
|
if (DEBUG) Log.d(TAG, "onRegistrationFailed(): " + session + ": "
|
||||||
+ SipErrorCode.toString(errorCode) + ": " + message);
|
+ SipErrorCode.toString(errorCode) + ": " + message);
|
||||||
synchronized (SipService.this) {
|
synchronized (SipService.this) {
|
||||||
if (!isStopped() && (session != mSession)) return;
|
if (notCurrentSession(session)) return;
|
||||||
mErrorCode = errorCode;
|
|
||||||
mErrorMessage = message;
|
|
||||||
mProxy.onRegistrationFailed(session, errorCode, message);
|
|
||||||
|
|
||||||
if (errorCode == SipErrorCode.INVALID_CREDENTIALS) {
|
if (errorCode == SipErrorCode.INVALID_CREDENTIALS) {
|
||||||
if (DEBUG) Log.d(TAG, " pause auto-registration");
|
if (DEBUG) Log.d(TAG, " pause auto-registration");
|
||||||
stopButKeepStates();
|
stop();
|
||||||
} else if (!isStopped()) {
|
} else {
|
||||||
onError();
|
onError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mErrorCode = errorCode;
|
||||||
|
mErrorMessage = message;
|
||||||
|
mProxy.onRegistrationFailed(session, errorCode, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,14 +806,11 @@ public final class SipService extends ISipService.Stub {
|
|||||||
public void onRegistrationTimeout(ISipSession session) {
|
public void onRegistrationTimeout(ISipSession session) {
|
||||||
if (DEBUG) Log.d(TAG, "onRegistrationTimeout(): " + session);
|
if (DEBUG) Log.d(TAG, "onRegistrationTimeout(): " + session);
|
||||||
synchronized (SipService.this) {
|
synchronized (SipService.this) {
|
||||||
if (!isStopped() && (session != mSession)) return;
|
if (notCurrentSession(session)) return;
|
||||||
|
|
||||||
mErrorCode = SipErrorCode.TIME_OUT;
|
mErrorCode = SipErrorCode.TIME_OUT;
|
||||||
mProxy.onRegistrationTimeout(session);
|
mProxy.onRegistrationTimeout(session);
|
||||||
|
onError();
|
||||||
if (!isStopped()) {
|
|
||||||
mRegistered = false;
|
|
||||||
onError();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -883,6 +917,7 @@ public final class SipService extends ISipService.Stub {
|
|||||||
mConnected = connected;
|
mConnected = connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// timeout handler
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// delegate to mExecutor
|
// delegate to mExecutor
|
||||||
|
@ -334,12 +334,12 @@ class SipSessionGroup implements SipListener {
|
|||||||
if (isRequestEvent(Request.INVITE, evt)) {
|
if (isRequestEvent(Request.INVITE, evt)) {
|
||||||
RequestEvent event = (RequestEvent) evt;
|
RequestEvent event = (RequestEvent) evt;
|
||||||
SipSessionImpl newSession = new SipSessionImpl(mProxy);
|
SipSessionImpl newSession = new SipSessionImpl(mProxy);
|
||||||
|
newSession.mState = SipSession.State.INCOMING_CALL;
|
||||||
newSession.mServerTransaction = mSipHelper.sendRinging(event,
|
newSession.mServerTransaction = mSipHelper.sendRinging(event,
|
||||||
generateTag());
|
generateTag());
|
||||||
newSession.mDialog = newSession.mServerTransaction.getDialog();
|
newSession.mDialog = newSession.mServerTransaction.getDialog();
|
||||||
newSession.mInviteReceived = event;
|
newSession.mInviteReceived = event;
|
||||||
newSession.mPeerProfile = createPeerProfile(event.getRequest());
|
newSession.mPeerProfile = createPeerProfile(event.getRequest());
|
||||||
newSession.mState = SipSession.State.INCOMING_CALL;
|
|
||||||
newSession.mPeerSessionDescription =
|
newSession.mPeerSessionDescription =
|
||||||
extractContent(event.getRequest());
|
extractContent(event.getRequest());
|
||||||
addSipSession(newSession);
|
addSipSession(newSession);
|
||||||
@ -708,7 +708,6 @@ class SipSessionGroup implements SipListener {
|
|||||||
case SipSession.State.PINGING:
|
case SipSession.State.PINGING:
|
||||||
reset();
|
reset();
|
||||||
mReRegisterFlag = true;
|
mReRegisterFlag = true;
|
||||||
mState = SipSession.State.READY_TO_CALL;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -877,6 +876,7 @@ class SipSessionGroup implements SipListener {
|
|||||||
private boolean readyForCall(EventObject evt) throws SipException {
|
private boolean readyForCall(EventObject evt) throws SipException {
|
||||||
// expect MakeCallCommand, RegisterCommand, DEREGISTER
|
// expect MakeCallCommand, RegisterCommand, DEREGISTER
|
||||||
if (evt instanceof MakeCallCommand) {
|
if (evt instanceof MakeCallCommand) {
|
||||||
|
mState = SipSession.State.OUTGOING_CALL;
|
||||||
MakeCallCommand cmd = (MakeCallCommand) evt;
|
MakeCallCommand cmd = (MakeCallCommand) evt;
|
||||||
mPeerProfile = cmd.getPeerProfile();
|
mPeerProfile = cmd.getPeerProfile();
|
||||||
mClientTransaction = mSipHelper.sendInvite(mLocalProfile,
|
mClientTransaction = mSipHelper.sendInvite(mLocalProfile,
|
||||||
@ -884,25 +884,24 @@ class SipSessionGroup implements SipListener {
|
|||||||
generateTag());
|
generateTag());
|
||||||
mDialog = mClientTransaction.getDialog();
|
mDialog = mClientTransaction.getDialog();
|
||||||
addSipSession(this);
|
addSipSession(this);
|
||||||
mState = SipSession.State.OUTGOING_CALL;
|
|
||||||
mProxy.onCalling(this);
|
mProxy.onCalling(this);
|
||||||
startSessionTimer(cmd.getTimeout());
|
startSessionTimer(cmd.getTimeout());
|
||||||
return true;
|
return true;
|
||||||
} else if (evt instanceof RegisterCommand) {
|
} else if (evt instanceof RegisterCommand) {
|
||||||
|
mState = SipSession.State.REGISTERING;
|
||||||
int duration = ((RegisterCommand) evt).getDuration();
|
int duration = ((RegisterCommand) evt).getDuration();
|
||||||
mClientTransaction = mSipHelper.sendRegister(mLocalProfile,
|
mClientTransaction = mSipHelper.sendRegister(mLocalProfile,
|
||||||
generateTag(), duration);
|
generateTag(), duration);
|
||||||
mDialog = mClientTransaction.getDialog();
|
mDialog = mClientTransaction.getDialog();
|
||||||
addSipSession(this);
|
addSipSession(this);
|
||||||
mState = SipSession.State.REGISTERING;
|
|
||||||
mProxy.onRegistering(this);
|
mProxy.onRegistering(this);
|
||||||
return true;
|
return true;
|
||||||
} else if (DEREGISTER == evt) {
|
} else if (DEREGISTER == evt) {
|
||||||
|
mState = SipSession.State.DEREGISTERING;
|
||||||
mClientTransaction = mSipHelper.sendRegister(mLocalProfile,
|
mClientTransaction = mSipHelper.sendRegister(mLocalProfile,
|
||||||
generateTag(), 0);
|
generateTag(), 0);
|
||||||
mDialog = mClientTransaction.getDialog();
|
mDialog = mClientTransaction.getDialog();
|
||||||
addSipSession(this);
|
addSipSession(this);
|
||||||
mState = SipSession.State.DEREGISTERING;
|
|
||||||
mProxy.onRegistering(this);
|
mProxy.onRegistering(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -913,11 +912,11 @@ class SipSessionGroup implements SipListener {
|
|||||||
// expect MakeCallCommand(answering) , END_CALL cmd , Cancel
|
// expect MakeCallCommand(answering) , END_CALL cmd , Cancel
|
||||||
if (evt instanceof MakeCallCommand) {
|
if (evt instanceof MakeCallCommand) {
|
||||||
// answer call
|
// answer call
|
||||||
|
mState = SipSession.State.INCOMING_CALL_ANSWERING;
|
||||||
mServerTransaction = mSipHelper.sendInviteOk(mInviteReceived,
|
mServerTransaction = mSipHelper.sendInviteOk(mInviteReceived,
|
||||||
mLocalProfile,
|
mLocalProfile,
|
||||||
((MakeCallCommand) evt).getSessionDescription(),
|
((MakeCallCommand) evt).getSessionDescription(),
|
||||||
mServerTransaction);
|
mServerTransaction);
|
||||||
mState = SipSession.State.INCOMING_CALL_ANSWERING;
|
|
||||||
startSessionTimer(((MakeCallCommand) evt).getTimeout());
|
startSessionTimer(((MakeCallCommand) evt).getTimeout());
|
||||||
return true;
|
return true;
|
||||||
} else if (END_CALL == evt) {
|
} else if (END_CALL == evt) {
|
||||||
@ -1009,8 +1008,8 @@ class SipSessionGroup implements SipListener {
|
|||||||
// RFC says that UA should not send out cancel when no
|
// RFC says that UA should not send out cancel when no
|
||||||
// response comes back yet. We are cheating for not checking
|
// response comes back yet. We are cheating for not checking
|
||||||
// response.
|
// response.
|
||||||
mSipHelper.sendCancel(mClientTransaction);
|
|
||||||
mState = SipSession.State.OUTGOING_CALL_CANCELING;
|
mState = SipSession.State.OUTGOING_CALL_CANCELING;
|
||||||
|
mSipHelper.sendCancel(mClientTransaction);
|
||||||
startSessionTimer(CANCEL_CALL_TIMER);
|
startSessionTimer(CANCEL_CALL_TIMER);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1065,8 +1064,8 @@ class SipSessionGroup implements SipListener {
|
|||||||
return true;
|
return true;
|
||||||
} else if (isRequestEvent(Request.INVITE, evt)) {
|
} else if (isRequestEvent(Request.INVITE, evt)) {
|
||||||
// got Re-INVITE
|
// got Re-INVITE
|
||||||
RequestEvent event = mInviteReceived = (RequestEvent) evt;
|
|
||||||
mState = SipSession.State.INCOMING_CALL;
|
mState = SipSession.State.INCOMING_CALL;
|
||||||
|
RequestEvent event = mInviteReceived = (RequestEvent) evt;
|
||||||
mPeerSessionDescription = extractContent(event.getRequest());
|
mPeerSessionDescription = extractContent(event.getRequest());
|
||||||
mServerTransaction = null;
|
mServerTransaction = null;
|
||||||
mProxy.onRinging(this, mPeerProfile, mPeerSessionDescription);
|
mProxy.onRinging(this, mPeerProfile, mPeerSessionDescription);
|
||||||
@ -1077,9 +1076,9 @@ class SipSessionGroup implements SipListener {
|
|||||||
return true;
|
return true;
|
||||||
} else if (evt instanceof MakeCallCommand) {
|
} else if (evt instanceof MakeCallCommand) {
|
||||||
// to change call
|
// to change call
|
||||||
|
mState = SipSession.State.OUTGOING_CALL;
|
||||||
mClientTransaction = mSipHelper.sendReinvite(mDialog,
|
mClientTransaction = mSipHelper.sendReinvite(mDialog,
|
||||||
((MakeCallCommand) evt).getSessionDescription());
|
((MakeCallCommand) evt).getSessionDescription());
|
||||||
mState = SipSession.State.OUTGOING_CALL;
|
|
||||||
startSessionTimer(((MakeCallCommand) evt).getTimeout());
|
startSessionTimer(((MakeCallCommand) evt).getTimeout());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user