Merge "Bluetooth: make it possible to advertise Transport Discovery Data"
This commit is contained in:
@@ -9546,6 +9546,7 @@ package android.bluetooth.le {
|
|||||||
method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData();
|
method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData();
|
||||||
method @NonNull public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids();
|
method @NonNull 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 @NonNull public java.util.List<android.bluetooth.le.TransportDiscoveryData> getTransportDiscoveryData();
|
||||||
method public void writeToParcel(android.os.Parcel, int);
|
method public void writeToParcel(android.os.Parcel, int);
|
||||||
field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertiseData> CREATOR;
|
field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertiseData> CREATOR;
|
||||||
}
|
}
|
||||||
@@ -9556,6 +9557,7 @@ package android.bluetooth.le {
|
|||||||
method public android.bluetooth.le.AdvertiseData.Builder addServiceData(android.os.ParcelUuid, byte[]);
|
method public android.bluetooth.le.AdvertiseData.Builder addServiceData(android.os.ParcelUuid, byte[]);
|
||||||
method @NonNull public android.bluetooth.le.AdvertiseData.Builder addServiceSolicitationUuid(@NonNull android.os.ParcelUuid);
|
method @NonNull public android.bluetooth.le.AdvertiseData.Builder addServiceSolicitationUuid(@NonNull android.os.ParcelUuid);
|
||||||
method public android.bluetooth.le.AdvertiseData.Builder addServiceUuid(android.os.ParcelUuid);
|
method public android.bluetooth.le.AdvertiseData.Builder addServiceUuid(android.os.ParcelUuid);
|
||||||
|
method @NonNull public android.bluetooth.le.AdvertiseData.Builder addTransportDiscoveryData(@NonNull android.bluetooth.le.TransportDiscoveryData);
|
||||||
method public android.bluetooth.le.AdvertiseData build();
|
method public android.bluetooth.le.AdvertiseData build();
|
||||||
method public android.bluetooth.le.AdvertiseData.Builder setIncludeDeviceName(boolean);
|
method public android.bluetooth.le.AdvertiseData.Builder setIncludeDeviceName(boolean);
|
||||||
method public android.bluetooth.le.AdvertiseData.Builder setIncludeTxPowerLevel(boolean);
|
method public android.bluetooth.le.AdvertiseData.Builder setIncludeTxPowerLevel(boolean);
|
||||||
@@ -9815,6 +9817,31 @@ package android.bluetooth.le {
|
|||||||
method public android.bluetooth.le.ScanSettings.Builder setScanMode(int);
|
method public android.bluetooth.le.ScanSettings.Builder setScanMode(int);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class TransportBlock implements android.os.Parcelable {
|
||||||
|
ctor public TransportBlock(int, int, int, @Nullable byte[]);
|
||||||
|
method public int describeContents();
|
||||||
|
method public int getOrgId();
|
||||||
|
method public int getTdsFlags();
|
||||||
|
method @Nullable public byte[] getTransportData();
|
||||||
|
method public int getTransportDataLength();
|
||||||
|
method @Nullable public byte[] toByteArray();
|
||||||
|
method public int totalBytes();
|
||||||
|
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||||
|
field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.TransportBlock> CREATOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class TransportDiscoveryData implements android.os.Parcelable {
|
||||||
|
ctor public TransportDiscoveryData(int, @NonNull java.util.List<android.bluetooth.le.TransportBlock>);
|
||||||
|
ctor public TransportDiscoveryData(@NonNull byte[]);
|
||||||
|
method public int describeContents();
|
||||||
|
method @NonNull public java.util.List<android.bluetooth.le.TransportBlock> getTransportBlocks();
|
||||||
|
method public int getTransportDataType();
|
||||||
|
method @Nullable public byte[] toByteArray();
|
||||||
|
method public int totalBytes();
|
||||||
|
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||||
|
field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.TransportDiscoveryData> CREATOR;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
package android.companion {
|
package android.companion {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import android.util.ArrayMap;
|
|||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -47,6 +48,9 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final List<ParcelUuid> mServiceSolicitationUuids;
|
private final List<ParcelUuid> mServiceSolicitationUuids;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private final List<TransportDiscoveryData> mTransportDiscoveryData;
|
||||||
|
|
||||||
private final SparseArray<byte[]> mManufacturerSpecificData;
|
private final SparseArray<byte[]> mManufacturerSpecificData;
|
||||||
private final Map<ParcelUuid, byte[]> mServiceData;
|
private final Map<ParcelUuid, byte[]> mServiceData;
|
||||||
private final boolean mIncludeTxPowerLevel;
|
private final boolean mIncludeTxPowerLevel;
|
||||||
@@ -54,12 +58,14 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
|
|
||||||
private AdvertiseData(List<ParcelUuid> serviceUuids,
|
private AdvertiseData(List<ParcelUuid> serviceUuids,
|
||||||
List<ParcelUuid> serviceSolicitationUuids,
|
List<ParcelUuid> serviceSolicitationUuids,
|
||||||
|
List<TransportDiscoveryData> transportDiscoveryData,
|
||||||
SparseArray<byte[]> manufacturerData,
|
SparseArray<byte[]> manufacturerData,
|
||||||
Map<ParcelUuid, byte[]> serviceData,
|
Map<ParcelUuid, byte[]> serviceData,
|
||||||
boolean includeTxPowerLevel,
|
boolean includeTxPowerLevel,
|
||||||
boolean includeDeviceName) {
|
boolean includeDeviceName) {
|
||||||
mServiceUuids = serviceUuids;
|
mServiceUuids = serviceUuids;
|
||||||
mServiceSolicitationUuids = serviceSolicitationUuids;
|
mServiceSolicitationUuids = serviceSolicitationUuids;
|
||||||
|
mTransportDiscoveryData = transportDiscoveryData;
|
||||||
mManufacturerSpecificData = manufacturerData;
|
mManufacturerSpecificData = manufacturerData;
|
||||||
mServiceData = serviceData;
|
mServiceData = serviceData;
|
||||||
mIncludeTxPowerLevel = includeTxPowerLevel;
|
mIncludeTxPowerLevel = includeTxPowerLevel;
|
||||||
@@ -82,6 +88,17 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
return mServiceSolicitationUuids;
|
return mServiceSolicitationUuids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of {@link TransportDiscoveryData} within the advertisement.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public List<TransportDiscoveryData> getTransportDiscoveryData() {
|
||||||
|
if (mTransportDiscoveryData == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return mTransportDiscoveryData;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of manufacturer Id and the corresponding manufacturer specific data. The
|
* Returns an array of manufacturer Id and the corresponding manufacturer specific data. The
|
||||||
* manufacturer id is a non-negative number assigned by Bluetooth SIG.
|
* manufacturer id is a non-negative number assigned by Bluetooth SIG.
|
||||||
@@ -116,8 +133,8 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(mServiceUuids, mServiceSolicitationUuids, mManufacturerSpecificData,
|
return Objects.hash(mServiceUuids, mServiceSolicitationUuids, mTransportDiscoveryData,
|
||||||
mServiceData, mIncludeDeviceName, mIncludeTxPowerLevel);
|
mManufacturerSpecificData, mServiceData, mIncludeDeviceName, mIncludeTxPowerLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -134,6 +151,7 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
AdvertiseData other = (AdvertiseData) obj;
|
AdvertiseData other = (AdvertiseData) obj;
|
||||||
return Objects.equals(mServiceUuids, other.mServiceUuids)
|
return Objects.equals(mServiceUuids, other.mServiceUuids)
|
||||||
&& Objects.equals(mServiceSolicitationUuids, other.mServiceSolicitationUuids)
|
&& Objects.equals(mServiceSolicitationUuids, other.mServiceSolicitationUuids)
|
||||||
|
&& Objects.equals(mTransportDiscoveryData, other.mTransportDiscoveryData)
|
||||||
&& BluetoothLeUtils.equals(mManufacturerSpecificData,
|
&& BluetoothLeUtils.equals(mManufacturerSpecificData,
|
||||||
other.mManufacturerSpecificData)
|
other.mManufacturerSpecificData)
|
||||||
&& BluetoothLeUtils.equals(mServiceData, other.mServiceData)
|
&& BluetoothLeUtils.equals(mServiceData, other.mServiceData)
|
||||||
@@ -144,7 +162,8 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mServiceSolicitationUuids="
|
return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mServiceSolicitationUuids="
|
||||||
+ mServiceSolicitationUuids + ", mManufacturerSpecificData="
|
+ mServiceSolicitationUuids + ", mTransportDiscoveryData="
|
||||||
|
+ mTransportDiscoveryData + ", mManufacturerSpecificData="
|
||||||
+ BluetoothLeUtils.toString(mManufacturerSpecificData) + ", mServiceData="
|
+ BluetoothLeUtils.toString(mManufacturerSpecificData) + ", mServiceData="
|
||||||
+ BluetoothLeUtils.toString(mServiceData)
|
+ BluetoothLeUtils.toString(mServiceData)
|
||||||
+ ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName="
|
+ ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName="
|
||||||
@@ -162,6 +181,8 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
dest.writeTypedArray(mServiceSolicitationUuids.toArray(
|
dest.writeTypedArray(mServiceSolicitationUuids.toArray(
|
||||||
new ParcelUuid[mServiceSolicitationUuids.size()]), flags);
|
new ParcelUuid[mServiceSolicitationUuids.size()]), flags);
|
||||||
|
|
||||||
|
dest.writeTypedList(mTransportDiscoveryData);
|
||||||
|
|
||||||
// mManufacturerSpecificData could not be null.
|
// mManufacturerSpecificData could not be null.
|
||||||
dest.writeInt(mManufacturerSpecificData.size());
|
dest.writeInt(mManufacturerSpecificData.size());
|
||||||
for (int i = 0; i < mManufacturerSpecificData.size(); ++i) {
|
for (int i = 0; i < mManufacturerSpecificData.size(); ++i) {
|
||||||
@@ -197,6 +218,12 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
builder.addServiceSolicitationUuid(uuid);
|
builder.addServiceSolicitationUuid(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<TransportDiscoveryData> transportDiscoveryData =
|
||||||
|
in.createTypedArrayList(TransportDiscoveryData.CREATOR);
|
||||||
|
for (TransportDiscoveryData tdd : transportDiscoveryData) {
|
||||||
|
builder.addTransportDiscoveryData(tdd);
|
||||||
|
}
|
||||||
|
|
||||||
int manufacturerSize = in.readInt();
|
int manufacturerSize = in.readInt();
|
||||||
for (int i = 0; i < manufacturerSize; ++i) {
|
for (int i = 0; i < manufacturerSize; ++i) {
|
||||||
int manufacturerId = in.readInt();
|
int manufacturerId = in.readInt();
|
||||||
@@ -223,6 +250,9 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>();
|
private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>();
|
||||||
@NonNull
|
@NonNull
|
||||||
private List<ParcelUuid> mServiceSolicitationUuids = new ArrayList<ParcelUuid>();
|
private List<ParcelUuid> mServiceSolicitationUuids = new ArrayList<ParcelUuid>();
|
||||||
|
@Nullable
|
||||||
|
private List<TransportDiscoveryData> mTransportDiscoveryData =
|
||||||
|
new ArrayList<TransportDiscoveryData>();
|
||||||
private SparseArray<byte[]> mManufacturerSpecificData = new SparseArray<byte[]>();
|
private SparseArray<byte[]> mManufacturerSpecificData = new SparseArray<byte[]>();
|
||||||
private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>();
|
private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>();
|
||||||
private boolean mIncludeTxPowerLevel;
|
private boolean mIncludeTxPowerLevel;
|
||||||
@@ -256,6 +286,7 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
mServiceSolicitationUuids.add(serviceSolicitationUuid);
|
mServiceSolicitationUuids.add(serviceSolicitationUuid);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add service data to advertise data.
|
* Add service data to advertise data.
|
||||||
*
|
*
|
||||||
@@ -273,6 +304,23 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Transport Discovery Data to advertise data.
|
||||||
|
*
|
||||||
|
* @param transportDiscoveryData Transport Discovery Data, consisting of one or more
|
||||||
|
* Transport Blocks. Transport Discovery Data AD Type Code is already included.
|
||||||
|
* @throws IllegalArgumentException If the {@code transportDiscoveryData} is empty
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder addTransportDiscoveryData(
|
||||||
|
@NonNull TransportDiscoveryData transportDiscoveryData) {
|
||||||
|
if (transportDiscoveryData == null) {
|
||||||
|
throw new IllegalArgumentException("transportDiscoveryData is null");
|
||||||
|
}
|
||||||
|
mTransportDiscoveryData.add(transportDiscoveryData);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add manufacturer specific data.
|
* Add manufacturer specific data.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -319,8 +367,8 @@ public final class AdvertiseData implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public AdvertiseData build() {
|
public AdvertiseData build() {
|
||||||
return new AdvertiseData(mServiceUuids, mServiceSolicitationUuids,
|
return new AdvertiseData(mServiceUuids, mServiceSolicitationUuids,
|
||||||
mManufacturerSpecificData, mServiceData, mIncludeTxPowerLevel,
|
mTransportDiscoveryData, mManufacturerSpecificData, mServiceData,
|
||||||
mIncludeDeviceName);
|
mIncludeTxPowerLevel, mIncludeDeviceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -567,6 +567,9 @@ public final class BluetoothLeAdvertiser {
|
|||||||
+ num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
|
+ num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (TransportDiscoveryData transportDiscoveryData : data.getTransportDiscoveryData()) {
|
||||||
|
size += OVERHEAD_BYTES_PER_FIELD + transportDiscoveryData.totalBytes();
|
||||||
|
}
|
||||||
for (ParcelUuid uuid : data.getServiceData().keySet()) {
|
for (ParcelUuid uuid : data.getServiceData().keySet()) {
|
||||||
int uuidLen = BluetoothUuid.uuidToBytes(uuid).length;
|
int uuidLen = BluetoothUuid.uuidToBytes(uuid).length;
|
||||||
size += OVERHEAD_BYTES_PER_FIELD + uuidLen
|
size += OVERHEAD_BYTES_PER_FIELD + uuidLen
|
||||||
|
|||||||
155
core/java/android/bluetooth/le/TransportBlock.java
Normal file
155
core/java/android/bluetooth/le/TransportBlock.java
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.bluetooth.le;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.nio.BufferOverflowException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for Transport Discovery Data Transport Blocks.
|
||||||
|
* This class represents a Transport Block from a Transport Discovery Data.
|
||||||
|
*
|
||||||
|
* @see TransportDiscoveryData
|
||||||
|
* @see AdvertiseData
|
||||||
|
*/
|
||||||
|
public final class TransportBlock implements Parcelable {
|
||||||
|
private static final String TAG = "TransportBlock";
|
||||||
|
private final int mOrgId;
|
||||||
|
private final int mTdsFlags;
|
||||||
|
private final int mTransportDataLength;
|
||||||
|
private final byte[] mTransportData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of TransportBlock from raw data.
|
||||||
|
*
|
||||||
|
* @param orgId the Organization ID
|
||||||
|
* @param tdsFlags the TDS flags
|
||||||
|
* @param transportDataLength the total length of the Transport Data
|
||||||
|
* @param transportData the Transport Data
|
||||||
|
*/
|
||||||
|
public TransportBlock(int orgId, int tdsFlags, int transportDataLength,
|
||||||
|
@Nullable byte[] transportData) {
|
||||||
|
mOrgId = orgId;
|
||||||
|
mTdsFlags = tdsFlags;
|
||||||
|
mTransportDataLength = transportDataLength;
|
||||||
|
mTransportData = transportData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TransportBlock(Parcel in) {
|
||||||
|
mOrgId = in.readInt();
|
||||||
|
mTdsFlags = in.readInt();
|
||||||
|
mTransportDataLength = in.readInt();
|
||||||
|
mTransportData = new byte[mTransportDataLength];
|
||||||
|
in.readByteArray(mTransportData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
dest.writeInt(mOrgId);
|
||||||
|
dest.writeInt(mTdsFlags);
|
||||||
|
dest.writeInt(mTransportDataLength);
|
||||||
|
dest.writeByteArray(mTransportData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final @NonNull Creator<TransportBlock> CREATOR = new Creator<TransportBlock>() {
|
||||||
|
@Override
|
||||||
|
public TransportBlock createFromParcel(Parcel in) {
|
||||||
|
return new TransportBlock(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransportBlock[] newArray(int size) {
|
||||||
|
return new TransportBlock[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Organization ID of the Transport Block which corresponds to one of the
|
||||||
|
* the Bluetooth SIG Assigned Numbers.
|
||||||
|
*/
|
||||||
|
public int getOrgId() {
|
||||||
|
return mOrgId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the TDS flags of the Transport Block which represents the role of the device and
|
||||||
|
* information about its state and supported features.
|
||||||
|
*/
|
||||||
|
public int getTdsFlags() {
|
||||||
|
return mTdsFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the total number of octets in the Transport Data field in this Transport Block.
|
||||||
|
*/
|
||||||
|
public int getTransportDataLength() {
|
||||||
|
return mTransportDataLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Transport Data of the Transport Block which contains organization-specific data.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public byte[] getTransportData() {
|
||||||
|
return mTransportData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts this TransportBlock to byte array
|
||||||
|
*
|
||||||
|
* @return byte array representation of this Transport Block or null if the conversion failed
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public byte[] toByteArray() {
|
||||||
|
try {
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(totalBytes());
|
||||||
|
buffer.put((byte) mOrgId);
|
||||||
|
buffer.put((byte) mTdsFlags);
|
||||||
|
buffer.put((byte) mTransportDataLength);
|
||||||
|
if (mTransportData != null) {
|
||||||
|
buffer.put(mTransportData);
|
||||||
|
}
|
||||||
|
return buffer.array();
|
||||||
|
} catch (BufferOverflowException e) {
|
||||||
|
Log.e(TAG, "Error converting to byte array: " + e.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return total byte count of this TransportBlock
|
||||||
|
*/
|
||||||
|
public int totalBytes() {
|
||||||
|
// 3 uint8 + byte[] length
|
||||||
|
int size = 3 + mTransportDataLength;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
168
core/java/android/bluetooth/le/TransportDiscoveryData.java
Normal file
168
core/java/android/bluetooth/le/TransportDiscoveryData.java
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.bluetooth.le;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.nio.BufferOverflowException;
|
||||||
|
import java.nio.BufferUnderflowException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for Transport Discovery Data AD Type.
|
||||||
|
* This class contains the Transport Discovery Data AD Type Code as well as
|
||||||
|
* a list of potential Transport Blocks.
|
||||||
|
*
|
||||||
|
* @see AdvertiseData
|
||||||
|
*/
|
||||||
|
public final class TransportDiscoveryData implements Parcelable {
|
||||||
|
private static final String TAG = "TransportDiscoveryData";
|
||||||
|
private final int mTransportDataType;
|
||||||
|
private final List<TransportBlock> mTransportBlocks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a TransportDiscoveryData instance.
|
||||||
|
*
|
||||||
|
* @param transportDataType the Transport Discovery Data AD Type
|
||||||
|
* @param transportBlocks the list of Transport Blocks
|
||||||
|
*/
|
||||||
|
public TransportDiscoveryData(int transportDataType,
|
||||||
|
@NonNull List<TransportBlock> transportBlocks) {
|
||||||
|
mTransportDataType = transportDataType;
|
||||||
|
mTransportBlocks = transportBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a TransportDiscoveryData instance from byte arrays.
|
||||||
|
*
|
||||||
|
* Uses the transport discovery data bytes and parses them into an usable class.
|
||||||
|
*
|
||||||
|
* @param transportDiscoveryData the raw discovery data
|
||||||
|
*/
|
||||||
|
public TransportDiscoveryData(@NonNull byte[] transportDiscoveryData) {
|
||||||
|
ByteBuffer byteBuffer = ByteBuffer.wrap(transportDiscoveryData);
|
||||||
|
mTransportBlocks = new ArrayList();
|
||||||
|
if (byteBuffer.remaining() > 0) {
|
||||||
|
mTransportDataType = byteBuffer.get();
|
||||||
|
} else {
|
||||||
|
mTransportDataType = -1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
while (byteBuffer.remaining() > 0) {
|
||||||
|
int orgId = byteBuffer.get();
|
||||||
|
int tdsFlags = byteBuffer.get();
|
||||||
|
int transportDataLength = byteBuffer.get();
|
||||||
|
byte[] transportData = new byte[transportDataLength];
|
||||||
|
byteBuffer.get(transportData, 0, transportDataLength);
|
||||||
|
mTransportBlocks.add(new TransportBlock(orgId, tdsFlags,
|
||||||
|
transportDataLength, transportData));
|
||||||
|
}
|
||||||
|
} catch (BufferUnderflowException e) {
|
||||||
|
Log.e(TAG, "Error while parsing data: " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TransportDiscoveryData(Parcel in) {
|
||||||
|
mTransportDataType = in.readInt();
|
||||||
|
mTransportBlocks = in.createTypedArrayList(TransportBlock.CREATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
dest.writeInt(mTransportDataType);
|
||||||
|
dest.writeTypedList(mTransportBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final @NonNull Creator<TransportDiscoveryData> CREATOR =
|
||||||
|
new Creator<TransportDiscoveryData>() {
|
||||||
|
@Override
|
||||||
|
public TransportDiscoveryData createFromParcel(Parcel in) {
|
||||||
|
return new TransportDiscoveryData(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransportDiscoveryData[] newArray(int size) {
|
||||||
|
return new TransportDiscoveryData[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the transport data type.
|
||||||
|
*/
|
||||||
|
public int getTransportDataType() {
|
||||||
|
return mTransportDataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the list of {@link TransportBlock} in this TransportDiscoveryData
|
||||||
|
* or an empty list if there are no Transport Blocks
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public List<TransportBlock> getTransportBlocks() {
|
||||||
|
if (mTransportBlocks == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return mTransportBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts this TransportDiscoveryData to byte array
|
||||||
|
*
|
||||||
|
* @return byte array representation of this Transport Discovery Data or null if the
|
||||||
|
* conversion failed
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public byte[] toByteArray() {
|
||||||
|
try {
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(totalBytes());
|
||||||
|
buffer.put((byte) mTransportDataType);
|
||||||
|
for (TransportBlock transportBlock : getTransportBlocks()) {
|
||||||
|
buffer.put(transportBlock.toByteArray());
|
||||||
|
}
|
||||||
|
return buffer.array();
|
||||||
|
} catch (BufferOverflowException e) {
|
||||||
|
Log.e(TAG, "Error converting to byte array: " + e.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return total byte count of this TransportDataDiscovery
|
||||||
|
*/
|
||||||
|
public int totalBytes() {
|
||||||
|
int size = 1; // Counting Transport Data Type here.
|
||||||
|
for (TransportBlock transportBlock : getTransportBlocks()) {
|
||||||
|
size += transportBlock.totalBytes();
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user