Merge "Support tethering IPv6 toward the first requested downstream." into nyc-mr1-dev
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user