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 */
16package android.bluetooth;
17
18import java.util.ArrayList;
19import java.util.List;
20import java.util.UUID;
21
22/**
23 * Represents a Bluetooth GATT Service
24 *
25 * <p> Gatt Service contains a collection of {@link BluetoothGattCharacteristic},
26 * as well as referenced services.
27 */
28public class BluetoothGattService {
29
30    /**
31     * Primary service
32     */
33    public static final int SERVICE_TYPE_PRIMARY = 0;
34
35    /**
36     * Secondary service (included by primary services)
37     */
38    public static final int SERVICE_TYPE_SECONDARY = 1;
39
40
41    /**
42     * The remote device his service is associated with.
43     * This applies to client applications only.
44     * @hide
45     */
46    protected BluetoothDevice mDevice;
47
48    /**
49     * The UUID of this service.
50     * @hide
51     */
52    protected UUID mUuid;
53
54    /**
55     * Instance ID for this service.
56     * @hide
57     */
58    protected int mInstanceId;
59
60    /**
61     * Handle counter override (for conformance testing).
62     * @hide
63     */
64    protected int mHandles = 0;
65
66    /**
67     * Service type (Primary/Secondary).
68     * @hide
69     */
70    protected int mServiceType;
71
72    /**
73     * List of characteristics included in this service.
74     */
75    protected List<BluetoothGattCharacteristic> mCharacteristics;
76
77    /**
78     * List of included services for this service.
79     */
80    protected List<BluetoothGattService> mIncludedServices;
81
82    /**
83     * Whether the service uuid should be advertised.
84     */
85    private boolean mAdvertisePreferred;
86
87    /**
88     * Create a new BluetoothGattService.
89     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
90     *
91     * @param uuid The UUID for this service
92     * @param serviceType The type of this service,
93     *        {@link BluetoothGattService#SERVICE_TYPE_PRIMARY} or
94     *        {@link BluetoothGattService#SERVICE_TYPE_SECONDARY}
95     */
96    public BluetoothGattService(UUID uuid, int serviceType) {
97        mDevice = null;
98        mUuid = uuid;
99        mInstanceId = 0;
100        mServiceType = serviceType;
101        mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
102        mIncludedServices = new ArrayList<BluetoothGattService>();
103    }
104
105    /**
106     * Create a new BluetoothGattService
107     * @hide
108     */
109    /*package*/ BluetoothGattService(BluetoothDevice device, UUID uuid,
110                                     int instanceId, int serviceType) {
111        mDevice = device;
112        mUuid = uuid;
113        mInstanceId = instanceId;
114        mServiceType = serviceType;
115        mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
116        mIncludedServices = new ArrayList<BluetoothGattService>();
117    }
118
119    /**
120     * Returns the device associated with this service.
121     * @hide
122     */
123    /*package*/ BluetoothDevice getDevice() {
124        return mDevice;
125    }
126
127    /**
128     * Add an included service to this service.
129     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
130     *
131     * @param service The service to be added
132     * @return true, if the included service was added to the service
133     */
134    public boolean addService(BluetoothGattService service) {
135        mIncludedServices.add(service);
136        return true;
137    }
138
139    /**
140     * Add a characteristic to this service.
141     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
142     *
143     * @param characteristic The characteristics to be added
144     * @return true, if the characteristic was added to the service
145     */
146    public boolean addCharacteristic(BluetoothGattCharacteristic characteristic) {
147        mCharacteristics.add(characteristic);
148        characteristic.setService(this);
149        return true;
150    }
151
152    /**
153     * Get characteristic by UUID and instanceId.
154     * @hide
155     */
156    /*package*/ BluetoothGattCharacteristic getCharacteristic(UUID uuid, int instanceId) {
157        for(BluetoothGattCharacteristic characteristic : mCharacteristics) {
158            if (uuid.equals(characteristic.getUuid())
159             && characteristic.getInstanceId() == instanceId)
160                return characteristic;
161        }
162        return null;
163    }
164
165    /**
166     * Force the instance ID.
167     * This is needed for conformance testing only.
168     * @hide
169     */
170    public void setInstanceId(int instanceId) {
171        mInstanceId = instanceId;
172    }
173
174    /**
175     * Get the handle count override (conformance testing.
176     * @hide
177     */
178    /*package*/ int getHandles() {
179        return mHandles;
180    }
181
182    /**
183     * Force the number of handles to reserve for this service.
184     * This is needed for conformance testing only.
185     * @hide
186     */
187    public void setHandles(int handles) {
188        mHandles = handles;
189    }
190
191    /**
192     * Add an included service to the internal map.
193     * @hide
194     */
195    /*package*/ void addIncludedService(BluetoothGattService includedService) {
196        mIncludedServices.add(includedService);
197    }
198
199    /**
200     * Returns the UUID of this service
201     *
202     * @return UUID of this service
203     */
204    public UUID getUuid() {
205        return mUuid;
206    }
207
208    /**
209     * Returns the instance ID for this service
210     *
211     * <p>If a remote device offers multiple services with the same UUID
212     * (ex. multiple battery services for different batteries), the instance
213     * ID is used to distuinguish services.
214     *
215     * @return Instance ID of this service
216     */
217    public int getInstanceId() {
218        return mInstanceId;
219    }
220
221    /**
222     * Get the type of this service (primary/secondary)
223     */
224    public int getType() {
225        return mServiceType;
226    }
227
228    /**
229     * Get the list of included GATT services for this service.
230     *
231     * @return List of included services or empty list if no included services
232     *         were discovered.
233     */
234    public List<BluetoothGattService> getIncludedServices() {
235        return mIncludedServices;
236    }
237
238    /**
239     * Returns a list of characteristics included in this service.
240     *
241     * @return Characteristics included in this service
242     */
243    public List<BluetoothGattCharacteristic> getCharacteristics() {
244        return mCharacteristics;
245    }
246
247    /**
248     * Returns a characteristic with a given UUID out of the list of
249     * characteristics offered by this service.
250     *
251     * <p>This is a convenience function to allow access to a given characteristic
252     * without enumerating over the list returned by {@link #getCharacteristics}
253     * manually.
254     *
255     * <p>If a remote service offers multiple characteristics with the same
256     * UUID, the first instance of a characteristic with the given UUID
257     * is returned.
258     *
259     * @return GATT characteristic object or null if no characteristic with the
260     *         given UUID was found.
261     */
262    public BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
263        for(BluetoothGattCharacteristic characteristic : mCharacteristics) {
264            if (uuid.equals(characteristic.getUuid()))
265                return characteristic;
266        }
267        return null;
268    }
269
270    /**
271     * Returns whether the uuid of the service should be advertised.
272     * @hide
273     */
274    public boolean isAdvertisePreferred() {
275      return mAdvertisePreferred;
276    }
277
278    /**
279     * Set whether the service uuid should be advertised.
280     * @hide
281     */
282    public void setAdvertisePreferred(boolean advertisePreferred) {
283      this.mAdvertisePreferred = advertisePreferred;
284    }
285}
286