Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 808be0d0 authored by Hung-ying Tyan's avatar Hung-ying Tyan Committed by Android (Google) Code Review
Browse files

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

parents 2c13dd77 e65f3a89
Loading
Loading
Loading
Loading
+53 −12
Original line number Original line Diff line number Diff line
@@ -462,17 +462,30 @@ public final class SipService extends ISipService.Stub {


    private void startPortMappingLifetimeMeasurement(
    private void startPortMappingLifetimeMeasurement(
            SipProfile localProfile) {
            SipProfile localProfile) {
        startPortMappingLifetimeMeasurement(localProfile, -1);
    }

    private void startPortMappingLifetimeMeasurement(
            SipProfile localProfile, int maxInterval) {
        if ((mIntervalMeasurementProcess == null)
        if ((mIntervalMeasurementProcess == null)
                && (mKeepAliveInterval == -1)
                && (mKeepAliveInterval == -1)
                && isBehindNAT(mLocalIp)) {
                && isBehindNAT(mLocalIp)) {
            Log.d(TAG, "start NAT port mapping timeout measurement on "
            Log.d(TAG, "start NAT port mapping timeout measurement on "
                    + localProfile.getUriString());
                    + localProfile.getUriString());


            mIntervalMeasurementProcess = new IntervalMeasurementProcess(localProfile);
            mIntervalMeasurementProcess =
                    new IntervalMeasurementProcess(localProfile, maxInterval);
            mIntervalMeasurementProcess.start();
            mIntervalMeasurementProcess.start();
        }
        }
    }
    }


    private void restartPortMappingLifetimeMeasurement(
            SipProfile localProfile, int maxInterval) {
        stopPortMappingMeasurement();
        mKeepAliveInterval = -1;
        startPortMappingLifetimeMeasurement(localProfile, maxInterval);
    }

    private synchronized void addPendingSession(ISipSession session) {
    private synchronized void addPendingSession(ISipSession session) {
        try {
        try {
            cleanUpPendingSessions();
            cleanUpPendingSessions();
@@ -746,18 +759,30 @@ public final class SipService extends ISipService.Stub {
    private class IntervalMeasurementProcess implements
    private class IntervalMeasurementProcess implements
            SipSessionGroup.KeepAliveProcessCallback {
            SipSessionGroup.KeepAliveProcessCallback {
        private static final String TAG = "SipKeepAliveInterval";
        private static final String TAG = "SipKeepAliveInterval";
        private static final int MAX_INTERVAL = 120; // seconds
        private static final int MAX_INTERVAL = 120; // in seconds
        private static final int MIN_INTERVAL = SHORT_EXPIRY_TIME;
        private static final int MIN_INTERVAL = 10; // in seconds
        private static final int PASS_THRESHOLD = 10;
        private static final int PASS_THRESHOLD = 10;
        private static final int MAX_RETRY_COUNT = 5;
        private SipSessionGroupExt mGroup;
        private SipSessionGroupExt mGroup;
        private SipSessionGroup.SipSessionImpl mSession;
        private SipSessionGroup.SipSessionImpl mSession;
        private boolean mRunning;
        private boolean mRunning;
        private int mMinInterval = 10; // in seconds
        private int mMinInterval = 10; // in seconds
        private int mMaxInterval = MAX_INTERVAL;
        private int mMaxInterval;
        private int mInterval = MAX_INTERVAL / 2;
        private int mInterval;
        private int mPassCounter = 0;
        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 {
            try {
                mGroup =  new SipSessionGroupExt(localProfile, null, null);
                mGroup =  new SipSessionGroupExt(localProfile, null, null);
                // TODO: remove this line once SipWakeupTimer can better handle
                // TODO: remove this line once SipWakeupTimer can better handle
@@ -801,8 +826,10 @@ public final class SipService extends ISipService.Stub {
        @Override
        @Override
        public void onResponse(boolean portChanged) {
        public void onResponse(boolean portChanged) {
            synchronized (SipService.this) {
            synchronized (SipService.this) {
                mErrorCount = 0;

                if (!portChanged) {
                if (!portChanged) {
                    if (++mPassCounter != PASS_THRESHOLD) return;
                    if (++mPassCount != PASS_THRESHOLD) return;
                    // update the interval, since the current interval is good to
                    // update the interval, since the current interval is good to
                    // keep the port mapping.
                    // keep the port mapping.
                    mKeepAliveInterval = mMinInterval = mInterval;
                    mKeepAliveInterval = mMinInterval = mInterval;
@@ -826,7 +853,7 @@ public final class SipService extends ISipService.Stub {
                } else {
                } else {
                    // calculate the new interval and continue.
                    // calculate the new interval and continue.
                    mInterval = (mMaxInterval + mMinInterval) / 2;
                    mInterval = (mMaxInterval + mMinInterval) / 2;
                    mPassCounter = 0;
                    mPassCount = 0;
                    if (DEBUG) {
                    if (DEBUG) {
                        Log.d(TAG, "current interval: " + mKeepAliveInterval
                        Log.d(TAG, "current interval: " + mKeepAliveInterval
                                + ", test new interval: " + mInterval);
                                + ", test new interval: " + mInterval);
@@ -841,6 +868,13 @@ public final class SipService extends ISipService.Stub {
        public void onError(int errorCode, String description) {
        public void onError(int errorCode, String description) {
            synchronized (SipService.this) {
            synchronized (SipService.this) {
                Log.w(TAG, "interval measurement error: " + description);
                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
        @Override
        public void onResponse(boolean portChanged) {
        public void onResponse(boolean portChanged) {
            synchronized (SipService.this) {
            synchronized (SipService.this) {
                // Start keep-alive interval measurement on the first successfully
                if (portChanged) {
                // kept-alive SipSessionGroup
                    restartPortMappingLifetimeMeasurement(
                startPortMappingLifetimeMeasurement(mSession.getLocalProfile());
                            mSession.getLocalProfile(), getKeepAliveInterval());
                } else {
                    // Start keep-alive interval measurement on the first
                    // successfully kept-alive SipSessionGroup
                    startPortMappingLifetimeMeasurement(
                            mSession.getLocalProfile());
                }


                if (!mRunning || !portChanged) return;
                if (!mRunning || !portChanged) return;


@@ -907,6 +947,7 @@ public final class SipService extends ISipService.Stub {
        @Override
        @Override
        public void onError(int errorCode, String description) {
        public void onError(int errorCode, String description) {
            Log.e(TAG, "keepalive error: " + description);
            Log.e(TAG, "keepalive error: " + description);
            onResponse(true); // re-register immediately
        }
        }


        public void stop() {
        public void stop() {
+3 −1
Original line number Original line Diff line number Diff line
@@ -1259,11 +1259,13 @@ class SipSessionGroup implements SipListener {


            private boolean mPortChanged = false;
            private boolean mPortChanged = false;
            private int mRPort = 0;
            private int mRPort = 0;
            private int mInterval; // just for debugging


            // @param interval in seconds
            // @param interval in seconds
            void start(int interval, KeepAliveProcessCallback callback) {
            void start(int interval, KeepAliveProcessCallback callback) {
                if (mRunning) return;
                if (mRunning) return;
                mRunning = true;
                mRunning = true;
                mInterval = interval;
                mCallback = new KeepAliveProcessCallbackProxy(callback);
                mCallback = new KeepAliveProcessCallbackProxy(callback);
                mWakeupTimer.set(interval * 1000, this);
                mWakeupTimer.set(interval * 1000, this);
                if (DEBUG) {
                if (DEBUG) {
@@ -1311,7 +1313,7 @@ class SipSessionGroup implements SipListener {


                    if (DEBUG_PING) {
                    if (DEBUG_PING) {
                        Log.d(TAG, "keepalive: " + mLocalProfile.getUriString()
                        Log.d(TAG, "keepalive: " + mLocalProfile.getUriString()
                                + " --> " + mPeerProfile);
                                + " --> " + mPeerProfile + ", interval=" + mInterval);
                    }
                    }
                    try {
                    try {
                        sendKeepAlive();
                        sendKeepAlive();