Huawei: Fix BR partial packets

Would crash before. See added test for example.
This commit is contained in:
Martin.JM 2024-06-20 14:55:07 +02:00 committed by José Rebelo
parent 5ad6d07983
commit 1f1fc33e43
2 changed files with 65 additions and 3 deletions

View File

@ -890,10 +890,19 @@ public class HuaweiSupportProvider {
}
public void onSocketRead(byte[] data) {
//Check multiple packet in data
// The data can contain multiple packets, which need to be split.
// But we also need to take into account partial packets (where data does not contain a full packet)
if (data[0] != 0x5a) {
// Part of partial packet, just parse
responseManager.handleData(data);
return;
}
ByteBuffer bData = ByteBuffer.wrap(data);
while (bData.remaining() != 0x00) {
int dataLen = bData.getShort(bData.position() + 1) + 0x05; // magic + len + CRC
while (bData.remaining() != 0) {
int dataLen = bData.getShort(bData.position() + 1) + 0x05;
if (dataLen > bData.remaining())
dataLen = bData.remaining(); // Part of partial packet, just parse the remainder
byte[] newData = new byte[dataLen];
bData.get(newData, 0, dataLen);
responseManager.handleData(newData);

View File

@ -0,0 +1,53 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei;
import org.junit.Test;
import org.mockito.Mockito;
public class TestHuaweiSupportProvider {
@Test
public void testOnSocketReadExactPacket() {
byte[] data1 = {(byte) 0x5A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x99, (byte) 0x6B};
HuaweiBRSupport support = new HuaweiBRSupport();
HuaweiSupportProvider supportProvider = new HuaweiSupportProvider(support);
supportProvider.responseManager = Mockito.mock(ResponseManager.class);
supportProvider.onSocketRead(data1);
Mockito.verify(supportProvider.responseManager, Mockito.times(1)).handleData(data1);
}
@Test
public void testOnSocketReadMultiplePacket() {
byte[] expected = {(byte) 0x5A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x99, (byte) 0x6B};
byte[] data1 = {(byte) 0x5A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x99, (byte) 0x6B, (byte) 0x5A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x99, (byte) 0x6B};
HuaweiBRSupport support = new HuaweiBRSupport();
HuaweiSupportProvider supportProvider = new HuaweiSupportProvider(support);
supportProvider.responseManager = Mockito.mock(ResponseManager.class);
supportProvider.onSocketRead(data1);
Mockito.verify(supportProvider.responseManager, Mockito.times(2)).handleData(expected);
}
@Test
public void testOnSocketReadPartialPacket() {
byte[] data1 = {(byte) 0x5A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x01};
byte[] data2 = {(byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x99, (byte) 0x6B};
HuaweiBRSupport support = new HuaweiBRSupport();
HuaweiSupportProvider supportProvider = new HuaweiSupportProvider(support);
supportProvider.responseManager = Mockito.mock(ResponseManager.class);
supportProvider.onSocketRead(data1);
supportProvider.onSocketRead(data2);
Mockito.verify(supportProvider.responseManager, Mockito.times(1)).handleData(data1);
Mockito.verify(supportProvider.responseManager, Mockito.times(1)).handleData(data2);
}
}