From 9261ca487726ea03cbaa7deaf192bc4f25d5aa9e Mon Sep 17 00:00:00 2001 From: Geoff Matrangola Date: Sun, 28 Jan 2018 11:39:12 -0500 Subject: [PATCH 1/4] Passing Information about connecting clients * BleApplicationListener.deviceConnected and BleApplicationListener.deviceDisconnected now have a path parameter. The path that is assigned by BlueZ D-Bus for the remote device that connected to the local Bluetooth adapter. deviceConnected also provides the unique Bluetooth Address of the remote Bluetooth Device. * BleCharacteristicListener.getValue and setValue now take a devicePath. If more than one device is connected to the characteristic, the correct one will read/receive the value. * BleCharacteristic.sendNotification now has a devicePath parameter to the notification can be sent to the proper device if multiple devices are listening. * BleCharacteristic now implements a getValue and setValue that can be overridden as an alternative to using the listener. * Created BleAdapter utility object to consolidate information about the local Bluetooth Adapter * Changed BleApplicaton.findAdapterPath to return the object * Added BleApplication.getBleAdapter method to return the Adapter currently being used by the BleApplication * Updated ExampleMain and ExampleCharacteristic to test and demonstrate the above changes. * Updated the build.gradle file so that it would work with more systems and IDEs. * Added runExample target in the build.gradle so that the example can be more easily run on the command line * Added example.conf to allow the example to run without elevated permissions * Added instructions to run the example from the command line and for the example.conf to README.md * Suggested using ./gradlew rather than requiring the user to install a specific version of Gradle. https://docs.gradle.org/current/userguide/gradle_wrapper.html * Fixed install instructions in READEME.md * General wordsmithing of the README.md * Added JetBrains IntilliJ project files to the .gitignore --- .gitignore | 6 +- README.md | 33 +++-- build.gradle | 41 +++---- gradle/wrapper/gradle-wrapper.properties | 3 +- .../java/it/tangodev/ble/BleApplication.java | 115 +++++++++++------- .../tangodev/ble/BleApplicationListener.java | 4 +- .../it/tangodev/ble/BleCharacteristic.java | 39 +++++- .../ble/BleCharacteristicListener.java | 4 +- .../java/it/tangodev/utils/BleAdapter.java | 42 +++++++ .../java/example/ExampleCharacteristic.java | 4 +- src/test/java/example/ExampleMain.java | 15 +-- 11 files changed, 206 insertions(+), 100 deletions(-) create mode 100644 src/main/java/it/tangodev/utils/BleAdapter.java diff --git a/.gitignore b/.gitignore index 3c3487c..545d934 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,8 @@ # ignore the eclipse project file .settings .project -.classpath +.classpath + +# ignore JetBrains IntilliJ project files +.idea/ +ble-java.iml \ No newline at end of file diff --git a/README.md b/README.md index 000248e..29f9d22 100644 --- a/README.md +++ b/README.md @@ -4,21 +4,22 @@ **ble-java** is a java library for building **BLE** GATT peripherals role application in JAVA. -**ble-java** is based on BlueZ, the linux Bluetooth stack. +**ble-java** is based on BlueZ, the Linux Bluetooth stack implemented on D-Bus. # Features * Create GATT Services * Create GATT Characteristic * Customize the Peripheral name -* Pure JAVA library +* JAVA library with minimal JNI interfaces to BlueZ over D-Bus # Dependencies 1. Java 8 or better 2. BlueZ 5.43 or better 3. d-bus Java library `libdbus-java` -Raspbian example: + +Raspbian install: ``` -sudo apt-get install +sudo apt-get install libdbus-java ``` you may also have to do run ``` @@ -26,21 +27,28 @@ sudo ldconfig ``` # Install -Clone the repository and build with Gradle (4.5 or higher): +Clone the repository and build with Gradle: ``` -gradle build +./gradlew build ``` # Example -You could see the main `MainExample.java` in `src/test/java/example`. -It's a sample main that create a BLE Application with one Service and 2 Characteristic. +`MainExample.java` in `src/test/java/example` demonstrates a sample main that +creates a BLE Application with one Service and 2 Characteristics. + +Before running the example, copy ```example.conf``` to ```/etc/dbus-1/system.d/``` + +To run from command line: ````./gradlew runExample```` + +Press ctrl-c to stop service. # BlueZ compatibility -Until now is tested with BlueZ 5.46 on Raspbian distribution. +Tested with BlueZ 5.46 on Raspbian distribution. -ble-java use the GattManager and LEAdvertising that was marked "Experimental" since 5.47, so you have to enable the Experimental features with the `--experimental` parameter in the BlueZ startup service. +**ble-java** usees the GattManager and LEAdvertising that was marked "Experimental" since 5.47. You need to enable the + Experimental features with the `--experimental` parameter in the BlueZ startup service. -Example for Raspbian `/lib/systemd/system/bluetooth.service` +For Raspbian and Ubuntu `/lib/systemd/system/bluetooth.service` ``` ... @@ -48,7 +56,8 @@ bluetoohd --experimental ... ``` -In the BlueZ 5.48 seem to be removed the experimental tag on the LEAdvertising features, but it was not yet tried. +If you are using BlueZ 5.48, the ```--experimental``` tag may not be needed for LEAdvertising features. But we have not tried +this yet. For more info about BlueZ see [http://www.bluez.org](http://www.bluez.org). diff --git a/build.gradle b/build.gradle index dc41220..32206e5 100644 --- a/build.gradle +++ b/build.gradle @@ -6,34 +6,24 @@ * user guide available at https://docs.gradle.org/4.5/userguide/java_library_plugin.html */ -buildscript { - version = '0.1' -} +// Apply the java plugin to add support for Java +apply plugin: 'java' +apply plugin: 'maven' + +project.version = '0.2' +project.group = 'it.tangodev' -plugins { - // Apply the java-library plugin to add support for Java Library - id 'java-library' +repositories { + mavenLocal() + mavenCentral() } +// In this section you declare the dependencies for your production and test code dependencies { - // This dependency is exported to consumers, that is to say found on their compile classpath. - //api 'org.apache.commons:commons-math3:3.6.1' - - // This dependency is used internally, and not exposed to consumers on their own compile classpath. - implementation name: 'unix' - implementation name: 'libmatthew-java-0.8' - implementation name: 'dbus-java-2.7' + // The production code uses the SLF4J logging API at compile time + compile 'org.slf4j:slf4j-api:1.7.21' - // Use JUnit test framework - testImplementation 'junit:junit:4.12' -} - -// In this section you declare where to find the dependencies of your project -repositories { - // Use jcenter for resolving your dependencies. - // You can declare any Maven/Ivy/file repository here. - jcenter() - flatDir { dirs 'libs' } + compile fileTree(dir: 'libs', include: ['*.jar']) } jar { @@ -42,3 +32,8 @@ jar { 'Implementation-Version': project.version) } } + +task (runExample, dependsOn: 'classes', type: JavaExec) { + main = 'example.ExampleMain' + classpath = sourceSets.test.runtimeClasspath +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index be280be..315aedd 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Sun Jan 28 10:16:02 EST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-all.zip diff --git a/src/main/java/it/tangodev/ble/BleApplication.java b/src/main/java/it/tangodev/ble/BleApplication.java index c287c97..3de44c1 100644 --- a/src/main/java/it/tangodev/ble/BleApplication.java +++ b/src/main/java/it/tangodev/ble/BleApplication.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Map; +import it.tangodev.utils.BleAdapter; import org.bluez.GattApplication1; import org.bluez.GattManager1; import org.bluez.LEAdvertisingManager1; @@ -33,10 +34,11 @@ public class BleApplication implements GattApplication1 { public static final String BLUEZ_ADAPTER_INTERFACE = "org.bluez.Adapter1"; public static final String BLUEZ_GATT_INTERFACE = "org.bluez.GattManager1"; public static final String BLUEZ_LE_ADV_INTERFACE = "org.bluez.LEAdvertisingManager1"; - + public static final String ADDRESS = "Address"; + private List servicesList = new ArrayList(); private String path = null; - private String adapterPath; + private BleAdapter bleAdapter; private BleService advService; private BleAdvertisement adv; private String adapterAlias; @@ -71,21 +73,23 @@ public BleApplication(String path, BleApplicationListener listener) { */ public void start() throws DBusException, InterruptedException { DBusConnection dbusConnection = DBusConnection.getConnection(DBusConnection.SYSTEM); - - adapterPath = findAdapterPath(); - if(adapterPath == null) { throw new RuntimeException("No BLE adapter found"); } - + + bleAdapter = findAdapterPath(); + if (bleAdapter == null) { + throw new RuntimeException("No BLE adapter found"); + } + this.export(dbusConnection); - - Properties adapterProperties = (Properties) dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, adapterPath, Properties.class); + + Properties adapterProperties = (Properties) dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, bleAdapter.getPath(), Properties.class); adapterProperties.Set(BLUEZ_ADAPTER_INTERFACE, "Powered", new Variant(true)); if(adapterAlias != null) { adapterProperties.Set(BLUEZ_ADAPTER_INTERFACE, "Alias", new Variant(adapterAlias)); } - - GattManager1 gattManager = (GattManager1) dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, adapterPath, GattManager1.class); - - LEAdvertisingManager1 advManager = (LEAdvertisingManager1) dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, adapterPath, LEAdvertisingManager1.class); + + GattManager1 gattManager = (GattManager1) dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, bleAdapter.getPath(), GattManager1.class); + + LEAdvertisingManager1 advManager = (LEAdvertisingManager1) dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, bleAdapter.getPath(), LEAdvertisingManager1.class); String advPath = path + "/advertisement"; adv = new BleAdvertisement(BleAdvertisement.ADVERTISEMENT_TYPE_PERIPHERAL, advPath); @@ -113,12 +117,16 @@ public void start() throws DBusException, InterruptedException { * @throws InterruptedException */ public void stop() throws DBusException, InterruptedException { - if(adapterPath == null) { return; } + if (bleAdapter == null) { + return; + } DBusConnection dbusConnection = DBusConnection.getConnection(DBusConnection.SYSTEM); - GattManager1 gattManager = (GattManager1) dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, adapterPath, GattManager1.class); - LEAdvertisingManager1 advManager = (LEAdvertisingManager1) dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, adapterPath, LEAdvertisingManager1.class); - - if(adv != null) { advManager.UnregisterAdvertisement(adv); } + GattManager1 gattManager = (GattManager1) dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, bleAdapter.getPath(), GattManager1.class); + LEAdvertisingManager1 advManager = (LEAdvertisingManager1) dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, bleAdapter.getPath(), LEAdvertisingManager1.class); + + if (adv != null) { + advManager.UnregisterAdvertisement(adv); + } gattManager.UnregisterApplication(this); dbusConnection.removeSigHandler(InterfacesAdded.class, interfacesAddedSignalHandler); @@ -136,12 +144,13 @@ protected void initInterfacesHandler() throws DBusException { @Override public void handle(InterfacesAdded signal) { Map iamap = signal.getInterfacesAdded().get(BLUEZ_DEVICE_INTERFACE); - if(iamap != null) { - Variant address = iamap.get("Address"); - System.out.println("Device address: " + address.getValue()); - System.out.println("Device added path: " + signal.getObjectPath().toString()); + if (iamap != null) { + Variant address = iamap.get(ADDRESS); + String path = signal.getObjectPath().toString(); hasDeviceConnected = true; - if(listener != null) { listener.deviceConnected(); } + if (listener != null) { + listener.deviceConnected(path, address.getValue()); + } } } }; @@ -151,10 +160,12 @@ public void handle(InterfacesAdded signal) { public void handle(InterfacesRemoved signal) { List irlist = signal.getInterfacesRemoved(); for (String ir : irlist) { - if(BLUEZ_DEVICE_INTERFACE.equals(ir)) { - System.out.println("Device Removed path: " + signal.getObjectPath().toString()); + if (BLUEZ_DEVICE_INTERFACE.equals(ir)) { + String path = signal.getObjectPath().toString(); hasDeviceConnected = false; - if(listener != null) { listener.deviceDisconnected(); } + if (listener != null) { + listener.deviceDisconnected(path); + } } } } @@ -191,27 +202,37 @@ public boolean hasDeviceConnected() { /** * Search for a Adapter that has GattManager1 and LEAdvertisement1 interfaces, otherwise return null. - * @return - * @throws DBusException + * @return BleAdapter based on the map stored in the D-Bus Managed object org.bluez.Adapter1 + * @throws DBusException if there is an error communicating with BlueZ over D-Bus */ - public static String findAdapterPath() throws DBusException { + public static BleAdapter findAdapterPath() throws DBusException { DBusConnection dbusConnection = DBusConnection.getConnection(DBusConnection.SYSTEM); - ObjectManager bluezObjectManager = (ObjectManager) dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, "/", ObjectManager.class); - if(bluezObjectManager == null) { return null; } - + ObjectManager bluezObjectManager = dbusConnection.getRemoteObject(BLUEZ_DBUS_BUSNAME, "/", ObjectManager.class); + if (bluezObjectManager == null) { + return null; + } + Map>> bluezManagedObject = bluezObjectManager.GetManagedObjects(); - if(bluezManagedObject == null) { return null; } - + if (bluezManagedObject == null) { + return null; + } + for (Path path : bluezManagedObject.keySet()) { Map> value = bluezManagedObject.get(path); boolean hasGattManager = false; boolean hasAdvManager = false; - - for(String key : value.keySet()) { - if(key.equals(BLUEZ_GATT_INTERFACE)) { hasGattManager = true; } - if(key.equals(BLUEZ_LE_ADV_INTERFACE)) { hasAdvManager = true; } - - if(hasGattManager && hasAdvManager) { return path.toString(); } + + for (Map.Entry> entry : value.entrySet()) { + if (entry.getKey().equals(BLUEZ_GATT_INTERFACE)) { + hasGattManager = true; + } + if (entry.getKey().equals(BLUEZ_LE_ADV_INTERFACE)) { + hasAdvManager = true; + } + if (hasGattManager && hasAdvManager) { + return new BleAdapter(path, value.get("org.bluez.Adapter1")); + } + } } @@ -231,13 +252,15 @@ private void export(DBusConnection dbusConnection) throws DBusException { } @Override - public boolean isRemote() { return false; } - + public boolean isRemote() { + return false; + } + @Override public Map>> GetManagedObjects() { System.out.println("Application -> GetManagedObjects"); - - Map>> response = new HashMap>>(); + + Map>> response = new HashMap>>(); for (BleService service : servicesList) { response.put(service.getPath(), service.getProperties()); for (BleCharacteristic characteristic : service.getCharacteristics()) { @@ -250,4 +273,8 @@ public Map>> GetManagedObjects() { return response; } -} + public BleAdapter getBleAdapter() { + return bleAdapter; + } + +} \ No newline at end of file diff --git a/src/main/java/it/tangodev/ble/BleApplicationListener.java b/src/main/java/it/tangodev/ble/BleApplicationListener.java index a3c1905..9916475 100644 --- a/src/main/java/it/tangodev/ble/BleApplicationListener.java +++ b/src/main/java/it/tangodev/ble/BleApplicationListener.java @@ -1,6 +1,6 @@ package it.tangodev.ble; public interface BleApplicationListener { - public void deviceConnected(); - public void deviceDisconnected(); + public void deviceConnected(String path, String address); + public void deviceDisconnected(String path); } diff --git a/src/main/java/it/tangodev/ble/BleCharacteristic.java b/src/main/java/it/tangodev/ble/BleCharacteristic.java index ef59362..1c976cb 100644 --- a/src/main/java/it/tangodev/ble/BleCharacteristic.java +++ b/src/main/java/it/tangodev/ble/BleCharacteristic.java @@ -137,11 +137,11 @@ public Map> getProperties() { /** * Call this method to send a notification to a central. */ - public void sendNotification() { + public void sendNotification(String devicePath) { try { DBusConnection dbusConnection = DBusConnection.getConnection(DBusConnection.SYSTEM); - Variant signalValueVariant = new Variant(listener.getValue()); + Variant signalValueVariant = new Variant(getValue(devicePath)); Map signalValue = new HashMap(); signalValue.put(BleCharacteristic.CHARACTERISTIC_VALUE_PROPERTY_KEY, signalValueVariant); @@ -164,12 +164,15 @@ public boolean isRemote() { public byte[] ReadValue(Map option) { System.out.println("Characteristic Read option[" + option + "]"); int offset = 0; - if(option.get("offset") != null) { + if(option.containsKey("offset")) { Variant voffset = option.get("offset"); offset = (voffset.getValue() != null) ? voffset.getValue().intValue() : offset; } - - byte[] valueBytes = listener.getValue(); + + String devicePath = null; + devicePath = stringVarientToString(option, devicePath); + + byte[] valueBytes = getValue(devicePath); byte[] slice = Arrays.copyOfRange(valueBytes, offset, valueBytes.length); return slice; } @@ -180,7 +183,31 @@ public byte[] ReadValue(Map option) { @Override public void WriteValue(byte[] value, Map option) { System.out.println("Characteristic Write option[" + option + "]"); - listener.setValue(value); + int offset = 0; + if(option.containsKey("offset")) { + Variant voffset = option.get("offset"); + offset = (voffset.getValue() != null) ? voffset.getValue().intValue() : offset; + } + + String devicePath = null; + setValue(stringVarientToString(option, devicePath), offset, value); + } + + protected String stringVarientToString(Map option, String devicePath) { + if (option.containsKey("device")) { + Variant pathVariant = null; + pathVariant = option.get("pathVariant"); + if (pathVariant != null) devicePath = pathVariant.getValue().getPath(); + } + return devicePath; + } + + protected byte[] getValue(String devicePath) { + return listener.getValue(devicePath); + } + + protected void setValue(String devicePath, int offset, byte[] value) { + listener.setValue(devicePath, offset, value); } @Override diff --git a/src/main/java/it/tangodev/ble/BleCharacteristicListener.java b/src/main/java/it/tangodev/ble/BleCharacteristicListener.java index 58746e8..62e44a4 100644 --- a/src/main/java/it/tangodev/ble/BleCharacteristicListener.java +++ b/src/main/java/it/tangodev/ble/BleCharacteristicListener.java @@ -6,6 +6,6 @@ * */ public interface BleCharacteristicListener { - public byte[] getValue(); - public void setValue(byte[] value); + public byte[] getValue(String devicePath); + public void setValue(String devicePath, int offset, byte[] value); } diff --git a/src/main/java/it/tangodev/utils/BleAdapter.java b/src/main/java/it/tangodev/utils/BleAdapter.java new file mode 100644 index 0000000..63fab81 --- /dev/null +++ b/src/main/java/it/tangodev/utils/BleAdapter.java @@ -0,0 +1,42 @@ +package it.tangodev.utils; + + +import org.freedesktop.dbus.Path; +import org.freedesktop.dbus.Variant; + +import java.util.Map; + +/** + * Consolidates the information about the local Bluetooth Adapter returned by BlueZ + * Provides Java-friendly getters for the BlueZ D-Bus mappings of Variant values + */ +public class BleAdapter { + private final Map fields; + private final Path path; + + /** + * Based on the map stored in the D-Bus Managed object org.bluez.Adapter1 + * @param path path to the Adapter in the D-Bus i.e. /org/bluez/hci0 + * @param value map of Adapter Properties storied as Variant types + */ + public BleAdapter(Path path, Map value) { + this.path = path; + this.fields = value; + } + + public String getPath() { + return path.toString(); + } + + public String getAddress() { + return fields.get("Address").toString(); + } + + public String getName() { + return fields.get("Name").toString(); + } + + public String getAlias() { + return fields.get("Alias").toString(); + } +} diff --git a/src/test/java/example/ExampleCharacteristic.java b/src/test/java/example/ExampleCharacteristic.java index ce5c520..97a68b1 100644 --- a/src/test/java/example/ExampleCharacteristic.java +++ b/src/test/java/example/ExampleCharacteristic.java @@ -26,7 +26,7 @@ public ExampleCharacteristic(BleService service) { this.listener = new BleCharacteristicListener() { @Override - public void setValue(byte[] value) { + public void setValue(String devicePath, int offset, byte[] value) { try { exampleValue = new String(value, "UTF8"); } catch(Exception e) { @@ -35,7 +35,7 @@ public void setValue(byte[] value) { } @Override - public byte[] getValue() { + public byte[] getValue(String devicePath) { try { return exampleValue.getBytes("UTF8"); } catch(Exception e) { diff --git a/src/test/java/example/ExampleMain.java b/src/test/java/example/ExampleMain.java index 49ccb57..60020f9 100644 --- a/src/test/java/example/ExampleMain.java +++ b/src/test/java/example/ExampleMain.java @@ -21,19 +21,19 @@ public class ExampleMain implements Runnable { public void notifyBle(String value) { this.valueString = value; - characteristic.sendNotification(); + characteristic.sendNotification(null); } public ExampleMain() throws DBusException, InterruptedException { BleApplicationListener appListener = new BleApplicationListener() { @Override - public void deviceDisconnected() { - System.out.println("Device disconnected"); + public void deviceDisconnected(String path) { + System.out.println("Device disconnected: " + path); } @Override - public void deviceConnected() { - System.out.println("Device connected"); + public void deviceConnected(String path, String address) { + System.out.println("Device connected: " + path + " ADDR: " + address); } }; app = new BleApplication("/tango", appListener); @@ -45,7 +45,7 @@ public void deviceConnected() { characteristic = new BleCharacteristic("/tango/s/c", service, flags, "13333333-3333-3333-3333-333333333002", new BleCharacteristicListener() { @Override - public void setValue(byte[] value) { + public void setValue(String devicePath, int offset, byte[] value) { try { valueString = new String(value, "UTF8"); } catch(Exception e) { @@ -54,7 +54,7 @@ public void setValue(byte[] value) { } @Override - public byte[] getValue() { + public byte[] getValue(String devicePath) { try { return valueString.getBytes("UTF8"); } catch(Exception e) { @@ -68,6 +68,7 @@ public byte[] getValue() { ExampleCharacteristic exampleCharacteristic = new ExampleCharacteristic(service); service.addCharacteristic(exampleCharacteristic); app.start(); + System.out.println("Lisenting on adapter " + app.getBleAdapter().getAddress() + " path: " + app.getBleAdapter().getPath()); } @Override From 1f38226b92d4893a78854c651db0e63ee93fda7c Mon Sep 17 00:00:00 2001 From: Geoff Matrangola Date: Mon, 29 Jan 2018 22:15:11 +0000 Subject: [PATCH 2/4] updated runExample runtime java path to find jni library --- build.gradle | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 32206e5..427a415 100644 --- a/build.gradle +++ b/build.gradle @@ -35,5 +35,6 @@ jar { task (runExample, dependsOn: 'classes', type: JavaExec) { main = 'example.ExampleMain' - classpath = sourceSets.test.runtimeClasspath -} \ No newline at end of file + systemProperty "java.library.path", "/usr/lib/jni" + classpath = sourceSets.test.runtimeClasspath +} From 83920de9e9ef050baac4160286e348c38248f61b Mon Sep 17 00:00:00 2001 From: Geoff Matrangola Date: Mon, 29 Jan 2018 17:18:34 -0500 Subject: [PATCH 3/4] Cleanup * Added some more informaiton to the README.md * created an example.conf to configure D-Bus properly --- README.md | 5 +++-- example.conf | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 example.conf diff --git a/README.md b/README.md index 29f9d22..606a95b 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,8 @@ # Dependencies 1. Java 8 or better 2. BlueZ 5.43 or better -3. d-bus Java library `libdbus-java` +3. libunixsocket-java (```apt-get install libsocket-java```) +4. d-bus Java library `libdbus-java` Raspbian install: ``` @@ -38,7 +39,7 @@ creates a BLE Application with one Service and 2 Characteristics. Before running the example, copy ```example.conf``` to ```/etc/dbus-1/system.d/``` -To run from command line: ````./gradlew runExample```` +To run from command line: ````sudo ./gradlew runExample```` Press ctrl-c to stop service. diff --git a/example.conf b/example.conf new file mode 100644 index 0000000..f77ace7 --- /dev/null +++ b/example.conf @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + From 5cc71d8d8a90befd088aa7a805a05215066594ba Mon Sep 17 00:00:00 2001 From: Geoff Matrangola Date: Tue, 30 Jan 2018 17:40:48 -0500 Subject: [PATCH 4/4] Changes based on code review * put java-library back * using implementation instead of compile to match latest version of gradle * fixed spelling error in method name. --- build.gradle | 6 +++--- src/main/java/it/tangodev/ble/BleCharacteristic.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 427a415..fb180b2 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ */ // Apply the java plugin to add support for Java -apply plugin: 'java' +apply plugin: 'java-library' apply plugin: 'maven' project.version = '0.2' @@ -21,9 +21,9 @@ repositories { // In this section you declare the dependencies for your production and test code dependencies { // The production code uses the SLF4J logging API at compile time - compile 'org.slf4j:slf4j-api:1.7.21' + implementation 'org.slf4j:slf4j-api:1.7.21' - compile fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(dir: 'libs', include: ['*.jar']) } jar { diff --git a/src/main/java/it/tangodev/ble/BleCharacteristic.java b/src/main/java/it/tangodev/ble/BleCharacteristic.java index 1c976cb..12676f0 100644 --- a/src/main/java/it/tangodev/ble/BleCharacteristic.java +++ b/src/main/java/it/tangodev/ble/BleCharacteristic.java @@ -170,7 +170,7 @@ public byte[] ReadValue(Map option) { } String devicePath = null; - devicePath = stringVarientToString(option, devicePath); + devicePath = stringVariantToString(option, devicePath); byte[] valueBytes = getValue(devicePath); byte[] slice = Arrays.copyOfRange(valueBytes, offset, valueBytes.length); @@ -190,10 +190,10 @@ public void WriteValue(byte[] value, Map option) { } String devicePath = null; - setValue(stringVarientToString(option, devicePath), offset, value); + setValue(stringVariantToString(option, devicePath), offset, value); } - protected String stringVarientToString(Map option, String devicePath) { + protected String stringVariantToString(Map option, String devicePath) { if (option.containsKey("device")) { Variant pathVariant = null; pathVariant = option.get("pathVariant");