2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.bluetooth;
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
19 import java.util.UUID;
20 import java.util.concurrent.ConcurrentHashMap;
23 * The {@link BluetoothCharacteristic} class defines the BLE Service.
25 * Services are collections of characteristics and relationships to other services that encapsulate the behavior of part
28 * https://www.bluetooth.com/specifications/gatt/services
30 * @author Chris Jackson - Initial contribution
31 * @author Kai Kreuzer - Cleaned up code
33 public class BluetoothService {
36 private final UUID uuid;
39 * The start handle for this service
41 private final int handleStart;
44 * The end handle for this service
46 private final int handleEnd;
48 protected int instanceId;
51 * Indicates if this is a primary service (true) or secondary service (false)
53 protected boolean primaryService;
56 * Map of {@link BluetoothCharacteristic}s supported in this service
58 protected final Map<UUID, BluetoothCharacteristic> supportedCharacteristics = new ConcurrentHashMap<>();
63 * @param uuid the uuid of the service
65 public BluetoothService(UUID uuid) {
66 this(uuid, true, 0, 0);
72 * @param uuid the uuid of the service
73 * @param primaryService true, if this service is a primary service
75 public BluetoothService(UUID uuid, boolean primaryService) {
76 this(uuid, primaryService, 0, 0);
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
87 public BluetoothService(UUID uuid, boolean primaryService, int handleStart, int handleEnd) {
89 this.primaryService = primaryService;
90 this.handleStart = handleStart;
91 this.handleEnd = handleEnd;
95 * Get characteristic based on {@link UUID}
97 * @return the {@link BluetoothCharacteristic} with the requested {@link UUID}
99 public BluetoothCharacteristic getCharacteristic(UUID uuid) {
100 return supportedCharacteristics.get(uuid);
104 * Get list of characteristics of the service
106 * @return the list of {@link BluetoothCharacteristic}s
108 public List<BluetoothCharacteristic> getCharacteristics() {
109 return new ArrayList<>(supportedCharacteristics.values());
113 * Return the UUID of this service
115 * @return the {@link UUID} of the service
117 public UUID getUuid() {
122 * Gets the starting handle for this service
124 * @return the start handle
126 public int getHandleStart() {
131 * Gets the end handle for this service
133 * @return the end handle
135 public int getHandleEnd() {
140 * Get the type of this service (primary/secondary)
142 * @return true if this is a primary service
144 public boolean isPrimary() {
145 return primaryService;
149 * Returns the instance ID for this service
151 * @return Instance ID of this service
153 public int getInstanceId() {
158 * Checks if the service provides a specific characteristic
160 * @return true if the characteristic is provided in this service
162 public boolean providesCharacteristic(UUID uuid) {
163 return supportedCharacteristics.containsKey(uuid);
167 * Add a characteristic to this service
169 * @param characteristic The characteristics to be added
170 * @return true, if the characteristic was added to the service
172 public boolean addCharacteristic(BluetoothCharacteristic characteristic) {
173 if (supportedCharacteristics.get(characteristic.getUuid()) != null) {
177 supportedCharacteristics.put(characteristic.getUuid(), characteristic);
178 characteristic.setService(this);
183 * Gets a characteristic by the handle
185 * @param handle the handle of the characteristic to return
186 * @return return the {@link BluetoothCharacteristic} or null if not found
188 public BluetoothCharacteristic getCharacteristicByHandle(int handle) {
189 synchronized (supportedCharacteristics) {
190 for (BluetoothCharacteristic characteristic : supportedCharacteristics.values()) {
191 if (characteristic.getHandle() == handle) {
192 return characteristic;
200 * Gets the {@link GattService} for this service. This is an enum defining the available GATT services.
202 * @return the {@link GattService} relating to this service
204 public GattService getService() {
205 return GattService.getService(uuid);
208 public enum GattService {
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),
226 HEALTH_THERMOMETER(0x1809),
229 HUMAN_INTERFACE_DEVICE(0x1812),
230 IMMEDIATE_ALERT(0x1802),
231 INDOOR_POSITIONING(0x1821),
232 INTERNET_PROTOCOL_SUPPORT(0x1820),
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),
242 WEIGHT_SCALE(0x181D);
244 private static Map<UUID, GattService> uuidToServiceMapping;
248 private GattService(long key) {
249 this.uuid = BluetoothBindingConstants.createBluetoothUUID(key);
252 private static void initMapping() {
253 uuidToServiceMapping = new HashMap<>();
254 for (GattService s : values()) {
255 uuidToServiceMapping.put(s.uuid, s);
259 public static GattService getService(UUID uuid) {
260 if (uuidToServiceMapping == null) {
263 return uuidToServiceMapping.get(uuid);
269 public UUID getUUID() {
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);
284 return builder.toString();