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

View File

@@ -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 LinkProperties lp = getIPv6OnlyLinkProperties(
mUpstreamNetworkState.linkProperties);
if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) {
return lp;
}
break;
final TetherInterfaceStateMachine currentActive = mActiveDownstreams.peek();
if (currentActive != null && currentActive == sm) {
final LinkProperties lp = getIPv6OnlyLinkProperties(
mUpstreamNetworkState.linkProperties);
if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) {
return lp;
}
}
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);
}
}