diff options
| author | Hung-ying Tyan <tyanh@google.com> | 2011-06-24 15:17:25 +0800 |
|---|---|---|
| committer | Hung-ying Tyan <tyanh@google.com> | 2011-06-24 15:28:15 +0800 |
| commit | e65f3a896f03bba5327ce4f3989c0422855450ca (patch) | |
| tree | 28e247e2cb528746e5567a204eb7836cabbdbc9e | |
| parent | 4af085ff26fbe9e13f7002496fd505dbdb36b282 (diff) | |
| download | frameworks_base-e65f3a896f03bba5327ce4f3989c0422855450ca.zip frameworks_base-e65f3a896f03bba5327ce4f3989c0422855450ca.tar.gz frameworks_base-e65f3a896f03bba5327ce4f3989c0422855450ca.tar.bz2 | |
Restart NAT port timeout measurement when keepalive fails and other fixes
Misc keepalive fixes including:
+ Restart NAT port timeout measurement when keepalive fails. The max interval
is set to the current keepalive interval.
+ When exception occurs during sending a keepalive, restarts registration.
+ When exception occurs during measurement, retry for a limited times before
giving up.
Change-Id: I7aa787a5ec7c4c9b4334aa1017371d9049b3520c
| -rw-r--r-- | voip/java/com/android/server/sip/SipService.java | 65 | ||||
| -rw-r--r-- | voip/java/com/android/server/sip/SipSessionGroup.java | 4 |
2 files changed, 56 insertions, 13 deletions
diff --git a/voip/java/com/android/server/sip/SipService.java b/voip/java/com/android/server/sip/SipService.java index f8e5b3a..3b0f546 100644 --- a/voip/java/com/android/server/sip/SipService.java +++ b/voip/java/com/android/server/sip/SipService.java @@ -462,17 +462,30 @@ public final class SipService extends ISipService.Stub { private void startPortMappingLifetimeMeasurement( SipProfile localProfile) { + startPortMappingLifetimeMeasurement(localProfile, -1); + } + + private void startPortMappingLifetimeMeasurement( + SipProfile localProfile, int maxInterval) { if ((mIntervalMeasurementProcess == null) && (mKeepAliveInterval == -1) && isBehindNAT(mLocalIp)) { Log.d(TAG, "start NAT port mapping timeout measurement on " + localProfile.getUriString()); - mIntervalMeasurementProcess = new IntervalMeasurementProcess(localProfile); + mIntervalMeasurementProcess = + new IntervalMeasurementProcess(localProfile, maxInterval); mIntervalMeasurementProcess.start(); } } + private void restartPortMappingLifetimeMeasurement( + SipProfile localProfile, int maxInterval) { + stopPortMappingMeasurement(); + mKeepAliveInterval = -1; + startPortMappingLifetimeMeasurement(localProfile, maxInterval); + } + private synchronized void addPendingSession(ISipSession session) { try { cleanUpPendingSessions(); @@ -746,18 +759,30 @@ public final class SipService extends ISipService.Stub { private class IntervalMeasurementProcess implements SipSessionGroup.KeepAliveProcessCallback { private static final String TAG = "SipKeepAliveInterval"; - private static final int MAX_INTERVAL = 120; // seconds - private static final int MIN_INTERVAL = SHORT_EXPIRY_TIME; + private static final int MAX_INTERVAL = 120; // in seconds + private static final int MIN_INTERVAL = 10; // in seconds private static final int PASS_THRESHOLD = 10; + private static final int MAX_RETRY_COUNT = 5; private SipSessionGroupExt mGroup; private SipSessionGroup.SipSessionImpl mSession; private boolean mRunning; private int mMinInterval = 10; // in seconds - private int mMaxInterval = MAX_INTERVAL; - private int mInterval = MAX_INTERVAL / 2; - private int mPassCounter = 0; + private int mMaxInterval; + private int mInterval; + private int mPassCount = 0; + private int mErrorCount = 0; + + public IntervalMeasurementProcess(SipProfile localProfile, int maxInterval) { + mMaxInterval = (maxInterval < 0) ? MAX_INTERVAL : maxInterval; + mInterval = (mMaxInterval + mMinInterval) / 2; + + // Don't start measurement if the interval is too small + if (mInterval < MIN_INTERVAL) { + Log.w(TAG, "interval is too small; measurement aborted; " + + "maxInterval=" + mMaxInterval); + return; + } - public IntervalMeasurementProcess(SipProfile localProfile) { try { mGroup = new SipSessionGroupExt(localProfile, null, null); // TODO: remove this line once SipWakeupTimer can better handle @@ -801,8 +826,10 @@ public final class SipService extends ISipService.Stub { @Override public void onResponse(boolean portChanged) { synchronized (SipService.this) { + mErrorCount = 0; + if (!portChanged) { - if (++mPassCounter != PASS_THRESHOLD) return; + if (++mPassCount != PASS_THRESHOLD) return; // update the interval, since the current interval is good to // keep the port mapping. mKeepAliveInterval = mMinInterval = mInterval; @@ -826,7 +853,7 @@ public final class SipService extends ISipService.Stub { } else { // calculate the new interval and continue. mInterval = (mMaxInterval + mMinInterval) / 2; - mPassCounter = 0; + mPassCount = 0; if (DEBUG) { Log.d(TAG, "current interval: " + mKeepAliveInterval + ", test new interval: " + mInterval); @@ -841,6 +868,13 @@ public final class SipService extends ISipService.Stub { public void onError(int errorCode, String description) { synchronized (SipService.this) { Log.w(TAG, "interval measurement error: " + description); + if (++mErrorCount < MAX_RETRY_COUNT) { + Log.w(TAG, " retry count = " + mErrorCount); + mPassCount = 0; + restart(); + } else { + Log.w(TAG, " max retry count reached; measurement aborted"); + } } } } @@ -885,9 +919,15 @@ public final class SipService extends ISipService.Stub { @Override public void onResponse(boolean portChanged) { synchronized (SipService.this) { - // Start keep-alive interval measurement on the first successfully - // kept-alive SipSessionGroup - startPortMappingLifetimeMeasurement(mSession.getLocalProfile()); + if (portChanged) { + restartPortMappingLifetimeMeasurement( + mSession.getLocalProfile(), getKeepAliveInterval()); + } else { + // Start keep-alive interval measurement on the first + // successfully kept-alive SipSessionGroup + startPortMappingLifetimeMeasurement( + mSession.getLocalProfile()); + } if (!mRunning || !portChanged) return; @@ -907,6 +947,7 @@ public final class SipService extends ISipService.Stub { @Override public void onError(int errorCode, String description) { Log.e(TAG, "keepalive error: " + description); + onResponse(true); // re-register immediately } public void stop() { diff --git a/voip/java/com/android/server/sip/SipSessionGroup.java b/voip/java/com/android/server/sip/SipSessionGroup.java index cc3e410..2d0dd9c 100644 --- a/voip/java/com/android/server/sip/SipSessionGroup.java +++ b/voip/java/com/android/server/sip/SipSessionGroup.java @@ -1259,11 +1259,13 @@ class SipSessionGroup implements SipListener { private boolean mPortChanged = false; private int mRPort = 0; + private int mInterval; // just for debugging // @param interval in seconds void start(int interval, KeepAliveProcessCallback callback) { if (mRunning) return; mRunning = true; + mInterval = interval; mCallback = new KeepAliveProcessCallbackProxy(callback); mWakeupTimer.set(interval * 1000, this); if (DEBUG) { @@ -1311,7 +1313,7 @@ class SipSessionGroup implements SipListener { if (DEBUG_PING) { Log.d(TAG, "keepalive: " + mLocalProfile.getUriString() - + " --> " + mPeerProfile); + + " --> " + mPeerProfile + ", interval=" + mInterval); } try { sendKeepAlive(); |
