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

Commit 3c915e42 authored by Subramanian Srinivasan's avatar Subramanian Srinivasan Committed by Bruno Martins
Browse files

Add scan filter for Transport Discovery data

Add scan filter support for Transport Discovery
data.

CRs-Fixed: 2418407
Change-Id: I84b791d7424620bc7db5b19e8f6a14938b1526af
parent 59855ff1
Loading
Loading
Loading
Loading
+121 −5
Original line number Diff line number Diff line
@@ -47,6 +47,12 @@ import java.util.UUID;
 */
public final class ScanFilter implements Parcelable {

    /**
    * Provide TDS data scan results for WiFi Alliance Org id
    * @hide
    */
    public static final int WIFI_ALLIANCE_ORG_ID = 2;

    @Nullable
    private final String mDeviceName;

@@ -76,6 +82,11 @@ public final class ScanFilter implements Parcelable {
    @Nullable
    private final byte[] mManufacturerDataMask;

    private final int mOrgId;
    private final int mTDSFlags;
    private final int mTDSFlagsMask;
    private final byte[] mWifiNANHash;

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

@@ -84,7 +95,8 @@ public final class ScanFilter implements Parcelable {
            ParcelUuid uuidMask, ParcelUuid solicitationUuid,
            ParcelUuid solicitationUuidMask, ParcelUuid serviceDataUuid,
            byte[] serviceData, byte[] serviceDataMask,
            int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask) {
            int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask,
            int orgId, int TDSFlags, int TDSFlagsMask, byte[] wifiNANHash) {
        mDeviceName = name;
        mServiceUuid = uuid;
        mServiceUuidMask = uuidMask;
@@ -97,6 +109,10 @@ public final class ScanFilter implements Parcelable {
        mManufacturerId = manufacturerId;
        mManufacturerData = manufacturerData;
        mManufacturerDataMask = manufacturerDataMask;
        mOrgId = orgId;
        mTDSFlags = TDSFlags;
        mTDSFlagsMask = TDSFlagsMask;
        mWifiNANHash = wifiNANHash;
    }

    @Override
@@ -157,6 +173,14 @@ public final class ScanFilter implements Parcelable {
                dest.writeByteArray(mManufacturerDataMask);
            }
        }
        dest.writeInt(mOrgId);
        dest.writeInt(mTDSFlags);
        dest.writeInt(mTDSFlagsMask);
        dest.writeInt(mWifiNANHash == null ? 0 : 1);
        if (mWifiNANHash != null) {
            dest.writeInt(mWifiNANHash.length);
            dest.writeByteArray(mWifiNANHash);
        }
    }

    /**
@@ -234,6 +258,20 @@ public final class ScanFilter implements Parcelable {
                }
            }

            int orgId = in.readInt();
            int TDSFlags = in.readInt();
            int TDSFlagsMask = in.readInt();
            if (in.readInt() == 1) {
                int wifiNANHashLength = in.readInt();
                byte[] wifiNanHash = new byte[wifiNANHashLength];
                in.readByteArray(wifiNanHash);
                builder.setTransportDiscoveryData(orgId, TDSFlags, TDSFlagsMask,
                        wifiNanHash);
            }
            else {
                builder.setTransportDiscoveryData(orgId, TDSFlags, TDSFlagsMask, null);
            }

            return builder.build();
        }
    };
@@ -312,6 +350,37 @@ public final class ScanFilter implements Parcelable {
        return mManufacturerDataMask;
    }

    /**
     * @hide
     * Returns the organization id. -1 if the organization id is not set.
     */
    public int getOrgId() {
        return mOrgId;
    }

    /**
     * @hide
     * Returns the TDS flags. -1 if TDS flags is not set.
     */
    public int getTDSFlags() {
        return mTDSFlags;
    }

    /**
     * @hide
     * Returns the TDS flags mask. -1 if TDS flags mask is not set.
     */
    public int getTDSFlagsMask() {
        return mTDSFlagsMask;
    }

    /**
     * @hide
     */
    public byte[] getWifiNANHash() {
        return mWifiNANHash;
    }

