1 /*
2  * Copyright (C) 2013 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;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.os.Parcel;
21 import android.os.ParcelUuid;
22 import android.os.Parcelable;
23 
24 import java.util.UUID;
25 
26 /**
27  * Represents a Bluetooth GATT Descriptor
28  *
29  * <p> GATT Descriptors contain additional information and attributes of a GATT
30  * characteristic, {@link BluetoothGattCharacteristic}. They can be used to describe
31  * the characteristic's features or to control certain behaviours of the characteristic.
32  */
33 public class BluetoothGattDescriptor implements Parcelable {
34 
35     /**
36      * Value used to enable notification for a client configuration descriptor
37      */
38     public static final byte[] ENABLE_NOTIFICATION_VALUE = {0x01, 0x00};
39 
40     /**
41      * Value used to enable indication for a client configuration descriptor
42      */
43     public static final byte[] ENABLE_INDICATION_VALUE = {0x02, 0x00};
44 
45     /**
46      * Value used to disable notifications or indicatinos
47      */
48     public static final byte[] DISABLE_NOTIFICATION_VALUE = {0x00, 0x00};
49 
50     /**
51      * Descriptor read permission
52      */
53     public static final int PERMISSION_READ = 0x01;
54 
55     /**
56      * Descriptor permission: Allow encrypted read operations
57      */
58     public static final int PERMISSION_READ_ENCRYPTED = 0x02;
59 
60     /**
61      * Descriptor permission: Allow reading with man-in-the-middle protection
62      */
63     public static final int PERMISSION_READ_ENCRYPTED_MITM = 0x04;
64 
65     /**
66      * Descriptor write permission
67      */
68     public static final int PERMISSION_WRITE = 0x10;
69 
70     /**
71      * Descriptor permission: Allow encrypted writes
72      */
73     public static final int PERMISSION_WRITE_ENCRYPTED = 0x20;
74 
75     /**
76      * Descriptor permission: Allow encrypted writes with man-in-the-middle
77      * protection
78      */
79     public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 0x40;
80 
81     /**
82      * Descriptor permission: Allow signed write operations
83      */
84     public static final int PERMISSION_WRITE_SIGNED = 0x80;
85 
86     /**
87      * Descriptor permission: Allow signed write operations with
88      * man-in-the-middle protection
89      */
90     public static final int PERMISSION_WRITE_SIGNED_MITM = 0x100;
91 
92     /**
93      * The UUID of this descriptor.
94      *
95      * @hide
96      */
97     protected UUID mUuid;
98 
99     /**
100      * Instance ID for this descriptor.
101      *
102      * @hide
103      */
104     @UnsupportedAppUsage
105     protected int mInstance;
106 
107     /**
108      * Permissions for this descriptor
109      *
110      * @hide
111      */
112     protected int mPermissions;
113 
114     /**
115      * Back-reference to the characteristic this descriptor belongs to.
116      *
117      * @hide
118      */
119     @UnsupportedAppUsage
120     protected BluetoothGattCharacteristic mCharacteristic;
121 
122     /**
123      * The value for this descriptor.
124      *
125      * @hide
126      */
127     protected byte[] mValue;
128 
129     /**
130      * Create a new BluetoothGattDescriptor.
131      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
132      *
133      * @param uuid The UUID for this descriptor
134      * @param permissions Permissions for this descriptor
135      */
BluetoothGattDescriptor(UUID uuid, int permissions)136     public BluetoothGattDescriptor(UUID uuid, int permissions) {
137         initDescriptor(null, uuid, 0, permissions);
138     }
139 
140     /**
141      * Create a new BluetoothGattDescriptor.
142      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
143      *
144      * @param characteristic The characteristic this descriptor belongs to
145      * @param uuid The UUID for this descriptor
146      * @param permissions Permissions for this descriptor
147      */
BluetoothGattDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid, int instance, int permissions)148     /*package*/ BluetoothGattDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
149             int instance, int permissions) {
150         initDescriptor(characteristic, uuid, instance, permissions);
151     }
152 
153     /**
154      * @hide
155      */
BluetoothGattDescriptor(UUID uuid, int instance, int permissions)156     public BluetoothGattDescriptor(UUID uuid, int instance, int permissions) {
157         initDescriptor(null, uuid, instance, permissions);
158     }
159 
initDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid, int instance, int permissions)160     private void initDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
161             int instance, int permissions) {
162         mCharacteristic = characteristic;
163         mUuid = uuid;
164         mInstance = instance;
165         mPermissions = permissions;
166     }
167 
168     @Override
describeContents()169     public int describeContents() {
170         return 0;
171     }
172 
173     @Override
writeToParcel(Parcel out, int flags)174     public void writeToParcel(Parcel out, int flags) {
175         out.writeParcelable(new ParcelUuid(mUuid), 0);
176         out.writeInt(mInstance);
177         out.writeInt(mPermissions);
178     }
179 
180     public static final @android.annotation.NonNull Parcelable.Creator<BluetoothGattDescriptor> CREATOR =
181             new Parcelable.Creator<BluetoothGattDescriptor>() {
182         public BluetoothGattDescriptor createFromParcel(Parcel in) {
183             return new BluetoothGattDescriptor(in);
184         }
185 
186         public BluetoothGattDescriptor[] newArray(int size) {
187             return new BluetoothGattDescriptor[size];
188         }
189     };
190 
BluetoothGattDescriptor(Parcel in)191     private BluetoothGattDescriptor(Parcel in) {
192         mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
193         mInstance = in.readInt();
194         mPermissions = in.readInt();
195     }
196 
197     /**
198      * Returns the characteristic this descriptor belongs to.
199      *
200      * @return The characteristic.
201      */
getCharacteristic()202     public BluetoothGattCharacteristic getCharacteristic() {
203         return mCharacteristic;
204     }
205 
206     /**
207      * Set the back-reference to the associated characteristic
208      *
209      * @hide
210      */
211     @UnsupportedAppUsage
setCharacteristic(BluetoothGattCharacteristic characteristic)212     /*package*/ void setCharacteristic(BluetoothGattCharacteristic characteristic) {
213         mCharacteristic = characteristic;
214     }
215 
216     /**
217      * Returns the UUID of this descriptor.
218      *
219      * @return UUID of this descriptor
220      */
getUuid()221     public UUID getUuid() {
222         return mUuid;
223     }
224 
225     /**
226      * Returns the instance ID for this descriptor.
227      *
228      * <p>If a remote device offers multiple descriptors with the same UUID,
229      * the instance ID is used to distuinguish between descriptors.
230      *
231      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
232      *
233      * @return Instance ID of this descriptor
234      * @hide
235      */
getInstanceId()236     public int getInstanceId() {
237         return mInstance;
238     }
239 
240     /**
241      * Force the instance ID.
242      *
243      * @hide
244      */
setInstanceId(int instanceId)245     public void setInstanceId(int instanceId) {
246         mInstance = instanceId;
247     }
248 
249     /**
250      * Returns the permissions for this descriptor.
251      *
252      * @return Permissions of this descriptor
253      */
getPermissions()254     public int getPermissions() {
255         return mPermissions;
256     }
257 
258     /**
259      * Returns the stored value for this descriptor
260      *
261      * <p>This function returns the stored value for this descriptor as
262      * retrieved by calling {@link BluetoothGatt#readDescriptor}. The cached
263      * value of the descriptor is updated as a result of a descriptor read
264      * operation.
265      *
266      * @return Cached value of the descriptor
267      */
getValue()268     public byte[] getValue() {
269         return mValue;
270     }
271 
272     /**
273      * Updates the locally stored value of this descriptor.
274      *
275      * <p>This function modifies the locally stored cached value of this
276      * descriptor. To send the value to the remote device, call
277      * {@link BluetoothGatt#writeDescriptor} to send the value to the
278      * remote device.
279      *
280      * @param value New value for this descriptor
281      * @return true if the locally stored value has been set, false if the requested value could not
282      * be stored locally.
283      */
setValue(byte[] value)284     public boolean setValue(byte[] value) {
285         mValue = value;
286         return true;
287     }
288 }
289