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

Commit 2f7509a7 authored by Erik Kline's avatar Erik Kline Committed by android-build-merger
Browse files

Support tethering IPv6 toward the first requested downstream. am: 6e29bf00

am: ea6634fb

Change-Id: I60fff390f3142c7a5e4336816b56b4e18aa2122e
parents d254d188 ea6634fb
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -1616,6 +1616,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
                        if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
                        if (mNotifyList.indexOf(who) < 0) {
                            mNotifyList.add(who);
                            mIPv6TetheringCoordinator.addActiveDownstream(who);
                        }
                        transitionTo(mTetherModeAliveState);
                        break;
@@ -1623,6 +1624,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
                        who = (TetherInterfaceStateMachine)message.obj;
                        if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
                        mNotifyList.remove(who);
                        mIPv6TetheringCoordinator.removeActiveDownstream(who);
                        break;
                    default:
                        retValue = false;
@@ -1661,17 +1663,19 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
                maybeLogMessage(this, message.what);
                boolean retValue = true;
                switch (message.what) {
                    case CMD_TETHER_MODE_REQUESTED:
                    case CMD_TETHER_MODE_REQUESTED: {
                        TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
                        if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
                        if (mNotifyList.indexOf(who) < 0) {
                            mNotifyList.add(who);
                            mIPv6TetheringCoordinator.addActiveDownstream(who);
                        }
                        who.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED,
                                mCurrentUpstreamIface);
                        break;
                    case CMD_TETHER_MODE_UNREQUESTED:
                        who = (TetherInterfaceStateMachine)message.obj;
                    }
                    case CMD_TETHER_MODE_UNREQUESTED: {
                        TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
                        if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
                        if (mNotifyList.remove(who)) {
                            if (DBG) Log.d(TAG, "TetherModeAlive removing notifyee " + who);
@@ -1689,7 +1693,9 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
                        } else {
                           Log.e(TAG, "TetherModeAliveState UNREQUESTED has unknown who: " + who);
                        }
                        mIPv6TetheringCoordinator.removeActiveDownstream(who);
                        break;
                    }
                    case CMD_UPSTREAM_CHANGED:
                        // need to try DUN immediately if Wifi goes down
                        mTryCell = true;
+40 −14
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.util.Log;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.LinkedList;


/**
@@ -45,10 +46,28 @@ public class IPv6TetheringCoordinator {
    private static final boolean VDBG = false;

    private final ArrayList<TetherInterfaceStateMachine> mNotifyList;
    private final LinkedList<TetherInterfaceStateMachine> mActiveDownstreams;
    private NetworkState mUpstreamNetworkState;

    public IPv6TetheringCoordinator(ArrayList<TetherInterfaceStateMachine> notifyList) {
        mNotifyList = notifyList;
        mActiveDownstreams = new LinkedList<>();
    }

    public void addActiveDownstream(TetherInterfaceStateMachine downstream) {
        if (mActiveDownstreams.indexOf(downstream) == -1) {
            // Adding a new downstream appends it to the list. Adding a
            // downstream a second time without first removing it has no effect.
            mActiveDownstreams.offer(downstream);
            updateIPv6TetheringInterfaces();
        }
    }

    public void removeActiveDownstream(TetherInterfaceStateMachine downstream) {
        stopIPv6TetheringOn(downstream);
        if (mActiveDownstreams.remove(downstream)) {
            updateIPv6TetheringInterfaces();
        }
    }

    public void updateUpstreamNetworkState(NetworkState ns) {
@@ -72,8 +91,7 @@ public class IPv6TetheringCoordinator {

    private void stopIPv6TetheringOnAllInterfaces() {
        for (TetherInterfaceStateMachine sm : mNotifyList) {
            sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE,
                    0, 0, null);
            stopIPv6TetheringOn(sm);
        }
    }

@@ -98,28 +116,32 @@ public class IPv6TetheringCoordinator {

    private void updateIPv6TetheringInterfaces() {
        for (TetherInterfaceStateMachine sm : mNotifyList) {
            final LinkProperties lp = getInterfaceIPv6LinkProperties(sm.interfaceType());
            final LinkProperties lp = getInterfaceIPv6LinkProperties(sm);
            sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, lp);
            break;
        }
    }

    private LinkProperties getInterfaceIPv6LinkProperties(int interfaceType) {
    private LinkProperties getInterfaceIPv6LinkProperties(TetherInterfaceStateMachine sm) {
        if (mUpstreamNetworkState == null) return null;

        if (sm.interfaceType() == ConnectivityManager.TETHERING_BLUETOOTH) {
            // TODO: Figure out IPv6 support on PAN interfaces.
            return null;
        }

        // NOTE: Here, in future, we would have policies to decide how to divvy
        // up the available dedicated prefixes among downstream interfaces.
        // At this time we have no such mechanism--we only support tethering
        // IPv6 toward Wi-Fi interfaces.
        // IPv6 toward the oldest (first requested) active downstream.

        switch (interfaceType) {
            case ConnectivityManager.TETHERING_WIFI:
        final TetherInterfaceStateMachine currentActive = mActiveDownstreams.peek();
        if (currentActive != null && currentActive == sm) {
            final LinkProperties lp = getIPv6OnlyLinkProperties(
                    mUpstreamNetworkState.linkProperties);
            if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) {
                return lp;
            }
                break;
        }

        return null;
@@ -250,4 +272,8 @@ public class IPv6TetheringCoordinator {
                ns.networkCapabilities,
                ns.linkProperties);
    }

    private static void stopIPv6TetheringOn(TetherInterfaceStateMachine sm) {
        sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
    }
}