    /**
     * Check if the scan filter matches a {@code scanResult}. A scan result is considered as a match
     * if it matches all the field filters.
@@ -369,6 +438,18 @@ public final class ScanFilter implements Parcelable {
                return false;
            }
        }

        //Transport Discovery data match
        if(mOrgId >= 0) {
            byte[] tdsData = scanRecord.getTDSData();
            if ((tdsData != null) && (tdsData.length > 0)) {
                if ((mOrgId != tdsData[0]) ||
                    ((mTDSFlags & mTDSFlagsMask) != (tdsData[1] & mTDSFlagsMask))) {
                    return false;
                }
            }
        }

        // All filters match.
        return true;
    }
@@ -463,7 +544,10 @@ public final class ScanFilter implements Parcelable {
                + Arrays.toString(mServiceData) + ", mServiceDataMask="
                + Arrays.toString(mServiceDataMask) + ", mManufacturerId=" + mManufacturerId
                + ", mManufacturerData=" + Arrays.toString(mManufacturerData)
                + ", mManufacturerDataMask=" + Arrays.toString(mManufacturerDataMask) + "]";
                + ", mManufacturerDataMask=" + Arrays.toString(mManufacturerDataMask)
                + ", mOrganizationId=" + mOrgId + ", mTDSFlags=" + mTDSFlags
                + ", mTDSFlagsMask=" + mTDSFlagsMask
                + ", mWifiNANHash=" + Arrays.toString(mWifiNANHash) +"]";
    }

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

    @Override
@@ -499,7 +584,11 @@ public final class ScanFilter implements Parcelable {
                && Objects.equals(mServiceUuidMask, other.mServiceUuidMask)
                && Objects.equals(mServiceSolicitationUuid, other.mServiceSolicitationUuid)
                && Objects.equals(mServiceSolicitationUuidMask,
                        other.mServiceSolicitationUuidMask);
                        other.mServiceSolicitationUuidMask)
                && mOrgId == other.mOrgId
                && mTDSFlags == other.mTDSFlags
                && mTDSFlagsMask == other.mTDSFlagsMask
                && Objects.deepEquals(mWifiNANHash, other.mWifiNANHash);
    }

    /**
@@ -533,6 +622,11 @@ public final class ScanFilter implements Parcelable {
        private byte[] mManufacturerData;
        private byte[] mManufacturerDataMask;

        private int mOrgId = -1;
        private int mTDSFlags = -1;
        private int mTDSFlagsMask = -1;
        private byte[] mWifiNANHash;

        /**
         * Set filter on device name.
         */
@@ -717,6 +811,27 @@ public final class ScanFilter implements Parcelable {
            return this;
        }


        /**
         * @hide
         * Set filter on transport discovery data.
         * @throws IllegalArgumentException If the {@code orgId} is invalid or {@code
         * wifiNANhash} is not null while {@code orgId} is non-Wifi.
         */
        public Builder setTransportDiscoveryData(int orgId, int TDSFlags, int TDSFlagsMask,
                byte[] wifiNANHash) {
            if (orgId < 0) {
                throw new IllegalArgumentException("invalid organization id");
            }
            if ((orgId != WIFI_ALLIANCE_ORG_ID) && (wifiNANHash != null)) {
                throw new IllegalArgumentException("Wifi NAN Hash is not null for non-Wifi Org Id");
            }
            mOrgId = orgId;
            mTDSFlags = TDSFlags;
            mTDSFlagsMask = TDSFlagsMask;
            mWifiNANHash = wifiNANHash;
            return this;
        }
        /**
         * Build {@link ScanFilter}.
         *
@@ -727,7 +842,8 @@ public final class ScanFilter implements Parcelable {
                    mServiceUuid, mUuidMask, mServiceSolicitationUuid,
                    mServiceSolicitationUuidMask,
                    mServiceDataUuid, mServiceData, mServiceDataMask,
                    mManufacturerId, mManufacturerData, mManufacturerDataMask);
                    mManufacturerId, mManufacturerData, mManufacturerDataMask,
                    mOrgId, mTDSFlags, mTDSFlagsMask, mWifiNANHash);
        }
    }
}
+23 −4
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ public final class ScanRecord {
    private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_32_BIT = 0x1F;
    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;

    // Flags of the advertising data.
    private final int mAdvertiseFlags;
@@ -78,6 +79,9 @@ public final class ScanRecord {
    // Raw bytes of scan record.
    private final byte[] mBytes;

    // Transport Discovery data.
    private final byte[] mTDSData;

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

    /**
     * @hide
     * Returns Transport Discovery data
     */
    public byte[] getTDSData() {
        return mTDSData;
    }

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

@@ -211,6 +224,8 @@ public final class ScanRecord {
        SparseArray<byte[]> manufacturerData = new SparseArray<byte[]>();
        Map<ParcelUuid, byte[]> serviceData = new ArrayMap<ParcelUuid, byte[]>();

        byte[] tdsData = null;

        try {
            while (currentPos < scanRecord.length) {
                // length is unsigned int.
@@ -288,6 +303,9 @@ public final class ScanRecord {
                                dataLength - 2);
                        manufacturerData.put(manufacturerId, manufacturerDataBytes);
                        break;
                    case DATA_TYPE_TRANSPORT_DISCOVERY_DATA:
                        tdsData = extractBytes(scanRecord, currentPos, dataLength);
                        break;
                    default:
                        // Just ignore, we don't handle such data type.
                        break;
@@ -299,12 +317,12 @@ public final class ScanRecord {
                serviceUuids = null;
            }
            return new ScanRecord(serviceUuids, serviceSolicitationUuids, manufacturerData,
                    serviceData, advertiseFlag, txPowerLevel, localName, scanRecord);
                    serviceData, advertiseFlag, txPowerLevel, localName, tdsData, 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, scanRecord);
            return new ScanRecord(null, null, null, null, -1, Integer.MIN_VALUE, null, null, scanRecord);
        }
    }

@@ -315,7 +333,8 @@ public final class ScanRecord {
                + ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(
                mManufacturerSpecificData)
                + ", mServiceData=" + BluetoothLeUtils.toString(mServiceData)
                + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]";
                + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName +
                ", mTDSData=" + BluetoothLeUtils.toString(mTDSData) +"]";
    }

    // Parse service UUIDs.