Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
DBTManager.java
Go to the documentation of this file.
1 /**
2  * Author: Sven Gothel <sgothel@jausoft.com>
3  * Copyright (c) 2020 Gothel Software e.K.
4  * Copyright (c) 2020 ZAFENA AB
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 package jau.direct_bt;
27 
28 import java.security.AccessController;
29 import java.security.PrivilegedAction;
30 import java.util.ArrayList;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.concurrent.CopyOnWriteArrayList;
34 import java.util.function.Consumer;
35 import java.util.function.Predicate;
36 
37 import org.direct_bt.BTAdapter;
38 import org.direct_bt.BTDevice;
40 import org.direct_bt.BTFactory;
41 import org.direct_bt.BTGattChar;
42 import org.direct_bt.BTGattDesc;
44 import org.direct_bt.BTManager;
45 import org.direct_bt.BTObject;
46 import org.direct_bt.BTType;
48 import org.direct_bt.ScanType;
49 
50 public class DBTManager implements BTManager
51 {
52  protected static final boolean DEBUG = BTFactory.DEBUG;
53  protected static final boolean VERBOSE = BTFactory.VERBOSE;
54 
55  private static volatile boolean isJVMShuttingDown = false;
56  private static final List<Runnable> userShutdownHooks = new ArrayList<Runnable>();
57  private static boolean unifyUUID128Bit = true;
58 
59  static {
60  AccessController.doPrivileged(new PrivilegedAction<Object>() {
61  @Override
62  public Object run() {
63  Runtime.getRuntime().addShutdownHook(
64  new Thread(null, new Runnable() {
65  @Override
66  public void run() {
67  DBTManager.shutdownImpl(true);
68  } }, "DBTManager_ShutdownHook" ) ) ;
69  return null;
70  } } ) ;
71  }
72 
73  private static synchronized void shutdownImpl(final boolean _isJVMShuttingDown) {
74  isJVMShuttingDown = _isJVMShuttingDown;
75  if(DEBUG) {
76  System.err.println("DBTManager.shutdown() START: JVM Shutdown "+isJVMShuttingDown+", on thread "+Thread.currentThread().getName());
77  }
78  synchronized(userShutdownHooks) {
79  final int cshCount = userShutdownHooks.size();
80  for(int i=0; i < cshCount; i++) {
81  try {
82  if( DEBUG ) {
83  System.err.println("DBTManager.shutdown - userShutdownHook #"+(i+1)+"/"+cshCount);
84  }
85  userShutdownHooks.get(i).run();
86  } catch(final Throwable t) {
87  System.err.println("DBTManager.shutdown: Caught "+t.getClass().getName()+" during userShutdownHook #"+(i+1)+"/"+cshCount);
88  if( DEBUG ) {
89  t.printStackTrace();
90  }
91  }
92  }
93  userShutdownHooks.clear();
94  }
95  if(DEBUG) {
96  System.err.println("DBTManager.shutdown(): Post userShutdownHook");
97  }
98 
99  try {
100  final BTManager mgmt = getManager();
101  mgmt.shutdown();
102  } catch(final Throwable t) {
103  System.err.println("DBTManager.shutdown: Caught "+t.getClass().getName()+" during DBTManager.shutdown()");
104  if( DEBUG ) {
105  t.printStackTrace();
106  }
107  }
108 
109  if(DEBUG) {
110  System.err.println(Thread.currentThread().getName()+" - DBTManager.shutdown() END JVM Shutdown "+isJVMShuttingDown);
111  }
112  }
113 
114  /** Returns true if the JVM is shutting down, otherwise false. */
115  public static final boolean isJVMShuttingDown() { return isJVMShuttingDown; }
116 
117  /**
118  * Add a shutdown hook to be performed at JVM shutdown before shutting down DBTManager instance.
119  *
120  * @param head if true add runnable at the start, otherwise at the end
121  * @param runnable runnable to be added.
122  */
123  public static void addShutdownHook(final boolean head, final Runnable runnable) {
124  synchronized( userShutdownHooks ) {
125  if( !userShutdownHooks.contains( runnable ) ) {
126  if( head ) {
127  userShutdownHooks.add(0, runnable);
128  } else {
129  userShutdownHooks.add( runnable );
130  }
131  }
132  }
133  }
134 
135  /**
136  * Returns whether uuid128_t consolidation is enabled
137  * for native uuid16_t and uuid32_t values before string conversion.
138  * @see #setUnifyUUID128Bit(boolean)
139  */
140  public static boolean getUnifyUUID128Bit() { return unifyUUID128Bit; }
141 
142  /**
143  * Enables or disables uuid128_t consolidation
144  * for native uuid16_t and uuid32_t values before string conversion.
145  * <p>
146  * Default is {@code true}.
147  * </p>
148  * <p>
149  * If desired, this value should be set once before the first call of {@link #getManager()}!
150  * </p>
151  * @see #getUnifyUUID128Bit()
152  */
153  public static void setUnifyUUID128Bit(final boolean v) { unifyUUID128Bit=v; }
154 
155  private long nativeInstance;
156  private final List<BTAdapter> adapters = new CopyOnWriteArrayList<BTAdapter>();
157  private final List<ChangedAdapterSetListener> changedAdapterSetListenerList = new CopyOnWriteArrayList<ChangedAdapterSetListener>();
158 
159  private final Settings settings;
160 
161  @Override
162  public final Settings getSettings() { return settings; }
163 
164  public BTType getBluetoothType() { return BTType.NONE; }
165 
166  @Override
167  public DBTObject find(final BTType type, final String name, final String identifier, final BTObject parent, final long timeoutMS) {
168  return findInCache((DBTObject)parent, type, name, identifier);
169  }
170 
171  @Override
172  public DBTObject find(final BTType type, final String name, final String identifier, final BTObject parent) {
173  return find(type, name, identifier, parent, 0);
174  }
175 
176  @Override
177  public List<BTAdapter> getAdapters() { return new ArrayList<BTAdapter>(adapters); }
178 
179  @Override
180  public BTAdapter getAdapter(final int dev_id) {
181  for(final Iterator<BTAdapter> iter = adapters.iterator(); iter.hasNext(); ) {
182  final BTAdapter a = iter.next();
183  if( dev_id == a.getDevID() ) {
184  return a;
185  }
186  }
187  return null;
188  }
189 
190  @Override
191  public List<BTDevice> getDevices() { return getDefaultAdapter().getDiscoveredDevices(); }
192 
193  /**
194  * {@inheritDoc}
195  * <p>
196  * This call could be a quite expensive service query, see below.
197  * </p>
198  * <p>
199  * This implementation returns all {@link BTGattService} from all {@link BTDevice}s
200  * from the {@link #getDefaultAdapter()} using {@link BTDevice#getServices()}.
201  * </p>
202  * <p>
203  * This implementation does not {@link BTAdapter#startDiscovery() start} an explicit discovery,
204  * but previous {@link BTAdapter#getDiscoveredDevices() discovered devices} are being queried.
205  * </p>
206  */
207  @Override
208  public List<BTGattService> getServices() {
209  final List<BTGattService> res = new ArrayList<BTGattService>();
210  for(final Iterator<BTAdapter> iterA=adapters.iterator(); iterA.hasNext(); ) {
211  final BTAdapter adapter = iterA.next();
212  final List<BTDevice> devices = adapter.getDiscoveredDevices();
213  for(final Iterator<BTDevice> iterD=devices.iterator(); iterD.hasNext(); ) {
214  final BTDevice device = iterD.next();
215  final List<BTGattService> devServices = device.getServices();
216  if( null != devServices ) {
217  res.addAll(devServices);
218  }
219  }
220  }
221  return res;
222  }
223 
224  @Override
225  public boolean setDefaultAdapter(final BTAdapter adapter) {
226  return false;
227  }
228 
229  @Override
231  for(final Iterator<BTAdapter> iter = adapters.iterator(); iter.hasNext(); ) {
232  final BTAdapter a = iter.next();
233  if( a.isPowered() ) {
234  return a;
235  }
236  }
237  return null;
238  }
239 
240  @Override
241  public HCIStatusCode startDiscovery(final boolean keepAlive, final boolean le_scan_active) throws BTException {
242  return getDefaultAdapter().startDiscovery(keepAlive, le_scan_active);
243  }
244 
245  @Override
247 
248  @Override
249  public final ScanType getCurrentScanType() {
251  }
252 
253  @Override
255  changedAdapterSetListenerList.add(l);
256 
257  adapters.forEach(new Consumer<BTAdapter>() {
258  @Override
259  public void accept(final BTAdapter adapter) {
260  l.adapterAdded(adapter);
261  }
262  });
263  }
264 
265  @Override
267  // Using removeIf allows performing test on all object and remove within one write-lock cycle
268  final int count[] = { 0 };
269  changedAdapterSetListenerList.removeIf(new Predicate<ChangedAdapterSetListener>() {
270  @Override
271  public boolean test(final ChangedAdapterSetListener t) {
272  if( t.equals(l) ) {
273  count[0]++;
274  return true;
275  }
276  return false;
277  }
278  });
279  return count[0];
280  }
281 
282  private native List<BTAdapter> getAdapterListImpl();
283  private native BTAdapter getAdapterImpl(int dev_id);
284 
285  /**
286  * Removal entry for DBTAdapter.close()
287  * @param adapter ref to the close'ed adapter
288  * @return true if contained and removed, otherwise false
289  */
290  /* pp */ final boolean removeAdapter(final DBTAdapter adapter) {
291  if( adapters.remove(adapter) ) {
292  if( DEBUG ) {
293  System.err.println("DBTManager.removeAdapter: Removed "+adapter);
294  }
295  return true;
296  } else {
297  if( DEBUG ) {
298  System.err.println("DBTManager.removeAdapter: Not found "+adapter);
299  }
300  return false;
301  }
302  }
303 
304  /** callback from native adapter remove */
305  /* pp */ final void removeAdapterCB(final int dev_id, final int opc_reason) {
306  final BTAdapter[] removed = { null };
307  final int count[] = { 0 };
308  adapters.removeIf(new Predicate<BTAdapter>() {
309  @Override
310  public boolean test(final BTAdapter a) {
311  if( 0 == count[0] && dev_id == a.getDevID() ) {
312  removed[0] = a;
313  count[0]++;
314  return true;
315  } else {
316  return false;
317  }
318  }
319  });
320  if( null != removed[0] ) {
321  if( DEBUG ) {
322  System.err.println("DBTManager.removeAdapterCB[dev_id "+dev_id+", opc 0x"+Integer.toHexString(opc_reason)+
323  "]: removing "+removed[0].toString());
324  }
325  if( 0x0005 == opc_reason ) {
326  // MgmtEvent::Opcode::INDEX_REMOVED = 0x0005
327  changedAdapterSetListenerList.forEach(new Consumer<ChangedAdapterSetListener>() {
328  @Override
329  public void accept(final ChangedAdapterSetListener t) {
330  t.adapterRemoved( removed[0] );
331  } } );
332  }
333  removed[0] = null; // DBTAdapter::close() issued by DBTManager after all callbacks
334  }
335  if( DEBUG ) {
336  System.err.println("DBTManager.removeAdapterCB[dev_id "+dev_id+", opc 0x"+Integer.toHexString(opc_reason)+
337  "]: removed "+count[0]+" adapter, size "+adapters.size());
338  }
339  }
340  /** callback from native adapter add or POWERED on */
341  private final void updatedAdapterCB(final int dev_id, final int opc_reason) {
342  final BTAdapter preInstance = getAdapter(dev_id);
343  if( null != preInstance ) {
344  if( DEBUG ) {
345  System.err.println("DBTManager.updatedAdapterCB[dev_id "+dev_id+", opc 0x"+Integer.toHexString(opc_reason)+
346  "]: existing "+preInstance.toString()+", size "+adapters.size());
347  }
348  return;
349  }
350  final BTAdapter newInstance = getAdapterImpl(dev_id);
351  if( null == newInstance ) {
352  if( DEBUG ) {
353  System.err.println("DBTManager.updatedAdapterCB[dev_id "+dev_id+", opc 0x"+Integer.toHexString(opc_reason)+
354  "]: Adapter not found, size "+adapters.size());
355  }
356  return;
357  }
358  final boolean added = adapters.add(newInstance);
359  if( DEBUG ) {
360  System.err.println("DBTManager.updatedAdapterCB[dev_id "+dev_id+", opc 0x"+Integer.toHexString(opc_reason)+
361  "]: added "+added+": new "+newInstance.toString()+", size "+adapters.size());
362  }
363  if( added && 0x0004 == opc_reason ) {
364  // MgmtEvent::Opcode::INDEX_ADDED = 0x0004
365  changedAdapterSetListenerList.forEach(new Consumer<ChangedAdapterSetListener>() {
366  @Override
367  public void accept(final ChangedAdapterSetListener t) {
368  t.adapterAdded(newInstance);
369  } } );
370  }
371  }
372 
373  private native void initImpl(final boolean unifyUUID128Bit, final int btMode) throws BTException;
374  private native void deleteImpl(long nativeInstance);
375  private DBTManager()
376  {
377  initImpl(unifyUUID128Bit, BTFactory.DEFAULT_BTMODE.value);
378  try {
379  adapters.addAll(getAdapterListImpl());
380  } catch (final BTException be) {
381  be.printStackTrace();
382  }
383  settings = new Settings() {
384  @Override
385  public final boolean isDirectBT() {
386  return true;
387  }
388  @Override
389  public String toString() {
390  return "Settings[dbt true]";
391  }
392  };
393  }
394 
395  /** Returns an instance of BluetoothManager, to be used instead of constructor.
396  * @return An initialized BluetoothManager instance.
397  */
398  public static BTManager getManager() throws RuntimeException, BTException {
399  return LazySingletonHolder.singleton;
400  }
401  /** Initialize-On-Demand Holder Class, similar to C++11's "Magic Statics". */
402  private static class LazySingletonHolder {
403  private static final DBTManager singleton = new DBTManager();
404  }
405 
406  @Override
407  protected void finalize() {
408  shutdown();
409  }
410 
411  @Override
412  public void shutdown() {
413  for(final Iterator<BTAdapter> ia= adapters.iterator(); ia.hasNext(); ) {
414  final DBTAdapter a = (DBTAdapter)ia.next();
415  a.close();
416  }
417  adapters.clear();
418  deleteImpl(nativeInstance);
419  }
420 
421  /**
422  * Returns the matching {@link DBTObject} from the internal cache if found,
423  * otherwise {@code null}.
424  * <p>
425  * The returned {@link DBTObject} may be of type
426  * <ul>
427  * <li>{@link DBTAdapter}</li>
428  * <li>{@link DBTDevice}</li>
429  * <li>{@link DBTGattService}</li>
430  * <li>{@link DBTGattChar}</li>
431  * <li>{@link DBTGattDesc}</li>
432  * </ul>
433  * or alternatively in {@link BTObject} space
434  * <ul>
435  * <li>{@link BTType#ADAPTER} -> {@link BTAdapter}</li>
436  * <li>{@link BTType#DEVICE} -> {@link BTDevice}</li>
437  * <li>{@link BTType#GATT_SERVICE} -> {@link BTGattService}</li>
438  * <li>{@link BTType#GATT_CHARACTERISTIC} -> {@link BTGattChar}</li>
439  * <li>{@link BTType#GATT_DESCRIPTOR} -> {@link BTGattDesc}</li>
440  * </ul>
441  * </p>
442  * @param name name of the desired {@link BTType#ADAPTER adapter} or {@link BTType#DEVICE device}.
443  * Maybe {@code null}.
444  * @param identifier EUI48 address of the desired {@link BTType#ADAPTER adapter} or {@link BTType#DEVICE device}
445  * or UUID of the desired {@link BTType#GATT_SERVICE service},
446  * {@link BTType#GATT_CHARACTERISTIC characteristic} or {@link BTType#GATT_DESCRIPTOR descriptor} to be found.
447  * Maybe {@code null}, in which case the first object of the desired type is being returned - if existing.
448  * @param type specify the type of the object to be found, either
449  * {@link BTType#ADAPTER adapter}, {@link BTType#DEVICE device},
450  * {@link BTType#GATT_SERVICE service}, {@link BTType#GATT_CHARACTERISTIC characteristic}
451  * or {@link BTType#GATT_DESCRIPTOR descriptor}.
452  * {@link BTType#NONE none} means anything.
453  */
454  /* pp */ DBTObject findInCache(final String name, final String identifier, final BTType type) {
455  final boolean anyType = BTType.NONE == type;
456  final boolean adapterType = BTType.ADAPTER == type;
457 
458  if( null == name && null == identifier && ( anyType || adapterType ) ) {
459  // special case for 1st valid adapter
460  if( adapters.size() > 0 ) {
461  return (DBTAdapter) adapters.get(0);
462  }
463  return null; // no adapter
464  }
465  for(final Iterator<BTAdapter> iter = adapters.iterator(); iter.hasNext(); ) {
466  final DBTAdapter adapter = (DBTAdapter) iter.next();
467  if( !adapter.isValid() ) {
468  continue;
469  }
470  if( ( anyType || adapterType ) ) {
471  if( null != name && null != identifier &&
472  adapter.getName().equals(name) &&
473  adapter.getAddressAndType().address.toString().equals(identifier)
474  )
475  {
476  return adapter;
477  }
478  if( null != identifier &&
479  adapter.getAddressAndType().address.toString().equals(identifier)
480  )
481  {
482  return adapter;
483  }
484  if( null != name &&
485  adapter.getName().equals(name)
486  )
487  {
488  return adapter;
489  }
490  }
491  final DBTObject dbtObj = adapter.findInCache(name, identifier, type);
492  if( null != dbtObj ) {
493  return dbtObj;
494  }
495  }
496  return null;
497  }
498 
499  /* pp */ DBTObject findInCache(final DBTObject parent, final BTType type, final String name, final String identifier) {
500  if( null == parent ) {
501  return findInCache(name, identifier, type);
502  }
503  final boolean anyType = BTType.NONE == type;
504  final boolean deviceType = BTType.DEVICE == type;
505  final boolean serviceType = BTType.GATT_SERVICE == type;
506  final boolean charType = BTType.GATT_CHARACTERISTIC== type;
507  final boolean descType = BTType.GATT_DESCRIPTOR == type;
508 
509  final BTType parentType = parent.getBluetoothType();
510 
511  if( BTType.ADAPTER == parentType &&
512  ( anyType || deviceType || serviceType || charType || descType )
513  )
514  {
515  return ((DBTAdapter) parent).findInCache(name, identifier, type);
516  }
517  if( BTType.DEVICE == parentType &&
518  ( anyType || serviceType || charType || descType )
519  )
520  {
521  return ((DBTDevice) parent).findInCache(identifier, type);
522  }
523  if( BTType.GATT_SERVICE == parentType &&
524  ( anyType || charType || descType )
525  )
526  {
527  final DBTGattService service = (DBTGattService) parent;
528  if( !service.checkServiceCache() ) {
529  return null;
530  }
531  return service.findInCache(identifier, type);
532  }
533  if( BTType.GATT_CHARACTERISTIC == parentType &&
534  ( anyType || descType )
535  )
536  {
537  final DBTGattChar characteristic = (DBTGattChar) parent;
538  if( !characteristic.checkServiceCache() ) {
539  return null;
540  }
541  return characteristic.findInCache(identifier, type);
542  }
543  return null;
544  }
545 
546 }
org.direct_bt.BTFactory.DEBUG
static final boolean DEBUG
Debug logging enabled or disabled.
Definition: BTFactory.java:147
org.direct_bt.BTAdapter
Provides access to Bluetooth adapters.
Definition: BTAdapter.java:41
jau.direct_bt.DBTManager.stopDiscovery
HCIStatusCode stopDiscovery()
Turns off device discovery on the default adapter if it is enabled.
Definition: DBTManager.java:246
org.direct_bt.BTDevice.getServices
List< BTGattService > getServices()
Returns a list of BluetoothGattServices available on this device.
jau.direct_bt.DBTManager.finalize
void finalize()
Definition: DBTManager.java:407
org.direct_bt.BTAdapter.isPowered
boolean isPowered()
Returns whether the adapter is valid, plugged in and powered.
jau.direct_bt.DBTManager.addChangedAdapterSetListener
final void addChangedAdapterSetListener(final ChangedAdapterSetListener l)
Add the given ChangedAdapterSetListener to this manager.
Definition: DBTManager.java:254
jau.direct_bt.DBTManager.getAdapters
List< BTAdapter > getAdapters()
Returns a list of BluetoothAdapters available in the system.
Definition: DBTManager.java:177
org.direct_bt
Author: Sven Gothel sgothel@jausoft.com Copyright (c) 2020 Gothel Software e.K.
jau.direct_bt.DBTManager.isJVMShuttingDown
static final boolean isJVMShuttingDown()
Returns true if the JVM is shutting down, otherwise false.
Definition: DBTManager.java:115
org.direct_bt.BTManager.ChangedAdapterSetListener.adapterAdded
void adapterAdded(final BTAdapter adapter)
BTAdapter was added to the system.
org.direct_bt.BTFactory
One stop BTManager API entry point.
Definition: BTFactory.java:52
jau.direct_bt.DBTManager.getUnifyUUID128Bit
static boolean getUnifyUUID128Bit()
Returns whether uuid128_t consolidation is enabled for native uuid16_t and uuid32_t values before str...
Definition: DBTManager.java:140
jau.direct_bt.DBTManager
Definition: DBTManager.java:51
jau.direct_bt.DBTManager.getAdapter
BTAdapter getAdapter(final int dev_id)
Returns the BluetoothAdapter matching the given dev_id or null if not found.
Definition: DBTManager.java:180
org.direct_bt.BTGattService
Provides access to Bluetooth GATT characteristic.
Definition: BTGattService.java:41
jau.direct_bt.DBTManager.shutdown
void shutdown()
Release the native memory associated with this object and all related Bluetooth resources.
Definition: DBTManager.java:412
jau.direct_bt.DBTManager.find
DBTObject find(final BTType type, final String name, final String identifier, final BTObject parent, final long timeoutMS)
Find a BluetoothObject of a type matching type.
Definition: DBTManager.java:167
jau.direct_bt.DBTManager.getSettings
final Settings getSettings()
Returns this implmentation's Settings.
Definition: DBTManager.java:162
org.direct_bt.BTManager
Definition: BTManager.java:34
test
org.direct_bt.BTAdapter.getDevID
int getDevID()
Returns the BluetoothAdapter's internal temporary device id.
jau.direct_bt.DBTManager.setDefaultAdapter
boolean setDefaultAdapter(final BTAdapter adapter)
Sets a default adapter to use for discovery.
Definition: DBTManager.java:225
org.direct_bt.BTAdapter.getCurrentScanType
ScanType getCurrentScanType()
Returns the current meta discovering ScanType.
org.direct_bt.BTFactory.VERBOSE
static final boolean VERBOSE
Verbose logging enabled or disabled.
Definition: BTFactory.java:139
jau.direct_bt.DBTManager.VERBOSE
static final boolean VERBOSE
Definition: DBTManager.java:53
jau.direct_bt.DBTAdapter
Definition: DBTAdapter.java:59
org.direct_bt.BTAdapter.startDiscovery
HCIStatusCode startDiscovery(final boolean keepAlive, final boolean le_scan_active)
Turns on device discovery if it is disabled.
jau.direct_bt.DBTManager.removeChangedAdapterSetListener
final int removeChangedAdapterSetListener(final ChangedAdapterSetListener l)
Remove the given ChangedAdapterSetListener from this manager.
Definition: DBTManager.java:266
org.direct_bt.ScanType
Meta ScanType as derived from BTMode with defined value mask consisting of BDAddressType bits.
Definition: ScanType.java:36
jau.direct_bt.DBTManager.getManager
static BTManager getManager()
Returns an instance of BluetoothManager, to be used instead of constructor.
Definition: DBTManager.java:398
jau.direct_bt.DBTManager.find
DBTObject find(final BTType type, final String name, final String identifier, final BTObject parent)
Find a BluetoothObject of a type matching type.
Definition: DBTManager.java:172
org.direct_bt.HCIStatusCode
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
Definition: HCIStatusCode.java:34
org.direct_bt.BTGattChar
Provides access to Bluetooth GATT characteristic.
Definition: BTGattChar.java:40
org.direct_bt.BTDevice
Provides access to Bluetooth adapters.
Definition: BTDevice.java:42
org.direct_bt.BTType.NONE
NONE
Definition: BTType.java:29
org.direct_bt.BTGattDesc
Provides access to Bluetooth GATT descriptor.
Definition: BTGattDesc.java:38
jau.direct_bt.DBTManager.addShutdownHook
static void addShutdownHook(final boolean head, final Runnable runnable)
Add a shutdown hook to be performed at JVM shutdown before shutting down DBTManager instance.
Definition: DBTManager.java:123
jau.direct_bt.DBTManager.DEBUG
static final boolean DEBUG
Definition: DBTManager.java:52
org
org.direct_bt.BTAdapter.stopDiscovery
HCIStatusCode stopDiscovery()
Turns off device discovery if it is enabled.
org.direct_bt.BTType
Definition: BTType.java:28
org.direct_bt.BTException
Definition: BTException.java:32
org.direct_bt.BTManager.Settings
Interface allowing to retrieve certain settings of the implementation.
Definition: BTManager.java:43
org.direct_bt.BTType.ADAPTER
ADAPTER
Definition: BTType.java:29
jau.direct_bt.DBTManager.getBluetoothType
BTType getBluetoothType()
Definition: DBTManager.java:164
org.direct_bt.BTAdapter.getDiscoveredDevices
List< BTDevice > getDiscoveredDevices()
Returns a list of discovered BluetoothDevices from this adapter.
org.direct_bt.BTObject
Definition: BTObject.java:31
jau.direct_bt.DBTManager.getServices
List< BTGattService > getServices()
Returns a list of available BluetoothGattServices.A list of available BluetoothGattServices
Definition: DBTManager.java:208
jau.direct_bt.DBTManager.setUnifyUUID128Bit
static void setUnifyUUID128Bit(final boolean v)
Enables or disables uuid128_t consolidation for native uuid16_t and uuid32_t values before string con...
Definition: DBTManager.java:153
jau.direct_bt.DBTManager.getCurrentScanType
final ScanType getCurrentScanType()
Returns the current meta discovering ScanType of the getDefaultAdapter() via BTAdapter#getCurrentScan...
Definition: DBTManager.java:249
jau.direct_bt.DBTManager.getDevices
List< BTDevice > getDevices()
Returns a list of discovered BluetoothDevices.
Definition: DBTManager.java:191
jau.direct_bt.DBTManager.startDiscovery
HCIStatusCode startDiscovery(final boolean keepAlive, final boolean le_scan_active)
Turns on device discovery on the default adapter if it is disabled.
Definition: DBTManager.java:241
jau.direct_bt.DBTAdapter.close
void close()
Release the native memory associated with this object The object should not be used following a call ...
Definition: DBTAdapter.java:106
jau.direct_bt.DBTManager.getDefaultAdapter
BTAdapter getDefaultAdapter()
Gets the default adapter to use for discovery.
Definition: DBTManager.java:230
jau.direct_bt.DBTObject
Definition: DBTObject.java:32
org.direct_bt.BTManager.ChangedAdapterSetListener
Event listener to receive change events regarding the system's BTAdapter set, e.g.
Definition: BTManager.java:69