Merge "BLE: Add service solicitation uuid feature in scan filter"
This commit is contained in:
@@ -8689,6 +8689,8 @@ package android.bluetooth.le {
|
|||||||
method public byte[] getServiceData();
|
method public byte[] getServiceData();
|
||||||
method public byte[] getServiceDataMask();
|
method public byte[] getServiceDataMask();
|
||||||
method public android.os.ParcelUuid getServiceDataUuid();
|
method public android.os.ParcelUuid getServiceDataUuid();
|
||||||
|
method public android.os.ParcelUuid getServiceSolicitationUuid();
|
||||||
|
method public android.os.ParcelUuid getServiceSolicitationUuidMask();
|
||||||
method public android.os.ParcelUuid getServiceUuid();
|
method public android.os.ParcelUuid getServiceUuid();
|
||||||
method public android.os.ParcelUuid getServiceUuidMask();
|
method public android.os.ParcelUuid getServiceUuidMask();
|
||||||
method public boolean matches(android.bluetooth.le.ScanResult);
|
method public boolean matches(android.bluetooth.le.ScanResult);
|
||||||
@@ -8705,6 +8707,8 @@ package android.bluetooth.le {
|
|||||||
method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[], byte[]);
|
method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[], byte[]);
|
||||||
method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[]);
|
method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[]);
|
||||||
method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[], byte[]);
|
method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[], byte[]);
|
||||||
|
method public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(android.os.ParcelUuid);
|
||||||
|
method public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(android.os.ParcelUuid, android.os.ParcelUuid);
|
||||||
method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid);
|
method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid);
|
||||||
method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
|
method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
|
||||||
}
|
}
|
||||||
@@ -8717,6 +8721,7 @@ package android.bluetooth.le {
|
|||||||
method public byte[] getManufacturerSpecificData(int);
|
method public byte[] getManufacturerSpecificData(int);
|
||||||
method public java.util.Map<android.os.ParcelUuid, byte[]> getServiceData();
|
method public java.util.Map<android.os.ParcelUuid, byte[]> getServiceData();
|
||||||
method public byte[] getServiceData(android.os.ParcelUuid);
|
method public byte[] getServiceData(android.os.ParcelUuid);
|
||||||
|
method public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids();
|
||||||
method public java.util.List<android.os.ParcelUuid> getServiceUuids();
|
method public java.util.List<android.os.ParcelUuid> getServiceUuids();
|
||||||
method public int getTxPowerLevel();
|
method public int getTxPowerLevel();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ public final class ScanFilter implements Parcelable {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private final ParcelUuid mServiceUuidMask;
|
private final ParcelUuid mServiceUuidMask;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private final ParcelUuid mServiceSolicitationUuid;
|
||||||
|
@Nullable
|
||||||
|
private final ParcelUuid mServiceSolicitationUuidMask;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final ParcelUuid mServiceDataUuid;
|
private final ParcelUuid mServiceDataUuid;
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -75,12 +80,15 @@ public final class ScanFilter implements Parcelable {
|
|||||||
|
|
||||||
|
|
||||||
private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
|
private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
|
||||||
ParcelUuid uuidMask, ParcelUuid serviceDataUuid,
|
ParcelUuid uuidMask, ParcelUuid solicitationUuid,
|
||||||
|
ParcelUuid solicitationUuidMask, ParcelUuid serviceDataUuid,
|
||||||
byte[] serviceData, byte[] serviceDataMask,
|
byte[] serviceData, byte[] serviceDataMask,
|
||||||
int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask) {
|
int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask) {
|
||||||
mDeviceName = name;
|
mDeviceName = name;
|
||||||
mServiceUuid = uuid;
|
mServiceUuid = uuid;
|
||||||
mServiceUuidMask = uuidMask;
|
mServiceUuidMask = uuidMask;
|
||||||
|
mServiceSolicitationUuid = solicitationUuid;
|
||||||
|
mServiceSolicitationUuidMask = solicitationUuidMask;
|
||||||
mDeviceAddress = deviceAddress;
|
mDeviceAddress = deviceAddress;
|
||||||
mServiceDataUuid = serviceDataUuid;
|
mServiceDataUuid = serviceDataUuid;
|
||||||
mServiceData = serviceData;
|
mServiceData = serviceData;
|
||||||
@@ -113,6 +121,14 @@ public final class ScanFilter implements Parcelable {
|
|||||||
dest.writeParcelable(mServiceUuidMask, flags);
|
dest.writeParcelable(mServiceUuidMask, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dest.writeInt(mServiceSolicitationUuid == null ? 0 : 1);
|
||||||
|
if (mServiceSolicitationUuid != null) {
|
||||||
|
dest.writeParcelable(mServiceSolicitationUuid, flags);
|
||||||
|
dest.writeInt(mServiceSolicitationUuidMask == null ? 0 : 1);
|
||||||
|
if (mServiceSolicitationUuidMask != null) {
|
||||||
|
dest.writeParcelable(mServiceSolicitationUuidMask, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
dest.writeInt(mServiceDataUuid == null ? 0 : 1);
|
dest.writeInt(mServiceDataUuid == null ? 0 : 1);
|
||||||
if (mServiceDataUuid != null) {
|
if (mServiceDataUuid != null) {
|
||||||
dest.writeParcelable(mServiceDataUuid, flags);
|
dest.writeParcelable(mServiceDataUuid, flags);
|
||||||
@@ -171,6 +187,17 @@ public final class ScanFilter implements Parcelable {
|
|||||||
builder.setServiceUuid(uuid, uuidMask);
|
builder.setServiceUuid(uuid, uuidMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (in.readInt() == 1) {
|
||||||
|
ParcelUuid solicitationUuid = in.readParcelable(
|
||||||
|
ParcelUuid.class.getClassLoader());
|
||||||
|
builder.setServiceSolicitationUuid(solicitationUuid);
|
||||||
|
if (in.readInt() == 1) {
|
||||||
|
ParcelUuid solicitationUuidMask = in.readParcelable(
|
||||||
|
ParcelUuid.class.getClassLoader());
|
||||||
|
builder.setServiceSolicitationUuid(solicitationUuid,
|
||||||
|
solicitationUuidMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (in.readInt() == 1) {
|
if (in.readInt() == 1) {
|
||||||
ParcelUuid servcieDataUuid =
|
ParcelUuid servcieDataUuid =
|
||||||
in.readParcelable(ParcelUuid.class.getClassLoader());
|
in.readParcelable(ParcelUuid.class.getClassLoader());
|
||||||
@@ -231,6 +258,22 @@ public final class ScanFilter implements Parcelable {
|
|||||||
return mServiceUuidMask;
|
return mServiceUuidMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the filter set on the service Solicitation uuid.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public ParcelUuid getServiceSolicitationUuid() {
|
||||||
|
return mServiceSolicitationUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the filter set on the service Solicitation uuid mask.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public ParcelUuid getServiceSolicitationUuidMask() {
|
||||||
|
return mServiceSolicitationUuidMask;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getDeviceAddress() {
|
public String getDeviceAddress() {
|
||||||
return mDeviceAddress;
|
return mDeviceAddress;
|
||||||
@@ -288,7 +331,7 @@ public final class ScanFilter implements Parcelable {
|
|||||||
// Scan record is null but there exist filters on it.
|
// Scan record is null but there exist filters on it.
|
||||||
if (scanRecord == null
|
if (scanRecord == null
|
||||||
&& (mDeviceName != null || mServiceUuid != null || mManufacturerData != null
|
&& (mDeviceName != null || mServiceUuid != null || mManufacturerData != null
|
||||||
|| mServiceData != null)) {
|
|| mServiceData != null || mServiceSolicitationUuid != null)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,6 +346,13 @@ public final class ScanFilter implements Parcelable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// solicitation UUID match.
|
||||||
|
if (mServiceSolicitationUuid != null && !matchesServiceSolicitationUuids(
|
||||||
|
mServiceSolicitationUuid, mServiceSolicitationUuidMask,
|
||||||
|
scanRecord.getServiceSolicitationUuids())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Service data match
|
// Service data match
|
||||||
if (mServiceDataUuid != null) {
|
if (mServiceDataUuid != null) {
|
||||||
if (!matchesPartialData(mServiceData, mServiceDataMask,
|
if (!matchesPartialData(mServiceData, mServiceDataMask,
|
||||||
@@ -350,6 +400,36 @@ public final class ScanFilter implements Parcelable {
|
|||||||
return BitUtils.maskedEquals(data, uuid, mask);
|
return BitUtils.maskedEquals(data, uuid, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the solicitation uuid pattern is contained in a list of parcel uuids.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static boolean matchesServiceSolicitationUuids(ParcelUuid solicitationUuid,
|
||||||
|
ParcelUuid parcelSolicitationUuidMask, List<ParcelUuid> solicitationUuids) {
|
||||||
|
if (solicitationUuid == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (solicitationUuids == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ParcelUuid parcelSolicitationUuid : solicitationUuids) {
|
||||||
|
UUID solicitationUuidMask = parcelSolicitationUuidMask == null
|
||||||
|
? null : parcelSolicitationUuidMask.getUuid();
|
||||||
|
if (matchesServiceUuid(solicitationUuid.getUuid(), solicitationUuidMask,
|
||||||
|
parcelSolicitationUuid.getUuid())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the solicitation uuid pattern matches the particular service solicitation uuid.
|
||||||
|
private static boolean matchesServiceSolicitationUuid(UUID solicitationUuid,
|
||||||
|
UUID solicitationUuidMask, UUID data) {
|
||||||
|
return BitUtils.maskedEquals(data, solicitationUuid, solicitationUuidMask);
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether the data pattern matches the parsed data.
|
// Check whether the data pattern matches the parsed data.
|
||||||
private boolean matchesPartialData(byte[] data, byte[] dataMask, byte[] parsedData) {
|
private boolean matchesPartialData(byte[] data, byte[] dataMask, byte[] parsedData) {
|
||||||
if (parsedData == null || parsedData.length < data.length) {
|
if (parsedData == null || parsedData.length < data.length) {
|
||||||
@@ -376,6 +456,8 @@ public final class ScanFilter implements Parcelable {
|
|||||||
return "BluetoothLeScanFilter [mDeviceName=" + mDeviceName + ", mDeviceAddress="
|
return "BluetoothLeScanFilter [mDeviceName=" + mDeviceName + ", mDeviceAddress="
|
||||||
+ mDeviceAddress
|
+ mDeviceAddress
|
||||||
+ ", mUuid=" + mServiceUuid + ", mUuidMask=" + mServiceUuidMask
|
+ ", mUuid=" + mServiceUuid + ", mUuidMask=" + mServiceUuidMask
|
||||||
|
+ ", mServiceSolicitationUuid=" + mServiceSolicitationUuid
|
||||||
|
+ ", mServiceSolicitationUuidMask=" + mServiceSolicitationUuidMask
|
||||||
+ ", mServiceDataUuid=" + Objects.toString(mServiceDataUuid) + ", mServiceData="
|
+ ", mServiceDataUuid=" + Objects.toString(mServiceDataUuid) + ", mServiceData="
|
||||||
+ Arrays.toString(mServiceData) + ", mServiceDataMask="
|
+ Arrays.toString(mServiceData) + ", mServiceDataMask="
|
||||||
+ Arrays.toString(mServiceDataMask) + ", mManufacturerId=" + mManufacturerId
|
+ Arrays.toString(mServiceDataMask) + ", mManufacturerId=" + mManufacturerId
|
||||||
@@ -391,7 +473,8 @@ public final class ScanFilter implements Parcelable {
|
|||||||
mServiceDataUuid,
|
mServiceDataUuid,
|
||||||
Arrays.hashCode(mServiceData),
|
Arrays.hashCode(mServiceData),
|
||||||
Arrays.hashCode(mServiceDataMask),
|
Arrays.hashCode(mServiceDataMask),
|
||||||
mServiceUuid, mServiceUuidMask);
|
mServiceUuid, mServiceUuidMask,
|
||||||
|
mServiceSolicitationUuid, mServiceSolicitationUuidMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -412,7 +495,10 @@ public final class ScanFilter implements Parcelable {
|
|||||||
&& Objects.deepEquals(mServiceData, other.mServiceData)
|
&& Objects.deepEquals(mServiceData, other.mServiceData)
|
||||||
&& Objects.deepEquals(mServiceDataMask, other.mServiceDataMask)
|
&& Objects.deepEquals(mServiceDataMask, other.mServiceDataMask)
|
||||||
&& Objects.equals(mServiceUuid, other.mServiceUuid)
|
&& Objects.equals(mServiceUuid, other.mServiceUuid)
|
||||||
&& Objects.equals(mServiceUuidMask, other.mServiceUuidMask);
|
&& Objects.equals(mServiceUuidMask, other.mServiceUuidMask)
|
||||||
|
&& Objects.equals(mServiceSolicitationUuid, other.mServiceSolicitationUuid)
|
||||||
|
&& Objects.equals(mServiceSolicitationUuidMask,
|
||||||
|
other.mServiceSolicitationUuidMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -435,6 +521,9 @@ public final class ScanFilter implements Parcelable {
|
|||||||
private ParcelUuid mServiceUuid;
|
private ParcelUuid mServiceUuid;
|
||||||
private ParcelUuid mUuidMask;
|
private ParcelUuid mUuidMask;
|
||||||
|
|
||||||
|
private ParcelUuid mServiceSolicitationUuid;
|
||||||
|
private ParcelUuid mServiceSolicitationUuidMask;
|
||||||
|
|
||||||
private ParcelUuid mServiceDataUuid;
|
private ParcelUuid mServiceDataUuid;
|
||||||
private byte[] mServiceData;
|
private byte[] mServiceData;
|
||||||
private byte[] mServiceDataMask;
|
private byte[] mServiceDataMask;
|
||||||
@@ -493,6 +582,36 @@ public final class ScanFilter implements Parcelable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set filter on service solicitation uuid.
|
||||||
|
*/
|
||||||
|
public Builder setServiceSolicitationUuid(ParcelUuid serviceSolicitationUuid) {
|
||||||
|
mServiceSolicitationUuid = serviceSolicitationUuid;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set filter on partial service Solicitation uuid. The {@code SolicitationUuidMask} is the
|
||||||
|
* bit mask for the {@code serviceSolicitationUuid}. Set any bit in the mask to 1 to
|
||||||
|
* indicate a match is needed for the bit in {@code serviceSolicitationUuid}, and 0 to
|
||||||
|
* ignore that bit.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException If {@code serviceSolicitationUuid} is {@code null} but
|
||||||
|
* {@code serviceSolicitationUuidMask} is not {@code null}.
|
||||||
|
*/
|
||||||
|
public Builder setServiceSolicitationUuid(ParcelUuid serviceSolicitationUuid,
|
||||||
|
ParcelUuid solicitationUuidMask) {
|
||||||
|
if (mServiceSolicitationUuidMask != null && mServiceSolicitationUuid == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"SolicitationUuid is null while SolicitationUuidMask is not null!");
|
||||||
|
}
|
||||||
|
mServiceSolicitationUuid = serviceSolicitationUuid;
|
||||||
|
mServiceSolicitationUuidMask = solicitationUuidMask;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set filtering on service data.
|
* Set filtering on service data.
|
||||||
*
|
*
|
||||||
@@ -598,7 +717,8 @@ public final class ScanFilter implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public ScanFilter build() {
|
public ScanFilter build() {
|
||||||
return new ScanFilter(mDeviceName, mDeviceAddress,
|
return new ScanFilter(mDeviceName, mDeviceAddress,
|
||||||
mServiceUuid, mUuidMask,
|
mServiceUuid, mUuidMask, mServiceSolicitationUuid,
|
||||||
|
mServiceSolicitationUuidMask,
|
||||||
mServiceDataUuid, mServiceData, mServiceDataMask,
|
mServiceDataUuid, mServiceData, mServiceDataMask,
|
||||||
mManufacturerId, mManufacturerData, mManufacturerDataMask);
|
mManufacturerId, mManufacturerData, mManufacturerDataMask);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ public final class ScanRecord {
|
|||||||
private static final int DATA_TYPE_SERVICE_DATA_16_BIT = 0x16;
|
private static final int DATA_TYPE_SERVICE_DATA_16_BIT = 0x16;
|
||||||
private static final int DATA_TYPE_SERVICE_DATA_32_BIT = 0x20;
|
private static final int DATA_TYPE_SERVICE_DATA_32_BIT = 0x20;
|
||||||
private static final int DATA_TYPE_SERVICE_DATA_128_BIT = 0x21;
|
private static final int DATA_TYPE_SERVICE_DATA_128_BIT = 0x21;
|
||||||
|
private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_16_BIT = 0x14;
|
||||||
|
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_MANUFACTURER_SPECIFIC_DATA = 0xFF;
|
||||||
|
|
||||||
// Flags of the advertising data.
|
// Flags of the advertising data.
|
||||||
@@ -58,6 +61,8 @@ public final class ScanRecord {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final List<ParcelUuid> mServiceUuids;
|
private final List<ParcelUuid> mServiceUuids;
|
||||||
|
@Nullable
|
||||||
|
private final List<ParcelUuid> mServiceSolicitationUuids;
|
||||||
|
|
||||||
private final SparseArray<byte[]> mManufacturerSpecificData;
|
private final SparseArray<byte[]> mManufacturerSpecificData;
|
||||||
|
|
||||||
@@ -88,6 +93,15 @@ public final class ScanRecord {
|
|||||||
return mServiceUuids;
|
return mServiceUuids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of service solicitation UUIDs within the advertisement that are used to
|
||||||
|
* identify the Bluetooth GATT services.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public List<ParcelUuid> getServiceSolicitationUuids() {
|
||||||
|
return mServiceSolicitationUuids;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a sparse array of manufacturer identifier and its corresponding manufacturer specific
|
* Returns a sparse array of manufacturer identifier and its corresponding manufacturer specific
|
||||||
* data.
|
* data.
|
||||||
@@ -151,10 +165,12 @@ public final class ScanRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ScanRecord(List<ParcelUuid> serviceUuids,
|
private ScanRecord(List<ParcelUuid> serviceUuids,
|
||||||
|
List<ParcelUuid> serviceSolicitationUuids,
|
||||||
SparseArray<byte[]> manufacturerData,
|
SparseArray<byte[]> manufacturerData,
|
||||||
Map<ParcelUuid, byte[]> serviceData,
|
Map<ParcelUuid, byte[]> serviceData,
|
||||||
int advertiseFlags, int txPowerLevel,
|
int advertiseFlags, int txPowerLevel,
|
||||||
String localName, byte[] bytes) {
|
String localName, byte[] bytes) {
|
||||||
|
mServiceSolicitationUuids = serviceSolicitationUuids;
|
||||||
mServiceUuids = serviceUuids;
|
mServiceUuids = serviceUuids;
|
||||||
mManufacturerSpecificData = manufacturerData;
|
mManufacturerSpecificData = manufacturerData;
|
||||||
mServiceData = serviceData;
|
mServiceData = serviceData;
|
||||||
@@ -184,6 +200,7 @@ public final class ScanRecord {
|
|||||||
int currentPos = 0;
|
int currentPos = 0;
|
||||||
int advertiseFlag = -1;
|
int advertiseFlag = -1;
|
||||||
List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
|
List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
|
||||||
|
List<ParcelUuid> serviceSolicitationUuids = new ArrayList<ParcelUuid>();
|
||||||
String localName = null;
|
String localName = null;
|
||||||
int txPowerLevel = Integer.MIN_VALUE;
|
int txPowerLevel = Integer.MIN_VALUE;
|
||||||
|
|
||||||
@@ -220,6 +237,18 @@ public final class ScanRecord {
|
|||||||
parseServiceUuid(scanRecord, currentPos, dataLength,
|
parseServiceUuid(scanRecord, currentPos, dataLength,
|
||||||
BluetoothUuid.UUID_BYTES_128_BIT, serviceUuids);
|
BluetoothUuid.UUID_BYTES_128_BIT, serviceUuids);
|
||||||
break;
|
break;
|
||||||
|
case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_16_BIT:
|
||||||
|
parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
|
||||||
|
BluetoothUuid.UUID_BYTES_16_BIT, serviceSolicitationUuids);
|
||||||
|
break;
|
||||||
|
case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_32_BIT:
|
||||||
|
parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
|
||||||
|
BluetoothUuid.UUID_BYTES_32_BIT, serviceSolicitationUuids);
|
||||||
|
break;
|
||||||
|
case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_128_BIT:
|
||||||
|
parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
|
||||||
|
BluetoothUuid.UUID_BYTES_128_BIT, serviceSolicitationUuids);
|
||||||
|
break;
|
||||||
case DATA_TYPE_LOCAL_NAME_SHORT:
|
case DATA_TYPE_LOCAL_NAME_SHORT:
|
||||||
case DATA_TYPE_LOCAL_NAME_COMPLETE:
|
case DATA_TYPE_LOCAL_NAME_COMPLETE:
|
||||||
localName = new String(
|
localName = new String(
|
||||||
@@ -265,19 +294,23 @@ public final class ScanRecord {
|
|||||||
if (serviceUuids.isEmpty()) {
|
if (serviceUuids.isEmpty()) {
|
||||||
serviceUuids = null;
|
serviceUuids = null;
|
||||||
}
|
}
|
||||||
return new ScanRecord(serviceUuids, manufacturerData, serviceData,
|
if (serviceSolicitationUuids.isEmpty()) {
|
||||||
advertiseFlag, txPowerLevel, localName, scanRecord);
|
serviceSolicitationUuids = null;
|
||||||
|
}
|
||||||
|
return new ScanRecord(serviceUuids, serviceSolicitationUuids, manufacturerData,
|
||||||
|
serviceData, advertiseFlag, txPowerLevel, localName, scanRecord);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
|
Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
|
||||||
// As the record is invalid, ignore all the parsed results for this packet
|
// As the record is invalid, ignore all the parsed results for this packet
|
||||||
// and return an empty record with raw scanRecord bytes in results
|
// and return an empty record with raw scanRecord bytes in results
|
||||||
return new ScanRecord(null, null, null, -1, Integer.MIN_VALUE, null, scanRecord);
|
return new ScanRecord(null, null, null, null, -1, Integer.MIN_VALUE, null, scanRecord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ScanRecord [mAdvertiseFlags=" + mAdvertiseFlags + ", mServiceUuids=" + mServiceUuids
|
return "ScanRecord [mAdvertiseFlags=" + mAdvertiseFlags + ", mServiceUuids=" + mServiceUuids
|
||||||
|
+ ", mServiceSolicitationUuids=" + mServiceSolicitationUuids
|
||||||
+ ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(
|
+ ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(
|
||||||
mManufacturerSpecificData)
|
mManufacturerSpecificData)
|
||||||
+ ", mServiceData=" + BluetoothLeUtils.toString(mServiceData)
|
+ ", mServiceData=" + BluetoothLeUtils.toString(mServiceData)
|
||||||
@@ -297,6 +330,20 @@ public final class ScanRecord {
|
|||||||
return currentPos;
|
return currentPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse service Solicitation UUIDs.
|
||||||
|
*/
|
||||||
|
private static int parseServiceSolicitationUuid(byte[] scanRecord, int currentPos,
|
||||||
|
int dataLength, int uuidLength, List<ParcelUuid> serviceSolicitationUuids) {
|
||||||
|
while (dataLength > 0) {
|
||||||
|
byte[] uuidBytes = extractBytes(scanRecord, currentPos, uuidLength);
|
||||||
|
serviceSolicitationUuids.add(BluetoothUuid.parseUuidFrom(uuidBytes));
|
||||||
|
dataLength -= uuidLength;
|
||||||
|
currentPos += uuidLength;
|
||||||
|
}
|
||||||
|
return currentPos;
|
||||||
|
}
|
||||||
|
|
||||||
// Helper method to extract bytes from byte array.
|
// Helper method to extract bytes from byte array.
|
||||||
private static byte[] extractBytes(byte[] scanRecord, int start, int length) {
|
private static byte[] extractBytes(byte[] scanRecord, int start, int length) {
|
||||||
byte[] bytes = new byte[length];
|
byte[] bytes = new byte[length];
|
||||||
|
|||||||
Reference in New Issue
Block a user