mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-26 02:25:50 +01:00
FitPro: add MTU based chunking, add more device names, fix #2688
This commit is contained in:
parent
8c1c7fbe63
commit
49dcb04b62
@ -37,13 +37,13 @@ public class FitProConstants {
|
|||||||
|
|
||||||
public static final byte[] DATA_TEMPLATE = {
|
public static final byte[] DATA_TEMPLATE = {
|
||||||
(byte) DATA_HEADER, // header
|
(byte) DATA_HEADER, // header
|
||||||
(byte) 0x00, // delimiter or first byte of argument count?
|
(byte) 0x00, // data len hi
|
||||||
(byte) 0, // argument count, calculated
|
(byte) 0, // data len low
|
||||||
(byte) 0, // command 1
|
(byte) 0, // command 1
|
||||||
(byte) 0x1, // delimiter?
|
(byte) 0x1, // delimiter?
|
||||||
(byte) 0, // command 2
|
(byte) 0, // command 2
|
||||||
(byte) 0x0, // delimiter or first byte of data length?
|
(byte) 0x0, // data len hi
|
||||||
(byte) 0, // data length calculated
|
(byte) 0, // data len low
|
||||||
// data payload
|
// data payload
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import android.app.Activity;
|
|||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.ParcelUuid;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@ -62,9 +63,11 @@ public class FitProDeviceCoordinator extends AbstractDeviceCoordinator {
|
|||||||
|
|
||||||
if (name != null && (
|
if (name != null && (
|
||||||
name.startsWith("M6") ||
|
name.startsWith("M6") ||
|
||||||
name.startsWith("M4") ||
|
name.startsWith("M4") ||
|
||||||
name.equals("LH716") ||
|
name.equals("LH716") ||
|
||||||
name.equals("Fit1900"))
|
name.equals("Sunset 6") ||
|
||||||
|
name.equals("Watch7") ||
|
||||||
|
name.equals("Fit1900"))
|
||||||
) {
|
) {
|
||||||
return DeviceType.FITPRO;
|
return DeviceType.FITPRO;
|
||||||
}
|
}
|
||||||
@ -178,7 +181,7 @@ public class FitProDeviceCoordinator extends AbstractDeviceCoordinator {
|
|||||||
R.xml.devicesettings_donotdisturb_no_auto,
|
R.xml.devicesettings_donotdisturb_no_auto,
|
||||||
R.xml.devicesettings_sleep_time,
|
R.xml.devicesettings_sleep_time,
|
||||||
R.xml.devicesettings_wearlocation,
|
R.xml.devicesettings_wearlocation,
|
||||||
R.xml.devicesettings_autoheartrate,
|
//R.xml.devicesettings_autoheartrate, //removed, this is most likely not supported by these bands
|
||||||
R.xml.devicesettings_vibrations_enable,
|
R.xml.devicesettings_vibrations_enable,
|
||||||
R.xml.devicesettings_notifications_enable,
|
R.xml.devicesettings_notifications_enable,
|
||||||
R.xml.devicesettings_fitpro,
|
R.xml.devicesettings_fitpro,
|
||||||
|
@ -106,6 +106,7 @@ import java.text.DateFormat;
|
|||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
@ -114,7 +115,6 @@ import java.util.Locale;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
|
import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||||
@ -126,7 +126,6 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicContr
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.fitpro.FitProConstants;
|
import nodomain.freeyourgadget.gadgetbridge.devices.fitpro.FitProConstants;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.fitpro.FitProSampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.fitpro.FitProSampleProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.FitProActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.FitProActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
||||||
@ -167,6 +166,7 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
public BluetoothGattCharacteristic readCharacteristic;
|
public BluetoothGattCharacteristic readCharacteristic;
|
||||||
public BluetoothGattCharacteristic writeCharacteristic;
|
public BluetoothGattCharacteristic writeCharacteristic;
|
||||||
private static final boolean debugEnabled = false;
|
private static final boolean debugEnabled = false;
|
||||||
|
private int mtuSize=20;
|
||||||
|
|
||||||
public FitProDeviceSupport() {
|
public FitProDeviceSupport() {
|
||||||
super(LOG);
|
super(LOG);
|
||||||
@ -276,16 +276,27 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
//0xCD 0x00 0x09 0x12 0x01 0x01 0x00 0x04 0xA5 0x83 0x73 0xDB
|
//0xCD 0x00 0x09 0x12 0x01 0x01 0x00 0x04 0xA5 0x83 0x73 0xDB
|
||||||
byte[] result = new byte[FitProConstants.DATA_TEMPLATE.length + data.length];
|
byte[] result = new byte[FitProConstants.DATA_TEMPLATE.length + data.length];
|
||||||
System.arraycopy(FitProConstants.DATA_TEMPLATE, 0, result, 0, FitProConstants.DATA_TEMPLATE.length);
|
System.arraycopy(FitProConstants.DATA_TEMPLATE, 0, result, 0, FitProConstants.DATA_TEMPLATE.length);
|
||||||
result[2] = (byte) (FitProConstants.DATA_TEMPLATE.length + data.length - 3);
|
result[1] = (byte) (((FitProConstants.DATA_TEMPLATE.length + data.length - 3) >> 8) & 0xff);
|
||||||
|
result[2] = (byte) ((FitProConstants.DATA_TEMPLATE.length + data.length - 3) & 0xff);
|
||||||
result[3] = command_group;
|
result[3] = command_group;
|
||||||
result[5] = command;
|
result[5] = command;
|
||||||
result[7] = (byte) data.length;
|
result[6] = (byte) ((data.length >> 8 ) & 0xff);
|
||||||
|
result[7] = (byte) (data.length & 0xff);
|
||||||
System.arraycopy(data, 0, result, 8, data.length);
|
System.arraycopy(data, 0, result, 8, data.length);
|
||||||
//debug
|
//debug
|
||||||
debugPrintArray(result, "crafted packet");
|
debugPrintArray(result, "crafted packet");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send chucked up data
|
||||||
|
public void writeChunckedData(TransactionBuilder builder, byte[] data){
|
||||||
|
for (int start = 0; start < data.length; start += mtuSize) {
|
||||||
|
int end = start + mtuSize;
|
||||||
|
if (end > data.length) end = data.length;
|
||||||
|
builder.write(writeCharacteristic, Arrays.copyOfRange(data, start, end));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCharacteristicChanged(BluetoothGatt gatt,
|
public boolean onCharacteristicChanged(BluetoothGatt gatt,
|
||||||
BluetoothGattCharacteristic characteristic) {
|
BluetoothGattCharacteristic characteristic) {
|
||||||
@ -476,7 +487,9 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
LOG.error("error sending call notification: " + e);
|
LOG.error("error sending call notification: " + e);
|
||||||
}
|
}
|
||||||
debugPrintArray(craftData(CMD_GROUP_GENERAL, CMD_NOTIFICATION_CALL, outputStream.toByteArray()), "crafted call notify");
|
debugPrintArray(craftData(CMD_GROUP_GENERAL, CMD_NOTIFICATION_CALL, outputStream.toByteArray()), "crafted call notify");
|
||||||
builder.write(writeCharacteristic, craftData(CMD_GROUP_GENERAL, CMD_NOTIFICATION_CALL, outputStream.toByteArray()));
|
|
||||||
|
writeChunckedData(builder, craftData(CMD_GROUP_GENERAL, CMD_NOTIFICATION_CALL, outputStream.toByteArray()));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
builder.write(writeCharacteristic, craftData(CMD_GROUP_GENERAL, CMD_NOTIFICATION_CALL, VALUE_OFF));
|
builder.write(writeCharacteristic, craftData(CMD_GROUP_GENERAL, CMD_NOTIFICATION_CALL, VALUE_OFF));
|
||||||
}
|
}
|
||||||
@ -631,7 +644,7 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
byte currentConditionCode = Weather.mapToFitProCondition(weatherSpec.currentConditionCode);
|
byte currentConditionCode = Weather.mapToFitProCondition(weatherSpec.currentConditionCode);
|
||||||
TransactionBuilder builder = new TransactionBuilder("weather");
|
TransactionBuilder builder = new TransactionBuilder("weather");
|
||||||
builder.write(writeCharacteristic, craftData(CMD_GROUP_GENERAL, CMD_WEATHER, new byte[]{(byte) todayMin, (byte) todayMax, (byte) currentConditionCode, (byte) weatherUnit}));
|
writeChunckedData(builder, craftData(CMD_GROUP_GENERAL, CMD_WEATHER, new byte[]{(byte) todayMin, (byte) todayMax, (byte) currentConditionCode, (byte) weatherUnit}));
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,11 +721,11 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
LOG.error("FitPro error sending notification: " + e);
|
LOG.error("FitPro error sending notification: " + e);
|
||||||
}
|
}
|
||||||
String output = outputStream.toString();
|
String output = outputStream.toString();
|
||||||
if (outputStream.toString().length() > 60) {
|
if (outputStream.toString().length() > 250) {
|
||||||
output = outputStream.toString().substring(0, 60);
|
output = outputStream.toString().substring(0, 250);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.write(writeCharacteristic, craftData(CMD_GROUP_GENERAL, CMD_NOTIFICATION_MESSAGE, output.getBytes(StandardCharsets.UTF_8)));
|
writeChunckedData(builder, craftData(CMD_GROUP_GENERAL, CMD_NOTIFICATION_MESSAGE, output.getBytes(StandardCharsets.UTF_8)));
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -990,7 +1003,8 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.write(writeCharacteristic, craftData(CMD_GROUP_GENERAL, CMD_ALARM, all_alarms));
|
writeChunckedData(builder, craftData(CMD_GROUP_GENERAL, CMD_ALARM, all_alarms));
|
||||||
|
//builder.write(writeCharacteristic, craftData(CMD_GROUP_GENERAL, CMD_ALARM, all_alarms));
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
if (anyAlarmEnabled) {
|
if (anyAlarmEnabled) {
|
||||||
GB.toast(getContext(), getContext().getString(R.string.user_feedback_miband_set_alarms_ok), Toast.LENGTH_SHORT, GB.INFO);
|
GB.toast(getContext(), getContext().getString(R.string.user_feedback_miband_set_alarms_ok), Toast.LENGTH_SHORT, GB.INFO);
|
||||||
|
Loading…
Reference in New Issue
Block a user