mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-12 01:51:58 +01:00
adjusted some MTU specific file handling
This commit is contained in:
parent
5cab9fa9da
commit
56d5b95181
@ -6,20 +6,15 @@ import android.os.Build;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.RequiresApi;
|
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
|
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper;
|
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilter;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
@ -31,11 +26,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationGetRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationGetRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.connection.SetConnectionParametersRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileCloseRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileDeleteRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileVerifyRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.NotificationFilterPutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.NotificationFilterPutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayNotificationRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayNotificationRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest;
|
||||||
@ -49,6 +40,10 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
private FossilRequest fossilRequest;
|
private FossilRequest fossilRequest;
|
||||||
|
|
||||||
|
private int MTU = 23;
|
||||||
|
|
||||||
|
private String ITEM_MTU = "MTU";
|
||||||
|
|
||||||
public FossilWatchAdapter(QHybridSupport deviceSupport) {
|
public FossilWatchAdapter(QHybridSupport deviceSupport) {
|
||||||
super(deviceSupport);
|
super(deviceSupport);
|
||||||
}
|
}
|
||||||
@ -57,16 +52,22 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
playPairingAnimation();
|
playPairingAnimation();
|
||||||
// queueWrite(new FileDeleteRequest((short) 0x0200));
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
queueWrite(new RequestMtuRequest(512));
|
queueWrite(new RequestMtuRequest(512));
|
||||||
|
}
|
||||||
queueWrite(new ConfigurationGetRequest(this));
|
queueWrite(new ConfigurationGetRequest(this));
|
||||||
// queueWrite(new SetConnectionParametersRequest());
|
|
||||||
|
|
||||||
syncNotificationSettings();
|
syncNotificationSettings();
|
||||||
|
|
||||||
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED));
|
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getMTU(){
|
||||||
|
if(this.MTU < 0) throw new RuntimeException("MTU not configured");
|
||||||
|
|
||||||
|
return this.MTU;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playPairingAnimation() {
|
public void playPairingAnimation() {
|
||||||
queueWrite(new AnimationRequest());
|
queueWrite(new AnimationRequest());
|
||||||
@ -315,6 +316,11 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
|
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
|
||||||
super.onMtuChanged(gatt, mtu, status);
|
super.onMtuChanged(gatt, mtu, status);
|
||||||
|
this.MTU = mtu;
|
||||||
|
|
||||||
|
getDeviceSupport().getDevice().addDeviceInfo(new GenericItem(ITEM_MTU, String.valueOf(mtu)));
|
||||||
|
getDeviceSupport().getDevice().sendDeviceUpdateIntent(getContext());
|
||||||
|
|
||||||
((RequestMtuRequest)fossilRequest).setFinished(true);
|
((RequestMtuRequest)fossilRequest).setFinished(true);
|
||||||
try {
|
try {
|
||||||
queueWrite(requestQueue.remove(0));
|
queueWrite(requestQueue.remove(0));
|
||||||
@ -325,7 +331,6 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
//TODO split to multiple methods instead of switch
|
//TODO split to multiple methods instead of switch
|
||||||
public void queueWrite(Request request, boolean priorise) {
|
public void queueWrite(Request request, boolean priorise) {
|
||||||
if(request instanceof RequestMtuRequest){
|
if(request instanceof RequestMtuRequest){
|
||||||
//TODO mtu on older devices
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
new TransactionBuilder("requestMtu")
|
new TransactionBuilder("requestMtu")
|
||||||
.requestMtu(512)
|
.requestMtu(512)
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
public class RequestMtuRequest extends FossilRequest {
|
public class RequestMtuRequest extends FossilRequest {
|
||||||
private int mtu;
|
private int mtu;
|
||||||
private boolean finished = false;
|
private boolean finished = false;
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
public RequestMtuRequest(int mtu) {
|
public RequestMtuRequest(int mtu) {
|
||||||
this.mtu = mtu;
|
this.mtu = mtu;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
public class FilePutRequest extends FossilRequest {
|
public class FilePutRequest extends FossilRequest {
|
||||||
public enum UploadState{INITIALIZED, UPLOADING, CLOSING, UPLOADED}
|
public enum UploadState {INITIALIZED, UPLOADING, CLOSING, UPLOADED}
|
||||||
|
|
||||||
public UploadState state;
|
public UploadState state;
|
||||||
|
|
||||||
@ -29,6 +29,8 @@ public class FilePutRequest extends FossilRequest {
|
|||||||
|
|
||||||
private FossilWatchAdapter adapter;
|
private FossilWatchAdapter adapter;
|
||||||
|
|
||||||
|
byte[] file;
|
||||||
|
|
||||||
public FilePutRequest(short handle, byte[] file, FossilWatchAdapter adapter) {
|
public FilePutRequest(short handle, byte[] file, FossilWatchAdapter adapter) {
|
||||||
this.handle = handle;
|
this.handle = handle;
|
||||||
this.adapter = adapter;
|
this.adapter = adapter;
|
||||||
@ -42,7 +44,7 @@ public class FilePutRequest extends FossilRequest {
|
|||||||
|
|
||||||
this.data = buffer.array();
|
this.data = buffer.array();
|
||||||
|
|
||||||
prepareFilePackets(file);
|
this.file = file;
|
||||||
|
|
||||||
state = UploadState.INITIALIZED;
|
state = UploadState.INITIALIZED;
|
||||||
}
|
}
|
||||||
@ -54,7 +56,7 @@ public class FilePutRequest extends FossilRequest {
|
|||||||
@Override
|
@Override
|
||||||
public void handleResponse(BluetoothGattCharacteristic characteristic) {
|
public void handleResponse(BluetoothGattCharacteristic characteristic) {
|
||||||
byte[] value = characteristic.getValue();
|
byte[] value = characteristic.getValue();
|
||||||
if(characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")) {
|
if (characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")) {
|
||||||
int responseType = value[0] & 0x0F;
|
int responseType = value[0] & 0x0F;
|
||||||
log("response: " + responseType);
|
log("response: " + responseType);
|
||||||
switch (responseType) {
|
switch (responseType) {
|
||||||
@ -63,15 +65,17 @@ public class FilePutRequest extends FossilRequest {
|
|||||||
throw new RuntimeException("wrong answer header");
|
throw new RuntimeException("wrong answer header");
|
||||||
}
|
}
|
||||||
state = UploadState.UPLOADING;
|
state = UploadState.UPLOADING;
|
||||||
byte[] initialPacket = packets.get(0);
|
|
||||||
BtLEQueue queue = adapter.getDeviceSupport().getQueue();
|
|
||||||
|
|
||||||
new TransactionBuilder("file upload")
|
TransactionBuilder transactionBuilder = new TransactionBuilder("file upload");
|
||||||
.write(
|
BluetoothGattCharacteristic uploadCharacteristic = adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0004-957f-7d4a-34a6-74696673696d"));
|
||||||
adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0004-957f-7d4a-34a6-74696673696d")),
|
|
||||||
initialPacket
|
this.prepareFilePackets(this.file);
|
||||||
)
|
|
||||||
.queue(queue);
|
for (byte[] packet : packets) {
|
||||||
|
transactionBuilder.write(uploadCharacteristic, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
transactionBuilder.queue(adapter.getDeviceSupport().getQueue());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 8: {
|
case 8: {
|
||||||
@ -101,34 +105,21 @@ public class FilePutRequest extends FossilRequest {
|
|||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
packetIndex++;
|
|
||||||
|
|
||||||
if (packetIndex < packets.size()) {
|
ByteBuffer buffer2 = ByteBuffer.allocate(3);
|
||||||
byte[] initialPacket = packets.get(packetIndex);
|
buffer2.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
buffer2.put((byte) 4);
|
||||||
|
buffer2.putShort(this.handle);
|
||||||
|
|
||||||
new TransactionBuilder("file upload")
|
new TransactionBuilder("file close")
|
||||||
.write(
|
.write(
|
||||||
adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0004-957f-7d4a-34a6-74696673696d")),
|
adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d")),
|
||||||
initialPacket
|
buffer2.array()
|
||||||
)
|
)
|
||||||
.queue(adapter.getDeviceSupport().getQueue());
|
.queue(adapter.getDeviceSupport().getQueue());
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
ByteBuffer buffer2 = ByteBuffer.allocate(3);
|
|
||||||
buffer2.order(ByteOrder.LITTLE_ENDIAN);
|
|
||||||
buffer2.put((byte) 4);
|
|
||||||
buffer2.putShort(this.handle);
|
|
||||||
|
|
||||||
new TransactionBuilder("file close")
|
this.state = UploadState.CLOSING;
|
||||||
.write(
|
break;
|
||||||
adapter.getDeviceSupport().getCharacteristic(UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d")),
|
|
||||||
buffer2.array()
|
|
||||||
)
|
|
||||||
.queue(adapter.getDeviceSupport().getQueue());
|
|
||||||
|
|
||||||
this.state = UploadState.CLOSING;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case 4: {
|
case 4: {
|
||||||
if (value.length == 9) return;
|
if (value.length == 9) return;
|
||||||
@ -184,18 +175,19 @@ public class FilePutRequest extends FossilRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFinished(){
|
public boolean isFinished() {
|
||||||
return this.state == UploadState.UPLOADED;
|
return this.state == UploadState.UPLOADED;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareFilePackets(byte[] file) {
|
private void prepareFilePackets(byte[] file) {
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(file.length + 13 + 4);
|
int maxPacketSize = adapter.getMTU() - 4;
|
||||||
|
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(file.length + 12 + 4);
|
||||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
buffer.put((byte)0);
|
|
||||||
buffer.putShort(handle);
|
buffer.putShort(handle);
|
||||||
buffer.put((byte)2);
|
buffer.put((byte) 2);
|
||||||
buffer.put((byte)0);
|
buffer.put((byte) 0);
|
||||||
buffer.putInt(0);
|
buffer.putInt(0);
|
||||||
buffer.putInt(file.length);
|
buffer.putInt(file.length);
|
||||||
|
|
||||||
@ -206,10 +198,22 @@ public class FilePutRequest extends FossilRequest {
|
|||||||
crc.update(file);
|
crc.update(file);
|
||||||
buffer.putInt((int) crc.getValue());
|
buffer.putInt((int) crc.getValue());
|
||||||
|
|
||||||
packets.add(buffer.array());
|
byte[] data = buffer.array();
|
||||||
|
|
||||||
|
int packetCount = (int) Math.ceil(data.length / (float) maxPacketSize);
|
||||||
|
|
||||||
|
for (int i = 0; i < packetCount; i++) {
|
||||||
|
int currentPacketLength = Math.min(maxPacketSize, data.length - i * maxPacketSize);
|
||||||
|
byte[] packet = new byte[currentPacketLength + 1];
|
||||||
|
packet[0] = (byte) i;
|
||||||
|
System.arraycopy(data, i * maxPacketSize, packet, 1, currentPacketLength);
|
||||||
|
|
||||||
|
packets.add(packet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFilePut(boolean success){}
|
public void onFilePut(boolean success) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] getStartSequence() {
|
public byte[] getStartSequence() {
|
||||||
|
Loading…
Reference in New Issue
Block a user