diff --git a/framework/src/android/net/L2capNetworkSpecifier.java b/framework/src/android/net/L2capNetworkSpecifier.java index 3331123f96..3c95dd0ec2 100644 --- a/framework/src/android/net/L2capNetworkSpecifier.java +++ b/framework/src/android/net/L2capNetworkSpecifier.java @@ -251,8 +251,29 @@ public final class L2capNetworkSpecifier extends NetworkSpecifier implements Par /** @hide */ @Override public boolean canBeSatisfiedBy(NetworkSpecifier other) { - // TODO: implement matching semantics. - return false; + if (!(other instanceof L2capNetworkSpecifier)) return false; + final L2capNetworkSpecifier rhs = (L2capNetworkSpecifier) other; + + // A network / offer cannot be ROLE_ANY, but it is added for consistency. + if (mRole != rhs.mRole && mRole != ROLE_ANY && rhs.mRole != ROLE_ANY) { + return false; + } + + if (mHeaderCompression != rhs.mHeaderCompression + && mHeaderCompression != HEADER_COMPRESSION_ANY + && rhs.mHeaderCompression != HEADER_COMPRESSION_ANY) { + return false; + } + + if (!Objects.equals(mRemoteAddress, rhs.mRemoteAddress) + && mRemoteAddress != null && rhs.mRemoteAddress != null) { + return false; + } + + if (mPsm != rhs.mPsm && mPsm != PSM_ANY && rhs.mPsm != PSM_ANY) { + return false; + } + return true; } /** @hide */ diff --git a/tests/cts/net/src/android/net/cts/L2capNetworkSpecifierTest.kt b/tests/cts/net/src/android/net/cts/L2capNetworkSpecifierTest.kt index 51ccdd5b24..484cce8fea 100644 --- a/tests/cts/net/src/android/net/cts/L2capNetworkSpecifierTest.kt +++ b/tests/cts/net/src/android/net/cts/L2capNetworkSpecifierTest.kt @@ -18,8 +18,11 @@ package android.net.cts import android.net.L2capNetworkSpecifier import android.net.L2capNetworkSpecifier.HEADER_COMPRESSION_6LOWPAN +import android.net.L2capNetworkSpecifier.HEADER_COMPRESSION_ANY import android.net.L2capNetworkSpecifier.HEADER_COMPRESSION_NONE +import android.net.L2capNetworkSpecifier.PSM_ANY import android.net.L2capNetworkSpecifier.ROLE_CLIENT +import android.net.L2capNetworkSpecifier.ROLE_SERVER import android.net.MacAddress import android.os.Build import com.android.testutils.ConnectivityModuleTest @@ -27,6 +30,8 @@ import com.android.testutils.DevSdkIgnoreRule import com.android.testutils.DevSdkIgnoreRunner import com.android.testutils.assertParcelingIsLossless import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue import org.junit.Test import org.junit.runner.RunWith @@ -60,4 +65,53 @@ class L2capNetworkSpecifierTest { assertEquals(123, specifier.getPsm()) assertEquals(remoteMac, specifier.getRemoteAddress()) } + + @Test + fun testCanBeSatisfiedBy() { + val blanketOffer = L2capNetworkSpecifier.Builder() + .setRole(ROLE_SERVER) + .setHeaderCompression(HEADER_COMPRESSION_ANY) + .setPsm(PSM_ANY) + .build() + + val reservedOffer = L2capNetworkSpecifier.Builder() + .setRole(ROLE_SERVER) + .setHeaderCompression(HEADER_COMPRESSION_6LOWPAN) + .setPsm(42) + .build() + + val clientOffer = L2capNetworkSpecifier.Builder() + .setRole(ROLE_CLIENT) + .setHeaderCompression(HEADER_COMPRESSION_ANY) + .build() + + val serverReservation = L2capNetworkSpecifier.Builder() + .setRole(ROLE_SERVER) + .setHeaderCompression(HEADER_COMPRESSION_6LOWPAN) + .build() + + assertTrue(serverReservation.canBeSatisfiedBy(blanketOffer)) + assertTrue(serverReservation.canBeSatisfiedBy(reservedOffer)) + // Note: serverReservation can be filed using reserveNetwork, or it could be a regular + // request filed using requestNetwork. + assertFalse(serverReservation.canBeSatisfiedBy(clientOffer)) + + val clientRequest = L2capNetworkSpecifier.Builder() + .setRole(ROLE_CLIENT) + .setHeaderCompression(HEADER_COMPRESSION_6LOWPAN) + .setRemoteAddress(MacAddress.fromString("00:01:02:03:04:05")) + .setPsm(42) + .build() + + assertTrue(clientRequest.canBeSatisfiedBy(clientOffer)) + // Note: the BlanketOffer also includes a RES_ID_MATCH_ALL_RESERVATIONS. Since the + // clientRequest is not a reservation, it won't match that request to begin with. + assertFalse(clientRequest.canBeSatisfiedBy(blanketOffer)) + assertFalse(clientRequest.canBeSatisfiedBy(reservedOffer)) + + val matchAny = L2capNetworkSpecifier.Builder().build() + assertTrue(matchAny.canBeSatisfiedBy(blanketOffer)) + assertTrue(matchAny.canBeSatisfiedBy(reservedOffer)) + assertTrue(matchAny.canBeSatisfiedBy(clientOffer)) + } }