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

Commit dd6879f9 authored by Sumit Deshmukh's avatar Sumit Deshmukh Committed by Bruno Martins
Browse files

BLE: Add support for Group AD Type based scan filtering.

This change contains
- API's to do filtered scan based on Group AD Type.
- Extract Group identifier data from ScanRecord.

CRs-Fixed: 2826578
Change-Id: I75982a1acf982c03234d9e1084aee287d3d3623d
parent 973f6cc9
Loading
Loading
Loading
Loading
+46 −5
Original line number Diff line number Diff line
@@ -96,6 +96,10 @@ public final class ScanFilter implements Parcelable {
    private final int mTDSFlagsMask;
    private final byte[] mWifiNANHash;

    private final boolean mGroupBasedFiltering;

    private static final int GROUP_DATA_LEN = 6;

    /** @hide */
    public static final ScanFilter EMPTY = new ScanFilter.Builder().build();

@@ -105,7 +109,8 @@ public final class ScanFilter implements Parcelable {
            byte[] serviceData, byte[] serviceDataMask,
            int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask,
            @AddressType int addressType, @Nullable byte[] irk,
            int orgId, int TDSFlags, int TDSFlagsMask, byte[] wifiNANHash) {
            int orgId, int TDSFlags, int TDSFlagsMask, byte[] wifiNANHash,
            boolean groupBasedFiltering) {
        mDeviceName = name;
        mServiceUuid = uuid;
        mServiceUuidMask = uuidMask;
@@ -124,6 +129,7 @@ public final class ScanFilter implements Parcelable {
        mTDSFlags = TDSFlags;
        mTDSFlagsMask = TDSFlagsMask;
        mWifiNANHash = wifiNANHash;
        mGroupBasedFiltering = groupBasedFiltering;
    }

    @Override
@@ -205,6 +211,7 @@ public final class ScanFilter implements Parcelable {
                dest.writeByteArray(mWifiNANHash);
            }
        }
        dest.writeBoolean(mGroupBasedFiltering);
    }

    /**
@@ -312,6 +319,8 @@ public final class ScanFilter implements Parcelable {
                }
            }

            boolean groupBasedFiltering = in.readBoolean();
            builder.setGroupBasedFiltering(groupBasedFiltering);
            return builder.build();
        }
    };
@@ -438,6 +447,14 @@ public final class ScanFilter implements Parcelable {
        return mWifiNANHash;
    }

    /**
     * @hide
     * Returns true, if Group AD Type based filtering is enabled. Otherwise, false.
     */
    public boolean getGroupFilteringValue() {
        return mGroupBasedFiltering;
    }

    /**
     * Check if the scan filter matches a {@code scanResult}. A scan result is considered as a match
     * if it matches all the field filters.
@@ -507,6 +524,13 @@ public final class ScanFilter implements Parcelable {
            }
        }

        // Group AD Type filter match
        if (mGroupBasedFiltering) {
            if (scanRecord.getGroupIdentifierData().length != GROUP_DATA_LEN) {
                return false;
            }
        }

        // All filters match.
        return true;
    }
@@ -604,7 +628,8 @@ public final class ScanFilter implements Parcelable {
                + ", mManufacturerDataMask=" + Arrays.toString(mManufacturerDataMask)
                + ", mOrganizationId=" + mOrgId + ", mTDSFlags=" + mTDSFlags
                + ", mTDSFlagsMask=" + mTDSFlagsMask
                + ", mWifiNANHash=" + Arrays.toString(mWifiNANHash) +"]";
                + ", mWifiNANHash=" + Arrays.toString(mWifiNANHash) +"]"
                + ", mGroupBasedFiltering=" + mGroupBasedFiltering;
    }

    @Override
@@ -617,7 +642,8 @@ public final class ScanFilter implements Parcelable {
                Arrays.hashCode(mServiceDataMask),
                mServiceUuid, mServiceUuidMask,
                mServiceSolicitationUuid, mServiceSolicitationUuidMask,
                mOrgId, mTDSFlags, mTDSFlagsMask, Arrays.hashCode(mWifiNANHash));
                mOrgId, mTDSFlags, mTDSFlagsMask, Arrays.hashCode(mWifiNANHash),
                mGroupBasedFiltering);
    }

    @Override
@@ -645,7 +671,8 @@ public final class ScanFilter implements Parcelable {
                && mOrgId == other.mOrgId
                && mTDSFlags == other.mTDSFlags
                && mTDSFlagsMask == other.mTDSFlagsMask
                && Objects.deepEquals(mWifiNANHash, other.mWifiNANHash);
                && Objects.deepEquals(mWifiNANHash, other.mWifiNANHash)
                && mGroupBasedFiltering == other.mGroupBasedFiltering;
    }

    /**
@@ -692,6 +719,8 @@ public final class ScanFilter implements Parcelable {
        private int mTDSFlagsMask = -1;
        private byte[] mWifiNANHash;

        private boolean mGroupBasedFiltering;

        /**
         * Set filter on device name.
         */
