[Thread] add vendor & model name support for net diag
1. allow OEMs to default the vendor and model name to system properties. 2. use the vendor & model name for net diag TLVs Change-Id: I30e988ba3e9cb9f9c5dc3a096f162d5dbcdfbc11
This commit is contained in:
parent
4b2271398c
commit
6303c84ef5
7 changed files with 166 additions and 64 deletions
|
|
@ -46,11 +46,12 @@
|
|||
<bool name="config_thread_location_use_for_country_code_enabled">true</bool>
|
||||
|
||||
<!-- Specifies the UTF-8 vendor name of this device. If this value is not an empty string, it
|
||||
will be included in TXT value (key is 'vn') of the "_meshcop._udp" mDNS service which is
|
||||
published by the Thread service. A non-empty string value must not exceed length of 24 UTF-8
|
||||
bytes.
|
||||
will be included in TXT value (key is 'vn') of the "_meshcop._udp" mDNS service as well as the
|
||||
Vendor Name TLV for network diagnostic. A non-empty string value must not exceed length of 24
|
||||
UTF-8 bytes. A special value "ro.product.manufacturer" indicates this value should be derived
|
||||
from the `ro.product.manufacturer` system property.
|
||||
-->
|
||||
<string translatable="false" name="config_thread_vendor_name">Android</string>
|
||||
<string translatable="false" name="config_thread_vendor_name">ro.product.manufacturer</string>
|
||||
|
||||
<!-- Specifies the 24 bits vendor OUI of this device. If this value is not an empty string, it
|
||||
will be included in TXT (key is 'vo') value of the "_meshcop._udp" mDNS service which is
|
||||
|
|
@ -61,11 +62,12 @@
|
|||
<string translatable="false" name="config_thread_vendor_oui"></string>
|
||||
|
||||
<!-- Specifies the UTF-8 product model name of this device. If this value is not an empty
|
||||
string, it will be included in TXT (key is 'mn') value of the "_meshcop._udp" mDNS service
|
||||
which is published by the Thread service. A non-empty string value must not exceed length of 24
|
||||
UTF-8 bytes.
|
||||
string, it will be included in TXT (key is 'mn') value of the "_meshcop._udp" mDNS service as
|
||||
well as the Vendor Model TLV for network diagnostic. A non-empty string value must not exceed
|
||||
length of 24 UTF-8 bytes. A special value "ro.product.model" indicates this value should be
|
||||
derived from the `ro.product.model` system property.
|
||||
-->
|
||||
<string translatable="false" name="config_thread_model_name">Thread Border Router</string>
|
||||
<string translatable="false" name="config_thread_model_name">ro.product.model</string>
|
||||
|
||||
<!-- Specifies vendor-specific mDNS TXT entries which will be included in the "_meshcop._udp"
|
||||
service. The TXT entries list MUST conform to the format requirement in RFC 6763 section 6. For
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ import com.android.net.module.util.RoutingCoordinatorManager;
|
|||
import com.android.net.module.util.SharedLog;
|
||||
import com.android.server.ServiceManagerWrapper;
|
||||
import com.android.server.connectivity.ConnectivityResources;
|
||||
import com.android.server.connectivity.MockableSystemProperties;
|
||||
import com.android.server.thread.openthread.BackboneRouterState;
|
||||
import com.android.server.thread.openthread.DnsTxtAttribute;
|
||||
import com.android.server.thread.openthread.IChannelMasksReceiver;
|
||||
|
|
@ -191,6 +192,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
|
||||
private final Context mContext;
|
||||
private final Handler mHandler;
|
||||
private final MockableSystemProperties mSystemProperties;
|
||||
|
||||
// Below member fields can only be accessed from the handler thread (`mHandler`). In
|
||||
// particular, the constructor does not run on the handler thread, so it must not touch any of
|
||||
|
|
@ -235,6 +237,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
ThreadNetworkControllerService(
|
||||
Context context,
|
||||
Handler handler,
|
||||
MockableSystemProperties systemProperties,
|
||||
NetworkProvider networkProvider,
|
||||
Supplier<IOtDaemon> otDaemonSupplier,
|
||||
ConnectivityManager connectivityManager,
|
||||
|
|
@ -249,6 +252,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
Map<Network, LinkProperties> networkToLinkProperties) {
|
||||
mContext = context;
|
||||
mHandler = handler;
|
||||
mSystemProperties = systemProperties;
|
||||
mNetworkProvider = networkProvider;
|
||||
mOtDaemonSupplier = otDaemonSupplier;
|
||||
mConnectivityManager = connectivityManager;
|
||||
|
|
@ -286,6 +290,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
return new ThreadNetworkControllerService(
|
||||
context,
|
||||
handler,
|
||||
new MockableSystemProperties(),
|
||||
networkProvider,
|
||||
() -> IOtDaemon.Stub.asInterface(ServiceManagerWrapper.waitForService("ot_daemon")),
|
||||
connectivityManager,
|
||||
|
|
@ -355,7 +360,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
newOtDaemonConfig(mPersistentSettings.getConfiguration()),
|
||||
mTunIfController.getTunFd(),
|
||||
mNsdPublisher,
|
||||
getMeshcopTxtAttributes(mResources.get()),
|
||||
getMeshcopTxtAttributes(mResources.get(), mSystemProperties),
|
||||
mCountryCodeSupplier.get(),
|
||||
FeatureFlags.isTrelEnabled(),
|
||||
mOtDaemonCallbackProxy);
|
||||
|
|
@ -365,10 +370,37 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
return mOtDaemon;
|
||||
}
|
||||
|
||||
static String getVendorName(Resources resources, MockableSystemProperties systemProperties) {
|
||||
final String PROP_MANUFACTURER = "ro.product.manufacturer";
|
||||
String vendorName = resources.getString(R.string.config_thread_vendor_name);
|
||||
if (vendorName.equalsIgnoreCase(PROP_MANUFACTURER)) {
|
||||
vendorName = systemProperties.get(PROP_MANUFACTURER);
|
||||
// Assume it's always ASCII chars in ro.product.manufacturer
|
||||
if (vendorName.length() > MAX_VENDOR_NAME_UTF8_BYTES) {
|
||||
vendorName = vendorName.substring(0, MAX_VENDOR_NAME_UTF8_BYTES);
|
||||
}
|
||||
}
|
||||
return vendorName;
|
||||
}
|
||||
|
||||
static String getModelName(Resources resources, MockableSystemProperties systemProperties) {
|
||||
final String PROP_MODEL = "ro.product.model";
|
||||
String modelName = resources.getString(R.string.config_thread_model_name);
|
||||
if (modelName.equalsIgnoreCase(PROP_MODEL)) {
|
||||
modelName = systemProperties.get(PROP_MODEL);
|
||||
// Assume it's always ASCII chars in ro.product.model
|
||||
if (modelName.length() > MAX_MODEL_NAME_UTF8_BYTES) {
|
||||
modelName = modelName.substring(0, MAX_MODEL_NAME_UTF8_BYTES);
|
||||
}
|
||||
}
|
||||
return modelName;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static MeshcopTxtAttributes getMeshcopTxtAttributes(Resources resources) {
|
||||
final String modelName = resources.getString(R.string.config_thread_model_name);
|
||||
final String vendorName = resources.getString(R.string.config_thread_vendor_name);
|
||||
static MeshcopTxtAttributes getMeshcopTxtAttributes(
|
||||
Resources resources, MockableSystemProperties systemProperties) {
|
||||
final String vendorName = getVendorName(resources, systemProperties);
|
||||
final String modelName = getModelName(resources, systemProperties);
|
||||
final String vendorOui = resources.getString(R.string.config_thread_vendor_oui);
|
||||
final String[] vendorSpecificTxts =
|
||||
resources.getStringArray(R.array.config_thread_mdns_vendor_specific_txts);
|
||||
|
|
@ -637,6 +669,8 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
.setSrpServerWaitForBorderRoutingEnabled(srpServerWaitEnabled)
|
||||
.setBorderRouterAutoJoinEnabled(autoJoinEnabled)
|
||||
.setCountryCodeEnabled(countryCodeEnabled)
|
||||
.setVendorName(getVendorName(mResources.get(), mSystemProperties))
|
||||
.setModelName(getModelName(mResources.get(), mSystemProperties))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ import android.net.thread.utils.ThreadFeatureCheckerRule.RequiresSimulationThrea
|
|||
import android.net.thread.utils.ThreadFeatureCheckerRule.RequiresThreadFeature;
|
||||
import android.net.thread.utils.ThreadNetworkControllerWrapper;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.SystemProperties;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.filters.LargeTest;
|
||||
|
|
@ -454,14 +455,22 @@ public class ServiceDiscoveryTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void meshcopOverlay_vendorAndModelNameAreSetToOverlayValue() throws Exception {
|
||||
public void meshcopOverlay_vendorAndModelNameAreSetToSystemProperties() throws Exception {
|
||||
NsdServiceInfo discoveredService = discoverService(mNsdManager, "_meshcop._udp");
|
||||
assertThat(discoveredService).isNotNull();
|
||||
NsdServiceInfo meshcopService = resolveService(mNsdManager, discoveredService);
|
||||
String expectedVendorName = SystemProperties.get("ro.product.manufacturer");
|
||||
if (expectedVendorName.length() > 24) {
|
||||
expectedVendorName = expectedVendorName.substring(0, 24);
|
||||
}
|
||||
String expectedModelName = SystemProperties.get("ro.product.model");
|
||||
if (expectedModelName.length() > 24) {
|
||||
expectedModelName = expectedModelName.substring(0, 24);
|
||||
}
|
||||
|
||||
Map<String, byte[]> txtMap = meshcopService.getAttributes();
|
||||
assertThat(txtMap.get("vn")).isEqualTo("Android".getBytes(UTF_8));
|
||||
assertThat(txtMap.get("mn")).isEqualTo("Thread Border Router".getBytes(UTF_8));
|
||||
assertThat(txtMap.get("vn")).isEqualTo(expectedVendorName.getBytes(UTF_8));
|
||||
assertThat(txtMap.get("mn")).isEqualTo(expectedModelName.getBytes(UTF_8));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import static android.net.thread.utils.IntegrationTestUtils.CALLBACK_TIMEOUT;
|
|||
import static android.net.thread.utils.IntegrationTestUtils.getIpv6Addresses;
|
||||
import static android.net.thread.utils.IntegrationTestUtils.getIpv6LinkAddresses;
|
||||
import static android.net.thread.utils.IntegrationTestUtils.waitFor;
|
||||
import static android.net.thread.utils.OtDaemonController.DIAG_VENDOR_MODEL_TLV_TYPE;
|
||||
import static android.net.thread.utils.OtDaemonController.DIAG_VENDOR_NAME_TLV_TYPE;
|
||||
import static android.net.thread.utils.ThreadNetworkControllerWrapper.JOIN_TIMEOUT;
|
||||
import static android.os.SystemClock.elapsedRealtime;
|
||||
|
||||
|
|
@ -290,6 +292,17 @@ public class ThreadIntegrationTest {
|
|||
// TODO: b/376217403 - enables / disables Border Agent at runtime
|
||||
}
|
||||
|
||||
@Test
|
||||
public void networkDiagnostic_vendorAndModelNameAreSet() throws Exception {
|
||||
mController.joinAndWait(DEFAULT_DATASET);
|
||||
|
||||
var tlvTypes = List.of(DIAG_VENDOR_NAME_TLV_TYPE, DIAG_VENDOR_MODEL_TLV_TYPE);
|
||||
var result = mOtCtl.netDiagGet(mOtCtl.getMlEid(), tlvTypes);
|
||||
|
||||
assertThat(result.get("Vendor Name")).isNotEmpty();
|
||||
assertThat(result.get("Vendor Model")).isNotEmpty();
|
||||
}
|
||||
|
||||
private NetworkCapabilities registerNetworkCallbackAndWait(NetworkRequest request)
|
||||
throws Exception {
|
||||
CompletableFuture<Network> networkFuture = new CompletableFuture<>();
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import static android.net.thread.ThreadNetworkManager.DISALLOW_THREAD_NETWORK;
|
|||
import static android.net.thread.ThreadNetworkManager.PERMISSION_THREAD_NETWORK_PRIVILEGED;
|
||||
import static android.net.thread.ThreadNetworkManager.PERMISSION_THREAD_NETWORK_TESTING;
|
||||
|
||||
import static com.android.server.thread.ThreadNetworkControllerService.getMeshcopTxtAttributes;
|
||||
import static com.android.server.thread.ThreadNetworkCountryCode.DEFAULT_COUNTRY_CODE;
|
||||
import static com.android.server.thread.ThreadPersistentSettings.KEY_THREAD_ENABLED;
|
||||
import static com.android.server.thread.openthread.IOtDaemon.ErrorCode.OT_ERROR_INVALID_STATE;
|
||||
|
|
@ -49,8 +50,6 @@ import static org.mockito.ArgumentMatchers.anyInt;
|
|||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNotNull;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
|
|
@ -101,10 +100,10 @@ import com.android.connectivity.resources.R;
|
|||
import com.android.dx.mockito.inline.extended.ExtendedMockito;
|
||||
import com.android.net.module.util.RoutingCoordinatorManager;
|
||||
import com.android.server.connectivity.ConnectivityResources;
|
||||
import com.android.server.connectivity.MockableSystemProperties;
|
||||
import com.android.server.thread.openthread.DnsTxtAttribute;
|
||||
import com.android.server.thread.openthread.IOtStatusReceiver;
|
||||
import com.android.server.thread.openthread.MeshcopTxtAttributes;
|
||||
import com.android.server.thread.openthread.OtDaemonConfiguration;
|
||||
import com.android.server.thread.openthread.testing.FakeOtDaemon;
|
||||
|
||||
import org.junit.After;
|
||||
|
|
@ -181,6 +180,7 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
private static final String TEST_MODEL_NAME = "test model";
|
||||
private static final LinkAddress TEST_NAT64_CIDR = new LinkAddress("192.168.255.0/24");
|
||||
|
||||
@Mock private MockableSystemProperties mMockSystemProperties;
|
||||
@Mock private ConnectivityManager mMockConnectivityManager;
|
||||
@Mock private RoutingCoordinatorManager mMockRoutingCoordinatorManager;
|
||||
@Mock private NetworkAgent mMockNetworkAgent;
|
||||
|
|
@ -271,6 +271,7 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
new ThreadNetworkControllerService(
|
||||
mContext,
|
||||
handler,
|
||||
mMockSystemProperties,
|
||||
networkProvider,
|
||||
() -> mFakeOtDaemon,
|
||||
mMockConnectivityManager,
|
||||
|
|
@ -335,6 +336,23 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
.containsExactly(new DnsTxtAttribute("vt", "test".getBytes(UTF_8)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_vendorAndModelNameSetToProperty_propertiesAreSetToOtDaemon()
|
||||
throws Exception {
|
||||
when(mMockSystemProperties.get(eq("ro.product.manufacturer"))).thenReturn("Banana");
|
||||
when(mResources.getString(eq(R.string.config_thread_vendor_name)))
|
||||
.thenReturn("ro.product.manufacturer");
|
||||
when(mMockSystemProperties.get(eq("ro.product.model"))).thenReturn("Orange");
|
||||
when(mResources.getString(eq(R.string.config_thread_model_name)))
|
||||
.thenReturn("ro.product.model");
|
||||
|
||||
mService.initialize();
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mFakeOtDaemon.getConfiguration().vendorName).isEqualTo("Banana");
|
||||
assertThat(mFakeOtDaemon.getConfiguration().modelName).isEqualTo("Orange");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_nat64Disabled_doesNotRequestNat64CidrAndConfiguresOtDaemon()
|
||||
throws Exception {
|
||||
|
|
@ -345,8 +363,7 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
mTestLooper.dispatchAll();
|
||||
|
||||
verify(mMockRoutingCoordinatorManager, never()).requestDownstreamAddress(any());
|
||||
verify(mFakeOtDaemon, times(1)).setNat64Cidr(isNull(), any());
|
||||
verify(mFakeOtDaemon, never()).setNat64Cidr(isNotNull(), any());
|
||||
assertThat(mFakeOtDaemon.getNat64Cidr()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -359,11 +376,8 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
mTestLooper.dispatchAll();
|
||||
|
||||
verify(mMockRoutingCoordinatorManager, times(1)).requestDownstreamAddress(any());
|
||||
verify(mFakeOtDaemon, times(1))
|
||||
.setConfiguration(
|
||||
new OtDaemonConfiguration.Builder().setNat64Enabled(true).build(),
|
||||
null /* receiver */);
|
||||
verify(mFakeOtDaemon, times(1)).setNat64Cidr(eq(TEST_NAT64_CIDR.toString()), any());
|
||||
assertThat(mFakeOtDaemon.getConfiguration().nat64Enabled).isTrue();
|
||||
assertThat(mFakeOtDaemon.getNat64Cidr()).isEqualTo(TEST_NAT64_CIDR.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -400,7 +414,7 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
when(mResources.getString(eq(R.string.config_thread_vendor_name))).thenReturn("");
|
||||
|
||||
MeshcopTxtAttributes meshcopTxts =
|
||||
ThreadNetworkControllerService.getMeshcopTxtAttributes(mResources);
|
||||
getMeshcopTxtAttributes(mResources, mMockSystemProperties);
|
||||
|
||||
assertThat(meshcopTxts.vendorName).isEqualTo("");
|
||||
}
|
||||
|
|
@ -412,7 +426,31 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
|
||||
assertThrows(
|
||||
IllegalStateException.class,
|
||||
() -> ThreadNetworkControllerService.getMeshcopTxtAttributes(mResources));
|
||||
() -> getMeshcopTxtAttributes(mResources, mMockSystemProperties));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMeshcopTxtAttributes_VendorNameSetToManufacturer_manufacturerPropertyIsUsed() {
|
||||
when(mMockSystemProperties.get(eq("ro.product.manufacturer"))).thenReturn("Banana");
|
||||
when(mResources.getString(eq(R.string.config_thread_vendor_name)))
|
||||
.thenReturn("ro.product.manufacturer");
|
||||
|
||||
MeshcopTxtAttributes meshcopTxts =
|
||||
getMeshcopTxtAttributes(mResources, mMockSystemProperties);
|
||||
|
||||
assertThat(meshcopTxts.vendorName).isEqualTo("Banana");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMeshcopTxtAttributes_ModelNameSetToModelProperty_modelPropertyIsUsed() {
|
||||
when(mMockSystemProperties.get(eq("ro.product.model"))).thenReturn("Orange");
|
||||
when(mResources.getString(eq(R.string.config_thread_model_name)))
|
||||
.thenReturn("ro.product.model");
|
||||
|
||||
MeshcopTxtAttributes meshcopTxts =
|
||||
getMeshcopTxtAttributes(mResources, mMockSystemProperties);
|
||||
|
||||
assertThat(meshcopTxts.modelName).isEqualTo("Orange");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -422,14 +460,14 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
|
||||
assertThrows(
|
||||
IllegalStateException.class,
|
||||
() -> ThreadNetworkControllerService.getMeshcopTxtAttributes(mResources));
|
||||
() -> getMeshcopTxtAttributes(mResources, mMockSystemProperties));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMeshcopTxtAttributes_emptyModelName_accepted() {
|
||||
when(mResources.getString(eq(R.string.config_thread_model_name))).thenReturn("");
|
||||
|
||||
var meshcopTxts = ThreadNetworkControllerService.getMeshcopTxtAttributes(mResources);
|
||||
var meshcopTxts = getMeshcopTxtAttributes(mResources, mMockSystemProperties);
|
||||
assertThat(meshcopTxts.modelName).isEqualTo("");
|
||||
}
|
||||
|
||||
|
|
@ -461,7 +499,7 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
|
||||
private byte[] getMeshcopTxtAttributesWithVendorOui(String vendorOui) {
|
||||
when(mResources.getString(eq(R.string.config_thread_vendor_oui))).thenReturn(vendorOui);
|
||||
return ThreadNetworkControllerService.getMeshcopTxtAttributes(mResources).vendorOui;
|
||||
return getMeshcopTxtAttributes(mResources, mMockSystemProperties).vendorOui;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -886,16 +924,12 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
|
||||
verify(mockReceiver, times(1)).onSuccess();
|
||||
verify(mMockRoutingCoordinatorManager, times(1)).requestDownstreamAddress(any());
|
||||
verify(mFakeOtDaemon, times(1))
|
||||
.setConfiguration(
|
||||
eq(new OtDaemonConfiguration.Builder().setNat64Enabled(true).build()),
|
||||
any(IOtStatusReceiver.class));
|
||||
verify(mFakeOtDaemon, times(1))
|
||||
.setNat64Cidr(eq(TEST_NAT64_CIDR.toString()), any(IOtStatusReceiver.class));
|
||||
assertThat(mFakeOtDaemon.getConfiguration().nat64Enabled).isTrue();
|
||||
assertThat(mFakeOtDaemon.getNat64Cidr()).isEqualTo(TEST_NAT64_CIDR.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setConfiguration_enablesNat64_otDaemonRemoteFailure_serviceDoesNotCrash()
|
||||
public void setConfiguration_enablesNat64AndOtDaemonRemoteFailure_serviceDoesNotCrash()
|
||||
throws Exception {
|
||||
mService.initialize();
|
||||
mTestLooper.dispatchAll();
|
||||
|
|
@ -929,12 +963,8 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
verify(mockReceiver, times(1)).onSuccess();
|
||||
verify(mMockRoutingCoordinatorManager, times(1)).releaseDownstream(any());
|
||||
verify(mMockRoutingCoordinatorManager, never()).requestDownstreamAddress(any());
|
||||
verify(mFakeOtDaemon, times(1))
|
||||
.setConfiguration(
|
||||
eq(new OtDaemonConfiguration.Builder().setNat64Enabled(false).build()),
|
||||
any(IOtStatusReceiver.class));
|
||||
verify(mFakeOtDaemon, times(1)).setNat64Cidr(isNull(), any(IOtStatusReceiver.class));
|
||||
verify(mFakeOtDaemon, never()).setNat64Cidr(isNotNull(), any(IOtStatusReceiver.class));
|
||||
assertThat(mFakeOtDaemon.getConfiguration().nat64Enabled).isFalse();
|
||||
assertThat(mFakeOtDaemon.getNat64Cidr()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -24,10 +24,13 @@ import android.os.SystemClock;
|
|||
import com.android.compatibility.common.util.SystemUtil;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
|
@ -37,6 +40,9 @@ import java.util.stream.Collectors;
|
|||
* <p>Note that this class takes root privileged to run.
|
||||
*/
|
||||
public final class OtDaemonController {
|
||||
public static final int DIAG_VENDOR_NAME_TLV_TYPE = 25;
|
||||
public static final int DIAG_VENDOR_MODEL_TLV_TYPE = 26;
|
||||
|
||||
private static final String OT_CTL = "/system/bin/ot-ctl";
|
||||
|
||||
/**
|
||||
|
|
@ -187,6 +193,35 @@ public final class OtDaemonController {
|
|||
return SystemUtil.runShellCommand(OT_CTL + " " + cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends DIAG_GET request to the given peer device and returns the parsed result as a dict of
|
||||
* the requested TLV values.
|
||||
*
|
||||
* <p>For example, a request {@code netDiagGet("fdad:3d13:7b11:4049:ed1a:7e87:4770:a345",
|
||||
* [DIAG_VENDOR_NAME_TLV_TYPE, DIAG_VENDOR_MODEL_TLV_TYPE])} can return a dict of {@code
|
||||
* {"Vendor Name" : "ABC", "Vendor Model" : "Cuttlefish"}}
|
||||
*/
|
||||
public Map<String, String> netDiagGet(InetAddress peerAddr, List<Integer> tlvTypes) {
|
||||
String tlvTypeList =
|
||||
tlvTypes.stream().map(Object::toString).collect(Collectors.joining(" "));
|
||||
|
||||
List<String> outputs =
|
||||
executeCommandAndParse(
|
||||
"networkdiagnostic get " + peerAddr.getHostAddress() + " " + tlvTypeList);
|
||||
Map<String, String> result = new HashMap<>();
|
||||
for (String line : outputs) {
|
||||
if (line.startsWith("DIAG_GET")) {
|
||||
continue;
|
||||
}
|
||||
String[] keyValue = line.split(":");
|
||||
if (keyValue.length != 2) {
|
||||
throw new IllegalStateException("Unexpected OT output: " + line);
|
||||
}
|
||||
result.put(keyValue[0].strip(), keyValue[1].strip());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a ot-ctl command and parse the output to a list of strings.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -16,44 +16,23 @@
|
|||
package android.net.thread.utils;
|
||||
|
||||
import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
|
||||
import static android.net.InetAddresses.parseNumericAddress;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
|
||||
import static android.system.OsConstants.AF_INET6;
|
||||
import static android.system.OsConstants.IPPROTO_UDP;
|
||||
import static android.system.OsConstants.SOCK_DGRAM;
|
||||
|
||||
import static com.android.testutils.RecorderCallback.CallbackEntry.LINK_PROPERTIES_CHANGED;
|
||||
import static com.android.testutils.TestPermissionUtil.runAsShell;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkAgentConfig;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.TestNetworkInterface;
|
||||
import android.net.TestNetworkManager;
|
||||
import android.net.TestNetworkSpecifier;
|
||||
import android.os.Looper;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
|
||||
import com.android.compatibility.common.util.PollingCheck;
|
||||
import com.android.testutils.TestableNetworkAgent;
|
||||
import com.android.testutils.TestableNetworkCallback;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.net.InterfaceAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** A class that can create/destroy a test network based on TAP interface. */
|
||||
public final class TapTestNetworkTracker {
|
||||
|
|
|
|||
Loading…
Reference in a new issue