mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Garmin: Fix MLR retransmission request numbers
This commit is contained in:
+2
-1
@@ -821,7 +821,8 @@ public interface DeviceCoordinator {
|
||||
int[] getSupportedDeviceSpecificAuthenticationSettings();
|
||||
|
||||
/**
|
||||
* Returns device specific debug settings. This section is only shown in debug builds.
|
||||
* Returns device specific debug settings. This section is only shown in debug builds, and all behavior-altering
|
||||
* preferences should be gate-kept by the BuildConfig.DEBUG flag.
|
||||
*/
|
||||
int[] getSupportedDebugSettings(final GBDevice device);
|
||||
|
||||
|
||||
+10
@@ -8,6 +8,8 @@ import android.app.Activity;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -228,6 +230,14 @@ public abstract class GarminCoordinator extends AbstractBLEDeviceCoordinator {
|
||||
return new int[]{R.xml.devicesettings_garmin_experimental};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getSupportedDebugSettings(final GBDevice device) {
|
||||
return ArrayUtils.add(
|
||||
super.getSupportedDebugSettings(device),
|
||||
R.xml.devicesettings_debug_drop_packets
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) {
|
||||
final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings();
|
||||
|
||||
+26
-3
@@ -21,7 +21,9 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
@@ -161,6 +163,18 @@ public class CommunicatorV2 implements ICommunicator {
|
||||
final int handle = ((value[0] & MlrCommunicator.HANDLE_MASK) >> 4) | MlrCommunicator.MLR_FLAG_MASK;
|
||||
final MlrCommunicator mlrComm = mlrCommunicators.get(handle);
|
||||
if (mlrComm != null) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
final int packetPercentageIn = mSupport.getDevicePrefs().getInt("pref_debug_drop_packet_percentage_in", 0);
|
||||
if (packetPercentageIn > 0 && ThreadLocalRandom.current().nextInt(100) < packetPercentageIn) {
|
||||
LOG.warn(
|
||||
"Simulating dropped inbound packet handle={}, dataLen={}",
|
||||
handle,
|
||||
value.length
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
mlrComm.onPacketReceived(value);
|
||||
return true;
|
||||
}
|
||||
@@ -639,9 +653,18 @@ public class CommunicatorV2 implements ICommunicator {
|
||||
}
|
||||
|
||||
private MlrCommunicator createMlrCommunicator(final int handle, final ServiceCallback callback) {
|
||||
final MlrCommunicator.MessageSender messageSender = (taskName, packet) -> mSupport.createTransactionBuilder(taskName)
|
||||
.write(characteristicSend, packet)
|
||||
.queue();
|
||||
final MlrCommunicator.MessageSender messageSender = (taskName, packet) -> {
|
||||
if (BuildConfig.DEBUG) {
|
||||
final int packetPercentageOut = mSupport.getDevicePrefs().getInt("pref_debug_drop_packet_percentage_out", 0);
|
||||
if (packetPercentageOut > 0 && ThreadLocalRandom.current().nextInt(100) < packetPercentageOut) {
|
||||
LOG.warn("Simulating dropped outbound packet for {} ({})", taskName, GB.hexdump(packet));
|
||||
return;
|
||||
}
|
||||
}
|
||||
mSupport.createTransactionBuilder(taskName)
|
||||
.write(characteristicSend, packet)
|
||||
.queue();
|
||||
};
|
||||
|
||||
return new MlrCommunicator(handle, maxWriteSize, messageSender, callback::onMessage);
|
||||
}
|
||||
|
||||
+8
-5
@@ -81,12 +81,12 @@ public class MlrCommunicator {
|
||||
int position = 0;
|
||||
while (remainingBytes > 0) {
|
||||
final byte[] fragment = Arrays.copyOfRange(message, position, position + Math.min(remainingBytes, maxPacketSize - 2));
|
||||
fragmentQueue.add(new Fragment(taskName, i++, fragment));
|
||||
fragmentQueue.add(new Fragment(taskName, i++, fragment, 0));
|
||||
position += fragment.length;
|
||||
remainingBytes -= fragment.length;
|
||||
}
|
||||
} else {
|
||||
fragmentQueue.add(new Fragment(taskName, 0, message));
|
||||
fragmentQueue.add(new Fragment(taskName, 0, message, 0));
|
||||
}
|
||||
|
||||
runProtocol();
|
||||
@@ -219,9 +219,11 @@ public class MlrCommunicator {
|
||||
// Send next fragment if available
|
||||
final Fragment fragment = fragmentQueue.poll();
|
||||
if (fragment != null) {
|
||||
// Update the fragment with the current reqNum before storing it
|
||||
final Fragment fragmentWithReqNum = new Fragment(fragment.taskName, fragment.num, fragment.data, nextRcvSeq);
|
||||
final byte[] packet = createPacket(nextRcvSeq, nextSendSeq, fragment.data);
|
||||
messageSender.sendPacket(fragment.taskName + " (" + fragment.num + ")", packet);
|
||||
sentFragments[nextSendSeq] = fragment;
|
||||
sentFragments[nextSendSeq] = fragmentWithReqNum;
|
||||
|
||||
nextSendSeq = (nextSendSeq + 1) % (MAX_SEQ_NUM + 1);
|
||||
|
||||
@@ -278,7 +280,8 @@ public class MlrCommunicator {
|
||||
LOG.error("Attempting to re-send null fragment at index {}", i);
|
||||
continue;
|
||||
}
|
||||
final byte[] packet = createPacket(nextRcvSeq, i, fragment.data);
|
||||
// Use the original reqNum that was stored when the fragment was first sent
|
||||
final byte[] packet = createPacket(fragment.reqNum, i, fragment.data);
|
||||
messageSender.sendPacket("retransmission " + fragment.taskName + " (" + fragment.num + ")", packet);
|
||||
}
|
||||
|
||||
@@ -307,6 +310,6 @@ public class MlrCommunicator {
|
||||
void onDataReceived(final byte[] data);
|
||||
}
|
||||
|
||||
private record Fragment(String taskName, int num, byte[] data) {
|
||||
private record Fragment(String taskName, int num, byte[] data, int reqNum) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<SeekBarPreference
|
||||
android:defaultValue="0"
|
||||
android:icon="@drawable/ic_file_upload"
|
||||
android:key="pref_debug_drop_packet_percentage_out"
|
||||
android:max="100"
|
||||
android:summary="Probability of failing to send a packet"
|
||||
android:title="Simulate packet loss - outbound"
|
||||
app:showSeekBarValue="true" />
|
||||
<SeekBarPreference
|
||||
android:defaultValue="0"
|
||||
android:icon="@drawable/ic_download"
|
||||
android:key="pref_debug_drop_packet_percentage_in"
|
||||
android:max="100"
|
||||
android:summary="Probability of failing to receive a packet"
|
||||
android:title="Simulate packet loss - inbound"
|
||||
app:showSeekBarValue="true" />
|
||||
</androidx.preference.PreferenceScreen>
|
||||
Reference in New Issue
Block a user