Merge "Restart NAT port timeout measurement when keepalive fails and other fixes"

This commit is contained in:
Hung-ying Tyan
2011-06-24 01:37:53 -07:00
committed by Android (Google) Code Review
2 changed files with 56 additions and 13 deletions

View File

@@ -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() {

View File

@@ -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();