2 * Copyright (c) 2010-2022 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.roaming.internal;
15 import java.util.Collections;
17 import java.util.concurrent.CopyOnWriteArraySet;
18 import java.util.function.BiConsumer;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.bluetooth.BluetoothAdapter;
23 import org.openhab.binding.bluetooth.discovery.BluetoothDiscoveryDevice;
24 import org.openhab.binding.bluetooth.discovery.BluetoothDiscoveryParticipant;
25 import org.openhab.core.config.discovery.DiscoveryResult;
26 import org.openhab.core.thing.ThingTypeUID;
27 import org.openhab.core.thing.ThingUID;
28 import org.osgi.service.component.annotations.Component;
29 import org.osgi.service.component.annotations.Reference;
30 import org.osgi.service.component.annotations.ReferenceCardinality;
31 import org.osgi.service.component.annotations.ReferencePolicy;
34 * The {@link RoamingBluetoothDiscoveryParticipant} acts as the roaming adapter's gateway
35 * to the osgi layer where it can find other adapter instances to use as delegates.
36 * This class also serves to generate the default roaming adapter discovery result for the user.
38 * @author Connor Petty - Initial contribution
41 @Component(service = { BluetoothDiscoveryParticipant.class })
42 public class RoamingBluetoothDiscoveryParticipant implements BluetoothDiscoveryParticipant {
44 private final Set<BluetoothAdapter> adapters = new CopyOnWriteArraySet<>();
45 private final Set<RoamingBluetoothAdapter> roamingAdapters = new CopyOnWriteArraySet<>();
47 // private Optional<RoamingBluetoothAdapter> roamingAdapter = Optional.empty();
49 @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
50 protected void setRoamingBluetoothAdapter(RoamingBluetoothAdapter roamingAdapter) {
51 roamingAdapters.add(roamingAdapter);
52 adapters.forEach(roamingAdapter::addBluetoothAdapter);
55 protected void unsetRoamingBluetoothAdapter(RoamingBluetoothAdapter roamingAdapter) {
56 roamingAdapters.remove(roamingAdapter);
57 adapters.forEach(roamingAdapter::removeBluetoothAdapter);
60 @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
61 protected void addBluetoothAdapter(BluetoothAdapter adapter) {
62 this.adapters.add(adapter);
64 roamingAdapters.forEach(ra -> {
65 ra.addBluetoothAdapter(adapter);
69 protected void removeBluetoothAdapter(BluetoothAdapter adapter) {
70 this.adapters.remove(adapter);
72 roamingAdapters.forEach(ra -> {
73 ra.removeBluetoothAdapter(adapter);
78 public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
79 return Collections.emptySet();
83 public @Nullable DiscoveryResult createResult(BluetoothDiscoveryDevice device) {
88 public @Nullable ThingUID getThingUID(BluetoothDiscoveryDevice device) {
93 public void publishAdditionalResults(DiscoveryResult result,
94 BiConsumer<BluetoothAdapter, DiscoveryResult> publisher) {
95 // we create a roaming version of every discoveryResult.
96 roamingAdapters.forEach(roamingAdapter -> {
97 ThingUID adapterUID = result.getBridgeUID();
98 if (adapterUID != null && roamingAdapter.isDiscoveryEnabled()
99 && roamingAdapter.isRoamingMember(adapterUID)) {
100 publisher.accept(roamingAdapter, result);