summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHung-ying Tyan <tyanh@google.com>2011-06-24 15:17:25 +0800
committerHung-ying Tyan <tyanh@google.com>2011-06-24 15:28:15 +0800
commite65f3a896f03bba5327ce4f3989c0422855450ca (patch)
tree28e247e2cb528746e5567a204eb7836cabbdbc9e
parent4af085ff26fbe9e13f7002496fd505dbdb36b282 (diff)
downloadframeworks_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.java65
-rw-r--r--voip/java/com/android/server/sip/SipSessionGroup.java4
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();