Loading services/java/com/android/server/sip/SipService.java +64 −39 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.net.NetworkInfo; import android.net.sip.ISipService; import android.net.sip.ISipService; import android.net.sip.ISipSession; import android.net.sip.ISipSession; import android.net.sip.ISipSessionListener; import android.net.sip.ISipSessionListener; import android.net.sip.SipErrorCode; import android.net.sip.SipManager; import android.net.sip.SipManager; import android.net.sip.SipProfile; import android.net.sip.SipProfile; import android.net.sip.SipSessionAdapter; import android.net.sip.SipSessionAdapter; Loading Loading @@ -528,6 +529,8 @@ public final class SipService extends ISipService.Stub { private int mBackoff = 1; private int mBackoff = 1; private boolean mRegistered; private boolean mRegistered; private long mExpiryTime; private long mExpiryTime; private SipErrorCode mErrorCode; private String mErrorMessage; private String getAction() { private String getAction() { return toString(); return toString(); Loading @@ -551,16 +554,26 @@ public final class SipService extends ISipService.Stub { } } public void stop() { public void stop() { stop(false); } private void stopButKeepStates() { stop(true); } private void stop(boolean keepStates) { if (mSession == null) return; if (mSession == null) return; if (mConnected) 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; mSession = null; mRegistered = false; mRegistered = false; } } } private boolean isStopped() { private boolean isStopped() { return (mSession == null); return (mSession == null); Loading @@ -568,28 +581,43 @@ public final class SipService extends ISipService.Stub { public void setListener(ISipSessionListener listener) { public void setListener(ISipSessionListener listener) { Log.v(TAG, "setListener(): " + listener); Log.v(TAG, "setListener(): " + listener); synchronized (SipService.this) { mProxy.setListener(listener); mProxy.setListener(listener); if (mSession == null) return; if (mSession == null) return; try { try { if ((mSession != null) && SipSessionState.REGISTERING.equals( SipSessionState state = (mSession == null) mSession.getState())) { ? SipSessionState.READY_TO_CALL : Enum.valueOf( SipSessionState.class, mSession.getState()); if ((state == SipSessionState.REGISTERING) || (state == SipSessionState.DEREGISTERING)) { mProxy.onRegistering(mSession); mProxy.onRegistering(mSession); } else if (mRegistered) { } else if (mRegistered) { int duration = (int) int duration = (int) (mExpiryTime - SystemClock.elapsedRealtime()); (mExpiryTime - SystemClock.elapsedRealtime()); mProxy.onRegistrationDone(mSession, duration); mProxy.onRegistrationDone(mSession, duration); } else if (mErrorCode != null) { if (mErrorCode == SipErrorCode.TIME_OUT) { mProxy.onRegistrationTimeout(mSession); } else { mProxy.onRegistrationFailed(mSession, mErrorCode.toString(), mErrorMessage); } } } } catch (Throwable t) { } catch (Throwable t) { Log.w(TAG, "setListener(): " + t); Log.w(TAG, "setListener(): " + t); } } } } } public boolean isRegistered() { public boolean isRegistered() { return mRegistered; return mRegistered; } } public void run() { public void run() { mErrorCode = null; mErrorMessage = null; Log.v(TAG, " ~~~ registering"); Log.v(TAG, " ~~~ registering"); synchronized (SipService.this) { synchronized (SipService.this) { if (mConnected && !isStopped()) mSession.register(EXPIRY_TIME); if (mConnected && !isStopped()) mSession.register(EXPIRY_TIME); Loading Loading @@ -634,11 +662,7 @@ public final class SipService extends ISipService.Stub { synchronized (SipService.this) { synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; if (!isStopped() && (session != mSession)) return; mRegistered = false; mRegistered = false; try { mProxy.onRegistering(session); mProxy.onRegistering(session); } catch (Throwable t) { Log.w(TAG, "onRegistering()", t); } } } } } Loading @@ -647,11 +671,9 @@ public final class SipService extends ISipService.Stub { Log.v(TAG, "onRegistrationDone(): " + session + ": " + mSession); Log.v(TAG, "onRegistrationDone(): " + session + ": " + mSession); synchronized (SipService.this) { synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; if (!isStopped() && (session != mSession)) return; try { mProxy.onRegistrationDone(session, duration); mProxy.onRegistrationDone(session, duration); } catch (Throwable t) { Log.w(TAG, "onRegistrationDone()", t); } if (isStopped()) return; if (isStopped()) return; if (duration > 0) { if (duration > 0) { Loading Loading @@ -687,19 +709,25 @@ public final class SipService extends ISipService.Stub { } } @Override @Override public void onRegistrationFailed(ISipSession session, String className, public void onRegistrationFailed(ISipSession session, String message) { String errorCodeString, String message) { SipErrorCode errorCode = Enum.valueOf(SipErrorCode.class, errorCodeString); Log.v(TAG, "onRegistrationFailed(): " + session + ": " + mSession Log.v(TAG, "onRegistrationFailed(): " + session + ": " + mSession + ": " + className + ": " + message); + ": " + errorCode + ": " + message); synchronized (SipService.this) { synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; if (!isStopped() && (session != mSession)) return; try { mErrorCode = errorCode; mProxy.onRegistrationFailed(session, className, message); mErrorMessage = message; } catch (Throwable t) { mProxy.onRegistrationFailed(session, errorCode.toString(), Log.w(TAG, "onRegistrationFailed(): " + t); message); if (errorCode == SipErrorCode.INVALID_CREDENTIALS) { Log.d(TAG, " pause auto-registration"); stopButKeepStates(); } else if (!isStopped()) { onError(); } } if (!isStopped()) onError(); } } } } Loading @@ -708,11 +736,8 @@ public final class SipService extends ISipService.Stub { Log.v(TAG, "onRegistrationTimeout(): " + session + ": " + mSession); Log.v(TAG, "onRegistrationTimeout(): " + session + ": " + mSession); synchronized (SipService.this) { synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; if (!isStopped() && (session != mSession)) return; try { mErrorCode = SipErrorCode.TIME_OUT; mProxy.onRegistrationTimeout(session); mProxy.onRegistrationTimeout(session); } catch (Throwable t) { Log.w(TAG, "onRegistrationTimeout(): " + t); } if (!isStopped()) { if (!isStopped()) { mRegistered = false; mRegistered = false; Loading services/java/com/android/server/sip/SipSessionGroup.java +82 −64 Original line number Original line Diff line number Diff line Loading @@ -412,15 +412,9 @@ class SipSessionGroup implements SipListener { processCommand(command); processCommand(command); } catch (SipException e) { } catch (SipException e) { Log.w(TAG, "command error: " + command, e); Log.w(TAG, "command error: " + command, e); // TODO: find a better way to do this if ((command instanceof RegisterCommand) || (command == DEREGISTER)) { onRegistrationFailed(e); } else { onError(e); onError(e); } } } } } }).start(); }).start(); } } Loading Loading @@ -480,7 +474,9 @@ class SipSessionGroup implements SipListener { private void processCommand(EventObject command) throws SipException { private void processCommand(EventObject command) throws SipException { if (!process(command)) { if (!process(command)) { throw new SipException("wrong state to execute: " + command); onError(SipErrorCode.IN_PROGRESS, "cannot initiate a new transaction to execute: " + command); } } } } Loading Loading @@ -562,11 +558,8 @@ class SipSessionGroup implements SipListener { if (evt instanceof TimeoutEvent) { if (evt instanceof TimeoutEvent) { processTimeout((TimeoutEvent) evt); processTimeout((TimeoutEvent) evt); } else { } else { Log.d(TAG, "Transaction terminated:" + this); processTransactionTerminated( if (!SipSessionState.IN_CALL.equals(mState)) { (TransactionTerminatedEvent) evt); removeSipSession(this); } return true; } } return true; return true; } else if (evt instanceof DialogTerminatedEvent) { } else if (evt instanceof DialogTerminatedEvent) { Loading @@ -585,6 +578,20 @@ class SipSessionGroup implements SipListener { } } } } private void processTransactionTerminated( TransactionTerminatedEvent event) { switch (mState) { case IN_CALL: case READY_TO_CALL: Log.d(TAG, "Transaction terminated; do nothing"); break; default: Log.d(TAG, "Transaction terminated early: " + this); onError(SipErrorCode.TRANSACTION_TERMINTED, "transaction terminated"); } } private void processTimeout(TimeoutEvent event) { private void processTimeout(TimeoutEvent event) { Log.d(TAG, "processing Timeout..." + event); Log.d(TAG, "processing Timeout..." + event); Transaction current = event.isServerTransaction() Transaction current = event.isServerTransaction() Loading @@ -607,8 +614,9 @@ class SipSessionGroup implements SipListener { break; break; case INCOMING_CALL: case INCOMING_CALL: case INCOMING_CALL_ANSWERING: case INCOMING_CALL_ANSWERING: case OUTGOING_CALL: case OUTGOING_CALL_CANCELING: case OUTGOING_CALL_CANCELING: endCallOnError(SipErrorCode.TIME_OUT, event.toString()); onError(SipErrorCode.TIME_OUT, event.toString()); break; break; case PINGING: case PINGING: reset(); reset(); Loading @@ -617,7 +625,7 @@ class SipSessionGroup implements SipListener { break; break; default: default: // do nothing Log.d(TAG, " do nothing"); break; break; } } } } Loading Loading @@ -665,7 +673,7 @@ class SipSessionGroup implements SipListener { } else { } else { Log.w(TAG, "peer did not respect our rport request"); Log.w(TAG, "peer did not respect our rport request"); } } mState = SipSessionState.READY_TO_CALL; reset(); return true; return true; } } return false; return false; Loading @@ -687,7 +695,6 @@ class SipSessionGroup implements SipListener { switch (statusCode) { switch (statusCode) { case Response.OK: case Response.OK: SipSessionState state = mState; SipSessionState state = mState; reset(); onRegistrationDone((state == SipSessionState.REGISTERING) onRegistrationDone((state == SipSessionState.REGISTERING) ? getExpiryTime(((ResponseEvent) evt).getResponse()) ? getExpiryTime(((ResponseEvent) evt).getResponse()) : -1); : -1); Loading @@ -698,15 +705,13 @@ class SipSessionGroup implements SipListener { case Response.PROXY_AUTHENTICATION_REQUIRED: case Response.PROXY_AUTHENTICATION_REQUIRED: if (!handleAuthentication(event)) { if (!handleAuthentication(event)) { Log.v(TAG, "Incorrect username/password"); Log.v(TAG, "Incorrect username/password"); reset(); onRegistrationFailed(SipErrorCode.INVALID_CREDENTIALS, onRegistrationFailed(SipErrorCode.INVALID_CREDENTIALS, "incorrect username or password"); "incorrect username or password"); } } return true; return true; default: default: if (statusCode >= 500) { if (statusCode >= 500) { reset(); onRegistrationFailed(response); onRegistrationFailed(createCallbackException(response)); return true; return true; } } } } Loading @@ -720,7 +725,6 @@ class SipSessionGroup implements SipListener { String nonce = getNonceFromResponse(response); String nonce = getNonceFromResponse(response); if (((nonce != null) && nonce.equals(mLastNonce)) || if (((nonce != null) && nonce.equals(mLastNonce)) || (nonce == mLastNonce)) { (nonce == mLastNonce)) { Log.v(TAG, "Incorrect username/password"); return false; return false; } else { } else { mClientTransaction = mSipHelper.handleChallenge( mClientTransaction = mSipHelper.handleChallenge( Loading Loading @@ -906,7 +910,7 @@ class SipSessionGroup implements SipListener { } } if (statusCode >= 400) { if (statusCode >= 400) { onError(createCallbackException(response)); onError(response); return true; return true; } } } else if (evt instanceof TransactionTerminatedEvent) { } else if (evt instanceof TransactionTerminatedEvent) { Loading Loading @@ -954,10 +958,6 @@ class SipSessionGroup implements SipListener { response.getReasonPhrase(), response.getStatusCode()); response.getReasonPhrase(), response.getStatusCode()); } } private Exception createCallbackException(Response response) { return new SipException(createErrorMessage(response)); } private void establishCall() { private void establishCall() { mState = SipSessionState.IN_CALL; mState = SipSessionState.IN_CALL; mInCall = true; mInCall = true; Loading @@ -965,22 +965,22 @@ class SipSessionGroup implements SipListener { } } private void fallbackToPreviousInCall(Throwable exception) { private void fallbackToPreviousInCall(Throwable exception) { mState = SipSessionState.IN_CALL; exception = getRootCause(exception); exception = getRootCause(exception); mProxy.onCallChangeFailed(this, getErrorCode(exception).toString(), fallbackToPreviousInCall(getErrorCode(exception), exception.toString()); exception.toString()); } } private void fallbackToPreviousInCall(SipErrorCode errorCode, String message) { mState = SipSessionState.IN_CALL; mProxy.onCallChangeFailed(this, errorCode.toString(), message); } private void endCallNormally() { private void endCallNormally() { reset(); reset(); mProxy.onCallEnded(this); mProxy.onCallEnded(this); } } private void endCallOnError(Throwable exception) { exception = getRootCause(exception); endCallOnError(getErrorCode(exception), exception.toString()); } private void endCallOnError(SipErrorCode errorCode, String message) { private void endCallOnError(SipErrorCode errorCode, String message) { reset(); reset(); mProxy.onError(this, errorCode.toString(), message); mProxy.onError(this, errorCode.toString(), message); Loading @@ -991,26 +991,34 @@ class SipSessionGroup implements SipListener { mProxy.onCallBusy(this); mProxy.onCallBusy(this); } } private void onError(Throwable exception) { private void onError(SipErrorCode errorCode, String message) { switch (mState) { case REGISTERING: case DEREGISTERING: onRegistrationFailed(errorCode, message); break; default: if (mInCall) { if (mInCall) { fallbackToPreviousInCall(exception); fallbackToPreviousInCall(errorCode, message); } else { } else { endCallOnError(exception); endCallOnError(errorCode, message); } } } } } private void onError(Throwable exception) { exception = getRootCause(exception); onError(getErrorCode(exception), exception.toString()); } private void onError(Response response) { private void onError(Response response) { if (mInCall) { fallbackToPreviousInCall(createCallbackException(response)); } else { int statusCode = response.getStatusCode(); int statusCode = response.getStatusCode(); if ((statusCode == Response.TEMPORARILY_UNAVAILABLE) if (!mInCall && ((statusCode == Response.TEMPORARILY_UNAVAILABLE) || (statusCode == Response.BUSY_HERE)) { || (statusCode == Response.BUSY_HERE))) { endCallOnBusy(); endCallOnBusy(); } else { } else { endCallOnError(getErrorCode(statusCode), onError(getErrorCode(statusCode), createErrorMessage(response)); createErrorMessage(response)); } } } } } Loading Loading @@ -1053,19 +1061,29 @@ class SipSessionGroup implements SipListener { } } private void onRegistrationDone(int duration) { private void onRegistrationDone(int duration) { reset(); mProxy.onRegistrationDone(this, duration); mProxy.onRegistrationDone(this, duration); } } private void onRegistrationFailed(SipErrorCode errorCode, private void onRegistrationFailed(SipErrorCode errorCode, String message) { String message) { reset(); mProxy.onRegistrationFailed(this, errorCode.toString(), message); mProxy.onRegistrationFailed(this, errorCode.toString(), message); } } private void onRegistrationFailed(Throwable exception) { private void onRegistrationFailed(Throwable exception) { reset(); exception = getRootCause(exception); exception = getRootCause(exception); onRegistrationFailed(getErrorCode(exception), onRegistrationFailed(getErrorCode(exception), exception.toString()); exception.toString()); } } private void onRegistrationFailed(Response response) { reset(); int statusCode = response.getStatusCode(); onRegistrationFailed(getErrorCode(statusCode), createErrorMessage(response)); } } } /** /** Loading telephony/java/com/android/internal/telephony/Connection.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,7 @@ public abstract class Connection { MMI, /* not presently used; dial() returns null */ MMI, /* not presently used; dial() returns null */ INVALID_NUMBER, /* invalid dial string */ INVALID_NUMBER, /* invalid dial string */ INVALID_CREDENTIALS, /* invalid credentials */ INVALID_CREDENTIALS, /* invalid credentials */ TIMED_OUT, /* client timed out */ LOST_SIGNAL, LOST_SIGNAL, LIMIT_EXCEEDED, /* eg GSM ACM limit exceeded */ LIMIT_EXCEEDED, /* eg GSM ACM limit exceeded */ INCOMING_REJECTED, /* an incoming call that was rejected */ INCOMING_REJECTED, /* an incoming call that was rejected */ Loading telephony/java/com/android/internal/telephony/sip/SipPhone.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -826,7 +826,8 @@ public class SipPhone extends SipPhoneBase { onError(Connection.DisconnectCause.INVALID_NUMBER); onError(Connection.DisconnectCause.INVALID_NUMBER); break; break; case TIME_OUT: case TIME_OUT: onError(Connection.DisconnectCause.CONGESTION); case TRANSACTION_TERMINTED: onError(Connection.DisconnectCause.TIMED_OUT); break; break; case INVALID_CREDENTIALS: case INVALID_CREDENTIALS: onError(Connection.DisconnectCause.INVALID_CREDENTIALS); onError(Connection.DisconnectCause.INVALID_CREDENTIALS); Loading voip/java/android/net/sip/SipErrorCode.java +7 −1 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,9 @@ public enum SipErrorCode { /** When server responds with an error. */ /** When server responds with an error. */ SERVER_ERROR, SERVER_ERROR, /** When transaction is terminated unexpectedly. */ TRANSACTION_TERMINTED, /** When some error occurs on the device, possibly due to a bug. */ /** When some error occurs on the device, possibly due to a bug. */ CLIENT_ERROR, CLIENT_ERROR, Loading @@ -41,5 +44,8 @@ public enum SipErrorCode { INVALID_REMOTE_URI, INVALID_REMOTE_URI, /** When invalid credentials are provided. */ /** When invalid credentials are provided. */ INVALID_CREDENTIALS; INVALID_CREDENTIALS, /** The client is in a transaction and cannot initiate a new one. */ IN_PROGRESS; } } Loading
services/java/com/android/server/sip/SipService.java +64 −39 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.net.NetworkInfo; import android.net.sip.ISipService; import android.net.sip.ISipService; import android.net.sip.ISipSession; import android.net.sip.ISipSession; import android.net.sip.ISipSessionListener; import android.net.sip.ISipSessionListener; import android.net.sip.SipErrorCode; import android.net.sip.SipManager; import android.net.sip.SipManager; import android.net.sip.SipProfile; import android.net.sip.SipProfile; import android.net.sip.SipSessionAdapter; import android.net.sip.SipSessionAdapter; Loading Loading @@ -528,6 +529,8 @@ public final class SipService extends ISipService.Stub { private int mBackoff = 1; private int mBackoff = 1; private boolean mRegistered; private boolean mRegistered; private long mExpiryTime; private long mExpiryTime; private SipErrorCode mErrorCode; private String mErrorMessage; private String getAction() { private String getAction() { return toString(); return toString(); Loading @@ -551,16 +554,26 @@ public final class SipService extends ISipService.Stub { } } public void stop() { public void stop() { stop(false); } private void stopButKeepStates() { stop(true); } private void stop(boolean keepStates) { if (mSession == null) return; if (mSession == null) return; if (mConnected) 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; mSession = null; mRegistered = false; mRegistered = false; } } } private boolean isStopped() { private boolean isStopped() { return (mSession == null); return (mSession == null); Loading @@ -568,28 +581,43 @@ public final class SipService extends ISipService.Stub { public void setListener(ISipSessionListener listener) { public void setListener(ISipSessionListener listener) { Log.v(TAG, "setListener(): " + listener); Log.v(TAG, "setListener(): " + listener); synchronized (SipService.this) { mProxy.setListener(listener); mProxy.setListener(listener); if (mSession == null) return; if (mSession == null) return; try { try { if ((mSession != null) && SipSessionState.REGISTERING.equals( SipSessionState state = (mSession == null) mSession.getState())) { ? SipSessionState.READY_TO_CALL : Enum.valueOf( SipSessionState.class, mSession.getState()); if ((state == SipSessionState.REGISTERING) || (state == SipSessionState.DEREGISTERING)) { mProxy.onRegistering(mSession); mProxy.onRegistering(mSession); } else if (mRegistered) { } else if (mRegistered) { int duration = (int) int duration = (int) (mExpiryTime - SystemClock.elapsedRealtime()); (mExpiryTime - SystemClock.elapsedRealtime()); mProxy.onRegistrationDone(mSession, duration); mProxy.onRegistrationDone(mSession, duration); } else if (mErrorCode != null) { if (mErrorCode == SipErrorCode.TIME_OUT) { mProxy.onRegistrationTimeout(mSession); } else { mProxy.onRegistrationFailed(mSession, mErrorCode.toString(), mErrorMessage); } } } } catch (Throwable t) { } catch (Throwable t) { Log.w(TAG, "setListener(): " + t); Log.w(TAG, "setListener(): " + t); } } } } } public boolean isRegistered() { public boolean isRegistered() { return mRegistered; return mRegistered; } } public void run() { public void run() { mErrorCode = null; mErrorMessage = null; Log.v(TAG, " ~~~ registering"); Log.v(TAG, " ~~~ registering"); synchronized (SipService.this) { synchronized (SipService.this) { if (mConnected && !isStopped()) mSession.register(EXPIRY_TIME); if (mConnected && !isStopped()) mSession.register(EXPIRY_TIME); Loading Loading @@ -634,11 +662,7 @@ public final class SipService extends ISipService.Stub { synchronized (SipService.this) { synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; if (!isStopped() && (session != mSession)) return; mRegistered = false; mRegistered = false; try { mProxy.onRegistering(session); mProxy.onRegistering(session); } catch (Throwable t) { Log.w(TAG, "onRegistering()", t); } } } } } Loading @@ -647,11 +671,9 @@ public final class SipService extends ISipService.Stub { Log.v(TAG, "onRegistrationDone(): " + session + ": " + mSession); Log.v(TAG, "onRegistrationDone(): " + session + ": " + mSession); synchronized (SipService.this) { synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; if (!isStopped() && (session != mSession)) return; try { mProxy.onRegistrationDone(session, duration); mProxy.onRegistrationDone(session, duration); } catch (Throwable t) { Log.w(TAG, "onRegistrationDone()", t); } if (isStopped()) return; if (isStopped()) return; if (duration > 0) { if (duration > 0) { Loading Loading @@ -687,19 +709,25 @@ public final class SipService extends ISipService.Stub { } } @Override @Override public void onRegistrationFailed(ISipSession session, String className, public void onRegistrationFailed(ISipSession session, String message) { String errorCodeString, String message) { SipErrorCode errorCode = Enum.valueOf(SipErrorCode.class, errorCodeString); Log.v(TAG, "onRegistrationFailed(): " + session + ": " + mSession Log.v(TAG, "onRegistrationFailed(): " + session + ": " + mSession + ": " + className + ": " + message); + ": " + errorCode + ": " + message); synchronized (SipService.this) { synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; if (!isStopped() && (session != mSession)) return; try { mErrorCode = errorCode; mProxy.onRegistrationFailed(session, className, message); mErrorMessage = message; } catch (Throwable t) { mProxy.onRegistrationFailed(session, errorCode.toString(), Log.w(TAG, "onRegistrationFailed(): " + t); message); if (errorCode == SipErrorCode.INVALID_CREDENTIALS) { Log.d(TAG, " pause auto-registration"); stopButKeepStates(); } else if (!isStopped()) { onError(); } } if (!isStopped()) onError(); } } } } Loading @@ -708,11 +736,8 @@ public final class SipService extends ISipService.Stub { Log.v(TAG, "onRegistrationTimeout(): " + session + ": " + mSession); Log.v(TAG, "onRegistrationTimeout(): " + session + ": " + mSession); synchronized (SipService.this) { synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; if (!isStopped() && (session != mSession)) return; try { mErrorCode = SipErrorCode.TIME_OUT; mProxy.onRegistrationTimeout(session); mProxy.onRegistrationTimeout(session); } catch (Throwable t) { Log.w(TAG, "onRegistrationTimeout(): " + t); } if (!isStopped()) { if (!isStopped()) { mRegistered = false; mRegistered = false; Loading
services/java/com/android/server/sip/SipSessionGroup.java +82 −64 Original line number Original line Diff line number Diff line Loading @@ -412,15 +412,9 @@ class SipSessionGroup implements SipListener { processCommand(command); processCommand(command); } catch (SipException e) { } catch (SipException e) { Log.w(TAG, "command error: " + command, e); Log.w(TAG, "command error: " + command, e); // TODO: find a better way to do this if ((command instanceof RegisterCommand) || (command == DEREGISTER)) { onRegistrationFailed(e); } else { onError(e); onError(e); } } } } } }).start(); }).start(); } } Loading Loading @@ -480,7 +474,9 @@ class SipSessionGroup implements SipListener { private void processCommand(EventObject command) throws SipException { private void processCommand(EventObject command) throws SipException { if (!process(command)) { if (!process(command)) { throw new SipException("wrong state to execute: " + command); onError(SipErrorCode.IN_PROGRESS, "cannot initiate a new transaction to execute: " + command); } } } } Loading Loading @@ -562,11 +558,8 @@ class SipSessionGroup implements SipListener { if (evt instanceof TimeoutEvent) { if (evt instanceof TimeoutEvent) { processTimeout((TimeoutEvent) evt); processTimeout((TimeoutEvent) evt); } else { } else { Log.d(TAG, "Transaction terminated:" + this); processTransactionTerminated( if (!SipSessionState.IN_CALL.equals(mState)) { (TransactionTerminatedEvent) evt); removeSipSession(this); } return true; } } return true; return true; } else if (evt instanceof DialogTerminatedEvent) { } else if (evt instanceof DialogTerminatedEvent) { Loading @@ -585,6 +578,20 @@ class SipSessionGroup implements SipListener { } } } } private void processTransactionTerminated( TransactionTerminatedEvent event) { switch (mState) { case IN_CALL: case READY_TO_CALL: Log.d(TAG, "Transaction terminated; do nothing"); break; default: Log.d(TAG, "Transaction terminated early: " + this); onError(SipErrorCode.TRANSACTION_TERMINTED, "transaction terminated"); } } private void processTimeout(TimeoutEvent event) { private void processTimeout(TimeoutEvent event) { Log.d(TAG, "processing Timeout..." + event); Log.d(TAG, "processing Timeout..." + event); Transaction current = event.isServerTransaction() Transaction current = event.isServerTransaction() Loading @@ -607,8 +614,9 @@ class SipSessionGroup implements SipListener { break; break; case INCOMING_CALL: case INCOMING_CALL: case INCOMING_CALL_ANSWERING: case INCOMING_CALL_ANSWERING: case OUTGOING_CALL: case OUTGOING_CALL_CANCELING: case OUTGOING_CALL_CANCELING: endCallOnError(SipErrorCode.TIME_OUT, event.toString()); onError(SipErrorCode.TIME_OUT, event.toString()); break; break; case PINGING: case PINGING: reset(); reset(); Loading @@ -617,7 +625,7 @@ class SipSessionGroup implements SipListener { break; break; default: default: // do nothing Log.d(TAG, " do nothing"); break; break; } } } } Loading Loading @@ -665,7 +673,7 @@ class SipSessionGroup implements SipListener { } else { } else { Log.w(TAG, "peer did not respect our rport request"); Log.w(TAG, "peer did not respect our rport request"); } } mState = SipSessionState.READY_TO_CALL; reset(); return true; return true; } } return false; return false; Loading @@ -687,7 +695,6 @@ class SipSessionGroup implements SipListener { switch (statusCode) { switch (statusCode) { case Response.OK: case Response.OK: SipSessionState state = mState; SipSessionState state = mState; reset(); onRegistrationDone((state == SipSessionState.REGISTERING) onRegistrationDone((state == SipSessionState.REGISTERING) ? getExpiryTime(((ResponseEvent) evt).getResponse()) ? getExpiryTime(((ResponseEvent) evt).getResponse()) : -1); : -1); Loading @@ -698,15 +705,13 @@ class SipSessionGroup implements SipListener { case Response.PROXY_AUTHENTICATION_REQUIRED: case Response.PROXY_AUTHENTICATION_REQUIRED: if (!handleAuthentication(event)) { if (!handleAuthentication(event)) { Log.v(TAG, "Incorrect username/password"); Log.v(TAG, "Incorrect username/password"); reset(); onRegistrationFailed(SipErrorCode.INVALID_CREDENTIALS, onRegistrationFailed(SipErrorCode.INVALID_CREDENTIALS, "incorrect username or password"); "incorrect username or password"); } } return true; return true; default: default: if (statusCode >= 500) { if (statusCode >= 500) { reset(); onRegistrationFailed(response); onRegistrationFailed(createCallbackException(response)); return true; return true; } } } } Loading @@ -720,7 +725,6 @@ class SipSessionGroup implements SipListener { String nonce = getNonceFromResponse(response); String nonce = getNonceFromResponse(response); if (((nonce != null) && nonce.equals(mLastNonce)) || if (((nonce != null) && nonce.equals(mLastNonce)) || (nonce == mLastNonce)) { (nonce == mLastNonce)) { Log.v(TAG, "Incorrect username/password"); return false; return false; } else { } else { mClientTransaction = mSipHelper.handleChallenge( mClientTransaction = mSipHelper.handleChallenge( Loading Loading @@ -906,7 +910,7 @@ class SipSessionGroup implements SipListener { } } if (statusCode >= 400) { if (statusCode >= 400) { onError(createCallbackException(response)); onError(response); return true; return true; } } } else if (evt instanceof TransactionTerminatedEvent) { } else if (evt instanceof TransactionTerminatedEvent) { Loading Loading @@ -954,10 +958,6 @@ class SipSessionGroup implements SipListener { response.getReasonPhrase(), response.getStatusCode()); response.getReasonPhrase(), response.getStatusCode()); } } private Exception createCallbackException(Response response) { return new SipException(createErrorMessage(response)); } private void establishCall() { private void establishCall() { mState = SipSessionState.IN_CALL; mState = SipSessionState.IN_CALL; mInCall = true; mInCall = true; Loading @@ -965,22 +965,22 @@ class SipSessionGroup implements SipListener { } } private void fallbackToPreviousInCall(Throwable exception) { private void fallbackToPreviousInCall(Throwable exception) { mState = SipSessionState.IN_CALL; exception = getRootCause(exception); exception = getRootCause(exception); mProxy.onCallChangeFailed(this, getErrorCode(exception).toString(), fallbackToPreviousInCall(getErrorCode(exception), exception.toString()); exception.toString()); } } private void fallbackToPreviousInCall(SipErrorCode errorCode, String message) { mState = SipSessionState.IN_CALL; mProxy.onCallChangeFailed(this, errorCode.toString(), message); } private void endCallNormally() { private void endCallNormally() { reset(); reset(); mProxy.onCallEnded(this); mProxy.onCallEnded(this); } } private void endCallOnError(Throwable exception) { exception = getRootCause(exception); endCallOnError(getErrorCode(exception), exception.toString()); } private void endCallOnError(SipErrorCode errorCode, String message) { private void endCallOnError(SipErrorCode errorCode, String message) { reset(); reset(); mProxy.onError(this, errorCode.toString(), message); mProxy.onError(this, errorCode.toString(), message); Loading @@ -991,26 +991,34 @@ class SipSessionGroup implements SipListener { mProxy.onCallBusy(this); mProxy.onCallBusy(this); } } private void onError(Throwable exception) { private void onError(SipErrorCode errorCode, String message) { switch (mState) { case REGISTERING: case DEREGISTERING: onRegistrationFailed(errorCode, message); break; default: if (mInCall) { if (mInCall) { fallbackToPreviousInCall(exception); fallbackToPreviousInCall(errorCode, message); } else { } else { endCallOnError(exception); endCallOnError(errorCode, message); } } } } } private void onError(Throwable exception) { exception = getRootCause(exception); onError(getErrorCode(exception), exception.toString()); } private void onError(Response response) { private void onError(Response response) { if (mInCall) { fallbackToPreviousInCall(createCallbackException(response)); } else { int statusCode = response.getStatusCode(); int statusCode = response.getStatusCode(); if ((statusCode == Response.TEMPORARILY_UNAVAILABLE) if (!mInCall && ((statusCode == Response.TEMPORARILY_UNAVAILABLE) || (statusCode == Response.BUSY_HERE)) { || (statusCode == Response.BUSY_HERE))) { endCallOnBusy(); endCallOnBusy(); } else { } else { endCallOnError(getErrorCode(statusCode), onError(getErrorCode(statusCode), createErrorMessage(response)); createErrorMessage(response)); } } } } } Loading Loading @@ -1053,19 +1061,29 @@ class SipSessionGroup implements SipListener { } } private void onRegistrationDone(int duration) { private void onRegistrationDone(int duration) { reset(); mProxy.onRegistrationDone(this, duration); mProxy.onRegistrationDone(this, duration); } } private void onRegistrationFailed(SipErrorCode errorCode, private void onRegistrationFailed(SipErrorCode errorCode, String message) { String message) { reset(); mProxy.onRegistrationFailed(this, errorCode.toString(), message); mProxy.onRegistrationFailed(this, errorCode.toString(), message); } } private void onRegistrationFailed(Throwable exception) { private void onRegistrationFailed(Throwable exception) { reset(); exception = getRootCause(exception); exception = getRootCause(exception); onRegistrationFailed(getErrorCode(exception), onRegistrationFailed(getErrorCode(exception), exception.toString()); exception.toString()); } } private void onRegistrationFailed(Response response) { reset(); int statusCode = response.getStatusCode(); onRegistrationFailed(getErrorCode(statusCode), createErrorMessage(response)); } } } /** /** Loading
telephony/java/com/android/internal/telephony/Connection.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,7 @@ public abstract class Connection { MMI, /* not presently used; dial() returns null */ MMI, /* not presently used; dial() returns null */ INVALID_NUMBER, /* invalid dial string */ INVALID_NUMBER, /* invalid dial string */ INVALID_CREDENTIALS, /* invalid credentials */ INVALID_CREDENTIALS, /* invalid credentials */ TIMED_OUT, /* client timed out */ LOST_SIGNAL, LOST_SIGNAL, LIMIT_EXCEEDED, /* eg GSM ACM limit exceeded */ LIMIT_EXCEEDED, /* eg GSM ACM limit exceeded */ INCOMING_REJECTED, /* an incoming call that was rejected */ INCOMING_REJECTED, /* an incoming call that was rejected */ Loading
telephony/java/com/android/internal/telephony/sip/SipPhone.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -826,7 +826,8 @@ public class SipPhone extends SipPhoneBase { onError(Connection.DisconnectCause.INVALID_NUMBER); onError(Connection.DisconnectCause.INVALID_NUMBER); break; break; case TIME_OUT: case TIME_OUT: onError(Connection.DisconnectCause.CONGESTION); case TRANSACTION_TERMINTED: onError(Connection.DisconnectCause.TIMED_OUT); break; break; case INVALID_CREDENTIALS: case INVALID_CREDENTIALS: onError(Connection.DisconnectCause.INVALID_CREDENTIALS); onError(Connection.DisconnectCause.INVALID_CREDENTIALS); Loading
voip/java/android/net/sip/SipErrorCode.java +7 −1 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,9 @@ public enum SipErrorCode { /** When server responds with an error. */ /** When server responds with an error. */ SERVER_ERROR, SERVER_ERROR, /** When transaction is terminated unexpectedly. */ TRANSACTION_TERMINTED, /** When some error occurs on the device, possibly due to a bug. */ /** When some error occurs on the device, possibly due to a bug. */ CLIENT_ERROR, CLIENT_ERROR, Loading @@ -41,5 +44,8 @@ public enum SipErrorCode { INVALID_REMOTE_URI, INVALID_REMOTE_URI, /** When invalid credentials are provided. */ /** When invalid credentials are provided. */ INVALID_CREDENTIALS; INVALID_CREDENTIALS, /** The client is in a transaction and cannot initiate a new one. */ IN_PROGRESS; } }