mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-24 09:35:50 +01:00
Garmin: Add support for V1
This commit is contained in:
parent
ce126b805e
commit
a6de977d50
@ -143,20 +143,26 @@ public class GarminSupport extends AbstractBTLEDeviceSupport implements ICommuni
|
||||
protected TransactionBuilder initializeDevice(final TransactionBuilder builder) {
|
||||
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext()));
|
||||
|
||||
if (getSupportedServices().contains(CommunicatorV2.UUID_SERVICE_GARMIN_ML_GFDI)) {
|
||||
communicator = new CommunicatorV2(this);
|
||||
} else if (getSupportedServices().contains(CommunicatorV1.UUID_SERVICE_GARMIN_GFDI)) {
|
||||
communicator = new CommunicatorV1(this);
|
||||
} else {
|
||||
LOG.warn("Failed to find a known Garmin service");
|
||||
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.NOT_CONNECTED, getContext()));
|
||||
return builder;
|
||||
}
|
||||
|
||||
if (getDevicePrefs().getBoolean(PREF_ALLOW_HIGH_MTU, true)) {
|
||||
builder.requestMtu(515);
|
||||
}
|
||||
|
||||
final CommunicatorV2 communicatorV2 = new CommunicatorV2(this);
|
||||
if (communicatorV2.initializeDevice(builder)) {
|
||||
communicator = communicatorV2;
|
||||
} else {
|
||||
// V2 did not manage to initialize, attempt V1
|
||||
final CommunicatorV1 communicatorV1 = new CommunicatorV1(this);
|
||||
if (!communicatorV1.initializeDevice(builder)) {
|
||||
// Neither V1 nor V2 worked, not a Garmin device?
|
||||
LOG.warn("Failed to find a known Garmin service");
|
||||
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.NOT_CONNECTED, getContext()));
|
||||
return builder;
|
||||
}
|
||||
|
||||
communicator = communicatorV1;
|
||||
}
|
||||
|
||||
communicator.initializeDevice(builder);
|
||||
|
||||
return builder;
|
||||
|
@ -10,7 +10,7 @@ public interface ICommunicator {
|
||||
|
||||
void onMtuChanged(final int mtu);
|
||||
|
||||
void initializeDevice(TransactionBuilder builder);
|
||||
boolean initializeDevice(TransactionBuilder builder);
|
||||
|
||||
boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic);
|
||||
|
||||
|
@ -6,40 +6,88 @@ import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.GarminSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.communicator.CobsCoDec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.communicator.ICommunicator;
|
||||
|
||||
public class CommunicatorV1 implements ICommunicator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CommunicatorV1.class);
|
||||
|
||||
public static final UUID UUID_SERVICE_GARMIN_GFDI = UUID.fromString("6A4E2401-667B-11E3-949A-0800200C9A66");
|
||||
public static final UUID UUID_CHARACTERISTIC_GARMIN_GFDI_SEND = UUID.fromString("6A4E4C80-667B-11E3-949A-0800200C9A66");
|
||||
public static final UUID UUID_CHARACTERISTIC_GARMIN_GFDI_RECEIVE = UUID.fromString("6A4ECD28-667B-11E3-949A-0800200C9A66");
|
||||
|
||||
private BluetoothGattCharacteristic characteristicSend;
|
||||
private BluetoothGattCharacteristic characteristicReceive;
|
||||
|
||||
private final GarminSupport mSupport;
|
||||
|
||||
public final CobsCoDec cobsCoDec;
|
||||
public int maxWriteSize = 20;
|
||||
|
||||
public CommunicatorV1(final GarminSupport garminSupport) {
|
||||
this.mSupport = garminSupport;
|
||||
this.cobsCoDec = new CobsCoDec();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMtuChanged(final int mtu) {
|
||||
|
||||
maxWriteSize = mtu - 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeDevice(final TransactionBuilder builder) {
|
||||
LOG.error("Initialization is not implemented for V1");
|
||||
public boolean initializeDevice(final TransactionBuilder builder) {
|
||||
characteristicSend = mSupport.getCharacteristic(UUID_CHARACTERISTIC_GARMIN_GFDI_SEND);
|
||||
characteristicReceive = mSupport.getCharacteristic(UUID_CHARACTERISTIC_GARMIN_GFDI_RECEIVE);
|
||||
|
||||
if (characteristicSend == null || characteristicReceive == null) {
|
||||
LOG.warn("Failed to find V1 GFDI characteristics");
|
||||
return false;
|
||||
}
|
||||
|
||||
builder.notify(characteristicReceive, true);
|
||||
|
||||
LOG.debug("Initializing as Garmin V1");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(final String taskName, final byte[] message) {
|
||||
if (null == message)
|
||||
return;
|
||||
|
||||
final byte[] payload = cobsCoDec.encode(message);
|
||||
|
||||
final TransactionBuilder builder = new TransactionBuilder(taskName);
|
||||
int remainingBytes = payload.length;
|
||||
if (remainingBytes > maxWriteSize - 1) {
|
||||
int position = 0;
|
||||
while (remainingBytes > 0) {
|
||||
final byte[] fragment = Arrays.copyOfRange(payload, position, position + Math.min(remainingBytes, maxWriteSize - 1));
|
||||
builder.write(characteristicSend, fragment);
|
||||
position += fragment.length;
|
||||
remainingBytes -= fragment.length;
|
||||
}
|
||||
} else {
|
||||
builder.write(characteristicSend, payload);
|
||||
}
|
||||
builder.queue(this.mSupport.getQueue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
|
||||
if (characteristic.getUuid().equals(characteristicReceive.getUuid())) {
|
||||
this.cobsCoDec.receivedBytes(characteristic.getValue());
|
||||
this.mSupport.onMessage(this.cobsCoDec.retrieveMessage());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ public class CommunicatorV2 implements ICommunicator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeDevice(final TransactionBuilder builder) {
|
||||
public boolean initializeDevice(final TransactionBuilder builder) {
|
||||
// Iterate through the known ML characteristics until we find a known pair
|
||||
// send characteristic = read characteristic + 0x10 (eg. 2810 / 2820)
|
||||
for (int i = 0x2810; i <= 0x2814; i++) {
|
||||
@ -90,13 +90,13 @@ public class CommunicatorV2 implements ICommunicator {
|
||||
builder.notify(characteristicReceive, true);
|
||||
builder.write(characteristicSend, closeAllServices());
|
||||
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
LOG.warn("Failed to find any known ML characteristics");
|
||||
|
||||
builder.add(new SetDeviceStateAction(mSupport.getDevice(), GBDevice.State.NOT_CONNECTED, mSupport.getContext()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user