Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
BTFactory.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 package org.direct_bt;
26 
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.lang.reflect.InvocationTargetException;
30 import java.lang.reflect.Method;
31 import java.net.URL;
32 import java.security.AccessController;
33 import java.security.PrivilegedAction;
34 import java.util.ArrayList;
35 import java.util.Enumeration;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Properties;
39 import java.util.Set;
40 import java.util.jar.Attributes;
41 import java.util.jar.Manifest;
42 
43 import org.jau.util.VersionUtil;
44 
45 /**
46  * One stop {@link BTManager} API entry point.
47  * <p>
48  * Further provides access to certain property settings,
49  * see {@link #DEBUG}, {@link #VERBOSE}, {@link #DEFAULT_BTMODE} and {@link BTManager.Settings}.
50  * </p>
51  */
52 public class BTFactory {
53 
54  /**
55  * Identifier names, allowing {@link BTFactory#getBTManager(ImplementationIdentifier)}
56  * to initialize the required native libraries and to instantiate the root {@link BTManager} instance.
57  * <p>
58  * The implementation class must provide the static factory method
59  * <pre>
60  * public static synchronized BluetoothManager getBluetoothManager() throws BluetoothException { .. }
61  * </pre>
62  * </p>
63  */
64  public static class ImplementationIdentifier {
65  /**
66  * Fully qualified class name for the {@link BTManager} implementation
67  * <p>
68  * The implementation class must provide the static factory method
69  * <pre>
70  * public static synchronized BluetoothManager getBluetoothManager() throws BluetoothException { .. }
71  * </pre>
72  * </p>
73  */
74  public final String BluetoothManagerClassName;
75  /** Native library basename for the implementation native library */
77  /** Native library basename for the Java binding native library */
78  public final String JavaNativeLibraryBasename;
79 
82  final String JavaNativeLibraryBasename) {
83  this.BluetoothManagerClassName = BluetoothManagerClassName;
84  this.ImplementationNativeLibraryBasename = ImplementationNativeLibraryBasename;
85  this.JavaNativeLibraryBasename = JavaNativeLibraryBasename;
86  }
87 
88  /**
89  * <p>
90  * Implementation compares {@link #BluetoothManagerClassName} only for equality.
91  * </p>
92  * {@inheritDoc}
93  */
94  @Override
95  public boolean equals(final Object other) {
96  if( null == other || !(other instanceof ImplementationIdentifier) ) {
97  return false;
98  }
101  }
102 
103  @Override
104  public String toString() {
105  return "ImplementationIdentifier[class "+BluetoothManagerClassName+
107  ", javaLib "+JavaNativeLibraryBasename+"]";
108  }
109  }
110 
111  /**
112  * {@link ImplementationIdentifier} for direct_bt implementation: {@value}
113  * <p>
114  * This value is exposed for convenience, user implementations are welcome.
115  * </p>
116  */
117  public static final ImplementationIdentifier DirectBTImplementationID = new ImplementationIdentifier("jau.direct_bt.DBTManager", "direct_bt", "javadirect_bt");
118 
119  private static final List<ImplementationIdentifier> implIDs = new ArrayList<ImplementationIdentifier>();
120 
121  /**
122  * Manifest's {@link Attributes.Name#SPECIFICATION_VERSION} or {@code null} if not available.
123  */
124  public static final String getAPIVersion() { return APIVersion; }
125  private static String APIVersion;
126 
127  /**
128  * Manifest's {@link Attributes.Name#IMPLEMENTATION_VERSION} or {@code null} if not available.
129  */
130  public static final String getImplVersion() { return ImplVersion; }
131  private static String ImplVersion;
132 
133  /**
134  * Verbose logging enabled or disabled.
135  * <p>
136  * System property {@code org.direct_bt.verbose}, boolean, default {@code false}.
137  * </p>
138  */
139  public static final boolean VERBOSE;
140 
141  /**
142  * Debug logging enabled or disabled.
143  * <p>
144  * System property {@code org.direct_bt.debug}, boolean, default {@code false}.
145  * </p>
146  */
147  public static final boolean DEBUG;
148 
149  /**
150  * Default {@link BTMode} when initializing new adapter
151  * <p>
152  * System property {@code org.direct_bt.btmode}, string, default {@code DUAL} {@link BTMode#DUAL}.
153  * </p>
154  * @since 2.0.0
155  */
156  public static final BTMode DEFAULT_BTMODE;
157 
158  /**
159  * True if jaulib {@link org.jau.sys.PlatformProps} has been detected.
160  */
161  public static final boolean JAULIB_AVAILABLE;
162 
163  /**
164  * True if jaulib {@link #JAULIB_AVAILABLE} and its {@link org.jau.sys.PlatformProps#USE_TEMP_JAR_CACHE} is true,
165  * i.e. the jar cache is available, enabled and in use.
166  */
167  public static final boolean JAULIB_JARCACHE_USED;
168 
169  static {
170  {
171  final String v = System.getProperty("org.direct_bt.debug", "false");
172  DEBUG = Boolean.valueOf(v);
173  }
174  if( DEBUG ) {
175  VERBOSE = true;
176  } else {
177  final String v = System.getProperty("org.direct_bt.verbose", "false");
178  VERBOSE = Boolean.valueOf(v);
179  }
180  {
181  final String v = System.getProperty("org.direct_bt.btmode", "DUAL");
182  BTMode btMode = BTMode.DUAL;
183  try {
184  btMode = BTMode.get(v);
185  } catch (final IllegalArgumentException ex) {
186  System.err.println("Invalid BTMode '"+v+"': "+ex.getMessage());
187  }
188  DEFAULT_BTMODE = btMode;
189  }
190  implIDs.add(DirectBTImplementationID);
191 
192  boolean isJaulibAvail = false;
193  try {
194  isJaulibAvail = null != Class.forName("org.jau.sys.PlatformProps", true /* initializeClazz */, BTFactory.class.getClassLoader());
195  } catch( final Throwable t ) {
196  if( DEBUG ) {
197  System.err.println("BTFactory Caught: "+t.getMessage());
198  t.printStackTrace();
199  }
200  }
201  JAULIB_AVAILABLE = isJaulibAvail;
202 
203  if( isJaulibAvail ) {
204  JAULIB_JARCACHE_USED = org.jau.sys.PlatformProps.USE_TEMP_JAR_CACHE;
205  } else {
206  JAULIB_JARCACHE_USED = false;
207  }
208  if( VERBOSE ) {
209  System.err.println("Jaulib available: "+JAULIB_AVAILABLE+", JarCache in use: "+JAULIB_JARCACHE_USED);
210  }
211  }
212 
213  private static ImplementationIdentifier initializedID = null;
214 
215  public static synchronized void checkInitialized() {
216  if( null == initializedID ) {
217  throw new IllegalStateException("BluetoothFactory not initialized.");
218  }
219  }
220  public static synchronized boolean isInitialized() {
221  return null == initializedID;
222  }
223 
224  private static synchronized void initLibrary(final ImplementationIdentifier id) {
225  if( null != initializedID ) {
226  if( id != initializedID ) {
227  throw new IllegalStateException("BluetoothFactory already initialized with "+initializedID+", can't override by "+id);
228  }
229  return;
230  }
231 
232  final ClassLoader cl = BTFactory.class.getClassLoader();
233  boolean libsLoaded = false;
234  if( JAULIB_AVAILABLE ) {
235  if( JAULIB_JARCACHE_USED ) {
236  try {
237  org.jau.pkg.JNIJarLibrary.addNativeJarLibs(new Class<?>[] { BTFactory.class }, null);
238  } catch (final Exception e0) {
239  System.err.println("BTFactory Caught "+e0.getClass().getSimpleName()+": "+e0.getMessage()+", while JNILibLoaderBase.addNativeJarLibs(..)");
240  if( DEBUG ) {
241  e0.printStackTrace();
242  }
243  }
244  }
245  try {
246  if( null != org.jau.sys.dl.NativeLibrary.open(id.ImplementationNativeLibraryBasename,
247  true /* searchSystemPath */, false /* searchSystemPathFirst */, cl, true /* global */) )
248  {
249  org.jau.sys.JNILibrary.loadLibrary(id.JavaNativeLibraryBasename, false, cl);
250  libsLoaded = true;
251  }
252  } catch (final Throwable t) {
253  System.err.println("Caught "+t.getClass().getSimpleName()+": "+t.getMessage()+", while loading libs..");
254  if( DEBUG ) {
255  t.printStackTrace();
256  }
257  }
258  if( DEBUG ) {
259  System.err.println("Jaulib: Native libs loaded: "+ libsLoaded);
260  }
261  }
262  if( !libsLoaded ) {
263  try {
264  final Throwable[] t = { null };
265  if( !PlatformToolkit.loadLibrary(id.ImplementationNativeLibraryBasename, cl, t) ) {
266  throw new RuntimeException("Couldn't load native library with basename <"+id.ImplementationNativeLibraryBasename+">", t[0]);
267  }
268  if( !PlatformToolkit.loadLibrary(id.JavaNativeLibraryBasename, cl, t) ) {
269  throw new RuntimeException("Couldn't load native library with basename <"+id.JavaNativeLibraryBasename+">", t[0]);
270  }
271  } catch (final Throwable e) {
272  System.err.println("Caught "+e.getClass().getSimpleName()+": "+e.getMessage()+", while loading libs (2) ..");
273  if( DEBUG ) {
274  e.printStackTrace();
275  }
276  throw e; // fwd exception - end here
277  }
278  }
279 
280  // Map all Java properties '[org.]direct_bt.*' and 'direct_bt.*' to native environment.
281  try {
282  if( DEBUG ) {
283  System.err.println("BlootoothFactory: Mapping '[org.|jau.]direct_bt.*' properties to native environment");
284  }
285  final Properties props = AccessController.doPrivileged(new PrivilegedAction<Properties>() {
286  @Override
287  public Properties run() {
288  return System.getProperties();
289  } });
290 
291  final Enumeration<?> enums = props.propertyNames();
292  while (enums.hasMoreElements()) {
293  final String key = (String) enums.nextElement();
294  if( key.startsWith("org.direct_bt.") || key.startsWith("jau.direct_bt.") ||
295  key.startsWith("direct_bt.") )
296  {
297  final String value = props.getProperty(key);
298  if( DEBUG ) {
299  System.err.println(" <"+key+"> := <"+value+">");
300  }
301  setenv(key, value, true /* overwrite */);
302  }
303  }
304  } catch (final Throwable e) {
305  System.err.println("Caught exception while forwarding system properties: "+e.getMessage());
306  e.printStackTrace();
307  }
308 
309  try {
310  final Manifest manifest = getManifest(cl, new String[] { "org.direct_bt" } );
311  final Attributes mfAttributes = null != manifest ? manifest.getMainAttributes() : null;
312 
313  // major.minor must match!
314  final String NAPIVersion = getNativeAPIVersion();
315  final String JAPIVersion = null != mfAttributes ? mfAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION) : null;
316  if ( null != JAPIVersion && JAPIVersion.equals(NAPIVersion) == false) {
317  final String[] NAPIVersionCode = NAPIVersion.split("\\D");
318  final String[] JAPIVersionCode = JAPIVersion.split("\\D");
319  if (JAPIVersionCode[0].equals(NAPIVersionCode[0]) == false) {
320  if (Integer.valueOf(JAPIVersionCode[0]) < Integer.valueOf(NAPIVersionCode[0])) {
321  throw new RuntimeException("Java library "+JAPIVersion+" < native library "+NAPIVersion+". Please update the Java library.");
322  } else {
323  throw new RuntimeException("Native library "+NAPIVersion+" < java library "+JAPIVersion+". Please update the native library.");
324  }
325  } else if (JAPIVersionCode[1].equals(NAPIVersionCode[1]) == false) {
326  if (Integer.valueOf(JAPIVersionCode[1]) < Integer.valueOf(NAPIVersionCode[1])) {
327  throw new RuntimeException("Java library "+JAPIVersion+" < native library "+NAPIVersion+". Please update the Java library.");
328  } else {
329  throw new RuntimeException("Native library "+NAPIVersion+" < java library "+JAPIVersion+". Please update the native library.");
330  }
331  }
332  }
333  initializedID = id; // initialized!
334 
335  APIVersion = JAPIVersion;
336  ImplVersion = null != mfAttributes ? mfAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION) : null;
337  if( VERBOSE ) {
338  System.err.println("direct_bt loaded "+id);
339  System.err.println("direct_bt java api version "+JAPIVersion);
340  System.err.println("direct_bt native api version "+NAPIVersion);
341  if( null != mfAttributes ) {
342  final Attributes.Name[] versionAttributeNames = new Attributes.Name[] {
343  Attributes.Name.SPECIFICATION_TITLE,
344  Attributes.Name.SPECIFICATION_VENDOR,
345  Attributes.Name.SPECIFICATION_VERSION,
346  Attributes.Name.IMPLEMENTATION_TITLE,
347  Attributes.Name.IMPLEMENTATION_VENDOR,
348  Attributes.Name.IMPLEMENTATION_VERSION,
349  new Attributes.Name("Implementation-Commit") };
350  for( final Attributes.Name an : versionAttributeNames ) {
351  System.err.println(" "+an+": "+mfAttributes.getValue(an));
352  }
353  } else {
354  System.err.println(" No Manifest available;");
355  }
356  }
357  } catch (final Throwable e) {
358  System.err.println("Error querying manifest information.");
359  e.printStackTrace();
360  throw e; // fwd exception - end here
361  }
362  }
363 
364  private static synchronized BTManager getBTManager(final Class<?> factoryImplClass)
365  throws BTException, NoSuchMethodException, SecurityException,
366  IllegalAccessException, IllegalArgumentException, InvocationTargetException
367  {
368  final Method m = factoryImplClass.getMethod("getManager");
369  return (BTManager)m.invoke(null);
370  }
371 
372  /**
373  * Registers a new {@link ImplementationIdentifier} to the internal list.
374  * The {@code id} is only added if not registered yet.
375  * @param id the {@link ImplementationIdentifier} to register
376  * @return {@code true} if the given {@link ImplementationIdentifier} has been newly added,
377  * otherwise {@code false}.
378  */
379  public static synchronized boolean registerImplementationIdentifier(final ImplementationIdentifier id) {
380  if( null == id ) {
381  return false;
382  }
383  if( implIDs.contains(id) ) {
384  return false;
385  }
386  return implIDs.add(id);
387  }
388 
389  /**
390  * Returns the matching {@link ImplementationIdentifier} from the internal list or {@code null} if not found.
391  * @param fqBluetoothManagerImplementationClassName fully qualified class name for the {@link BTManager} implementation
392  */
393  public static synchronized ImplementationIdentifier getImplementationIdentifier(final String fqBluetoothManagerImplementationClassName) {
394  for(final ImplementationIdentifier id : implIDs) {
395  if( id.BluetoothManagerClassName.equals(fqBluetoothManagerImplementationClassName) ) {
396  return id;
397  }
398  }
399  return null;
400  }
401 
402  /**
403  * Returns an initialized BluetoothManager instance using the given {@code fqBluetoothManagerImplementationClassName}
404  * to lookup a registered {@link ImplementationIdentifier}.
405  * <p>
406  * If found, method returns {@link #getBTManager(ImplementationIdentifier)}, otherwise {@code null}.
407  * </p>
408  * <p>
409  * The chosen implementation can't be changed within a running implementation, an exception is thrown if tried.
410  * </p>
411  *
412  * @param fqBluetoothManagerImplementationClassName fully qualified class name for the {@link BTManager} implementation
413  * @throws BTException
414  * @throws NoSuchMethodException
415  * @throws SecurityException
416  * @throws IllegalAccessException
417  * @throws IllegalArgumentException
418  * @throws InvocationTargetException
419  * @throws ClassNotFoundException
420  * @see {@link #DBusFactoryImplClassName}
421  * @see {@link #DirectBTFactoryImplClassName}
422  */
423  public static synchronized BTManager getBTManager(final String fqBluetoothManagerImplementationClassName)
424  throws BTException, NoSuchMethodException, SecurityException,
425  IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException
426  {
427  final ImplementationIdentifier id = getImplementationIdentifier(fqBluetoothManagerImplementationClassName);
428  if( null != id ) {
429  return getBTManager(id);
430  }
431  return null;
432  }
433 
434  /**
435  * Returns an initialized BluetoothManager instance using the given {@link ImplementationIdentifier}.
436  * <p>
437  * If the {@link ImplementationIdentifier} has not been {@link #registerImplementationIdentifier(ImplementationIdentifier)},
438  * it will be added to the list.
439  * </p>
440  * <p>
441  * The chosen implementation can't be changed within a running implementation, an exception is thrown if tried.
442  * </p>
443  * @param id the specific {@link ImplementationIdentifier}
444  * @throws BTException
445  * @throws NoSuchMethodException
446  * @throws SecurityException
447  * @throws IllegalAccessException
448  * @throws IllegalArgumentException
449  * @throws InvocationTargetException
450  * @throws ClassNotFoundException
451  * @see {@link #DBusFactoryImplClassName}
452  * @see {@link #DirectBTFactoryImplClassName}
453  */
454  public static synchronized BTManager getBTManager(final ImplementationIdentifier id)
455  throws BTException, NoSuchMethodException, SecurityException,
456  IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException
457  {
459  initLibrary(id);
460  final Class<?> factoryImpl = Class.forName(id.BluetoothManagerClassName);
461  return getBTManager(factoryImpl);
462  }
463 
464  /**
465  * Returns an initialized BluetoothManager instance using the DirectBT implementation.
466  * <p>
467  * Issues {@link #getBTManager(ImplementationIdentifier)} using {@link #DirectBTImplementationID}.
468  * </p>
469  * <p>
470  * The chosen implementation can't be changed within a running implementation, an exception is thrown if tried.
471  * </p>
472  * @throws BTException
473  * @throws NoSuchMethodException
474  * @throws SecurityException
475  * @throws IllegalAccessException
476  * @throws IllegalArgumentException
477  * @throws InvocationTargetException
478  * @throws ClassNotFoundException
479  */
480  public static synchronized BTManager getDirectBTManager()
481  throws BTException, NoSuchMethodException, SecurityException,
482  IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException
483  {
484  return getBTManager(DirectBTImplementationID);
485  }
486 
487  private static final Manifest getManifest(final ClassLoader cl, final String[] extensions) {
488  final Manifest[] extManifests = new Manifest[extensions.length];
489  try {
490  final Enumeration<URL> resources = cl.getResources("META-INF/MANIFEST.MF");
491  while (resources.hasMoreElements()) {
492  final URL resURL = resources.nextElement();
493  if( DEBUG ) {
494  System.err.println("resource: "+resURL);
495  }
496  final InputStream is = resURL.openStream();
497  final Manifest manifest;
498  try {
499  manifest = new Manifest(is);
500  } finally {
501  try {
502  is.close();
503  } catch (final IOException e) {}
504  }
505  final Attributes attributes = manifest.getMainAttributes();
506  if(attributes != null) {
507  final String attributesExtName = attributes.getValue( Attributes.Name.EXTENSION_NAME );
508  for(int i=0; i < extensions.length && null == extManifests[i]; i++) {
509  final String extension = extensions[i];
510  if( extension.equals( attributesExtName ) ) {
511  if( 0 == i ) {
512  return manifest; // 1st one has highest prio - done
513  }
514  extManifests[i] = manifest;
515  }
516  }
517  }
518  }
519  } catch (final IOException ex) {
520  throw new RuntimeException("Unable to read manifest.", ex);
521  }
522  for(int i=1; i<extManifests.length; i++) {
523  if( null != extManifests[i] ) {
524  return extManifests[i];
525  }
526  }
527  return null;
528  }
529 
530  public static void main(final String args[]) {
531  System.err.println("Jaulib: Available "+JAULIB_AVAILABLE+", JarCache in use "+JAULIB_JARCACHE_USED);
532  if( JAULIB_AVAILABLE ) {
533  System.err.println(VersionUtil.getPlatformInfo());
534  System.err.println("Version Info:");
536  System.err.println(v);
537  System.err.println("");
538  System.err.println("Full Manifest:");
539  System.err.println(v.getFullManifestInfo(null));
540  } else {
541  System.err.println("Full Manifest:");
542  final Manifest manifest = getManifest(BTFactory.class.getClassLoader(), new String[] { "org.direct_bt" } );
543  final Attributes attr = manifest.getMainAttributes();
544  final Set<Object> keys = attr.keySet();
545  final StringBuilder sb = new StringBuilder();
546  for(final Iterator<Object> iter=keys.iterator(); iter.hasNext(); ) {
547  final Attributes.Name key = (Attributes.Name) iter.next();
548  final String val = attr.getValue(key);
549  sb.append(" ");
550  sb.append(key);
551  sb.append(" = ");
552  sb.append(val);
553  sb.append(System.lineSeparator());
554  }
555  System.err.println(sb);
556  }
557  try {
558  final BTManager mngr = getDirectBTManager();
559  final List<BTAdapter> adapters = mngr.getAdapters();
560  System.err.println("BTManager: Settings "+mngr.getSettings().toString()+", adapters "+adapters.size());
561  final boolean isDBT = mngr.getSettings().isDirectBT();
562  int i=0;
563  for(final Iterator<BTAdapter> iter = adapters.iterator(); iter.hasNext(); ++i) {
564  if( isDBT ) {
565  System.err.println("BTAdapter["+i+"]: "+iter.next().toString()); // has full toString()
566  } else {
567  final BTAdapter a = iter.next();
568  System.err.println("BTAdapter["+i+"]: dev_id "+a.getDevID()+", address "+a.getAddressAndType()+", name "+a.getName());
569  }
570  }
571  } catch (BTException | NoSuchMethodException | SecurityException
572  | IllegalAccessException | IllegalArgumentException
573  | InvocationTargetException | ClassNotFoundException e) {
574  e.printStackTrace();
575  }
576  }
577 
578  public native static String getNativeVersion();
579  public native static String getNativeAPIVersion();
580  private native static void setenv(String name, String value, boolean overwrite);
581 }
582 
583 /** \example DBTScanner10.java
584  * This Java scanner example uses the Direct-BT fully event driven workflow
585  * and adds multithreading, i.e. one thread processes each found device found
586  * as notified via the event listener.
587  * <p>
588  * This example represents the recommended utilization of Direct-BT.
589  * </p>
590  * <p>
591  * See `dbt_scanner10.cpp` for invocation examples, since both apps are fully compatible.
592  * </p>
593  */
594 
org.direct_bt.BTFactory.DEBUG
static final boolean DEBUG
Debug logging enabled or disabled.
Definition: BTFactory.java:147
org.direct_bt.BTFactory.getImplementationIdentifier
static synchronized ImplementationIdentifier getImplementationIdentifier(final String fqBluetoothManagerImplementationClassName)
Returns the matching ImplementationIdentifier from the internal list or.
Definition: BTFactory.java:393
org.direct_bt.BTAdapter
Provides access to Bluetooth adapters.
Definition: BTAdapter.java:41
org.direct_bt.BTFactory.ImplementationIdentifier
Identifier names, allowing BTFactory#getBTManager(ImplementationIdentifier) to initialize the require...
Definition: BTFactory.java:64
org.direct_bt.BTFactory.ImplementationIdentifier.toString
String toString()
Definition: BTFactory.java:104
org.direct_bt.BTFactory.JAULIB_JARCACHE_USED
static final boolean JAULIB_JARCACHE_USED
True if jaulib JAULIB_AVAILABLE and its org.jau.sys.PlatformProps#USE_TEMP_JAR_CACHE is true,...
Definition: BTFactory.java:167
org.direct_bt.BTFactory.checkInitialized
static synchronized void checkInitialized()
Definition: BTFactory.java:215
org.direct_bt.DirectBTVersion.getInstance
static DirectBTVersion getInstance()
Returns a transient new instance.
Definition: DirectBTVersion.java:45
org.direct_bt.BTFactory.ImplementationIdentifier.equals
boolean equals(final Object other)
Definition: BTFactory.java:95
org.direct_bt.DirectBTVersion
This.
Definition: DirectBTVersion.java:36
org.direct_bt.BTFactory.ImplementationIdentifier.BluetoothManagerClassName
final String BluetoothManagerClassName
Fully qualified class name for the BTManager implementation.
Definition: BTFactory.java:74
org.direct_bt.BTFactory
One stop BTManager API entry point.
Definition: BTFactory.java:52
org.direct_bt.BTFactory.ImplementationIdentifier.ImplementationNativeLibraryBasename
final String ImplementationNativeLibraryBasename
Native library basename for the implementation native library.
Definition: BTFactory.java:76
org.direct_bt.BTAdapter.getName
String getName()
Returns the system name of this adapter.
org.direct_bt.BTFactory.ImplementationIdentifier.ImplementationIdentifier
ImplementationIdentifier(final String BluetoothManagerClassName, final String ImplementationNativeLibraryBasename, final String JavaNativeLibraryBasename)
Definition: BTFactory.java:80
org.direct_bt.BTFactory.registerImplementationIdentifier
static synchronized boolean registerImplementationIdentifier(final ImplementationIdentifier id)
Registers a new ImplementationIdentifier to the internal list.
Definition: BTFactory.java:379
org.direct_bt.BTFactory.getAPIVersion
static final String getAPIVersion()
Manifest's Attributes.Name#SPECIFICATION_VERSION or.
Definition: BTFactory.java:124
org.direct_bt.BTManager
Definition: BTManager.java:34
org.direct_bt.BTFactory.getNativeAPIVersion
static native String getNativeAPIVersion()
org.direct_bt.BTAdapter.getDevID
int getDevID()
Returns the BluetoothAdapter's internal temporary device id.
org.direct_bt.BTFactory.VERBOSE
static final boolean VERBOSE
Verbose logging enabled or disabled.
Definition: BTFactory.java:139
org.direct_bt.BTFactory.isInitialized
static synchronized boolean isInitialized()
Definition: BTFactory.java:220
org.direct_bt.BTManager.Settings.toString
String toString()
org.direct_bt.BTMode.get
static BTMode get(final String name)
Maps the specified name to a constant of BTMode.
Definition: BTMode.java:57
org.direct_bt.BTFactory.main
static void main(final String args[])
Definition: BTFactory.java:530
org.direct_bt.BTManager.getSettings
Settings getSettings()
Returns this implmentation's Settings.
org.direct_bt.BTManager.getAdapters
List< BTAdapter > getAdapters()
Returns a list of BluetoothAdapters available in the system.
org.direct_bt.BTFactory.DirectBTImplementationID
static final ImplementationIdentifier DirectBTImplementationID
ImplementationIdentifier for direct_bt implementation: {@value}
Definition: BTFactory.java:117
org.direct_bt.BTFactory.getBTManager
static synchronized BTManager getBTManager(final String fqBluetoothManagerImplementationClassName)
Returns an initialized BluetoothManager instance using the given.
Definition: BTFactory.java:423
org.direct_bt.BTFactory.JAULIB_AVAILABLE
static final boolean JAULIB_AVAILABLE
True if jaulib org.jau.sys.PlatformProps has been detected.
Definition: BTFactory.java:161
org.direct_bt.BTManager.Settings.isDirectBT
boolean isDirectBT()
Returns true if underlying implementation is Direct-BT.
org.direct_bt.BTFactory.getDirectBTManager
static synchronized BTManager getDirectBTManager()
Returns an initialized BluetoothManager instance using the DirectBT implementation.
Definition: BTFactory.java:480
org.direct_bt.BTFactory.getNativeVersion
static native String getNativeVersion()
org.direct_bt.BTMode.DUAL
DUAL
Dual Bluetooth mode, i.e.
Definition: BTMode.java:38
org.direct_bt.BTFactory.getImplVersion
static final String getImplVersion()
Manifest's Attributes.Name#IMPLEMENTATION_VERSION or.
Definition: BTFactory.java:130
org
org.direct_bt.BTMode
Bluetooth adapter operating mode.
Definition: BTMode.java:34
org.direct_bt.BTException
Definition: BTException.java:32
org.direct_bt.BTFactory.DEFAULT_BTMODE
static final BTMode DEFAULT_BTMODE
Default BTMode when initializing new adapter.
Definition: BTFactory.java:156
org.direct_bt.BTFactory.ImplementationIdentifier.JavaNativeLibraryBasename
final String JavaNativeLibraryBasename
Native library basename for the Java binding native library.
Definition: BTFactory.java:78
org.direct_bt.BTFactory.getBTManager
static synchronized BTManager getBTManager(final ImplementationIdentifier id)
Returns an initialized BluetoothManager instance using the given ImplementationIdentifier.
Definition: BTFactory.java:454
org.direct_bt.BTAdapter.getAddressAndType
BDAddressAndType getAddressAndType()
Returns the adapter's public BDAddressAndType.