@@ -1017,6 +1046,17 @@ public final class ScanFilter implements Parcelable {
            mWifiNANHash = wifiNANHash;
            return this;
        }

        /**
         * @hide
         * Enable filter on Group AD Type.
         */
        public @NonNull Builder setGroupBasedFiltering(
                boolean enable) {
            mGroupBasedFiltering = enable;
            return this;
        }

        /**
         * Build {@link ScanFilter}.
         *
@@ -1029,7 +1069,8 @@ public final class ScanFilter implements Parcelable {
                    mServiceDataUuid, mServiceData, mServiceDataMask,
                    mManufacturerId, mManufacturerData, mManufacturerDataMask,
                    mAddressType, mIrk,
                    mOrgId, mTDSFlags, mTDSFlagsMask, mWifiNANHash);
                    mOrgId, mTDSFlags, mTDSFlagsMask, mWifiNANHash,
                    mGroupBasedFiltering);
        }
    }
}
+27 −4
Original line number Diff line number Diff line
@@ -60,6 +60,10 @@ public final class ScanRecord {
    private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_128_BIT = 0x15;
    private static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
    private static final int DATA_TYPE_TRANSPORT_DISCOVERY_DATA = 0x26;
    /**
     * @hide
     */
    public static int DATA_TYPE_GROUP_AD_TYPE = 0x00;

    // Flags of the advertising data.
    private final int mAdvertiseFlags;
@@ -85,6 +89,9 @@ public final class ScanRecord {
    // Transport Discovery data.
    private final byte[] mTDSData;

    // Group Identifier Data
    private final byte[] mGroupIdentifierData;

    /**
     * Returns the advertising flags indicating the discoverable mode and capability of the device.
     * Returns -1 if the flag field is not set.
@@ -176,6 +183,14 @@ public final class ScanRecord {
        return mTDSData;
    }

    /**
     * @hide
     * Returns Group Identifier data
     */
    public byte[] getGroupIdentifierData() {
        return mGroupIdentifierData;
    }

    /**
     * Returns raw bytes of scan record.
     */
@@ -209,7 +224,7 @@ public final class ScanRecord {
            SparseArray<byte[]> manufacturerData,
            Map<ParcelUuid, byte[]> serviceData,
            int advertiseFlags, int txPowerLevel,
            String localName, byte[] tdsData, byte[] bytes) {
            String localName, byte[] tdsData, byte[] groupIdentifierData, byte[] bytes) {
        mServiceSolicitationUuids = serviceSolicitationUuids;
        mServiceUuids = serviceUuids;
        mManufacturerSpecificData = manufacturerData;
@@ -218,6 +233,7 @@ public final class ScanRecord {
        mAdvertiseFlags = advertiseFlags;
        mTxPowerLevel = txPowerLevel;
        mTDSData = tdsData;
        mGroupIdentifierData = groupIdentifierData;
        mBytes = bytes;
    }

@@ -249,6 +265,7 @@ public final class ScanRecord {
        Map<ParcelUuid, byte[]> serviceData = new ArrayMap<ParcelUuid, byte[]>();

        byte[] tdsData = null;
        byte[] groupIdentifierData = null;

        try {
            while (currentPos < scanRecord.length) {
@@ -330,8 +347,12 @@ public final class ScanRecord {
                    case DATA_TYPE_TRANSPORT_DISCOVERY_DATA:
                        tdsData = extractBytes(scanRecord, currentPos, dataLength);
                        break;

                    default:
                        // Just ignore, we don't handle such data type.
                        if (fieldType == DATA_TYPE_GROUP_AD_TYPE) {
                            Log.d(TAG, "Parsing Group Identifier data");
                            groupIdentifierData = extractBytes(scanRecord, currentPos, dataLength);
                        }
                        break;
                }
                currentPos += dataLength;
@@ -341,12 +362,14 @@ public final class ScanRecord {
                serviceUuids = null;
            }
            return new ScanRecord(serviceUuids, serviceSolicitationUuids, manufacturerData,
                    serviceData, advertiseFlag, txPowerLevel, localName, tdsData, scanRecord);
                    serviceData, advertiseFlag, txPowerLevel, localName, tdsData,
                    groupIdentifierData, scanRecord);
        } catch (Exception e) {
            Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
            // As the record is invalid, ignore all the parsed results for this packet
            // and return an empty record with raw scanRecord bytes in results
            return new ScanRecord(null, null, null, null, -1, Integer.MIN_VALUE, null, null, scanRecord);
            return new ScanRecord(null, null, null, null, -1, Integer.MIN_VALUE, null, null,
                                  null, scanRecord);
        }
    }