1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-08-01 03:23:26 +02:00
Gadgetbridge/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/TestWorkout.java
2024-02-09 12:03:01 +01:00

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);
}
}