From 15c82a8c56d07bdcb1165c5f8d62ad8bbd48cb30 Mon Sep 17 00:00:00 2001 From: Aleksander Nowakowski Date: Mon, 18 Jun 2018 17:28:23 +0200 Subject: [PATCH] Major refactoring: enqueue() method added to Request. --- .../nrftoolbox/battery/BatteryManager.java | 12 +- .../android/nrftoolbox/bpm/BPMManager.java | 7 +- .../android/nrftoolbox/cgms/CGMSManager.java | 107 +++++++++++------- .../android/nrftoolbox/csc/CSCManager.java | 14 ++- .../nrftoolbox/gls/GlucoseManager.java | 36 +++--- .../android/nrftoolbox/hrs/HRSManager.java | 5 +- .../android/nrftoolbox/hts/HTSManager.java | 4 +- ...ossFragment.java => LinkLossFragment.java} | 6 +- .../proximity/ProximityActivity.java | 15 +-- .../proximity/ProximityManager.java | 20 ++-- .../android/nrftoolbox/rsc/RSCManager.java | 6 +- .../nrftoolbox/template/TemplateManager.java | 78 +++++++------ .../android/nrftoolbox/uart/UARTManager.java | 84 ++++---------- 13 files changed, 206 insertions(+), 188 deletions(-) rename app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/{LinklossFragment.java => LinkLossFragment.java} (93%) diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/battery/BatteryManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/battery/BatteryManager.java index b14782d7..8c702513 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/battery/BatteryManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/battery/BatteryManager.java @@ -17,7 +17,8 @@ import no.nordicsemi.android.log.LogContract; /** * The Ble Manager with Battery Service support. - * @param The profile callbacks type + * + * @param The profile callbacks type. * @see BleManager */ @SuppressWarnings("WeakerAccess") @@ -62,7 +63,8 @@ public abstract class BatteryManager extends if (isConnected()) { readCharacteristic(mBatteryLevelCharacteristic) .with(mBatteryLevelDataCallback) - .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Battery Level characteristic not found")); + .fail((device, status) -> log(LogContract.Log.Level.WARNING,"Battery Level characteristic not found")) + .enqueue(); } } @@ -73,7 +75,8 @@ public abstract class BatteryManager extends .with(mBatteryLevelDataCallback); enableNotifications(mBatteryLevelCharacteristic) .done(device -> log(LogContract.Log.Level.INFO, "Battery Level notifications enabled")) - .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Battery Level characteristic not found")); + .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Battery Level characteristic not found")) + .enqueue(); } } @@ -83,7 +86,8 @@ public abstract class BatteryManager extends public void disableBatteryLevelCharacteristicNotifications() { if (isConnected()) { disableNotifications(mBatteryLevelCharacteristic) - .done(device -> log(LogContract.Log.Level.INFO, "Battery Level notifications disabled")); + .done(device -> log(LogContract.Log.Level.INFO, "Battery Level notifications disabled")) + .enqueue(); } } diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/bpm/BPMManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/bpm/BPMManager.java index 0839a5d3..5c078ea8 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/bpm/BPMManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/bpm/BPMManager.java @@ -121,7 +121,8 @@ public class BPMManager extends BatteryManager { final int unit, @Nullable final Float pulseRate, @Nullable final Integer userID, @Nullable final BPMStatus status, @Nullable final Calendar calendar) { - mCallbacks.onBloodPressureMeasurementReceived(device, systolic, diastolic, meanArterialPressure, unit, pulseRate, userID, status, calendar); + mCallbacks.onBloodPressureMeasurementReceived(device, systolic, diastolic, + meanArterialPressure, unit, pulseRate, userID, status, calendar); } @Override @@ -130,8 +131,8 @@ public class BPMManager extends BatteryManager { } }); - enableNotifications(mICPCharacteristic); - enableIndications(mBPMCharacteristic); + enableNotifications(mICPCharacteristic).enqueue(); + enableIndications(mBPMCharacteristic).enqueue(); } @Override diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/cgms/CGMSManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/cgms/CGMSManager.java index bad072f8..23c318b8 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/cgms/CGMSManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/cgms/CGMSManager.java @@ -48,19 +48,13 @@ import no.nordicsemi.android.nrftoolbox.parser.CGMSpecificOpsControlPointParser; import no.nordicsemi.android.nrftoolbox.parser.RecordAccessControlPointParser; public class CGMSManager extends BatteryManager { - private static final String TAG = "CGMSManager"; - - /** - * Cycling Speed and Cadence service UUID - */ + /** Cycling Speed and Cadence service UUID. */ public static final UUID CGMS_UUID = UUID.fromString("0000181F-0000-1000-8000-00805f9b34fb"); private static final UUID CGM_STATUS_UUID = UUID.fromString("00002AA9-0000-1000-8000-00805f9b34fb"); - private static final UUID CGM_FEAURE_UUID = UUID.fromString("00002AA8-0000-1000-8000-00805f9b34fb"); + private static final UUID CGM_FEATURE_UUID = UUID.fromString("00002AA8-0000-1000-8000-00805f9b34fb"); private static final UUID CGM_MEASUREMENT_UUID = UUID.fromString("00002AA7-0000-1000-8000-00805f9b34fb"); private static final UUID CGM_OPS_CONTROL_POINT_UUID = UUID.fromString("00002AAC-0000-1000-8000-00805f9b34fb"); - /** - * Record Access Control Point characteristic UUID - */ + /** Record Access Control Point characteristic UUID. */ private static final UUID RACP_UUID = UUID.fromString("00002A52-0000-1000-8000-00805f9b34fb"); private BluetoothGattCharacteristic mCGMStatusCharacteristic; @@ -111,7 +105,9 @@ public class CGMSManager extends BatteryManager { mSecured = features.e2eCrcSupported; log(LogContract.Log.Level.APPLICATION, "E2E CRC feature " + (mSecured ? "supported" : "not supported")); } - }).fail((device, status) -> log(LogContract.Log.Level.WARNING, "Could not read CGM Feature characteristic")); + }) + .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Could not read CGM Feature characteristic")) + .enqueue(); // Check if the session is already started. This is not supported in the experimental CGMS from the SDK. readCharacteristic(mCGMStatusCharacteristic) @@ -123,7 +119,9 @@ public class CGMSManager extends BatteryManager { log(LogContract.Log.Level.APPLICATION, "Session already started"); } } - }).fail((device, status) -> log(LogContract.Log.Level.WARNING, "Could not read CGM Status characteristic")); + }) + .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Could not read CGM Status characteristic")) + .enqueue(); // Set notification and indication callbacks setNotificationCallback(mCGMMeasurementCharacteristic) @@ -135,7 +133,13 @@ public class CGMSManager extends BatteryManager { } @Override - public void onContinuousGlucoseMeasurementReceived(@NonNull final BluetoothDevice device, final float glucoseConcentration, @Nullable final Float cgmTrend, @Nullable final Float cgmQuality, final CGMStatus status, final int timeOffset, final boolean secured) { + public void onContinuousGlucoseMeasurementReceived(@NonNull final BluetoothDevice device, + final float glucoseConcentration, + @Nullable final Float cgmTrend, + @Nullable final Float cgmQuality, + final CGMStatus status, + final int timeOffset, + final boolean secured) { // If the CGM Status characteristic has not been read and the session was already started before, // estimate the Session Start Time by subtracting timeOffset minutes from the current timestamp. if (mSessionStartTime == 0 && !mRecordAccessRequestInProgress) { @@ -151,7 +155,8 @@ public class CGMSManager extends BatteryManager { } @Override - public void onContinuousGlucoseMeasurementReceivedWithCrcError(@NonNull final BluetoothDevice device, @NonNull final Data data) { + public void onContinuousGlucoseMeasurementReceivedWithCrcError(@NonNull final BluetoothDevice device, + @NonNull final Data data) { log(LogContract.Log.Level.WARNING, "Continuous Glucose Measurement record received with CRC error"); } }); @@ -165,7 +170,8 @@ public class CGMSManager extends BatteryManager { } @Override - public void onCGMSpecificOpsOperationCompleted(@NonNull final BluetoothDevice device, final int requestCode, final boolean secured) { + public void onCGMSpecificOpsOperationCompleted(@NonNull final BluetoothDevice device, + final int requestCode, final boolean secured) { switch (requestCode) { case CGM_OP_CODE_START_SESSION: mSessionStartTime = System.currentTimeMillis(); @@ -176,14 +182,19 @@ public class CGMSManager extends BatteryManager { } } - @Override - public void onCGMSpecificOpsOperationError(@NonNull final BluetoothDevice device, final int requestCode, final int errorCode, final boolean secured) { + @SuppressWarnings("StatementWithEmptyBody") + @Override + public void onCGMSpecificOpsOperationError(@NonNull final BluetoothDevice device, + final int requestCode, final int errorCode, + final boolean secured) { switch (requestCode) { case CGM_OP_CODE_START_SESSION: if (errorCode == CGM_ERROR_PROCEDURE_NOT_COMPLETED) { // Session was already started before. - // Looks like the CGM Status characteristic has not been read, otherwise we would have got the Session Start Time before. - // The Session Start Time will be calculated when a next CGM packet is received based on it's Time Offset. + // Looks like the CGM Status characteristic has not been read, + // otherwise we would have got the Session Start Time before. + // The Session Start Time will be calculated when a next CGM + // packet is received based on it's Time Offset. } case CGM_OP_CODE_STOP_SESSION: mSessionStartTime = 0; @@ -192,7 +203,8 @@ public class CGMSManager extends BatteryManager { } @Override - public void onCGMSpecificOpsResponseReceivedWithCrcError(@NonNull final BluetoothDevice device, @NonNull final Data data) { + public void onCGMSpecificOpsResponseReceivedWithCrcError(@NonNull final BluetoothDevice device, + @NonNull final Data data) { log(LogContract.Log.Level.ERROR, "Request failed: CRC error"); } }); @@ -219,7 +231,8 @@ public class CGMSManager extends BatteryManager { } @Override - public void onRecordAccessOperationCompletedWithNoRecordsFound(@NonNull final BluetoothDevice device, final int requestCode) { + public void onRecordAccessOperationCompletedWithNoRecordsFound(@NonNull final BluetoothDevice device, + final int requestCode) { mRecordAccessRequestInProgress = false; mCallbacks.onOperationCompleted(device); } @@ -230,9 +243,11 @@ public class CGMSManager extends BatteryManager { if (numberOfRecords > 0) { if (mRecords.size() > 0) { final int sequenceNumber = mRecords.keyAt(mRecords.size() - 1) + 1; - writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportStoredRecordsGreaterThenOrEqualTo(sequenceNumber)); + writeCharacteristic(mRecordAccessControlPointCharacteristic, + RecordAccessControlPointData.reportStoredRecordsGreaterThenOrEqualTo(sequenceNumber)); } else { - writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportAllStoredRecords()); + writeCharacteristic(mRecordAccessControlPointCharacteristic, + RecordAccessControlPointData.reportAllStoredRecords()); } } else { mRecordAccessRequestInProgress = false; @@ -241,7 +256,8 @@ public class CGMSManager extends BatteryManager { } @Override - public void onRecordAccessOperationError(@NonNull final BluetoothDevice device, final int requestCode, final int errorCode) { + public void onRecordAccessOperationError(@NonNull final BluetoothDevice device, + final int requestCode, final int errorCode) { log(LogContract.Log.Level.WARNING, "Record Access operation failed (error " + errorCode + ")"); if (errorCode == RACP_ERROR_OP_CODE_NOT_SUPPORTED) { mCallbacks.onOperationNotSupported(device); @@ -253,17 +269,21 @@ public class CGMSManager extends BatteryManager { // Enable notifications and indications enableNotifications(mCGMMeasurementCharacteristic) - .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to enable Continuous Glucose Measurement notifications (" + status + ")")); + .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to enable Continuous Glucose Measurement notifications (" + status + ")")) + .enqueue(); enableIndications(mCGMSpecificOpsControlPointCharacteristic) - .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to enable CGM Specific Ops Control Point indications notifications (" + status + ")")); + .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to enable CGM Specific Ops Control Point indications notifications (" + status + ")")) + .enqueue(); enableIndications(mRecordAccessControlPointCharacteristic) - .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to enabled Record Access Control Point indications (error " + status + ")")); + .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to enabled Record Access Control Point indications (error " + status + ")")) + .enqueue(); // Start Continuous Glucose session if hasn't been started before if (mSessionStartTime == 0L) { writeCharacteristic(mCGMSpecificOpsControlPointCharacteristic, CGMSpecificOpsControlPointData.startSession(mSecured)) .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + CGMSpecificOpsControlPointParser.parse(data) + "\" sent")) - .fail((device, status) -> log(LogContract.Log.Level.ERROR, "Failed to start session (error " + status + ")")); + .fail((device, status) -> log(LogContract.Log.Level.ERROR, "Failed to start session (error " + status + ")")) + .enqueue(); } } @@ -272,12 +292,14 @@ public class CGMSManager extends BatteryManager { final BluetoothGattService service = gatt.getService(CGMS_UUID); if (service != null) { mCGMStatusCharacteristic = service.getCharacteristic(CGM_STATUS_UUID); - mCGMFeatureCharacteristic = service.getCharacteristic(CGM_FEAURE_UUID); + mCGMFeatureCharacteristic = service.getCharacteristic(CGM_FEATURE_UUID); mCGMMeasurementCharacteristic = service.getCharacteristic(CGM_MEASUREMENT_UUID); mCGMSpecificOpsControlPointCharacteristic = service.getCharacteristic(CGM_OPS_CONTROL_POINT_UUID); mRecordAccessControlPointCharacteristic = service.getCharacteristic(RACP_UUID); } - return mCGMMeasurementCharacteristic != null && mCGMSpecificOpsControlPointCharacteristic != null && mRecordAccessControlPointCharacteristic != null; + return mCGMMeasurementCharacteristic != null + && mCGMSpecificOpsControlPointCharacteristic != null + && mRecordAccessControlPointCharacteristic != null; } @Override @@ -307,8 +329,9 @@ public class CGMSManager extends BatteryManager { } /** - * Sends the request to obtain the last (most recent) record from glucose device. The data will be returned to Glucose Measurement characteristic as a notification followed by Record Access - * Control Point indication with status code Success or other in case of error. + * Sends the request to obtain the last (most recent) record from glucose device. + * The data will be returned to Glucose Measurement characteristic as a notification followed by + * Record Access Control Point indication with status code Success or other in case of error. */ public void getLastRecord() { if (mRecordAccessControlPointCharacteristic == null) @@ -318,13 +341,14 @@ public class CGMSManager extends BatteryManager { mCallbacks.onOperationStarted(getBluetoothDevice()); mRecordAccessRequestInProgress = true; writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportLastStoredRecord()) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); } /** * Sends the request to obtain the first (oldest) record from glucose device. - * The data will be returned to Glucose Measurement characteristic as a notification followed by Record Access Control - * Point indication with status code Success or other in case of error. + * The data will be returned to Glucose Measurement characteristic as a notification followed by + * Record Access Control Point indication with status code Success or other in case of error. */ public void getFirstRecord() { if (mRecordAccessControlPointCharacteristic == null) @@ -334,7 +358,8 @@ public class CGMSManager extends BatteryManager { mCallbacks.onOperationStarted(getBluetoothDevice()); mRecordAccessRequestInProgress = true; writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportFirstStoredRecord()) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); } /** @@ -345,7 +370,8 @@ public class CGMSManager extends BatteryManager { return; writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.abortOperation()) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); } /** @@ -362,7 +388,8 @@ public class CGMSManager extends BatteryManager { mCallbacks.onOperationStarted(getBluetoothDevice()); mRecordAccessRequestInProgress = true; writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportNumberOfAllStoredRecords()) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); } /** @@ -384,7 +411,8 @@ public class CGMSManager extends BatteryManager { final int sequenceNumber = mRecords.keyAt(mRecords.size() - 1) + 1; mRecordAccessRequestInProgress = true; writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportStoredRecordsGreaterThenOrEqualTo(sequenceNumber)) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); // Info: // Operators OPERATOR_GREATER_THEN_OR_EQUAL, OPERATOR_LESS_THEN_OR_EQUAL and OPERATOR_RANGE are not supported by the CGMS sample from SDK // The "Operation not supported" response will be received @@ -403,7 +431,8 @@ public class CGMSManager extends BatteryManager { clear(); mCallbacks.onOperationStarted(getBluetoothDevice()); writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.deleteAllStoredRecords()) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); } } diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCManager.java index c5397fe8..46be0af5 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCManager.java @@ -82,25 +82,29 @@ public class CSCManager extends BatteryManager { @Override public float getWheelCircumference() { - return Integer.parseInt(preferences.getString(SettingsFragment.SETTINGS_WHEEL_SIZE, String.valueOf(SettingsFragment.SETTINGS_WHEEL_SIZE_DEFAULT))); + return Integer.parseInt(preferences.getString(SettingsFragment.SETTINGS_WHEEL_SIZE, + String.valueOf(SettingsFragment.SETTINGS_WHEEL_SIZE_DEFAULT))); } @Override - public void onDistanceChanged(@NonNull final BluetoothDevice device, final float totalDistance, final float distance, final float speed) { + public void onDistanceChanged(@NonNull final BluetoothDevice device, + final float totalDistance, final float distance, final float speed) { mCallbacks.onDistanceChanged(device, totalDistance, distance, speed); } @Override - public void onCrankDataChanged(@NonNull final BluetoothDevice device, final float crankCadence, final float gearRatio) { + public void onCrankDataChanged(@NonNull final BluetoothDevice device, + final float crankCadence, final float gearRatio) { mCallbacks.onCrankDataChanged(device, crankCadence, gearRatio); } @Override - public void onInvalidDataReceived(@NonNull final BluetoothDevice device, final @NonNull Data data) { + public void onInvalidDataReceived(@NonNull final BluetoothDevice device, + final @NonNull Data data) { log(LogContract.Log.Level.WARNING, "Invalid CSC Measurement data received: " + data); } }); - enableNotifications(mCSCMeasurementCharacteristic); + enableNotifications(mCSCMeasurementCharacteristic).enqueue(); } @Override diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java index e7649edb..896cc319 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java @@ -222,9 +222,11 @@ public class GlucoseManager extends BatteryManager { if (numberOfRecords > 0) { if (mRecords.size() > 0) { final int sequenceNumber = mRecords.keyAt(mRecords.size() - 1) + 1; - writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportStoredRecordsGreaterThenOrEqualTo(sequenceNumber)); + writeCharacteristic(mRecordAccessControlPointCharacteristic, + RecordAccessControlPointData.reportStoredRecordsGreaterThenOrEqualTo(sequenceNumber)); } else { - writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportAllStoredRecords()); + writeCharacteristic(mRecordAccessControlPointCharacteristic, + RecordAccessControlPointData.reportAllStoredRecords()); } } else { mCallbacks.onOperationCompleted(device); @@ -232,7 +234,8 @@ public class GlucoseManager extends BatteryManager { } @Override - public void onRecordAccessOperationError(@NonNull final BluetoothDevice device, final int requestCode, final int errorCode) { + public void onRecordAccessOperationError(@NonNull final BluetoothDevice device, + final int requestCode, final int errorCode) { log(LogContract.Log.Level.WARNING, "Record Access operation failed (error " + errorCode + ")"); if (errorCode == RACP_ERROR_OP_CODE_NOT_SUPPORTED) { mCallbacks.onOperationNotSupported(device); @@ -242,10 +245,11 @@ public class GlucoseManager extends BatteryManager { } }); - enableNotifications(mGlucoseMeasurementCharacteristic); - enableNotifications(mGlucoseMeasurementContextCharacteristic); + enableNotifications(mGlucoseMeasurementCharacteristic).enqueue(); + enableNotifications(mGlucoseMeasurementContextCharacteristic).enqueue(); enableIndications(mRecordAccessControlPointCharacteristic) - .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to enabled Record Access Control Point indications (error " + status + ")")); + .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to enabled Record Access Control Point indications (error " + status + ")")) + .enqueue(); } @Override @@ -302,7 +306,8 @@ public class GlucoseManager extends BatteryManager { clear(); mCallbacks.onOperationStarted(getBluetoothDevice()); writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportLastStoredRecord()) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); } /** @@ -317,7 +322,8 @@ public class GlucoseManager extends BatteryManager { clear(); mCallbacks.onOperationStarted(getBluetoothDevice()); writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportFirstStoredRecord()) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); } /** @@ -333,7 +339,8 @@ public class GlucoseManager extends BatteryManager { clear(); mCallbacks.onOperationStarted(getBluetoothDevice()); writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportNumberOfAllStoredRecords()) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); } /** @@ -360,7 +367,8 @@ public class GlucoseManager extends BatteryManager { writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.reportStoredRecordsGreaterThenOrEqualTo(sequenceNumber)) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); // Info: // Operators OPERATOR_LESS_THEN_OR_EQUAL and OPERATOR_RANGE are not supported by Nordic Semiconductor Glucose Service in SDK 4.4.2. } @@ -374,14 +382,13 @@ public class GlucoseManager extends BatteryManager { return; writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.abortOperation()) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); } /** * Sends the request to delete all data from the device. A Record Access Control Point indication * with status code Success (or other in case of error) will be send. - * - * FIXME This method is not supported by Nordic Semiconductor Glucose Service in SDK 4.4.2. */ public void deleteAllRecords() { if (mRecordAccessControlPointCharacteristic == null) @@ -390,6 +397,7 @@ public class GlucoseManager extends BatteryManager { clear(); mCallbacks.onOperationStarted(getBluetoothDevice()); writeCharacteristic(mRecordAccessControlPointCharacteristic, RecordAccessControlPointData.deleteAllStoredRecords()) - .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")); + .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + RecordAccessControlPointParser.parse(data) + "\" sent")) + .enqueue(); } } diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hrs/HRSManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hrs/HRSManager.java index c9352217..29e70943 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hrs/HRSManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hrs/HRSManager.java @@ -97,7 +97,8 @@ public class HRSManager extends BatteryManager { mCallbacks.onBodySensorLocationReceived(device, sensorLocation); } }) - .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Body Sensor Location characteristic not found")); + .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Body Sensor Location characteristic not found")) + .enqueue(); setNotificationCallback(mHeartRateCharacteristic) .with(new HeartRateMeasurementDataCallback() { @Override @@ -115,7 +116,7 @@ public class HRSManager extends BatteryManager { mCallbacks.onHeartRateMeasurementReceived(device, heartRate, contactDetected, energyExpanded, rrIntervals); } }); - enableNotifications(mHeartRateCharacteristic); + enableNotifications(mHeartRateCharacteristic).enqueue(); } @Override diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSManager.java index 0f40a867..6a545191 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSManager.java @@ -45,8 +45,6 @@ import no.nordicsemi.android.nrftoolbox.parser.TemperatureMeasurementParser; * HTSActivity implements HTSManagerCallbacks in order to receive callbacks of BluetoothGatt operations. */ public class HTSManager extends BatteryManager { - private static final String TAG = "HTSManager"; - /** Health Thermometer service UUID */ public final static UUID HT_SERVICE_UUID = UUID.fromString("00001809-0000-1000-8000-00805f9b34fb"); /** Health Thermometer Measurement characteristic UUID */ @@ -87,7 +85,7 @@ public class HTSManager extends BatteryManager { mCallbacks.onTemperatureMeasurementReceived(device, temperature, unit, calendar, type); } }); - enableIndications(mHTCharacteristic); + enableIndications(mHTCharacteristic).enqueue(); } @Override diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/LinklossFragment.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/LinkLossFragment.java similarity index 93% rename from app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/LinklossFragment.java rename to app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/LinkLossFragment.java index 15d4f333..79d62949 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/LinklossFragment.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/LinkLossFragment.java @@ -29,13 +29,13 @@ import android.support.v7.app.AlertDialog; import no.nordicsemi.android.nrftoolbox.R; -public class LinklossFragment extends DialogFragment { +public class LinkLossFragment extends DialogFragment { private static final String ARG_NAME = "name"; private String mName; - public static LinklossFragment getInstance(String name) { - final LinklossFragment fragment = new LinklossFragment(); + public static LinkLossFragment getInstance(String name) { + final LinkLossFragment fragment = new LinkLossFragment(); final Bundle args = new Bundle(); args.putString(ARG_NAME, name); diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityActivity.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityActivity.java index 695d064d..ef3b9e48 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityActivity.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityActivity.java @@ -40,12 +40,6 @@ import no.nordicsemi.android.nrftoolbox.profile.multiconnect.BleMulticonnectProf import no.nordicsemi.android.nrftoolbox.widget.DividerItemDecoration; public class ProximityActivity extends BleMulticonnectProfileServiceReadyActivity { - private static final String TAG = "ProximityActivity"; - - // This is not used any more. Server is created always after the service is started or - // after Bluetooth adapter is enabled. - // public static final String PREFS_GATT_SERVER_ENABLED = "prefs_gatt_server_enabled"; - private RecyclerView mDevicesView; private DeviceAdapter mAdapter; @@ -99,7 +93,7 @@ public class ProximityActivity extends BleMulticonnectProfileServiceReadyActivit @Override protected UUID getFilterUUID() { - return ProximityManager.LINKLOSS_SERVICE_UUID; + return ProximityManager.LINK_LOSS_SERVICE_UUID; } @Override @@ -146,18 +140,19 @@ public class ProximityActivity extends BleMulticonnectProfileServiceReadyActivit // The link loss may also be called when Bluetooth adapter was disabled if (BluetoothAdapter.getDefaultAdapter().isEnabled()) - showLinklossDialog(device.getName()); + showLinkLossDialog(device.getName()); } + @SuppressWarnings("unused") private void onBatteryLevelChanged(final BluetoothDevice device, final int batteryLevel) { if (mAdapter != null) mAdapter.onBatteryValueReceived(device); // Value will be obtained from the service } - private void showLinklossDialog(final String name) { + private void showLinkLossDialog(final String name) { try { - final LinklossFragment dialog = LinklossFragment.getInstance(name); + final LinkLossFragment dialog = LinkLossFragment.getInstance(name); dialog.show(getSupportFragmentManager(), "scan_fragment"); } catch (final Exception e) { // the activity must have been destroyed 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 28f979af..1489b061 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 @@ -36,13 +36,11 @@ import no.nordicsemi.android.nrftoolbox.parser.AlertLevelParser; @SuppressWarnings("WeakerAccess") class ProximityManager extends BatteryManager { - private final String TAG = "ProximityManager"; - - /** Link Loss service UUID */ - final static UUID LINKLOSS_SERVICE_UUID = UUID.fromString("00001803-0000-1000-8000-00805f9b34fb"); - /** Immediate Alert service UUID */ + /** Link Loss service UUID. */ + final static UUID LINK_LOSS_SERVICE_UUID = UUID.fromString("00001803-0000-1000-8000-00805f9b34fb"); + /** Immediate Alert service UUID. */ private final static UUID IMMEDIATE_ALERT_SERVICE_UUID = UUID.fromString("00001802-0000-1000-8000-00805f9b34fb"); - /** Alert Level characteristic UUID */ + /** Alert Level characteristic UUID. */ private static final UUID ALERT_LEVEL_CHARACTERISTIC_UUID = UUID.fromString("00002A06-0000-1000-8000-00805f9b34fb"); private BluetoothGattCharacteristic mAlertLevelCharacteristic, mLinkLossCharacteristic; @@ -71,12 +69,13 @@ class ProximityManager extends BatteryManager { @Override protected void initialize() { super.initialize(); - writeCharacteristic(mLinkLossCharacteristic, AlertLevelData.highAlert()); + writeCharacteristic(mLinkLossCharacteristic, AlertLevelData.highAlert()) + .enqueue(); } @Override protected boolean isRequiredServiceSupported(@NonNull final BluetoothGatt gatt) { - final BluetoothGattService llService = gatt.getService(LINKLOSS_SERVICE_UUID); + final BluetoothGattService llService = gatt.getService(LINK_LOSS_SERVICE_UUID); if (llService != null) { mLinkLossCharacteristic = llService.getCharacteristic(ALERT_LEVEL_CHARACTERISTIC_UUID); } @@ -105,6 +104,7 @@ class ProximityManager extends BatteryManager { /** * Toggles the immediate alert on the target device. + * * @return true if alarm has been enabled, false if disabled */ public boolean toggleImmediateAlert() { @@ -114,6 +114,7 @@ class ProximityManager extends BatteryManager { /** * Writes the HIGH ALERT or NO ALERT command to the target device + * * @param on true to enable the alarm on proximity tag, false to disable it */ public void writeImmediateAlert(final boolean on) { @@ -124,7 +125,8 @@ class ProximityManager extends BatteryManager { writeCharacteristic(mAlertLevelCharacteristic, on ? AlertLevelData.highAlert() : AlertLevelData.noAlert()) .with((device, data) -> log(LogContract.Log.Level.APPLICATION, "\"" + AlertLevelParser.parse(data) + "\" sent")) .done(device -> mAlertOn = on) - .fail((device, status) -> log(LogContract.Log.Level.APPLICATION, "Alert Level characteristic not found")); + .fail((device, status) -> log(LogContract.Log.Level.APPLICATION, "Alert Level characteristic not found")) + .enqueue(); } /** diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java index f7df7469..4ddf9362 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java @@ -30,12 +30,8 @@ import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import java.util.Deque; -import java.util.LinkedList; import java.util.UUID; -import no.nordicsemi.android.ble.BleManager; -import no.nordicsemi.android.ble.Request; import no.nordicsemi.android.ble.common.callback.rsc.RunningSpeedAndCadenceMeasurementDataCallback; import no.nordicsemi.android.ble.data.Data; import no.nordicsemi.android.log.LogContract; @@ -85,7 +81,7 @@ public class RSCManager extends BatteryManager { instantaneousCadence, strideLength, totalDistance); } }); - enableNotifications(mRSCMeasurementCharacteristic); + enableNotifications(mRSCMeasurementCharacteristic).enqueue(); } @Override diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/template/TemplateManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/template/TemplateManager.java index ac4f2b54..a8735a13 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/template/TemplateManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/template/TemplateManager.java @@ -45,15 +45,25 @@ import no.nordicsemi.android.nrftoolbox.template.callback.TemplateDataCallback; */ public class TemplateManager extends BatteryManager { // TODO Replace the services and characteristics below to match your device. - /** The service UUID */ + /** + * The service UUID + */ static final UUID SERVICE_UUID = UUID.fromString("0000180D-0000-1000-8000-00805f9b34fb"); // Heart Rate service - /** A UUID of a characteristic with notify property */ + /** + * A UUID of a characteristic with notify property + */ private static final UUID MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00002A37-0000-1000-8000-00805f9b34fb"); // Heart Rate Measurement - /** A UUID of a characteristic with read property */ + /** + * A UUID of a characteristic with read property + */ private static final UUID READABLE_CHARACTERISTIC_UUID = UUID.fromString("00002A38-0000-1000-8000-00805f9b34fb"); // Body Sensor Location - /** Some other service UUID */ + /** + * Some other service UUID + */ private static final UUID OTHER_SERVICE_UUID = UUID.fromString("00001800-0000-1000-8000-00805f9b34fb"); // Generic Access service - /** A UUID of a characteristic with write property */ + /** + * A UUID of a characteristic with write property + */ private static final UUID WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00002A00-0000-1000-8000-00805f9b34fb"); // Device Name // TODO Add more services and characteristics references. @@ -88,38 +98,40 @@ public class TemplateManager extends BatteryManager { // Increase the MTU requestMtu(43) - .with((device, mtu) -> log(LogContract.Log.Level.APPLICATION, "MTU changed to " + mtu)) - .done(device -> { - // You may do some logic in here that should be done when the request finished successfully. - // In case of MTU this method is called also when the MTU hasn't changed, or has changed - // to a different (lower) value. Use .with(...) to get the MTU value. - }) - .fail((device, status) -> log(LogContract.Log.Level.WARNING, "MTU change not supported")); + .with((device, mtu) -> log(LogContract.Log.Level.APPLICATION, "MTU changed to " + mtu)) + .done(device -> { + // You may do some logic in here that should be done when the request finished successfully. + // In case of MTU this method is called also when the MTU hasn't changed, or has changed + // to a different (lower) value. Use .with(...) to get the MTU value. + }) + .fail((device, status) -> log(LogContract.Log.Level.WARNING, "MTU change not supported")) + .enqueue(); // Set notification callback setNotificationCallback(mRequiredCharacteristic) - // This callback will be called each time the notification is received - .with(new TemplateDataCallback() { - @Override - public void onSampleValueReceived(@NonNull final BluetoothDevice device, final int value) { - // Let's lass received data to the service - mCallbacks.onSampleValueReceived(device, value); - } + // This callback will be called each time the notification is received + .with(new TemplateDataCallback() { + @Override + public void onSampleValueReceived(@NonNull final BluetoothDevice device, final int value) { + // Let's lass received data to the service + mCallbacks.onSampleValueReceived(device, value); + } - @Override - public void onInvalidDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) { - log(LogContract.Log.Level.WARNING, "Invalid data received: " + data); - } - }); + @Override + public void onInvalidDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) { + log(LogContract.Log.Level.WARNING, "Invalid data received: " + data); + } + }); // Enable notifications enableNotifications(mRequiredCharacteristic) - // Method called after the data were sent (data will contain 0x0100 in this case) - .with((device, data) -> log(LogContract.Log.Level.DEBUG, "Data sent: " + data)) - // Method called when the request finished successfully. This will be called after .with(..) callback - .done(device -> log(LogContract.Log.Level.APPLICATION, "Notifications enabled successfully")) - // Methods called in case of an error, for example when the characteristic does not have Notify property - .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to enable notifications")); + // Method called after the data were sent (data will contain 0x0100 in this case) + .with((device, data) -> log(LogContract.Log.Level.DEBUG, "Data sent: " + data)) + // Method called when the request finished successfully. This will be called after .with(..) callback + .done(device -> log(LogContract.Log.Level.APPLICATION, "Notifications enabled successfully")) + // Methods called in case of an error, for example when the characteristic does not have Notify property + .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to enable notifications")) + .enqueue(); } @Override @@ -181,7 +193,8 @@ public class TemplateManager extends BatteryManager { } else { log(LogContract.Log.Level.WARNING, "Value is empty!"); } - }); + }) + .enqueue(); } }; @@ -206,6 +219,7 @@ public class TemplateManager extends BatteryManager { // Write Without Request type was used. This is called after .with(...) callback. .done(device -> log(LogContract.Log.Level.APPLICATION, "Device name set to \"" + parameter + "\"")) // Callback called when write has failed. - .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to change device name")); + .fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to change device name")) + .enqueue(); } } diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/uart/UARTManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/uart/UARTManager.java index 11d2e73a..0378fb9e 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/uart/UARTManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/uart/UARTManager.java @@ -29,13 +29,10 @@ import android.content.Context; import android.support.annotation.NonNull; import android.text.TextUtils; -import java.io.UnsupportedEncodingException; -import java.util.Deque; -import java.util.LinkedList; import java.util.UUID; import no.nordicsemi.android.ble.BleManager; -import no.nordicsemi.android.ble.Request; +import no.nordicsemi.android.ble.WriteRequest; import no.nordicsemi.android.log.LogContract; public class UARTManager extends BleManager { @@ -45,14 +42,11 @@ public class UARTManager extends BleManager { private final static UUID UART_RX_CHARACTERISTIC_UUID = UUID.fromString("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"); /** TX characteristic UUID */ private final static UUID UART_TX_CHARACTERISTIC_UUID = UUID.fromString("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"); - /** The maximum packet size is 20 bytes. */ - private static final int MAX_PACKET_SIZE = 20; private BluetoothGattCharacteristic mRXCharacteristic, mTXCharacteristic; - private byte[] mOutgoingBuffer; - private int mBufferOffset; + private boolean mUseLongWrite = true; - public UARTManager(final Context context) { + UARTManager(final Context context) { super(context); } @@ -63,15 +57,20 @@ public class UARTManager extends BleManager { } /** - * BluetoothGatt callbacks for connection/disconnection, service discovery, receiving indication, etc + * BluetoothGatt callbacks for connection/disconnection, service discovery, receiving indication, etc. */ private final BleManagerGattCallback mGattCallback = new BleManagerGattCallback() { @Override - protected Deque initGatt(@NonNull final BluetoothGatt gatt) { - final LinkedList requests = new LinkedList<>(); - requests.add(Request.newEnableNotificationsRequest(mTXCharacteristic)); - return requests; + protected void initialize() { + requestMtu(260).enqueue(); + setNotificationCallback(mTXCharacteristic) + .with((device, data) -> { + final String text = data.getStringValue(0); + log(LogContract.Log.Level.APPLICATION, "\"" + text + "\" received"); + mCallbacks.onDataReceived(device, text); + }); + enableNotifications(mTXCharacteristic).enqueue(); } @Override @@ -89,10 +88,14 @@ public class UARTManager extends BleManager { writeRequest = (rxProperties & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0; writeCommand = (rxProperties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0; - // Set the WRITE REQUEST type when the characteristic supports it. This will allow to send long write (also if the characteristic support it). - // In case there is no WRITE REQUEST property, this manager will divide texts longer then 20 bytes into up to 20 bytes chunks. + // Set the WRITE REQUEST type when the characteristic supports it. + // This will allow to send long write (also if the characteristic support it). + // In case there is no WRITE REQUEST property, this manager will divide texts + // longer then MTU-3 bytes into up to MTU-3 bytes chunks. if (writeRequest) mRXCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); + else + mUseLongWrite = false; } return mRXCharacteristic != null && mTXCharacteristic != null && (writeRequest || writeCommand); @@ -102,33 +105,7 @@ public class UARTManager extends BleManager { protected void onDeviceDisconnected() { mRXCharacteristic = null; mTXCharacteristic = null; - } - - @Override - public void onCharacteristicWrite(@NonNull final BluetoothGatt gatt, @NonNull final BluetoothGattCharacteristic characteristic) { - // When the whole buffer has been sent - final byte[] buffer = mOutgoingBuffer; - if (mBufferOffset == buffer.length) { - try { - final String data = new String(buffer, "UTF-8"); - log(LogContract.Log.Level.APPLICATION, "\"" + data + "\" sent"); - mCallbacks.onDataSent(gatt.getDevice(), data); - } catch (final UnsupportedEncodingException e) { - // do nothing - } - mOutgoingBuffer = null; - } else { // Otherwise... - final int length = Math.min(buffer.length - mBufferOffset, MAX_PACKET_SIZE); - enqueue(Request.newWriteRequest(mRXCharacteristic, buffer, mBufferOffset, length)); - mBufferOffset += length; - } - } - - @Override - public void onCharacteristicNotified(@NonNull final BluetoothGatt gatt, @NonNull final BluetoothGattCharacteristic characteristic) { - final String data = characteristic.getStringValue(0); - log(LogContract.Log.Level.APPLICATION, "\"" + data + "\" received"); - mCallbacks.onDataReceived(gatt.getDevice(), data); + mUseLongWrite = true; } }; @@ -147,23 +124,12 @@ public class UARTManager extends BleManager { if (mRXCharacteristic == null) return; - // An outgoing buffer may not be null if there is already another packet being sent. We do nothing in this case. - if (!TextUtils.isEmpty(text) && mOutgoingBuffer == null) { - final byte[] buffer = mOutgoingBuffer = text.getBytes(); - mBufferOffset = 0; - - // Depending on whether the characteristic has the WRITE REQUEST property or not, we will either send it as it is (hoping the long write is implemented), - // or divide it into up to 20 bytes chunks and send them one by one. - final boolean writeRequest = (mRXCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0; - - if (!writeRequest) { // no WRITE REQUEST property - final int length = Math.min(buffer.length, MAX_PACKET_SIZE); - mBufferOffset += length; - enqueue(Request.newWriteRequest(mRXCharacteristic, buffer, 0, length)); - } else { // there is WRITE REQUEST property, let's try Long Write - mBufferOffset = buffer.length; - enqueue(Request.newWriteRequest(mRXCharacteristic, buffer, 0, buffer.length)); + if (!TextUtils.isEmpty(text)) { + final WriteRequest request = writeCharacteristic(mRXCharacteristic, text.getBytes()); + if (!mUseLongWrite) { + request.split(); } + request.enqueue(); } } }