]> git.basschouten.com Git - openhab-addons.git/blob
d2642f13a9a3e1b08c6fd4125565f1454cb1eb3d
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.bluetooth;
14
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.UUID;
20 import java.util.concurrent.ConcurrentHashMap;
21
22 /**
23  * The {@link BluetoothCharacteristic} class defines the BLE Service.
24  * <p>
25  * Services are collections of characteristics and relationships to other services that encapsulate the behavior of part
26  * of a device.
27  * <p>
28  * https://www.bluetooth.com/specifications/gatt/services
29  *
30  * @author Chris Jackson - Initial contribution
31  * @author Kai Kreuzer - Cleaned up code
32  */
33 public class BluetoothService {
34
35     // The service UUID
36     private final UUID uuid;
37
38     /**
39      * The start handle for this service
40      */
41     private final int handleStart;
42
43     /**
44      * The end handle for this service
45      */
46     private final int handleEnd;
47
48     protected int instanceId;
49
50     /**
51      * Indicates if this is a primary service (true) or secondary service (false)
52      */
53     protected boolean primaryService;
54
55     /**
56      * Map of {@link BluetoothCharacteristic}s supported in this service
57      */
58     protected final Map<UUID, BluetoothCharacteristic> supportedCharacteristics = new ConcurrentHashMap<>();
59
60     /**
61      * Constructor
62      *
63      * @param uuid the uuid of the service
64      */
65     public BluetoothService(UUID uuid) {
66         this(uuid, true, 0, 0);
67     }
68
69     /**
70      * Constructor
71      *
72      * @param uuid the uuid of the service
73      * @param primaryService true, if this service is a primary service
74      */
75     public BluetoothService(UUID uuid, boolean primaryService) {
76         this(uuid, primaryService, 0, 0);
77     }
78
79     /**
80      * Constructor
81      *
82      * @param uuid the uuid of the service
83      * @param primaryService true, if this service is a primary service
84      * @param handleStart id of the lowest handle
85      * @param handleEnd id of the highest handle
86      */
87     public BluetoothService(UUID uuid, boolean primaryService, int handleStart, int handleEnd) {
88         this.uuid = uuid;
89         this.primaryService = primaryService;
90         this.handleStart = handleStart;
91         this.handleEnd = handleEnd;
92     }
93
94     /**
95      * Get characteristic based on {@link UUID}
96      *
97      * @return the {@link BluetoothCharacteristic} with the requested {@link UUID}
98      */
99     public BluetoothCharacteristic getCharacteristic(UUID uuid) {
100         return supportedCharacteristics.get(uuid);
101     }
102
103     /**
104      * Get list of characteristics of the service
105      *
106      * @return the list of {@link BluetoothCharacteristic}s
107      */
108     public List<BluetoothCharacteristic> getCharacteristics() {
109         return new ArrayList<>(supportedCharacteristics.values());
110     }
111
112     /**
113      * Return the UUID of this service
114      *
115      * @return the {@link UUID} of the service
116      */
117     public UUID getUuid() {
118         return uuid;
119     }
120
121     /**
122      * Gets the starting handle for this service
123      *
124      * @return the start handle
125      */
126     public int getHandleStart() {
127         return handleStart;
128     }
129
130     /**
131      * Gets the end handle for this service
132      *
133      * @return the end handle
134      */
135     public int getHandleEnd() {
136         return handleEnd;
137     }
138
139     /**
140      * Get the type of this service (primary/secondary)
141      *
142      * @return true if this is a primary service
143      */
144     public boolean isPrimary() {
145         return primaryService;
146     }
147
148     /**
149      * Returns the instance ID for this service
150      *
151      * @return Instance ID of this service
152      */
153     public int getInstanceId() {
154         return instanceId;
155     }
156
157     /**
158      * Checks if the service provides a specific characteristic
159      *
160      * @return true if the characteristic is provided in this service
161      */
162     public boolean providesCharacteristic(UUID uuid) {
163         return supportedCharacteristics.containsKey(uuid);
164     }
165
166     /**
167      * Add a characteristic to this service
168      *
169      * @param characteristic The characteristics to be added
170      * @return true, if the characteristic was added to the service
171      */
172     public boolean addCharacteristic(BluetoothCharacteristic characteristic) {
173         if (supportedCharacteristics.get(characteristic.getUuid()) != null) {
174             return false;
175         }
176
177         supportedCharacteristics.put(characteristic.getUuid(), characteristic);
178         characteristic.setService(this);
179         return true;
180     }
181
182     /**
183      * Gets a characteristic by the handle
184      *
185      * @param handle the handle of the characteristic to return
186      * @return return the {@link BluetoothCharacteristic} or null if not found
187      */
188     public BluetoothCharacteristic getCharacteristicByHandle(int handle) {
189         synchronized (supportedCharacteristics) {
190             for (BluetoothCharacteristic characteristic : supportedCharacteristics.values()) {
191                 if (characteristic.getHandle() == handle) {
192                     return characteristic;
193                 }
194             }
195         }
196         return null;
197     }
198
199     /**
200      * Gets the {@link GattService} for this service. This is an enum defining the available GATT services.
201      *
202      * @return the {@link GattService} relating to this service
203      */
204     public GattService getService() {
205         return GattService.getService(uuid);
206     }
207
208     public enum GattService {
209
210         // List of GATT Services
211         ALERT_NOTIFICATION_SERVICE(0x1811),
212         AUTOMATION_IO(0x1815),
213         BATTERY_SERVICE(0x180F),
214         BLOOD_PRESSURE(0x1810),
215         BODY_COMPOSITION(0x181B),
216         BOND_MANAGEMENT(0x181E),
217         CONTINUOUS_GLUCOSE_MONITORING(0x181F),
218         CURRENT_TIME_SERVICE(0x1805),
219         CYCLING_POWER(0x1818),
220         CYCLING_SPEED_AND_CADENCE(0x1816),
221         DEVICE_INFORMATION(0x180A),
222         ENVIRONMENTAL_SENSING(0x181A),
223         GENERIC_ACCESS(0x1800),
224         GENERIC_ATTRIBUTE(0x1801),
225         GLUCOSE(0x1808),
226         HEALTH_THERMOMETER(0x1809),
227         HEART_RATE(0x180D),
228         HTTP_PROXY(0x1823),
229         HUMAN_INTERFACE_DEVICE(0x1812),
230         IMMEDIATE_ALERT(0x1802),
231         INDOOR_POSITIONING(0x1821),
232         INTERNET_PROTOCOL_SUPPORT(0x1820),
233         LINK_LOSS(0x1803L),
234         LOCATION_AND_NAVIGATION(0x1819),
235         NEXT_DST_CHANGE_SERVICE(0x1807),
236         PHONE_ALERT_STATUS_SERVICE(0x180E),
237         REFERENCE_TIME_UPDATE_SERVICE(0x1806),
238         RUNNING_SPEED_AND_CADENCE(0x1814),
239         SCAN_PARAMETERS(0x1813),
240         TX_POWER(0x1804),
241         USER_DATA(0x181C),
242         WEIGHT_SCALE(0x181D);
243
244         private static Map<UUID, GattService> uuidToServiceMapping;
245
246         private UUID uuid;
247
248         private GattService(long key) {
249             this.uuid = BluetoothBindingConstants.createBluetoothUUID(key);
250         }
251
252         private static void initMapping() {
253             uuidToServiceMapping = new HashMap<>();
254             for (GattService s : values()) {
255                 uuidToServiceMapping.put(s.uuid, s);
256             }
257         }
258
259         public static GattService getService(UUID uuid) {
260             if (uuidToServiceMapping == null) {
261                 initMapping();
262             }
263             return uuidToServiceMapping.get(uuid);
264         }
265
266         /**
267          * @return the key
268          */
269         public UUID getUUID() {
270             return uuid;
271         }
272     }
273
274     @Override
275     public String toString() {
276         StringBuilder builder = new StringBuilder();
277         builder.append("BluetoothService [uuid=");
278         builder.append(uuid);
279         builder.append(", handleStart=");
280         builder.append(handleStart);
281         builder.append(", handleEnd=");
282         builder.append(handleEnd);
283         builder.append(']');
284         return builder.toString();
285     }
286 }