mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-08-01 03:23:26 +02:00
438 lines
26 KiB
Java
438 lines
26 KiB
Java
/* Copyright (C) 2022 Martin.JM
|
|
|
|
This file is part of Gadgetbridge.
|
|
|
|
Gadgetbridge is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as published
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Gadgetbridge is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
package nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets;
|
|
|
|
import org.junit.Assert;
|
|
import org.junit.Test;
|
|
|
|
import java.lang.reflect.Field;
|
|
import java.nio.ByteBuffer;
|
|
import java.util.List;
|
|
|
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTLV;
|
|
|
|
public class TestWorkout {
|
|
|
|
HuaweiPacket.ParamsProvider secretsProvider = new HuaweiPacket.ParamsProvider() {
|
|
@Override
|
|
public byte getDeviceSupportType() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public byte[] getSecretKey() {
|
|
return new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
}
|
|
|
|
@Override
|
|
public byte[] getIv() {
|
|
return new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
}
|
|
|
|
@Override
|
|
public boolean areTransactionsCrypted() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public int getMtu() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public int getSliceSize() {
|
|
return 0xF4;
|
|
}
|
|
};
|
|
|
|
@Test
|
|
public void testWorkoutCountRequest() throws NoSuchFieldException, IllegalAccessException, HuaweiPacket.CryptoException {
|
|
int start = 0x00000000;
|
|
int end = 0x01020304;
|
|
|
|
Field tlvField = HuaweiPacket.class.getDeclaredField("tlv");
|
|
tlvField.setAccessible(true);
|
|
|
|
HuaweiTLV expectedTlv = new HuaweiTLV().put(0x81, new HuaweiTLV()
|
|
.put(0x03, start)
|
|
.put(0x04, end)
|
|
);
|
|
|
|
byte[] expected = new byte[] {(byte) 0x5a, (byte) 0x00, (byte) 0x2a, (byte) 0x00, (byte) 0x17, (byte) 0x07, (byte) 0x7c, (byte) 0x01, (byte) 0x01, (byte) 0x7d, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x7e, (byte) 0x10, (byte) 0xf7, (byte) 0x48, (byte) 0xf7, (byte) 0x49, (byte) 0x4a, (byte) 0xa5, (byte) 0xb2, (byte) 0xc9, (byte) 0x41, (byte) 0xf5, (byte) 0x7f, (byte) 0xb4, (byte) 0xe9, (byte) 0x17, (byte) 0xac, (byte) 0xb5, (byte) 0x5f, (byte) 0x8e};
|
|
|
|
Workout.WorkoutCount.Request request = new Workout.WorkoutCount.Request(secretsProvider, start, end);
|
|
|
|
Assert.assertEquals(0x17, request.serviceId);
|
|
Assert.assertEquals(0x07, request.commandId);
|
|
Assert.assertEquals(expectedTlv, tlvField.get(request));
|
|
Assert.assertTrue(request.complete);
|
|
List<byte[]> out = request.serialize();
|
|
Assert.assertEquals(1, out.size());
|
|
Assert.assertArrayEquals(expected, out.get(0));
|
|
}
|
|
|
|
@Test
|
|
public void testWorkoutCountResponse() throws NoSuchFieldException, IllegalAccessException, HuaweiPacket.ParseException {
|
|
byte[] raw = new byte[] {(byte) 0x5a, (byte) 0x00, (byte) 0x4a, (byte) 0x00, (byte) 0x17, (byte) 0x07, (byte) 0x7c, (byte) 0x01, (byte) 0x01, (byte) 0x7d, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x7e, (byte) 0x30, (byte) 0xee, (byte) 0xdd, (byte) 0xa9, (byte) 0x23, (byte) 0x2c, (byte) 0xe4, (byte) 0x9f, (byte) 0x41, (byte) 0x0b, (byte) 0x9f, (byte) 0x7a, (byte) 0xc2, (byte) 0xe0, (byte) 0x72, (byte) 0x6d, (byte) 0xe1, (byte) 0x8f, (byte) 0xd0, (byte) 0xe7, (byte) 0x41, (byte) 0x59, (byte) 0x38, (byte) 0xac, (byte) 0x17, (byte) 0x66, (byte) 0xc8, (byte) 0x60, (byte) 0xd7, (byte) 0xd2, (byte) 0x32, (byte) 0x8b, (byte) 0xa5, (byte) 0x91, (byte) 0xc7, (byte) 0xc5, (byte) 0xe5, (byte) 0x7d, (byte) 0x8d, (byte) 0xa1, (byte) 0xd0, (byte) 0x6f, (byte) 0xe2, (byte) 0xe2, (byte) 0x24, (byte) 0x7d, (byte) 0xef, (byte) 0x02, (byte) 0x03, (byte) 0x59, (byte) 0x3e};
|
|
|
|
Field tlvField = HuaweiPacket.class.getDeclaredField("tlv");
|
|
tlvField.setAccessible(true);
|
|
|
|
HuaweiTLV expectedTlv = new HuaweiTLV().put(0x81, new HuaweiTLV()
|
|
.put(0x02, (short) 0x1337)
|
|
.put(0x85, new HuaweiTLV()
|
|
.put(0x06, (short) 0x0001)
|
|
.put(0x07, (short) 0x0002)
|
|
.put(0x08, (short) 0x0003)
|
|
.put(0x0a, (short) 0x0004)
|
|
)
|
|
.put(0x85, new HuaweiTLV()
|
|
.put(0x06, (short) 0x0005)
|
|
.put(0x07, (short) 0x0006)
|
|
.put(0x08, (short) 0x0007)
|
|
.put(0x0a, (short) 0x0008)
|
|
)
|
|
);
|
|
|
|
HuaweiPacket packet = new HuaweiPacket(secretsProvider).parse(raw);
|
|
packet.parseTlv();
|
|
|
|
Assert.assertEquals(0x17, packet.serviceId);
|
|
Assert.assertEquals(0x07, packet.commandId);
|
|
Assert.assertEquals(expectedTlv, tlvField.get(packet));
|
|
Assert.assertTrue(packet.complete);
|
|
Assert.assertTrue(packet instanceof Workout.WorkoutCount.Response);
|
|
Assert.assertEquals(0x1337, ((Workout.WorkoutCount.Response) packet).count);
|
|
Assert.assertEquals(2, ((Workout.WorkoutCount.Response) packet).workoutNumbers.size());
|
|
|
|
Assert.assertArrayEquals(new byte[] {0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0x02, 0x08, 0x02, 0x00, 0x03, 0x0a, 0x02, 0x00, 0x04}, ((Workout.WorkoutCount.Response) packet).workoutNumbers.get(0).rawData);
|
|
Assert.assertEquals(0x01, ((Workout.WorkoutCount.Response) packet).workoutNumbers.get(0).workoutNumber);
|
|
Assert.assertEquals(0x02, ((Workout.WorkoutCount.Response) packet).workoutNumbers.get(0).dataCount);
|
|
Assert.assertEquals(0x03, ((Workout.WorkoutCount.Response) packet).workoutNumbers.get(0).paceCount);
|
|
|
|
Assert.assertArrayEquals(new byte[] {0x06, 0x02, 0x00, 0x05, 0x07, 0x02, 0x00, 0x06, 0x08, 0x02, 0x00, 0x07, 0x0a, 0x02, 0x00, 0x08}, ((Workout.WorkoutCount.Response) packet).workoutNumbers.get(1).rawData);
|
|
Assert.assertEquals(0x05, ((Workout.WorkoutCount.Response) packet).workoutNumbers.get(1).workoutNumber);
|
|
Assert.assertEquals(0x06, ((Workout.WorkoutCount.Response) packet).workoutNumbers.get(1).dataCount);
|
|
Assert.assertEquals(0x07, ((Workout.WorkoutCount.Response) packet).workoutNumbers.get(1).paceCount);
|
|
}
|
|
|
|
@Test
|
|
public void testWorkoutTotalsRequest() throws NoSuchFieldException, IllegalAccessException, HuaweiPacket.CryptoException {
|
|
short number = 0x1337;
|
|
|
|
Field tlvField = HuaweiPacket.class.getDeclaredField("tlv");
|
|
tlvField.setAccessible(true);
|
|
|
|
HuaweiTLV expectedTlv = new HuaweiTLV().put(0x81, new HuaweiTLV()
|
|
.put(0x02, number)
|
|
);
|
|
|
|
byte[] expected = new byte[] {(byte) 0x5a, (byte) 0x00, (byte) 0x2a, (byte) 0x00, (byte) 0x17, (byte) 0x08, (byte) 0x7c, (byte) 0x01, (byte) 0x01, (byte) 0x7d, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x7e, (byte) 0x10, (byte) 0xf6, (byte) 0xfb, (byte) 0xc0, (byte) 0xb6, (byte) 0x4f, (byte) 0x9a, (byte) 0xfa, (byte) 0x77, (byte) 0x53, (byte) 0x28, (byte) 0x7d, (byte) 0x13, (byte) 0xca, (byte) 0x49, (byte) 0xda, (byte) 0xfd, (byte) 0x26, (byte) 0x91};
|
|
|
|
Workout.WorkoutTotals.Request request = new Workout.WorkoutTotals.Request(secretsProvider, number);
|
|
|
|
Assert.assertEquals(0x17, request.serviceId);
|
|
Assert.assertEquals(0x08, request.commandId);
|
|
Assert.assertEquals(expectedTlv, tlvField.get(request));
|
|
Assert.assertTrue(request.complete);
|
|
List<byte[]> out = request.serialize();
|
|
Assert.assertEquals(1, out.size());
|
|
Assert.assertArrayEquals(expected, out.get(0));
|
|
}
|
|
|
|
@Test
|
|
public void testWorkoutTotalsResponse() throws NoSuchFieldException, IllegalAccessException, HuaweiPacket.ParseException {
|
|
byte[] raw = new byte[] {(byte) 0x5a, (byte) 0x00, (byte) 0x5a, (byte) 0x00, (byte) 0x17, (byte) 0x08, (byte) 0x7c, (byte) 0x01, (byte) 0x01, (byte) 0x7d, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x7e, (byte) 0x40, (byte) 0x0f, (byte) 0xa0, (byte) 0x3a, (byte) 0x90, (byte) 0xae, (byte) 0x8c, (byte) 0xcf, (byte) 0x03, (byte) 0xce, (byte) 0x5a, (byte) 0x68, (byte) 0x87, (byte) 0x05, (byte) 0x51, (byte) 0xf7, (byte) 0x2f, (byte) 0x78, (byte) 0xbd, (byte) 0x84, (byte) 0xf1, (byte) 0x4f, (byte) 0xb8, (byte) 0x51, (byte) 0x28, (byte) 0xec, (byte) 0xfd, (byte) 0x8b, (byte) 0x2e, (byte) 0x99, (byte) 0xd3, (byte) 0x42, (byte) 0xd7, (byte) 0x65, (byte) 0xb2, (byte) 0x82, (byte) 0x02, (byte) 0x28, (byte) 0x00, (byte) 0x34, (byte) 0xbc, (byte) 0x39, (byte) 0x59, (byte) 0x8f, (byte) 0x0b, (byte) 0xa7, (byte) 0x3a, (byte) 0x5c, (byte) 0xfb, (byte) 0xf1, (byte) 0xd4, (byte) 0x8f, (byte) 0xf6, (byte) 0x6d, (byte) 0x98, (byte) 0xd6, (byte) 0x5a, (byte) 0x51, (byte) 0x0a, (byte) 0x4a, (byte) 0x1c, (byte) 0x42, (byte) 0xc8, (byte) 0x9d, (byte) 0xee, (byte) 0x55, (byte) 0x44};
|
|
|
|
Field tlvField = HuaweiPacket.class.getDeclaredField("tlv");
|
|
tlvField.setAccessible(true);
|
|
|
|
HuaweiTLV expectedTlv = new HuaweiTLV().put(0x81, new HuaweiTLV()
|
|
.put(0x02, (short) 0x1337)
|
|
.put(0x03, (byte) 0x01)
|
|
.put(0x04, 0x01020304)
|
|
.put(0x05, 0x05060708)
|
|
.put(0x06, 0x090a0b0c)
|
|
.put(0x07, 0x0d0e0f10)
|
|
.put(0x08, 0x11121314)
|
|
.put(0x09, 0x15161718)
|
|
.put(0x12, 0x191a1b1c)
|
|
.put(0x14, (byte) 0x1d)
|
|
);
|
|
|
|
HuaweiPacket packet = new HuaweiPacket(secretsProvider).parse(raw);
|
|
packet.parseTlv();
|
|
|
|
// TODO: find out what the status and type can be
|
|
|
|
Assert.assertEquals(0x17, packet.serviceId);
|
|
Assert.assertEquals(0x08, packet.commandId);
|
|
Assert.assertEquals(expectedTlv, tlvField.get(packet));
|
|
Assert.assertTrue(packet.complete);
|
|
Assert.assertTrue(packet instanceof Workout.WorkoutTotals.Response);
|
|
Assert.assertArrayEquals(new byte[] {0x02, 0x02, 0x13, 0x37, 0x03, 0x01, 0x01, 0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x08, 0x06, 0x04, 0x09, 0x0a, 0x0b, 0x0c, 0x07, 0x04, 0x0d, 0x0e, 0x0f, 0x10, 0x08, 0x04, 0x11, 0x12, 0x13, 0x14, 0x09, 0x04, 0x15, 0x16, 0x17, 0x18, 0x12, 0x04, 0x19, 0x1a, 0x1b, 0x1c, 0x14, 0x01, 0x1d}, ((Workout.WorkoutTotals.Response) packet).rawData);
|
|
Assert.assertEquals(0x1337, ((Workout.WorkoutTotals.Response) packet).number);
|
|
Assert.assertEquals(0x01, ((Workout.WorkoutTotals.Response) packet).status);
|
|
Assert.assertEquals(0x01020304, ((Workout.WorkoutTotals.Response) packet).startTime);
|
|
Assert.assertEquals(0x05060708, ((Workout.WorkoutTotals.Response) packet).endTime);
|
|
Assert.assertEquals(0x090a0b0c, ((Workout.WorkoutTotals.Response) packet).calories);
|
|
Assert.assertEquals(0x0d0e0f10, ((Workout.WorkoutTotals.Response) packet).distance);
|
|
Assert.assertEquals(0x11121314, ((Workout.WorkoutTotals.Response) packet).stepCount);
|
|
Assert.assertEquals(0x15161718, ((Workout.WorkoutTotals.Response) packet).totalTime);
|
|
Assert.assertEquals(0x191a1b1c, ((Workout.WorkoutTotals.Response) packet).duration);
|
|
Assert.assertEquals(0x1d, ((Workout.WorkoutTotals.Response) packet).type);
|
|
}
|
|
|
|
@Test
|
|
public void testWorkoutDataRequest() throws NoSuchFieldException, IllegalAccessException, HuaweiPacket.CryptoException {
|
|
short workoutNumber = 0x0102;
|
|
short dataNumber = 0x0304;
|
|
|
|
Field tlvField = HuaweiPacket.class.getDeclaredField("tlv");
|
|
tlvField.setAccessible(true);
|
|
|
|
HuaweiTLV expectedTlv = new HuaweiTLV().put(0x81, new HuaweiTLV()
|
|
.put(0x02, workoutNumber)
|
|
.put(0x03, dataNumber)
|
|
);
|
|
|
|
byte[] expected = {(byte) 0x5a, (byte) 0x00, (byte) 0x2a, (byte) 0x00, (byte) 0x17, (byte) 0x0a, (byte) 0x7c, (byte) 0x01, (byte) 0x01, (byte) 0x7d, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x7e, (byte) 0x10, (byte) 0xd2, (byte) 0xd7, (byte) 0x55, (byte) 0x23, (byte) 0xeb, (byte) 0x51, (byte) 0x4f, (byte) 0xe0, (byte) 0x35, (byte) 0x6c, (byte) 0x60, (byte) 0xc5, (byte) 0xbf, (byte) 0x61, (byte) 0x68, (byte) 0xd1, (byte) 0x03, (byte) 0x83};
|
|
|
|
Workout.WorkoutData.Request request = new Workout.WorkoutData.Request(secretsProvider, workoutNumber, dataNumber);
|
|
|
|
Assert.assertEquals(0x17, request.serviceId);
|
|
Assert.assertEquals(0x0a, request.commandId);
|
|
Assert.assertEquals(expectedTlv, tlvField.get(request));
|
|
Assert.assertTrue(request.complete);
|
|
List<byte[]> out = request.serialize();
|
|
Assert.assertEquals(1, out.size());
|
|
Assert.assertArrayEquals(expected, out.get(0));
|
|
}
|
|
|
|
@Test
|
|
public void testWorkoutDataResponse() throws NoSuchFieldException, IllegalAccessException, HuaweiPacket.ParseException {
|
|
byte[] raw = {(byte) 0x5a, (byte) 0x00, (byte) 0x5a, (byte) 0x00, (byte) 0x17, (byte) 0x0a, (byte) 0x7c, (byte) 0x01, (byte) 0x01, (byte) 0x7d, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x7e, (byte) 0x40, (byte) 0x03, (byte) 0x66, (byte) 0xf5, (byte) 0x16, (byte) 0xc9, (byte) 0x60, (byte) 0xb9, (byte) 0xf2, (byte) 0xe3, (byte) 0x88, (byte) 0x99, (byte) 0xab, (byte) 0x50, (byte) 0x22, (byte) 0xcb, (byte) 0x83, (byte) 0x53, (byte) 0xd0, (byte) 0xb2, (byte) 0xc3, (byte) 0x66, (byte) 0xa9, (byte) 0x16, (byte) 0x23, (byte) 0xa5, (byte) 0x8e, (byte) 0x81, (byte) 0x68, (byte) 0x85, (byte) 0x38, (byte) 0x3e, (byte) 0xd5, (byte) 0x8e, (byte) 0x21, (byte) 0xc8, (byte) 0xa1, (byte) 0x80, (byte) 0x98, (byte) 0x2d, (byte) 0x78, (byte) 0x75, (byte) 0x80, (byte) 0xa1, (byte) 0x39, (byte) 0x61, (byte) 0xa6, (byte) 0x3e, (byte) 0x61, (byte) 0x2c, (byte) 0x5e, (byte) 0xe2, (byte) 0x6f, (byte) 0xef, (byte) 0xdf, (byte) 0xdb, (byte) 0x39, (byte) 0x8f, (byte) 0xab, (byte) 0x21, (byte) 0xde, (byte) 0xba, (byte) 0xdb, (byte) 0x2c, (byte) 0xff, (byte) 0x97, (byte) 0x94};
|
|
|
|
short workoutNumber = 0x0102;
|
|
short dataNumber = 0x0304;
|
|
|
|
int timestamp = 0x05060708;
|
|
byte interval = 0x09;
|
|
short dataCount = 0x0002;
|
|
byte dataLength = 0x0F; // Data length must match
|
|
short bitmap = 0x0042; // Inner data and speed
|
|
|
|
short speed1 = 0x0a0b;
|
|
short cadence1 = 0x0c0d;
|
|
short stepLength1 = 0x0e0f;
|
|
short groundContactTime1 = 0x1011;
|
|
byte groundImpact1 = 0x12;
|
|
short swingAngle1 = 0x1314;
|
|
byte foreFootLanding1 = 0x15;
|
|
byte midFootLanding1 = 0x16;
|
|
byte backFootLanding1 = 0x17;
|
|
byte eversionAngle1 = 0x18;
|
|
|
|
short speed2 = 0x191a;
|
|
short cadence2 = 0x1b1c;
|
|
short stepLength2 = 0x1d1e;
|
|
short groundContactTime2 = 0x1f20;
|
|
byte groundImpact2 = 0x21;
|
|
short swingAngle2 = 0x2223;
|
|
byte foreFootLanding2 = 0x24;
|
|
byte midFootLanding2 = 0x25;
|
|
byte backFootLanding2 = 0x26;
|
|
byte eversionAngle2 = 0x27;
|
|
|
|
ByteBuffer headerBuf = ByteBuffer.allocate(14);
|
|
headerBuf.putShort(workoutNumber);
|
|
headerBuf.putShort(dataNumber);
|
|
headerBuf.putInt(timestamp);
|
|
headerBuf.put(interval);
|
|
headerBuf.putShort(dataCount);
|
|
headerBuf.put(dataLength);
|
|
headerBuf.putShort(bitmap);
|
|
|
|
ByteBuffer dataBuf = ByteBuffer.allocate(30);
|
|
|
|
dataBuf.putShort(speed1);
|
|
dataBuf.putShort(cadence1);
|
|
dataBuf.putShort(stepLength1);
|
|
dataBuf.putShort(groundContactTime1);
|
|
dataBuf.put(groundImpact1);
|
|
dataBuf.putShort(swingAngle1);
|
|
dataBuf.put(foreFootLanding1);
|
|
dataBuf.put(midFootLanding1);
|
|
dataBuf.put(backFootLanding1);
|
|
dataBuf.put(eversionAngle1);
|
|
|
|
dataBuf.putShort(speed2);
|
|
dataBuf.putShort(cadence2);
|
|
dataBuf.putShort(stepLength2);
|
|
dataBuf.putShort(groundContactTime2);
|
|
dataBuf.put(groundImpact2);
|
|
dataBuf.putShort(swingAngle2);
|
|
dataBuf.put(foreFootLanding2);
|
|
dataBuf.put(midFootLanding2);
|
|
dataBuf.put(backFootLanding2);
|
|
dataBuf.put(eversionAngle2);
|
|
|
|
Field tlvField = HuaweiPacket.class.getDeclaredField("tlv");
|
|
tlvField.setAccessible(true);
|
|
|
|
HuaweiTLV expectedTlv = new HuaweiTLV().put(0x81, new HuaweiTLV()
|
|
.put(0x02, workoutNumber)
|
|
.put(0x03, dataNumber)
|
|
.put(0x04, headerBuf.array())
|
|
.put(0x05, dataBuf.array())
|
|
);
|
|
|
|
HuaweiPacket packet = new HuaweiPacket(secretsProvider).parse(raw);
|
|
packet.parseTlv();
|
|
|
|
Assert.assertEquals(0x17, packet.serviceId);
|
|
Assert.assertEquals(0x0a, packet.commandId);
|
|
Assert.assertEquals(expectedTlv, tlvField.get(packet));
|
|
Assert.assertTrue(packet.complete);
|
|
Assert.assertTrue(packet instanceof Workout.WorkoutData.Response);
|
|
|
|
Assert.assertEquals(0x0102, ((Workout.WorkoutData.Response) packet).workoutNumber);
|
|
Assert.assertEquals(0x0304, ((Workout.WorkoutData.Response) packet).dataNumber);
|
|
Assert.assertArrayEquals(headerBuf.array(), ((Workout.WorkoutData.Response) packet).rawHeader);
|
|
Assert.assertArrayEquals(dataBuf.array(), ((Workout.WorkoutData.Response) packet).rawData);
|
|
|
|
Assert.assertEquals(0x0102, ((Workout.WorkoutData.Response) packet).header.workoutNumber);
|
|
Assert.assertEquals(0x0304, ((Workout.WorkoutData.Response) packet).header.dataNumber);
|
|
Assert.assertEquals(0x05060708, ((Workout.WorkoutData.Response) packet).header.timestamp);
|
|
Assert.assertEquals(0x09, ((Workout.WorkoutData.Response) packet).header.interval);
|
|
Assert.assertEquals(0x0002, ((Workout.WorkoutData.Response) packet).header.dataCount);
|
|
Assert.assertEquals(0x0f, ((Workout.WorkoutData.Response) packet).header.dataLength);
|
|
Assert.assertEquals(0x0042, ((Workout.WorkoutData.Response) packet).header.bitmap);
|
|
|
|
Assert.assertEquals(2, ((Workout.WorkoutData.Response) packet).dataList.size());
|
|
|
|
Assert.assertNull(((Workout.WorkoutData.Response) packet).dataList.get(0).unknownData);
|
|
Assert.assertEquals(0x0a0b, ((Workout.WorkoutData.Response) packet).dataList.get(0).speed);
|
|
Assert.assertEquals(0x0c0d, ((Workout.WorkoutData.Response) packet).dataList.get(0).cadence);
|
|
Assert.assertEquals(0x0e0f, ((Workout.WorkoutData.Response) packet).dataList.get(0).stepLength);
|
|
Assert.assertEquals(0x1011, ((Workout.WorkoutData.Response) packet).dataList.get(0).groundContactTime);
|
|
Assert.assertEquals(0x12, ((Workout.WorkoutData.Response) packet).dataList.get(0).impact);
|
|
Assert.assertEquals(0x1314, ((Workout.WorkoutData.Response) packet).dataList.get(0).swingAngle);
|
|
Assert.assertEquals(0x15, ((Workout.WorkoutData.Response) packet).dataList.get(0).foreFootLanding);
|
|
Assert.assertEquals(0x16, ((Workout.WorkoutData.Response) packet).dataList.get(0).midFootLanding);
|
|
Assert.assertEquals(0x17, ((Workout.WorkoutData.Response) packet).dataList.get(0).backFootLanding);
|
|
Assert.assertEquals(0x18, ((Workout.WorkoutData.Response) packet).dataList.get(0).eversionAngle);
|
|
|
|
Assert.assertNull(((Workout.WorkoutData.Response) packet).dataList.get(1).unknownData);
|
|
Assert.assertEquals(0x191a, ((Workout.WorkoutData.Response) packet).dataList.get(1).speed);
|
|
Assert.assertEquals(0x1b1c, ((Workout.WorkoutData.Response) packet).dataList.get(1).cadence);
|
|
Assert.assertEquals(0x1d1e, ((Workout.WorkoutData.Response) packet).dataList.get(1).stepLength);
|
|
Assert.assertEquals(0x1f20, ((Workout.WorkoutData.Response) packet).dataList.get(1).groundContactTime);
|
|
Assert.assertEquals(0x21, ((Workout.WorkoutData.Response) packet).dataList.get(1).impact);
|
|
Assert.assertEquals(0x2223, ((Workout.WorkoutData.Response) packet).dataList.get(1).swingAngle);
|
|
Assert.assertEquals(0x24, ((Workout.WorkoutData.Response) packet).dataList.get(1).foreFootLanding);
|
|
Assert.assertEquals(0x25, ((Workout.WorkoutData.Response) packet).dataList.get(1).midFootLanding);
|
|
Assert.assertEquals(0x26, ((Workout.WorkoutData.Response) packet).dataList.get(1).backFootLanding);
|
|
Assert.assertEquals(0x27, ((Workout.WorkoutData.Response) packet).dataList.get(1).eversionAngle);
|
|
}
|
|
|
|
@Test
|
|
public void testWorkoutPaceRequest() throws NoSuchFieldException, IllegalAccessException, HuaweiPacket.CryptoException {
|
|
short workoutNumber = 0x0102;
|
|
short paceNumber = 0x0304;
|
|
|
|
Field tlvField = HuaweiPacket.class.getDeclaredField("tlv");
|
|
tlvField.setAccessible(true);
|
|
|
|
HuaweiTLV expectedTlv = new HuaweiTLV().put(0x81, new HuaweiTLV()
|
|
.put(0x02, workoutNumber)
|
|
.put(0x08, paceNumber)
|
|
);
|
|
|
|
byte[] expected = {(byte) 0x5a, (byte) 0x00, (byte) 0x2a, (byte) 0x00, (byte) 0x17, (byte) 0x0c, (byte) 0x7c, (byte) 0x01, (byte) 0x01, (byte) 0x7d, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x7e, (byte) 0x10, (byte) 0x0c, (byte) 0x18, (byte) 0x24, (byte) 0x67, (byte) 0x5e, (byte) 0xe9, (byte) 0x8d, (byte) 0x36, (byte) 0x5f, (byte) 0xde, (byte) 0x1c, (byte) 0x9e, (byte) 0xa0, (byte) 0xd7, (byte) 0x0a, (byte) 0x01, (byte) 0xd3, (byte) 0xce};
|
|
|
|
Workout.WorkoutPace.Request request = new Workout.WorkoutPace.Request(secretsProvider, workoutNumber, paceNumber);
|
|
|
|
Assert.assertEquals(0x17, request.serviceId);
|
|
Assert.assertEquals(0x0c, request.commandId);
|
|
Assert.assertEquals(expectedTlv, tlvField.get(request));
|
|
Assert.assertTrue(request.complete);
|
|
List<byte[]> out = request.serialize();
|
|
Assert.assertEquals(1, out.size());
|
|
Assert.assertArrayEquals(expected, out.get(0));
|
|
}
|
|
|
|
@Test
|
|
public void testWorkoutPaceResponse() throws NoSuchFieldException, IllegalAccessException, HuaweiPacket.ParseException {
|
|
byte[] raw = {(byte) 0x5a, (byte) 0x00, (byte) 0x4a, (byte) 0x00, (byte) 0x17, (byte) 0x0c, (byte) 0x7c, (byte) 0x01, (byte) 0x01, (byte) 0x7d, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x7e, (byte) 0x30, (byte) 0xe8, (byte) 0xfe, (byte) 0xb9, (byte) 0x27, (byte) 0xa6, (byte) 0xc5, (byte) 0x81, (byte) 0x65, (byte) 0x51, (byte) 0xb8, (byte) 0x24, (byte) 0xfe, (byte) 0x2a, (byte) 0xdc, (byte) 0x3d, (byte) 0x22, (byte) 0xd7, (byte) 0x34, (byte) 0x62, (byte) 0xaf, (byte) 0x06, (byte) 0x5f, (byte) 0xfe, (byte) 0x9c, (byte) 0xe8, (byte) 0xa6, (byte) 0x87, (byte) 0x23, (byte) 0xd6, (byte) 0xc7, (byte) 0x7a, (byte) 0xeb, (byte) 0x07, (byte) 0x06, (byte) 0x5c, (byte) 0x35, (byte) 0xe8, (byte) 0x99, (byte) 0xd3, (byte) 0x96, (byte) 0x0b, (byte) 0x99, (byte) 0x38, (byte) 0x65, (byte) 0x48, (byte) 0xcf, (byte) 0x0f, (byte) 0x99, (byte) 0xe2, (byte) 0x23};
|
|
|
|
short workoutNumber = 0x0102;
|
|
short paceNumber = 0x0304;
|
|
|
|
short distance1 = 0x0506;
|
|
byte type1 = 0x07;
|
|
int pace1 = 0x08090a0b;
|
|
|
|
short distance2 = 0x0c0d;
|
|
byte type2 = 0x0e;
|
|
int pace2 = 0x0f101112;
|
|
short correction = 0x1314;
|
|
|
|
Field tlvField = HuaweiPacket.class.getDeclaredField("tlv");
|
|
tlvField.setAccessible(true);
|
|
|
|
HuaweiTLV expectedTlv = new HuaweiTLV().put(0x81, new HuaweiTLV()
|
|
.put(0x02, workoutNumber)
|
|
.put(0x08, paceNumber)
|
|
.put(0x83, new HuaweiTLV()
|
|
.put(0x04, distance1)
|
|
.put(0x05, type1)
|
|
.put(0x06, pace1)
|
|
)
|
|
.put(0x83, new HuaweiTLV()
|
|
.put(0x04, distance2)
|
|
.put(0x05, type2)
|
|
.put(0x06, pace2)
|
|
.put(0x09, correction)
|
|
)
|
|
);
|
|
|
|
HuaweiPacket packet = new HuaweiPacket(secretsProvider).parse(raw);
|
|
packet.parseTlv();
|
|
|
|
Assert.assertEquals(0x17, packet.serviceId);
|
|
Assert.assertEquals(0x0c, packet.commandId);
|
|
Assert.assertEquals(expectedTlv, tlvField.get(packet));
|
|
Assert.assertTrue(packet.complete);
|
|
Assert.assertTrue(packet instanceof Workout.WorkoutPace.Response);
|
|
Assert.assertEquals(0x0102, ((Workout.WorkoutPace.Response) packet).workoutNumber);
|
|
Assert.assertEquals(0x0304, ((Workout.WorkoutPace.Response) packet).paceNumber);
|
|
Assert.assertEquals(2, ((Workout.WorkoutPace.Response) packet).blocks.size());
|
|
|
|
Assert.assertEquals(0x0506, ((Workout.WorkoutPace.Response) packet).blocks.get(0).distance);
|
|
Assert.assertEquals(0x07, ((Workout.WorkoutPace.Response) packet).blocks.get(0).type);
|
|
Assert.assertEquals(0x08090a0b, ((Workout.WorkoutPace.Response) packet).blocks.get(0).pace);
|
|
Assert.assertEquals(0, ((Workout.WorkoutPace.Response) packet).blocks.get(0).correction);
|
|
|
|
Assert.assertEquals(0x0c0d, ((Workout.WorkoutPace.Response) packet).blocks.get(1).distance);
|
|
Assert.assertEquals(0x0e, ((Workout.WorkoutPace.Response) packet).blocks.get(1).type);
|
|
Assert.assertEquals(0x0f101112, ((Workout.WorkoutPace.Response) packet).blocks.get(1).pace);
|
|
Assert.assertEquals(0x1314, ((Workout.WorkoutPace.Response) packet).blocks.get(1).correction);
|
|
}
|
|
}
|