mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2026-01-09 17:54:27 +01:00
Major refactoring: enqueue() method added to Request.
This commit is contained in:
@@ -17,7 +17,8 @@ import no.nordicsemi.android.log.LogContract;
|
||||
|
||||
/**
|
||||
* The Ble Manager with Battery Service support.
|
||||
* @param <T> The profile callbacks type
|
||||
*
|
||||
* @param <T> The profile callbacks type.
|
||||
* @see BleManager
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@@ -62,7 +63,8 @@ public abstract class BatteryManager<T extends BatteryManagerCallbacks> 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<T extends BatteryManagerCallbacks> 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<T extends BatteryManagerCallbacks> 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,8 @@ public class BPMManager extends BatteryManager<BPMManagerCallbacks> {
|
||||
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<BPMManagerCallbacks> {
|
||||
}
|
||||
});
|
||||
|
||||
enableNotifications(mICPCharacteristic);
|
||||
enableIndications(mBPMCharacteristic);
|
||||
enableNotifications(mICPCharacteristic).enqueue();
|
||||
enableIndications(mBPMCharacteristic).enqueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -48,19 +48,13 @@ import no.nordicsemi.android.nrftoolbox.parser.CGMSpecificOpsControlPointParser;
|
||||
import no.nordicsemi.android.nrftoolbox.parser.RecordAccessControlPointParser;
|
||||
|
||||
public class CGMSManager extends BatteryManager<CGMSManagerCallbacks> {
|
||||
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<CGMSManagerCallbacks> {
|
||||
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<CGMSManagerCallbacks> {
|
||||
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<CGMSManagerCallbacks> {
|
||||
}
|
||||
|
||||
@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<CGMSManagerCallbacks> {
|
||||
}
|
||||
|
||||
@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<CGMSManagerCallbacks> {
|
||||
}
|
||||
|
||||
@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<CGMSManagerCallbacks> {
|
||||
}
|
||||
}
|
||||
|
||||
@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<CGMSManagerCallbacks> {
|
||||
}
|
||||
|
||||
@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<CGMSManagerCallbacks> {
|
||||
}
|
||||
|
||||
@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<CGMSManagerCallbacks> {
|
||||
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<CGMSManagerCallbacks> {
|
||||
}
|
||||
|
||||
@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<CGMSManagerCallbacks> {
|
||||
|
||||
// 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<CGMSManagerCallbacks> {
|
||||
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<CGMSManagerCallbacks> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<CGMSManagerCallbacks> {
|
||||
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<CGMSManagerCallbacks> {
|
||||
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<CGMSManagerCallbacks> {
|
||||
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<CGMSManagerCallbacks> {
|
||||
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<CGMSManagerCallbacks> {
|
||||
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<CGMSManagerCallbacks> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,25 +82,29 @@ public class CSCManager extends BatteryManager<CSCManagerCallbacks> {
|
||||
|
||||
@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
|
||||
|
||||
@@ -222,9 +222,11 @@ public class GlucoseManager extends BatteryManager<GlucoseManagerCallbacks> {
|
||||
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<GlucoseManagerCallbacks> {
|
||||
}
|
||||
|
||||
@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<GlucoseManagerCallbacks> {
|
||||
}
|
||||
});
|
||||
|
||||
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<GlucoseManagerCallbacks> {
|
||||
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<GlucoseManagerCallbacks> {
|
||||
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<GlucoseManagerCallbacks> {
|
||||
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<GlucoseManagerCallbacks> {
|
||||
|
||||
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<GlucoseManagerCallbacks> {
|
||||
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<GlucoseManagerCallbacks> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,8 @@ public class HRSManager extends BatteryManager<HRSManagerCallbacks> {
|
||||
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<HRSManagerCallbacks> {
|
||||
mCallbacks.onHeartRateMeasurementReceived(device, heartRate, contactDetected, energyExpanded, rrIntervals);
|
||||
}
|
||||
});
|
||||
enableNotifications(mHeartRateCharacteristic);
|
||||
enableNotifications(mHeartRateCharacteristic).enqueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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<HTSManagerCallbacks> {
|
||||
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<HTSManagerCallbacks> {
|
||||
mCallbacks.onTemperatureMeasurementReceived(device, temperature, unit, calendar, type);
|
||||
}
|
||||
});
|
||||
enableIndications(mHTCharacteristic);
|
||||
enableIndications(mHTCharacteristic).enqueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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);
|
||||
@@ -40,12 +40,6 @@ import no.nordicsemi.android.nrftoolbox.profile.multiconnect.BleMulticonnectProf
|
||||
import no.nordicsemi.android.nrftoolbox.widget.DividerItemDecoration;
|
||||
|
||||
public class ProximityActivity extends BleMulticonnectProfileServiceReadyActivity<ProximityService.ProximityBinder> {
|
||||
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
|
||||
|
||||
@@ -36,13 +36,11 @@ import no.nordicsemi.android.nrftoolbox.parser.AlertLevelParser;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
class ProximityManager extends BatteryManager<ProximityManagerCallbacks> {
|
||||
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<ProximityManagerCallbacks> {
|
||||
@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<ProximityManagerCallbacks> {
|
||||
|
||||
/**
|
||||
* 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<ProximityManagerCallbacks> {
|
||||
|
||||
/**
|
||||
* 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<ProximityManagerCallbacks> {
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<RSCManagerCallbacks> {
|
||||
instantaneousCadence, strideLength, totalDistance);
|
||||
}
|
||||
});
|
||||
enableNotifications(mRSCMeasurementCharacteristic);
|
||||
enableNotifications(mRSCMeasurementCharacteristic).enqueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,15 +45,25 @@ import no.nordicsemi.android.nrftoolbox.template.callback.TemplateDataCallback;
|
||||
*/
|
||||
public class TemplateManager extends BatteryManager<TemplateManagerCallbacks> {
|
||||
// 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<TemplateManagerCallbacks> {
|
||||
|
||||
// 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<TemplateManagerCallbacks> {
|
||||
} else {
|
||||
log(LogContract.Log.Level.WARNING, "Value is empty!");
|
||||
}
|
||||
});
|
||||
})
|
||||
.enqueue();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -206,6 +219,7 @@ public class TemplateManager extends BatteryManager<TemplateManagerCallbacks> {
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<UARTManagerCallbacks> {
|
||||
@@ -45,14 +42,11 @@ public class UARTManager extends BleManager<UARTManagerCallbacks> {
|
||||
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<UARTManagerCallbacks> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<Request> initGatt(@NonNull final BluetoothGatt gatt) {
|
||||
final LinkedList<Request> 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<UARTManagerCallbacks> {
|
||||
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<UARTManagerCallbacks> {
|
||||
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<UARTManagerCallbacks> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user