mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-24 09:13:04 +02:00
Add Converters.fromSignedInt* methods.
This commit is contained in:
@@ -33,7 +33,6 @@ import java.util.UUID;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static com.health.openscale.core.bluetooth.lib.TrisaBodyAnalyzeLib.convertJavaTimestampToDevice;
|
||||
import static com.health.openscale.core.bluetooth.lib.TrisaBodyAnalyzeLib.getInt32;
|
||||
import static com.health.openscale.core.bluetooth.lib.TrisaBodyAnalyzeLib.parseScaleMeasurementData;
|
||||
|
||||
/**
|
||||
@@ -219,7 +218,7 @@ public class BluetoothTrisaBodyAnalyze extends BluetoothCommunication {
|
||||
Timber.e("Password data too short");
|
||||
return;
|
||||
}
|
||||
password = getInt32(data, 1);
|
||||
password = Converters.fromSignedInt32Le(data, 1);
|
||||
if (deviceId == null) {
|
||||
Timber.e("Can't save password: device id not set!");
|
||||
} else {
|
||||
@@ -247,7 +246,7 @@ public class BluetoothTrisaBodyAnalyze extends BluetoothCommunication {
|
||||
disconnect(true);
|
||||
return;
|
||||
}
|
||||
int challenge = getInt32(data, 1);
|
||||
int challenge = Converters.fromSignedInt32Le(data, 1);
|
||||
int response = challenge ^ password;
|
||||
writeCommand(DOWNLOAD_INFORMATION_RESULT_COMMAND, response);
|
||||
int deviceTimestamp = convertJavaTimestampToDevice(System.currentTimeMillis());
|
||||
|
@@ -33,16 +33,6 @@ public class TrisaBodyAnalyzeLib {
|
||||
// Timestamp of 2010-01-01 00:00:00 UTC (or local time?)
|
||||
private static final long TIMESTAMP_OFFSET_SECONDS = 1262304000L;
|
||||
|
||||
/**
|
||||
* Converts 4 little-endian bytes to a 32-bit integer, starting from {@code offset}.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException if {@code offset < 0} or {@code offset + 4> data.length}
|
||||
*/
|
||||
public static int getInt32(byte[] data, int offset) {
|
||||
return (data[offset] & 0xff) | ((data[offset + 1] & 0xff) << 8) |
|
||||
((data[offset + 2] & 0xff) << 16) | ((data[offset + 3] & 0xff) << 24);
|
||||
}
|
||||
|
||||
/** Converts 4 bytes to a floating point number, starting from {@code offset}.
|
||||
*
|
||||
* <p>The first three little-endian bytes form the 24-bit mantissa. The last byte contains the
|
||||
@@ -92,7 +82,7 @@ public class TrisaBodyAnalyzeLib {
|
||||
return null;
|
||||
}
|
||||
double weightKg = getBase10Float(data, 1);
|
||||
int deviceTimestamp = getInt32(data, 5);
|
||||
int deviceTimestamp = Converters.fromSignedInt32Le(data, 5);
|
||||
|
||||
ScaleMeasurement measurement = new ScaleMeasurement();
|
||||
measurement.setDateTime(new Date(convertDeviceTimestampToJava(deviceTimestamp)));
|
||||
|
@@ -235,18 +235,26 @@ public class Converters {
|
||||
return kg;
|
||||
}
|
||||
|
||||
public static int fromUnsignedInt16Le(byte[] data, int offset) {
|
||||
int value = (data[offset + 1] & 0xFF) << 8;
|
||||
public static int fromSignedInt16Le(byte[] data, int offset) {
|
||||
int value = data[offset + 1] << 8;
|
||||
value += data[offset] & 0xFF;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int fromUnsignedInt16Be(byte[] data, int offset) {
|
||||
int value = (data[offset] & 0xFF) << 8;
|
||||
public static int fromSignedInt16Be(byte[] data, int offset) {
|
||||
int value = data[offset] << 8;
|
||||
value += data[offset + 1] & 0xFF;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int fromUnsignedInt16Le(byte[] data, int offset) {
|
||||
return fromSignedInt16Le(data, offset) & 0xFFFF;
|
||||
}
|
||||
|
||||
public static int fromUnsignedInt16Be(byte[] data, int offset) {
|
||||
return fromSignedInt16Be(data, offset) & 0xFFFF;
|
||||
}
|
||||
|
||||
public static void toInt16Le(byte[] data, int offset, int value) {
|
||||
data[offset + 0] = (byte) (value & 0xFF);
|
||||
data[offset + 1] = (byte) ((value >> 8) & 0xFF);
|
||||
@@ -269,29 +277,41 @@ public class Converters {
|
||||
return data;
|
||||
}
|
||||
|
||||
public static int fromUnsignedInt24Le(byte[] data, int offset) {
|
||||
int value = (data[offset + 2] & 0xFF) << 16;
|
||||
public static int fromSignedInt24Le(byte[] data, int offset) {
|
||||
int value = data[offset + 2] << 16;
|
||||
value += (data[offset + 1] & 0xFF) << 8;
|
||||
value += data[offset] & 0xFF;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static long fromUnsignedInt32Le(byte[] data, int offset) {
|
||||
long value = (long) (data[offset + 3] & 0xFF) << 24;
|
||||
public static int fromUnsignedInt24Le(byte[] data, int offset) {
|
||||
return fromSignedInt24Le(data, offset) & 0xFFFFFF;
|
||||
}
|
||||
|
||||
public static int fromSignedInt32Le(byte[] data, int offset) {
|
||||
int value = data[offset + 3] << 24;
|
||||
value += (data[offset + 2] & 0xFF) << 16;
|
||||
value += (data[offset + 1] & 0xFF) << 8;
|
||||
value += data[offset] & 0xFF;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static long fromUnsignedInt32Be(byte[] data, int offset) {
|
||||
long value = (long) (data[offset] & 0xFF) << 24;
|
||||
public static int fromSignedInt32Be(byte[] data, int offset) {
|
||||
int value = data[offset] << 24;
|
||||
value += (data[offset + 1] & 0xFF) << 16;
|
||||
value += (data[offset + 2] & 0xFF) << 8;
|
||||
value += data[offset + 3] & 0xFF;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static long fromUnsignedInt32Le(byte[] data, int offset) {
|
||||
return (long) fromSignedInt32Le(data, offset) & 0xFFFFFFFFL;
|
||||
}
|
||||
|
||||
public static long fromUnsignedInt32Be(byte[] data, int offset) {
|
||||
return (long) fromSignedInt32Be(data, offset) & 0xFFFFFFFFL;
|
||||
}
|
||||
|
||||
public static void toInt32Le(byte[] data, int offset, long value) {
|
||||
data[offset + 3] = (byte) ((value >> 24) & 0xFF);
|
||||
data[offset + 2] = (byte) ((value >> 16) & 0xFF);
|
||||
|
@@ -84,18 +84,33 @@ public class ConvertersTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromUnsignedInt16Converters() throws Exception {
|
||||
public void fromInt16Converters() throws Exception {
|
||||
byte[] data = new byte[]{(byte) 0xfd, (byte) 0xfe, (byte) 0xfc, (byte) 0x10, (byte) 0x7f};
|
||||
|
||||
assertEquals(0xfffffefd, Converters.fromSignedInt16Le(data, 0));
|
||||
assertEquals(0xfffffcfe, Converters.fromSignedInt16Le(data, 1));
|
||||
assertEquals(0x000010fc, Converters.fromSignedInt16Le(data, 2));
|
||||
assertEquals(0x00007f10, Converters.fromSignedInt16Le(data, 3));
|
||||
|
||||
assertEquals(0xfefd, Converters.fromUnsignedInt16Le(data, 0));
|
||||
assertEquals(0xfcfe, Converters.fromUnsignedInt16Le(data, 1));
|
||||
assertEquals(0x10fc, Converters.fromUnsignedInt16Le(data, 2));
|
||||
assertEquals(0x7f10, Converters.fromUnsignedInt16Le(data, 3));
|
||||
|
||||
assertEquals(0xfffffdfe, Converters.fromSignedInt16Be(data, 0));
|
||||
assertEquals(0xfffffefc, Converters.fromSignedInt16Be(data, 1));
|
||||
assertEquals(0xfffffc10, Converters.fromSignedInt16Be(data, 2));
|
||||
assertEquals(0x0000107f, Converters.fromSignedInt16Be(data, 3));
|
||||
|
||||
assertEquals(0xfdfe, Converters.fromUnsignedInt16Be(data, 0));
|
||||
assertEquals(0xfefc, Converters.fromUnsignedInt16Be(data, 1));
|
||||
assertEquals(0xfc10, Converters.fromUnsignedInt16Be(data, 2));
|
||||
assertEquals(0x107f, Converters.fromUnsignedInt16Be(data, 3));
|
||||
|
||||
assertEquals(-12345,
|
||||
Converters.fromSignedInt16Le(Converters.toInt16Le(-12345), 0));
|
||||
assertEquals(-12345,
|
||||
Converters.fromSignedInt16Be(Converters.toInt16Be(-12345), 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -113,31 +128,55 @@ public class ConvertersTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unsignedInt24Converters() throws Exception {
|
||||
public void fromInt24Converters() throws Exception {
|
||||
byte[] data = new byte[]{(byte) 0xfd, (byte) 0xfe, (byte) 0xfc, (byte) 0x10, (byte) 0x7f};
|
||||
|
||||
assertEquals(0xfffcfefd, Converters.fromSignedInt24Le(data, 0));
|
||||
assertEquals(0x0010fcfe, Converters.fromSignedInt24Le(data, 1));
|
||||
assertEquals(0x007f10fc, Converters.fromSignedInt24Le(data, 2));
|
||||
|
||||
assertEquals(0xfcfefd, Converters.fromUnsignedInt24Le(data, 0));
|
||||
assertEquals(0x10fcfe, Converters.fromUnsignedInt24Le(data, 1));
|
||||
assertEquals(0x7f10fc, Converters.fromUnsignedInt24Le(data, 2));
|
||||
|
||||
assertEquals(-1234567,
|
||||
Converters.fromSignedInt24Le(Converters.toInt32Le(-1234567), 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromUnsignedInt32Converters() throws Exception {
|
||||
public void fromInt32Converters() throws Exception {
|
||||
byte[] data = new byte[]{(byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0x7f, (byte) 0x7e};
|
||||
|
||||
assertEquals(0x7ff3f2f1, Converters.fromSignedInt32Le(data, 0));
|
||||
assertEquals(0x7e7ff3f2, Converters.fromSignedInt32Le(data, 1));
|
||||
|
||||
assertEquals(0x7ff3f2f1, Converters.fromUnsignedInt32Le(data, 0));
|
||||
assertEquals(0x7e7ff3f2, Converters.fromUnsignedInt32Le(data, 1));
|
||||
|
||||
assertEquals(0xf1f2f37f, Converters.fromSignedInt32Be(data, 0));
|
||||
assertEquals(0xf2f37f7e, Converters.fromSignedInt32Be(data, 1));
|
||||
|
||||
assertEquals(0xf1f2f37fL, Converters.fromUnsignedInt32Be(data, 0));
|
||||
assertEquals(0xf2f37f7eL, Converters.fromUnsignedInt32Be(data, 1));
|
||||
|
||||
data = new byte[]{(byte) 0x80, (byte) 0x00, (byte) 0x01, (byte) 0xff, (byte) 0x00};
|
||||
|
||||
assertEquals(0xff010080, Converters.fromSignedInt32Le(data, 0));
|
||||
assertEquals(0xff0100, Converters.fromSignedInt32Le(data, 1));
|
||||
|
||||
assertEquals(0xff010080L, Converters.fromUnsignedInt32Le(data, 0));
|
||||
assertEquals(0xff0100, Converters.fromUnsignedInt32Le(data, 1));
|
||||
|
||||
assertEquals(0x800001ff, Converters.fromSignedInt32Be(data, 0));
|
||||
assertEquals(0x1ff00, Converters.fromSignedInt32Be(data, 1));
|
||||
|
||||
assertEquals(0x800001ffL, Converters.fromUnsignedInt32Be(data, 0));
|
||||
assertEquals(0x1ff00L, Converters.fromUnsignedInt32Be(data, 1));
|
||||
|
||||
assertEquals(-1234567890,
|
||||
Converters.fromSignedInt32Le(Converters.toInt32Le(-1234567890), 0));
|
||||
assertEquals(-1234567890,
|
||||
Converters.fromSignedInt32Be(Converters.toInt32Be(-1234567890), 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -15,27 +15,12 @@ import java.util.GregorianCalendar;
|
||||
import static com.health.openscale.core.bluetooth.lib.TrisaBodyAnalyzeLib.convertDeviceTimestampToJava;
|
||||
import static com.health.openscale.core.bluetooth.lib.TrisaBodyAnalyzeLib.convertJavaTimestampToDevice;
|
||||
import static com.health.openscale.core.bluetooth.lib.TrisaBodyAnalyzeLib.getBase10Float;
|
||||
import static com.health.openscale.core.bluetooth.lib.TrisaBodyAnalyzeLib.getInt32;
|
||||
import static com.health.openscale.core.bluetooth.lib.TrisaBodyAnalyzeLib.parseScaleMeasurementData;
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
/** Unit tests for {@link com.health.openscale.core.bluetooth.lib.TrisaBodyAnalyzeLib}.*/
|
||||
public class TrisaBodyAnalyzeLibTest {
|
||||
|
||||
@Test
|
||||
public void getInt32Tests() {
|
||||
byte[] data = new byte[]{1, 2, 3, 4, 5, 6};
|
||||
assertEquals(0x04030201, getInt32(data, 0));
|
||||
assertEquals(0x05040302, getInt32(data, 1));
|
||||
assertEquals(0x06050403, getInt32(data, 2));
|
||||
|
||||
assertEquals(0xa7bdd385, getInt32(new byte[]{-123, -45, -67, -89}, 0));
|
||||
|
||||
assertThrows(IndexOutOfBoundsException.class, getInt32Runnable(data, -1));
|
||||
assertThrows(IndexOutOfBoundsException.class, getInt32Runnable(data, 5));
|
||||
assertThrows(IndexOutOfBoundsException.class, getInt32Runnable(new byte[]{1,2,3}, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getBase10FloatTests() {
|
||||
double eps = 1e-9; // margin of error for inexact floating point comparisons
|
||||
@@ -117,19 +102,6 @@ public class TrisaBodyAnalyzeLibTest {
|
||||
assertEquals(0f, measurement.getFat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Runnable} that will call getInt32(). In Java 8, this can be done more
|
||||
* easily with a lambda expression at the call site, but we are using Java 7.
|
||||
*/
|
||||
private static Runnable getInt32Runnable(final byte[] data, final int offset) {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getInt32(data, offset);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Runnable} that will call getBase10Float(). In Java 8, this can be done more
|
||||
* easily with a lambda expression at the call site, but we are using Java 7.
|
||||
|
Reference in New Issue
Block a user