diff --git a/.idea/gradle.xml b/.idea/gradle.xml index c99df1f6..e67a6ec3 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -8,7 +8,6 @@ - diff --git a/.idea/modules.xml b/.idea/modules.xml index bfd895e8..0a213726 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -4,7 +4,6 @@ - diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 0f416569..94a25f7f 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,8 +1,6 @@ - - - + \ No newline at end of file diff --git a/app/app.iml b/app/app.iml index 517941ff..8bfaffd1 100644 --- a/app/app.iml +++ b/app/app.iml @@ -71,11 +71,15 @@ - - - - + + + + + + + + @@ -94,19 +98,21 @@ + + + + - - + + - + + - - - - + + - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 5eb16d6f..d4d0c76b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "no.nordicsemi.android.nrftoolbox" minSdkVersion 18 targetSdkVersion 23 - versionCode 39 - versionName "1.16.0" + versionCode 40 + versionName "1.16.1" } buildTypes { release { @@ -21,9 +21,9 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.google.android.gms:play-services-wearable:7.8.0' - compile 'com.android.support:appcompat-v7:23.0.1' - compile 'com.android.support:design:23.0.1' + compile 'com.google.android.gms:play-services-wearable:8.3.0' + compile 'com.android.support:appcompat-v7:23.1.0' + compile 'com.android.support:design:23.1.0' compile 'no.nordicsemi.android.support.v18:scanner:0.1.1' compile 'no.nordicsemi.android:log:2.0.0' compile('org.simpleframework:simple-xml:2.7.1') { @@ -31,7 +31,15 @@ dependencies { exclude group: 'xpp3', module: 'xpp3' } compile files('libs/achartengine-1.1.0.jar') - compile project(':dfu') compile project(':common') wearApp project(':wear') + + // The DFU Library is imported automatically from jcenter. + compile 'no.nordicsemi.android:dfu:0.6' + // If you want to make some changes in the DFU Library, clone the https://github.com/NordicSemiconductor/Android-DFU-Library project into DFULibrary folder, + // add it as a module in Project Structure and uncomment the following line: + + // compile project(':dfu') + + // Also uncomment selected lines in settings.gradle } diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManager.java index 340aaf5a..47cf5dbc 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManager.java @@ -862,24 +862,6 @@ public abstract class BleManager { } } } - - /** - * Converts the connection state to String value - * @param state the connection state - * @return state as String - */ - private String stateToString(final int state) { - switch (state) { - case BluetoothProfile.STATE_CONNECTED: - return "CONNECTED"; - case BluetoothProfile.STATE_CONNECTING: - return "CONNECTING"; - case BluetoothProfile.STATE_DISCONNECTING: - return "DISCONNECTING"; - default: - return "DISCONNECTED"; - } - } } private static final int PAIRING_VARIANT_PIN = 0; @@ -890,7 +872,7 @@ public abstract class BleManager { private static final int PAIRING_VARIANT_DISPLAY_PIN = 5; private static final int PAIRING_VARIANT_OOB_CONSENT = 6; - private String pairingVariantToString(final int variant) { + protected String pairingVariantToString(final int variant) { switch (variant) { case PAIRING_VARIANT_PIN: return "PAIRING_VARIANT_PIN"; @@ -911,7 +893,7 @@ public abstract class BleManager { } } - private String bondStateToString(final int state) { + protected String bondStateToString(final int state) { switch (state) { case BluetoothDevice.BOND_NONE: return "BOND_NONE"; @@ -924,7 +906,7 @@ public abstract class BleManager { } } - private String getWriteType(final int type) { + protected String getWriteType(final int type) { switch (type) { case BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT: return "WRITE REQUEST"; @@ -936,4 +918,22 @@ public abstract class BleManager { return "UNKNOWN: " + type; } } + + /** + * Converts the connection state to String value + * @param state the connection state + * @return state as String + */ + protected String stateToString(final int state) { + switch (state) { + case BluetoothProfile.STATE_CONNECTED: + return "CONNECTED"; + case BluetoothProfile.STATE_CONNECTING: + return "CONNECTING"; + case BluetoothProfile.STATE_DISCONNECTING: + return "DISCONNECTING"; + default: + return "DISCONNECTED"; + } + } } diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityManager.java index 358607a4..23091887 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityManager.java @@ -39,6 +39,7 @@ import java.util.LinkedList; import java.util.Queue; import java.util.UUID; +import no.nordicsemi.android.error.GattError; import no.nordicsemi.android.log.Logger; import no.nordicsemi.android.nrftoolbox.profile.BleManager; import no.nordicsemi.android.nrftoolbox.parser.AlertLevelParser; @@ -102,7 +103,7 @@ public class ProximityManager extends BleManager { * This method must be called in UI thread. It works fine on Nexus devices but if called from other thread (f.e. from onServiceAdded in gatt server callback) it hangs the app. */ final BluetoothGattCharacteristic linklossAlertLevel = new BluetoothGattCharacteristic(ALERT_LEVEL_CHARACTERISTIC_UUID, BluetoothGattCharacteristic.PROPERTY_WRITE - | BluetoothGattCharacteristic.PROPERTY_READ, BluetoothGattCharacteristic.PERMISSION_WRITE); + | BluetoothGattCharacteristic.PROPERTY_READ, BluetoothGattCharacteristic.PERMISSION_WRITE | BluetoothGattCharacteristic.PERMISSION_READ); linklossAlertLevel.setValue(HIGH_ALERT); final BluetoothGattService linklossService = new BluetoothGattService(LINKLOSS_SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY); linklossService.addCharacteristic(linklossAlertLevel); @@ -122,7 +123,7 @@ public class ProximityManager extends BleManager { if (IMMEDIATE_ALERT_SERVICE_UUID.equals(service.getUuid())) addLinklossService(); else { - Logger.i(mLogSession, "[Proximity Server] Gatt server started"); + Logger.i(mLogSession, "[Server] Gatt server started"); ProximityManager.super.connect(mDeviceToConnect); mDeviceToConnect = null; } @@ -132,32 +133,56 @@ public class ProximityManager extends BleManager { @Override public void onConnectionStateChange(final BluetoothDevice device, final int status, final int newState) { - if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothGatt.STATE_CONNECTED) { - Logger.i(mLogSession, "[Server] Device with address " + device.getAddress() + " connected"); - } else { - if (newState == BluetoothGatt.STATE_DISCONNECTED) { - Logger.i(mLogSession, "[Server] Device disconnected"); + Logger.d(mLogSession, "[Server callback] Connection state changed with status: " + status + " and new state: " + stateToString(newState) + " (" + newState + ")"); + if (status == BluetoothGatt.GATT_SUCCESS) { + if (newState == BluetoothGatt.STATE_CONNECTED) { + Logger.i(mLogSession, "[Server] Device with address " + device.getAddress() + " connected"); } else { - Logger.e(mLogSession, "[Server] Connection state changed with error " + status); + Logger.i(mLogSession, "[Server] Device disconnected"); } + } else { + Logger.e(mLogSession, "[Server] Error " + status + " (0x" + Integer.toHexString(status) + "): " + GattError.parseConnectionError(status)); } } @Override public void onCharacteristicReadRequest(final BluetoothDevice device, final int requestId, final int offset, final BluetoothGattCharacteristic characteristic) { - Logger.i(mLogSession, "[Server] Read request for characteristic " + characteristic.getUuid() + " (requestId = " + requestId + ", offset = " + offset + ")"); - Logger.v(mLogSession, "[Server] Sending response: SUCCESS"); - Logger.d(mLogSession, "[Server] sendResponse(GATT_SUCCESS, " + ParserUtils.parse(characteristic.getValue()) + ")"); - mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, characteristic.getValue()); + Logger.d(mLogSession, "[Server callback] Read request for characteristic " + characteristic.getUuid() + " (requestId=" + requestId + ", offset=" + offset + ")"); + Logger.i(mLogSession, "[Server] READ request for characteristic " + characteristic.getUuid() + " received"); + + byte[] value = characteristic.getValue(); + if (value != null && offset > 0) { + byte[] offsetValue = new byte[value.length - offset]; + System.arraycopy(value, offset, offsetValue, 0, offsetValue.length); + value = offsetValue; + } + if (value != null) + Logger.d(mLogSession, "server.sendResponse(GATT_SUCCESS, value=" + ParserUtils.parse(value) + ")"); + else + Logger.d(mLogSession, "server.sendResponse(GATT_SUCCESS, value=null)"); + mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value); + Logger.v(mLogSession, "[Server] Response sent"); } @Override public void onCharacteristicWriteRequest(final BluetoothDevice device, final int requestId, final BluetoothGattCharacteristic characteristic, final boolean preparedWrite, final boolean responseNeeded, final int offset, final byte[] value) { - Logger.i(mLogSession, "[Server] Write request to characteristic " + characteristic.getUuid() + " (requestId = " + requestId + ", value = " + ParserUtils.parse(value) + ", offset = " + offset + ")"); - characteristic.setValue(value); + Logger.d(mLogSession, "[Server callback] Write request to characteristic " + characteristic.getUuid() + + " (requestId=" + requestId + ", prepareWrite=" + preparedWrite + ", responseNeeded=" + responseNeeded + ", offset=" + offset + ", value=" + ParserUtils.parse(value) + ")"); + final String writeType = !responseNeeded ? "WRITE NO RESPONSE" : "WRITE COMMAND"; + Logger.i(mLogSession, "[Server] " + writeType + " request for characteristic " + characteristic.getUuid() + " received, value: " + ParserUtils.parse(value)); - if (value != null && value.length == 1) { // small validation + if (offset == 0) { + characteristic.setValue(value); + } else { + final byte[] currentValue = characteristic.getValue(); + final byte[] newValue = new byte[currentValue.length + value.length]; + System.arraycopy(currentValue, 0, newValue, 0, currentValue.length); + System.arraycopy(value, 0, newValue, offset, value.length); + characteristic.setValue(newValue); + } + + if (!preparedWrite && value != null && value.length == 1) { // small validation if (value[0] != NO_ALERT[0]) { Logger.a(mLogSession, "[Server] Immediate alarm request received: " + AlertLevelParser.parse(characteristic)); mCallbacks.onAlarmTriggered(); @@ -166,39 +191,44 @@ public class ProximityManager extends BleManager { mCallbacks.onAlarmStopped(); } } - if (responseNeeded) { - Logger.v(mLogSession, "[Server] Sending response: SUCCESS"); - Logger.d(mLogSession, "[Server] sendResponse(GATT_SUCCESS)"); - mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, null); - } + + Logger.d(mLogSession, "server.sendResponse(GATT_SUCCESS, offset=" + offset + ", value=" + ParserUtils.parse(value) + ")"); + mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, null); + Logger.v(mLogSession, "[Server] Response sent"); } @Override public void onDescriptorReadRequest(final BluetoothDevice device, final int requestId, final int offset, final BluetoothGattDescriptor descriptor) { - Logger.i(mLogSession, "[Server] Write request to descriptor " + descriptor.getUuid() + " (requestId = " + requestId + ", offset = " + offset + ")"); + Logger.d(mLogSession, "[Server callback] Write request to descriptor " + descriptor.getUuid() + " (requestId=" + requestId + ", offset=" + offset + ")"); + Logger.i(mLogSession, "[Server] READ request for descriptor " + descriptor.getUuid() + " received"); // This method is not supported - Logger.v(mLogSession, "[Server] Sending response: REQUEST_NOT_SUPPORTED"); - Logger.d(mLogSession, "[Server] sendResponse(GATT_REQUEST_NOT_SUPPORTED)"); + Logger.w(mLogSession, "[Server] Operation not supported"); + Logger.d(mLogSession, "[Server] server.sendResponse(GATT_REQUEST_NOT_SUPPORTED)"); mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED, offset, null); + Logger.v(mLogSession, "[Server] Response sent"); } @Override public void onDescriptorWriteRequest(final BluetoothDevice device, final int requestId, final BluetoothGattDescriptor descriptor, final boolean preparedWrite, final boolean responseNeeded, final int offset, final byte[] value) { - Logger.i(mLogSession, "[Server] Write request to descriptor " + descriptor.getUuid() + " (requestId = " + requestId + ", value = " + ParserUtils.parse(value) + ", offset = " + offset + ")"); + Logger.d(mLogSession, "[Server callback] Write request to descriptor " + descriptor.getUuid() + + " (requestId=" + requestId + ", prepareWrite=" + preparedWrite + ", responseNeeded=" + responseNeeded + ", offset=" + offset + ", value=" + ParserUtils.parse(value) + ")"); + Logger.i(mLogSession, "[Server] READ request for descriptor " + descriptor.getUuid() + " received"); // This method is not supported - Logger.v(mLogSession, "[Server] Sending response: REQUEST_NOT_SUPPORTED"); - Logger.d(mLogSession, "[Server] sendResponse(GATT_REQUEST_NOT_SUPPORTED)"); + Logger.w(mLogSession, "[Server] Operation not supported"); + Logger.d(mLogSession, "[Server] server.sendResponse(GATT_REQUEST_NOT_SUPPORTED)"); mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED, offset, null); + Logger.v(mLogSession, "[Server] Response sent"); } @Override public void onExecuteWrite(final BluetoothDevice device, final int requestId, final boolean execute) { - Logger.i(mLogSession, "[Server] Execute write request (requestId = " + requestId + ")"); + Logger.d(mLogSession, "[Server callback] Execute write request (requestId=" + requestId + ", execute=" + execute + ")"); // This method is not supported - Logger.v(mLogSession, "[Server] Sending response: REQUEST_NOT_SUPPORTED"); - Logger.d(mLogSession, "[Server] sendResponse(GATT_REQUEST_NOT_SUPPORTED)"); + Logger.w(mLogSession, "[Server] Operation not supported"); + Logger.d(mLogSession, "[Server] server.sendResponse(GATT_REQUEST_NOT_SUPPORTED)"); mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED, 0, null); + Logger.v(mLogSession, "[Server] Response sent"); } }; diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 8f8df29d..00000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..e0dc75c6 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/build.gradle b/build.gradle index 1b7886d1..c6371d6c 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.3.0' + classpath 'com.android.tools.build:gradle:1.3.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/common/build.gradle b/common/build.gradle index 514483db..4a626da5 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -42,5 +42,5 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:support-v4:23.0.1' + compile 'com.android.support:support-v4:23.1.0' } diff --git a/common/common.iml b/common/common.iml index 353bc47d..ac05559d 100644 --- a/common/common.iml +++ b/common/common.iml @@ -89,7 +89,7 @@ - - + + \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f8298685..f64777bd 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Sep 15 10:34:57 CEST 2015 +#Mon Nov 02 11:30:44 CET 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-all.zip diff --git a/settings.gradle b/settings.gradle index 3c5b78f1..af2c9907 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,5 @@ include ':app', ':wear', ':common' -include ':dfu' -project(':dfu').projectDir = file('../DFULibrary/dfu') +// Uncomment these lines if you want to import the DFULibrary as a project, not from jcenter +// include ':dfu' +// project(':dfu').projectDir = file('../DFULibrary/dfu') \ No newline at end of file diff --git a/wear/build.gradle b/wear/build.gradle index 21286ff0..be142af2 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -9,8 +9,8 @@ android { applicationId "no.nordicsemi.android.nrftoolbox" minSdkVersion 20 targetSdkVersion 23 - versionCode 39 - versionName "1.16.0" + versionCode 40 + versionName "1.16.1" } buildTypes { release { @@ -23,7 +23,7 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.google.android.support:wearable:1.3.0' - compile 'com.google.android.gms:play-services-wearable:7.8.0' + compile 'com.google.android.gms:play-services-wearable:8.3.0' compile 'no.nordicsemi.android.support.v18:scanner:0.1.1' compile project(':common') } diff --git a/wear/wear.iml b/wear/wear.iml index d2ec81be..10964c23 100644 --- a/wear/wear.iml +++ b/wear/wear.iml @@ -90,13 +90,14 @@ - + + + - + - + - \ No newline at end of file