mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-01-23 16:17:32 +01:00
Mi Band: Support activity fetching in later firmwares (needs testing)
Based on the profile version which is 0x2000700 for both the bug reporter on a Mi Band 1 and for me on a Mi Band 1s this either expects packets with length 20 (old firmwares) or 16 for HR enabled bands and 18 for non-HR enabled bands (new firmwares) We check for profile version >=0x02000000 which is guessed, that needs confirmation for older firmwares and untested ones Fixes #915
This commit is contained in:
parent
f85fd2dc46
commit
dc51714d01
@ -95,6 +95,10 @@ public class DeviceInfo extends AbstractInfo {
|
|||||||
return fw2Version;
|
return fw2Version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getProfileVersion() {
|
||||||
|
return profileVersion;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTest1AHRMode(boolean enableTestMode) {
|
public void setTest1AHRMode(boolean enableTestMode) {
|
||||||
test1AHRMode = enableTestMode;
|
test1AHRMode = enableTestMode;
|
||||||
}
|
}
|
||||||
|
@ -67,11 +67,11 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
|
|||||||
|
|
||||||
private final int activityMetadataLength = 11;
|
private final int activityMetadataLength = 11;
|
||||||
|
|
||||||
//temporary buffer, size is a multiple of 60 because we want to store complete minutes (1 minute = 3 or 4 bytes)
|
|
||||||
private final int activityDataHolderSize;
|
|
||||||
private final boolean hasExtendedActivityData;
|
private final boolean hasExtendedActivityData;
|
||||||
|
private final boolean hasPacketCounter;
|
||||||
|
|
||||||
private static class ActivityStruct {
|
private class ActivityStruct {
|
||||||
|
private int maxDataPacketLength = 20;
|
||||||
private int lastNotifiedProgress;
|
private int lastNotifiedProgress;
|
||||||
private final byte[] activityDataHolder;
|
private final byte[] activityDataHolder;
|
||||||
private final int activityDataHolderSize;
|
private final int activityDataHolderSize;
|
||||||
@ -86,21 +86,22 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
|
|||||||
//same as above, but remains untouched for the ack message
|
//same as above, but remains untouched for the ack message
|
||||||
private GregorianCalendar activityDataTimestampToAck = null;
|
private GregorianCalendar activityDataTimestampToAck = null;
|
||||||
|
|
||||||
ActivityStruct(int activityDataHolderSize) {
|
ActivityStruct(int activityDataHolderSize, int maxDataPacketLength) {
|
||||||
this.activityDataHolderSize = activityDataHolderSize;
|
this.activityDataHolderSize = activityDataHolderSize;
|
||||||
|
this.maxDataPacketLength = maxDataPacketLength;
|
||||||
activityDataHolder = new byte[activityDataHolderSize];
|
activityDataHolder = new byte[activityDataHolderSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasRoomFor(byte[] value) {
|
boolean hasRoomFor(byte[] value) {
|
||||||
return activityDataRemainingBytes >= value.length;
|
return activityDataRemainingBytes >= value.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValidData(byte[] value) {
|
boolean isValidData(byte[] value) {
|
||||||
//I don't like this clause, but until we figure out why we get different data sometimes this should work
|
//I don't like this clause, but until we figure out why we get different data sometimes this should work
|
||||||
return value.length == 20 || value.length == activityDataRemainingBytes;
|
return value.length == maxDataPacketLength || value.length == activityDataRemainingBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBufferFull() {
|
boolean isBufferFull() {
|
||||||
return activityDataHolderSize == activityDataHolderProgress;
|
return activityDataHolderSize == activityDataHolderProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,11 +117,11 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
|
|||||||
GB.assertThat(activityDataRemainingBytes >= 0, "Illegal state, remaining bytes is negative");
|
GB.assertThat(activityDataRemainingBytes >= 0, "Illegal state, remaining bytes is negative");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFirstChunk() {
|
boolean isFirstChunk() {
|
||||||
return activityDataTimestampProgress == null;
|
return activityDataTimestampProgress == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startNewBlock(GregorianCalendar timestamp, int dataUntilNextHeader) {
|
void startNewBlock(GregorianCalendar timestamp, int dataUntilNextHeader) {
|
||||||
GB.assertThat(timestamp != null, "Timestamp must not be null");
|
GB.assertThat(timestamp != null, "Timestamp must not be null");
|
||||||
|
|
||||||
if (isFirstChunk()) {
|
if (isFirstChunk()) {
|
||||||
@ -140,11 +141,11 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
|
|||||||
validate();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBlockFinished() {
|
boolean isBlockFinished() {
|
||||||
return activityDataRemainingBytes == 0;
|
return activityDataRemainingBytes == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bufferFlushed(int minutes) {
|
void bufferFlushed(int minutes) {
|
||||||
activityDataTimestampProgress.add(Calendar.MINUTE, minutes);
|
activityDataTimestampProgress.add(Calendar.MINUTE, minutes);
|
||||||
activityDataHolderProgress = 0;
|
activityDataHolderProgress = 0;
|
||||||
lastNotifiedProgress = 0;
|
lastNotifiedProgress = 0;
|
||||||
@ -156,8 +157,11 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
|
|||||||
public FetchActivityOperation(MiBandSupport support) {
|
public FetchActivityOperation(MiBandSupport support) {
|
||||||
super(support);
|
super(support);
|
||||||
hasExtendedActivityData = support.getDeviceInfo().supportsHeartrate();
|
hasExtendedActivityData = support.getDeviceInfo().supportsHeartrate();
|
||||||
activityDataHolderSize = getBytesPerMinuteOfActivityData() * 60 * 4; // 4h
|
hasPacketCounter = support.getDeviceInfo().getProfileVersion() >= 0x02000000;
|
||||||
activityStruct = new ActivityStruct(activityDataHolderSize);
|
//temporary buffer, size is a multiple of 60 because we want to store complete minutes (1 minute = 3 or 4 bytes)
|
||||||
|
int activityDataHolderSize = getBytesPerMinuteOfActivityData() * 60 * 4;
|
||||||
|
int maxDataPacketLength = hasPacketCounter ? (hasExtendedActivityData ? 16 : 18) : 20;
|
||||||
|
activityStruct = new ActivityStruct(activityDataHolderSize, maxDataPacketLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -215,9 +219,15 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
|
|||||||
|
|
||||||
if (value.length == activityMetadataLength) {
|
if (value.length == activityMetadataLength) {
|
||||||
handleActivityMetadata(value);
|
handleActivityMetadata(value);
|
||||||
|
} else {
|
||||||
|
if (hasPacketCounter) {
|
||||||
|
byte[] valueChopped = new byte[value.length - 1];
|
||||||
|
System.arraycopy(value, 1, valueChopped, 0, value.length - 1);
|
||||||
|
bufferActivityData(valueChopped);
|
||||||
} else {
|
} else {
|
||||||
bufferActivityData(value);
|
bufferActivityData(value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("activity data: length: " + value.length + ", remaining bytes: " + activityStruct.activityDataRemainingBytes);
|
LOG.debug("activity data: length: " + value.length + ", remaining bytes: " + activityStruct.activityDataRemainingBytes);
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@
|
|||||||
<string name="user_feedback_miband_set_alarms_failed">Feil ved setting av alarm, prøv igjen.</string>
|
<string name="user_feedback_miband_set_alarms_failed">Feil ved setting av alarm, prøv igjen.</string>
|
||||||
<string name="user_feedback_miband_set_alarms_ok">Alarmer sendt til enhet.</string>
|
<string name="user_feedback_miband_set_alarms_ok">Alarmer sendt til enhet.</string>
|
||||||
<string name="chart_no_data_synchronize">Ingen data. Synkroniser enhet?</string>
|
<string name="chart_no_data_synchronize">Ingen data. Synkroniser enhet?</string>
|
||||||
<string name="user_feedback_miband_activity_data_transfer">I ferd med å overføre %1$d med data fra %2$s</string>
|
<string name="user_feedback_miband_activity_data_transfer">I ferd med å overføre %1$s med data fra %2$s</string>
|
||||||
<string name="miband_prefs_fitness_goal">Stegmål</string>
|
<string name="miband_prefs_fitness_goal">Stegmål</string>
|
||||||
<string name="dbaccess_error_executing">Feil under kjøring av \"%1$s\"</string>
|
<string name="dbaccess_error_executing">Feil under kjøring av \"%1$s\"</string>
|
||||||
<string name="controlcenter_start_activitymonitor">Din aktivitet (alfa)</string>
|
<string name="controlcenter_start_activitymonitor">Din aktivitet (alfa)</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user