Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0462468a authored by Wei Wang's avatar Wei Wang
Browse files

Make scan filter accepts prefix. Add tests.

Change-Id: I714dd6d95ad2bc874dce1106b325762b19159119
parent f4e0c0cb
Loading
Loading
Loading
Loading
+32 −19
Original line number Diff line number Diff line
@@ -110,21 +110,27 @@ public final class ScanFilter implements Parcelable {
        dest.writeInt(mServiceDataUuid == null ? 0 : 1);
        if (mServiceDataUuid != null) {
            dest.writeParcelable(mServiceDataUuid, flags);
            dest.writeInt(mServiceData == null ? 0 : mServiceData.length);
            dest.writeInt(mServiceData == null ? 0 : 1);
            if (mServiceData != null) {
                dest.writeInt(mServiceData.length);
                dest.writeByteArray(mServiceData);
                dest.writeInt(mServiceDataMask == null ? 0 : mServiceDataMask.length);

                dest.writeInt(mServiceDataMask == null ? 0 : 1);
                if (mServiceDataMask != null) {
                    dest.writeInt(mServiceDataMask.length);
                    dest.writeByteArray(mServiceDataMask);
                }
            }
        }
        dest.writeInt(mManufacturerId);
        dest.writeInt(mManufacturerData == null ? 0 : mManufacturerData.length);
        dest.writeInt(mManufacturerData == null ? 0 : 1);
        if (mManufacturerData != null) {
            dest.writeInt(mManufacturerData.length);
            dest.writeByteArray(mManufacturerData);
            dest.writeInt(mManufacturerDataMask == null ? 0 : mManufacturerDataMask.length);

            dest.writeInt(mManufacturerDataMask == null ? 0 : 1);
            if (mManufacturerDataMask != null) {
                dest.writeInt(mManufacturerDataMask.length);
                dest.writeByteArray(mManufacturerDataMask);
            }
        }
@@ -164,13 +170,14 @@ public final class ScanFilter implements Parcelable {
                    if (in.readInt() == 1) {
                        ParcelUuid servcieDataUuid =
                                in.readParcelable(ParcelUuid.class.getClassLoader());
                        if (in.readInt() == 1) {
                            int serviceDataLength = in.readInt();
                        if (serviceDataLength > 0) {
                            byte[] serviceData = new byte[serviceDataLength];
                            in.readByteArray(serviceData);
                            if (in.readInt() == 0) {
                                builder.setServiceData(servcieDataUuid, serviceData);
                            } else {
                                int serviceDataMaskLength = in.readInt();
                            if (serviceDataMaskLength > 0) {
                                byte[] serviceDataMask = new byte[serviceDataMaskLength];
                                in.readByteArray(serviceDataMask);
                                builder.setServiceData(
@@ -180,13 +187,14 @@ public final class ScanFilter implements Parcelable {
                    }

                    int manufacturerId = in.readInt();
                    if (in.readInt() == 1) {
                        int manufacturerDataLength = in.readInt();
                    if (manufacturerDataLength > 0) {
                        byte[] manufacturerData = new byte[manufacturerDataLength];
                        in.readByteArray(manufacturerData);
                        if (in.readInt() == 0) {
                            builder.setManufacturerData(manufacturerId, manufacturerData);
                        } else {
                            int manufacturerDataMaskLength = in.readInt();
                        if (manufacturerDataMaskLength > 0) {
                            byte[] manufacturerDataMask = new byte[manufacturerDataMaskLength];
                            in.readByteArray(manufacturerDataMask);
                            builder.setManufacturerData(manufacturerId, manufacturerData,
@@ -349,12 +357,17 @@ public final class ScanFilter implements Parcelable {

    // Check whether the data pattern matches the parsed data.
    private boolean matchesPartialData(byte[] data, byte[] dataMask, byte[] parsedData) {
        if (dataMask == null) {
            return Arrays.equals(data, parsedData);
        if (parsedData == null || parsedData.length < data.length) {
            return false;
        }
        if (parsedData == null) {
        if (dataMask == null) {
            for (int i = 0; i < data.length; ++i) {
                if (parsedData[i] != data[i]) {
                    return false;
                }
            }
            return true;
        }
        for (int i = 0; i < data.length; ++i) {
            if ((dataMask[i] & parsedData[i]) != (dataMask[i] & data[i])) {
                return false;
+45 −21
Original line number Diff line number Diff line
@@ -96,38 +96,56 @@ public class ScanFilterTest extends TestCase {
    @SmallTest
    public void testsetServiceDataFilter() {
        byte[] setServiceData = new byte[] {
                0x0b, 0x11, 0x50, 0x64 };
                0x50, 0x64 };
        ParcelUuid serviceDataUuid = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
        ScanFilter filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData).build();
        assertTrue("service data filter fails", filter.matches(mScanResult));

        byte[] nonMatchData = new byte[] {
                0x0b, 0x01, 0x50, 0x64 };
        filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData).build();
        assertFalse("service data filter fails", filter.matches(mScanResult));
        byte[] emptyData = new byte[0];
        filter = mFilterBuilder.setServiceData(serviceDataUuid, emptyData).build();
        assertTrue("service data filter fails", filter.matches(mScanResult));

        byte[] prefixData = new byte[] {
                0x50 };
        filter = mFilterBuilder.setServiceData(serviceDataUuid, prefixData).build();
        assertTrue("service data filter fails", filter.matches(mScanResult));

        byte[] nonMatchData = new byte[] {
                0x51, 0x64 };
        byte[] mask = new byte[] {
                (byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF };
                (byte) 0x00, (byte) 0xFF };
        filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData, mask).build();
        assertTrue("partial service data filter fails", filter.matches(mScanResult));

        filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData).build();
        assertFalse("service data filter fails", filter.matches(mScanResult));
    }

    @SmallTest
    public void testManufacturerSpecificData() {
        byte[] setManufacturerData = new byte[] {
                (byte) 0xE0, 0x00, 0x02, 0x15 };
        int manufacturerId = 224;
                0x02, 0x15 };
        int manufacturerId = 0xE0;
        ScanFilter filter =
                mFilterBuilder.setManufacturerData(manufacturerId, setManufacturerData).build();
        assertTrue("setManufacturerData filter fails", filter.matches(mScanResult));
        assertTrue("manufacturer data filter fails", filter.matches(mScanResult));

        byte[] emptyData = new byte[0];
        filter = mFilterBuilder.setManufacturerData(manufacturerId, emptyData).build();
        assertTrue("manufacturer data filter fails", filter.matches(mScanResult));

        byte[] prefixData = new byte[] {
                0x02 };
        filter = mFilterBuilder.setManufacturerData(manufacturerId, prefixData).build();
        assertTrue("manufacturer data filter fails", filter.matches(mScanResult));

        // Test data mask
        byte[] nonMatchData = new byte[] {
                (byte) 0xF0, 0x00, 0x02, 0x15 };
                0x02, 0x14 };
        filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData).build();
        assertFalse("setManufacturerData filter fails", filter.matches(mScanResult));

        assertFalse("manufacturer data filter fails", filter.matches(mScanResult));
        byte[] mask = new byte[] {
                (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF
                (byte) 0xFF, (byte) 0x00
        };
        filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData, mask).build();
        assertTrue("partial setManufacturerData filter fails", filter.matches(mScanResult));
@@ -153,27 +171,33 @@ public class ScanFilterTest extends TestCase {
                ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF")).build();
        testReadWriteParcelForFilter(filter);

        byte[] setServiceData = new byte[] {
                0x0b, 0x11, 0x50, 0x64 };
        byte[] serviceData = new byte[] {
                0x50, 0x64 };

        ParcelUuid serviceDataUuid = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
        filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData).build();
        filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData).build();
        testReadWriteParcelForFilter(filter);

        filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build();
        testReadWriteParcelForFilter(filter);

        byte[] serviceDataMask = new byte[] {
                (byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF };
        filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData, serviceDataMask)
                (byte) 0xFF, (byte) 0xFF };
        filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData, serviceDataMask)
                .build();
        testReadWriteParcelForFilter(filter);

        byte[] manufacturerData = new byte[] {
                (byte) 0xE0, 0x00, 0x02, 0x15 };
        int manufacturerId = 224;
                0x02, 0x15 };
        int manufacturerId = 0xE0;
        filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData).build();
        testReadWriteParcelForFilter(filter);

        filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build();
        testReadWriteParcelForFilter(filter);

        byte[] manufacturerDataMask = new byte[] {
                (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF
                (byte) 0xFF, (byte) 0xFF
        };
        filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData,
                manufacturerDataMask).build();