Merge "Support tethering IPv6 toward the first requested downstream." into nyc-mr1-dev

This commit is contained in:
Erik Kline
2016-08-17 00:43:35 +00:00
committed by Android (Google) Code Review
2 changed files with 48 additions and 16 deletions

View File

@@ -1616,6 +1616,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
if (mNotifyList.indexOf(who) < 0) { if (mNotifyList.indexOf(who) < 0) {
mNotifyList.add(who); mNotifyList.add(who);
mIPv6TetheringCoordinator.addActiveDownstream(who);
} }
transitionTo(mTetherModeAliveState); transitionTo(mTetherModeAliveState);
break; break;
@@ -1623,6 +1624,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
who = (TetherInterfaceStateMachine)message.obj; who = (TetherInterfaceStateMachine)message.obj;
if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
mNotifyList.remove(who); mNotifyList.remove(who);
mIPv6TetheringCoordinator.removeActiveDownstream(who);
break; break;
default: default:
retValue = false; retValue = false;
@@ -1661,17 +1663,19 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
maybeLogMessage(this, message.what); maybeLogMessage(this, message.what);
boolean retValue = true; boolean retValue = true;
switch (message.what) { switch (message.what) {
case CMD_TETHER_MODE_REQUESTED: case CMD_TETHER_MODE_REQUESTED: {
TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj; TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
if (mNotifyList.indexOf(who) < 0) { if (mNotifyList.indexOf(who) < 0) {
mNotifyList.add(who); mNotifyList.add(who);
mIPv6TetheringCoordinator.addActiveDownstream(who);
} }
who.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED, who.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED,
mCurrentUpstreamIface); mCurrentUpstreamIface);
break; 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 (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
if (mNotifyList.remove(who)) { if (mNotifyList.remove(who)) {
if (DBG) Log.d(TAG, "TetherModeAlive removing notifyee " + who); if (DBG) Log.d(TAG, "TetherModeAlive removing notifyee " + who);
@@ -1689,7 +1693,9 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
} else { } else {
Log.e(TAG, "TetherModeAliveState UNREQUESTED has unknown who: " + who); Log.e(TAG, "TetherModeAliveState UNREQUESTED has unknown who: " + who);
} }
mIPv6TetheringCoordinator.removeActiveDownstream(who);
break; break;
}
case CMD_UPSTREAM_CHANGED: case CMD_UPSTREAM_CHANGED:
// need to try DUN immediately if Wifi goes down // need to try DUN immediately if Wifi goes down
mTryCell = true; mTryCell = true;

View File

@@ -29,6 +29,7 @@ import android.util.Log;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
/** /**
@@ -45,10 +46,28 @@ public class IPv6TetheringCoordinator {
private static final boolean VDBG = false; private static final boolean VDBG = false;
private final ArrayList<TetherInterfaceStateMachine> mNotifyList; private final ArrayList<TetherInterfaceStateMachine> mNotifyList;
private final LinkedList<TetherInterfaceStateMachine> mActiveDownstreams;
private NetworkState mUpstreamNetworkState; private NetworkState mUpstreamNetworkState;
public IPv6TetheringCoordinator(ArrayList<TetherInterfaceStateMachine> notifyList) { public IPv6TetheringCoordinator(ArrayList<TetherInterfaceStateMachine> notifyList) {
mNotifyList = 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) { public void updateUpstreamNetworkState(NetworkState ns) {
@@ -72,8 +91,7 @@ public class IPv6TetheringCoordinator {
private void stopIPv6TetheringOnAllInterfaces() { private void stopIPv6TetheringOnAllInterfaces() {
for (TetherInterfaceStateMachine sm : mNotifyList) { for (TetherInterfaceStateMachine sm : mNotifyList) {
sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, stopIPv6TetheringOn(sm);
0, 0, null);
} }
} }
@@ -98,28 +116,32 @@ public class IPv6TetheringCoordinator {
private void updateIPv6TetheringInterfaces() { private void updateIPv6TetheringInterfaces() {
for (TetherInterfaceStateMachine sm : mNotifyList) { 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); sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, lp);
break; break;
} }
} }
private LinkProperties getInterfaceIPv6LinkProperties(int interfaceType) { private LinkProperties getInterfaceIPv6LinkProperties(TetherInterfaceStateMachine sm) {
if (mUpstreamNetworkState == null) return null; 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 // NOTE: Here, in future, we would have policies to decide how to divvy
// up the available dedicated prefixes among downstream interfaces. // up the available dedicated prefixes among downstream interfaces.
// At this time we have no such mechanism--we only support tethering // 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) { final TetherInterfaceStateMachine currentActive = mActiveDownstreams.peek();
case ConnectivityManager.TETHERING_WIFI: if (currentActive != null && currentActive == sm) {
final LinkProperties lp = getIPv6OnlyLinkProperties( final LinkProperties lp = getIPv6OnlyLinkProperties(
mUpstreamNetworkState.linkProperties); mUpstreamNetworkState.linkProperties);
if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) { if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) {
return lp; return lp;
} }
break;
} }
return null; return null;
@@ -250,4 +272,8 @@ public class IPv6TetheringCoordinator {
ns.networkCapabilities, ns.networkCapabilities,
ns.linkProperties); ns.linkProperties);
} }
private static void stopIPv6TetheringOn(TetherInterfaceStateMachine sm) {
sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
}
} }