1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.bluetooth.le;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.util.Log;
24 
25 import java.nio.BufferOverflowException;
26 import java.nio.ByteBuffer;
27 import java.util.Arrays;
28 
29 /**
30  * Wrapper for Transport Discovery Data Transport Blocks. This class represents a Transport Block
31  * from a Transport Discovery Data.
32  *
33  * @see TransportDiscoveryData
34  * @see AdvertiseData
35  */
36 public final class TransportBlock implements Parcelable {
37     private static final String TAG = "TransportBlock";
38     private final int mOrgId;
39     private final int mTdsFlags;
40     private final int mTransportDataLength;
41     private final byte[] mTransportData;
42 
43     /**
44      * Creates an instance of TransportBlock from raw data.
45      *
46      * @param orgId the Organization ID
47      * @param tdsFlags the TDS flags
48      * @param transportDataLength the total length of the Transport Data
49      * @param transportData the Transport Data
50      */
TransportBlock( int orgId, int tdsFlags, int transportDataLength, @Nullable byte[] transportData)51     public TransportBlock(
52             int orgId, int tdsFlags, int transportDataLength, @Nullable byte[] transportData) {
53         mOrgId = orgId;
54         mTdsFlags = tdsFlags;
55         mTransportDataLength = transportDataLength;
56         mTransportData = transportData;
57     }
58 
TransportBlock(Parcel in)59     private TransportBlock(Parcel in) {
60         mOrgId = in.readInt();
61         mTdsFlags = in.readInt();
62         mTransportDataLength = in.readInt();
63         if (mTransportDataLength > 0) {
64             mTransportData = new byte[mTransportDataLength];
65             in.readByteArray(mTransportData);
66         } else {
67             mTransportData = null;
68         }
69     }
70 
71     @Override
writeToParcel(@onNull Parcel dest, int flags)72     public void writeToParcel(@NonNull Parcel dest, int flags) {
73         dest.writeInt(mOrgId);
74         dest.writeInt(mTdsFlags);
75         dest.writeInt(mTransportDataLength);
76         if (mTransportData != null) {
77             dest.writeByteArray(mTransportData);
78         }
79     }
80 
81     /** @hide */
82     @Override
describeContents()83     public int describeContents() {
84         return 0;
85     }
86 
87     /** @hide */
88     @Override
equals(@ullable Object obj)89     public boolean equals(@Nullable Object obj) {
90         if (this == obj) {
91             return true;
92         }
93         if (obj == null || getClass() != obj.getClass()) {
94             return false;
95         }
96         TransportBlock other = (TransportBlock) obj;
97         return Arrays.equals(toByteArray(), other.toByteArray());
98     }
99 
100     /** @hide */
101     @Override
hashCode()102     public int hashCode() {
103         return Arrays.hashCode(toByteArray());
104     }
105 
106     public static final @NonNull Creator<TransportBlock> CREATOR =
107             new Creator<TransportBlock>() {
108                 @Override
109                 public TransportBlock createFromParcel(Parcel in) {
110                     return new TransportBlock(in);
111                 }
112 
113                 @Override
114                 public TransportBlock[] newArray(int size) {
115                     return new TransportBlock[size];
116                 }
117             };
118 
119     /**
120      * Gets the Organization ID of the Transport Block which corresponds to one of the Bluetooth SIG
121      * Assigned Numbers.
122      */
getOrgId()123     public int getOrgId() {
124         return mOrgId;
125     }
126 
127     /**
128      * Gets the TDS flags of the Transport Block which represents the role of the device and
129      * information about its state and supported features.
130      */
getTdsFlags()131     public int getTdsFlags() {
132         return mTdsFlags;
133     }
134 
135     /** Gets the total number of octets in the Transport Data field in this Transport Block. */
getTransportDataLength()136     public int getTransportDataLength() {
137         return mTransportDataLength;
138     }
139 
140     /** Gets the Transport Data of the Transport Block which contains organization-specific data. */
141     @Nullable
getTransportData()142     public byte[] getTransportData() {
143         return mTransportData;
144     }
145 
146     /**
147      * Converts this TransportBlock to byte array
148      *
149      * @return byte array representation of this Transport Block or null if the conversion failed
150      */
151     @Nullable
toByteArray()152     public byte[] toByteArray() {
153         try {
154             ByteBuffer buffer = ByteBuffer.allocate(totalBytes());
155             buffer.put((byte) mOrgId);
156             buffer.put((byte) mTdsFlags);
157             buffer.put((byte) mTransportDataLength);
158             if (mTransportData != null) {
159                 buffer.put(mTransportData);
160             }
161             return buffer.array();
162         } catch (BufferOverflowException e) {
163             Log.e(TAG, "Error converting to byte array: " + e.toString());
164             return null;
165         }
166     }
167 
168     /**
169      * @return total byte count of this TransportBlock
170      */
totalBytes()171     public int totalBytes() {
172         // 3 uint8 + byte[] length
173         int size = 3 + mTransportDataLength;
174         return size;
175     }
176 }
177