1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-28 03:25:49 +01:00

fixed file upload bug

This commit is contained in:
Daniel Dakhno 2019-11-14 04:56:34 +01:00
parent 64b407da92
commit 161236f3a2
10 changed files with 246 additions and 20 deletions

View File

@ -123,6 +123,7 @@ public class QHybridAppChoserActivity extends AbstractGBActivity {
if(success){
try {
helper.saveNotificationConfiguration(config);
LocalBroadcastManager.getInstance(QHybridAppChoserActivity.this).sendBroadcast(new Intent(QHybridSupport.QHYBRID_COMMAND_NOTIFICATION_CONFIG_CHANGED));
} catch (GBException e) {
e.printStackTrace();
GB.toast("error saving configuration", Toast.LENGTH_SHORT, GB.ERROR, e);

View File

@ -26,6 +26,7 @@ import java.io.StringWriter;
import java.util.HashMap;
import java.util.UUID;
import androidx.annotation.RequiresApi;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
@ -342,6 +343,13 @@ public class QHybridSupport extends QHybridBaseSupport {
}
}
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
if(watchAdapter == null) return;
watchAdapter.onMtuChanged(gatt, mtu, status);
}
private void playNotification(NotificationConfiguration config) {
if (config.getMin() == -1 && config.getHour() == -1 && config.getVibration() == PlayNotificationRequest.VibrationType.NO_VIBE)
return;
@ -508,6 +516,7 @@ public class QHybridSupport extends QHybridBaseSupport {
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic
characteristic) {
if(watchAdapter == null) return super.onCharacteristicChanged(gatt, characteristic);
return watchAdapter.onCharacteristicChanged(gatt, characteristic);
}

View File

@ -48,7 +48,7 @@ public abstract class WatchAdapter {
public abstract void onFetchActivityData();
public abstract boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic);
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status){};
public String arrayToString(byte[] bytes) {

View File

@ -2,16 +2,21 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fos
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.os.Build;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.Logging;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper;
import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilter;
@ -22,11 +27,15 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSuppo
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest;
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.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.FileVerifyRequest;
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.misfit.AnimationRequest;
@ -49,11 +58,13 @@ public class FossilWatchAdapter extends WatchAdapter {
public void initialize() {
// playPairingAnimation();
// queueWrite(new FileDeleteRequest((short) 0x0200));
// queueWrite(new ConfigurationGetRequest(this));
//
// syncNotificationSettings();
getDeviceSupport().getDevice().setState(GBDevice.State.INITIALIZED);
getDeviceSupport().getDevice().sendDeviceUpdateIntent(getContext());
queueWrite(new RequestMtuRequest(512));
queueWrite(new ConfigurationGetRequest(this));
// queueWrite(new SetConnectionParametersRequest());
syncNotificationSettings();
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED));
}
@Override
@ -139,14 +150,13 @@ public class FossilWatchAdapter extends WatchAdapter {
@Override
public void setVibrationStrength(short strength) {
ConfigurationPutRequest.ConfigItem vibrationItem = new ConfigurationPutRequest.VibrationStrengthConfigItem((byte)strength);
queueWrite(
new ConfigurationPutRequest(
new ConfigurationPutRequest.VibrationStrengthConfigItem(
(byte) strength
),
this
)
new ConfigurationPutRequest(new ConfigurationPutRequest.ConfigItem[]{vibrationItem, vibrationItem, vibrationItem}, this)
);
// queueWrite(new FileVerifyRequest((short) 0x0800));
}
@Override
@ -179,6 +189,7 @@ public class FossilWatchAdapter extends WatchAdapter {
@Override
public void onTestNewFunction() {
queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.ConfigItem[0], this));
}
@Override
@ -226,7 +237,8 @@ public class FossilWatchAdapter extends WatchAdapter {
public void onFetchActivityData() {
// queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.ConfigItem[0], this));
queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.VibrationStrengthConfigItem((byte) 100), this));
setVibrationStrength((byte) 50);
// queueWrite(new FileCloseRequest((short) 0x0800));
// queueWrite(new ConfigurationGetRequest(this));
}
@ -237,14 +249,20 @@ public class FossilWatchAdapter extends WatchAdapter {
handleBackgroundCharacteristic(characteristic);
break;
}
case "3dda0002-957f-7d4a-34a6-74696673696d": {
break;
}
case "3dda0002-957f-7d4a-34a6-74696673696d":
case "3dda0004-957f-7d4a-34a6-74696673696d":
case "3dda0003-957f-7d4a-34a6-74696673696d": {
if (fossilRequest != null) {
boolean requestFinished;
try {
if(characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")){
byte requestType = (byte)(characteristic.getValue()[0] & 0x0F);
if(requestType != 0x0A && requestType != fossilRequest.getType()){
// throw new RuntimeException("Answer type " + requestType + " does not match current request " + fossilRequest.getType());
}
}
fossilRequest.handleResponse(characteristic);
requestFinished = fossilRequest.isFinished();
} catch (RuntimeException e) {
@ -294,14 +312,44 @@ public class FossilWatchAdapter extends WatchAdapter {
this.queueWrite(request, false);
}
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
((RequestMtuRequest)fossilRequest).setFinished(true);
try {
queueWrite(requestQueue.remove(0));
} catch (IndexOutOfBoundsException e) {
}
}
//TODO split to multiple methods instead of switch
public void queueWrite(Request request, boolean priorise) {
if (request.isBasicRequest()) {
if(request instanceof RequestMtuRequest){
//TODO mtu on older devices
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
new TransactionBuilder("requestMtu")
.requestMtu(512)
.queue(getDeviceSupport().getQueue());
this.fossilRequest = (FossilRequest) request;
}
return;
}else if(request instanceof SetDeviceStateRequest){
log("setting device state: " + ((SetDeviceStateRequest)request).getDeviceState());
getDeviceSupport().getDevice().setState(((SetDeviceStateRequest)request).getDeviceState());
getDeviceSupport().getDevice().sendDeviceUpdateIntent(getContext());
try {
queueWrite(requestQueue.remove(0));
} catch (IndexOutOfBoundsException e) {
}
return;
} else if (request.isBasicRequest()) {
try {
queueWrite(requestQueue.remove(0));
} catch (IndexOutOfBoundsException e) {
}
} else {
if (fossilRequest != null) {
if (fossilRequest != null && !fossilRequest.isFinished()) {
log("queing request: " + request.getName());
if (priorise) {
requestQueue.add(0, request);

View File

@ -7,6 +7,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Req
public abstract class FossilRequest extends Request {
public abstract boolean isFinished();
public byte getType(){
return getStartSequence()[0];
}
@Override
public UUID getRequestUUID() {

View File

@ -0,0 +1,28 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil;
public class RequestMtuRequest extends FossilRequest {
private int mtu;
private boolean finished = false;
public RequestMtuRequest(int mtu) {
this.mtu = mtu;
}
public int getMtu() {
return mtu;
}
@Override
public boolean isFinished() {
return finished;
}
public void setFinished(boolean finished) {
this.finished = finished;
}
@Override
public byte[] getStartSequence() {
return new byte[0];
}
}

View File

@ -0,0 +1,25 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
public class SetDeviceStateRequest extends FossilRequest {
private GBDevice.State deviceState;
public SetDeviceStateRequest(GBDevice.State deviceState) {
this.deviceState = deviceState;
}
public GBDevice.State getDeviceState() {
return deviceState;
}
@Override
public boolean isFinished() {
return true;
}
@Override
public byte[] getStartSequence() {
return new byte[0];
}
}

View File

@ -0,0 +1,37 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.connection;
import android.bluetooth.BluetoothGattCharacteristic;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
public class SetConnectionParametersRequest extends FossilRequest {
private boolean finished = false;
@Override
public boolean isFinished() {
return finished;
}
@Override
public UUID getRequestUUID() {
return UUID.fromString("3dda0002-957f-7d4a-34a6-74696673696d");
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
this.finished = true;
}
@Override
public byte[] getStartSequence() {
return new byte[]{0x02, 0x09, 0x0C, 0x00, 0x0C, 0x00, 0x2D, 0x00, 0x58, 0x02};
}
@Override
public boolean isBasicRequest() {
return false;
}
}

View File

@ -66,7 +66,7 @@ public class FileLookupRequest extends FossilRequest {
byte status = buffer.get(3);
if(status != 0){
throw new RuntimeException("FileGet error: " + status);
throw new RuntimeException("file lookup error: " + status);
}
if(this.handle != handle){

View File

@ -0,0 +1,75 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file;
import android.bluetooth.BluetoothGattCharacteristic;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
public class FileVerifyRequest extends FossilRequest {
private boolean isFinished = false;
private short handle;
public FileVerifyRequest(short fileHandle) {
this.handle = fileHandle;
ByteBuffer buffer = this.createBuffer();
buffer.putShort(fileHandle);
this.data = buffer.array();
}
public short getHandle() {
return handle;
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
if(!characteristic.getUuid().toString().equals(this.getRequestUUID().toString())){
throw new RuntimeException("wrong response UUID");
}
byte[] value = characteristic.getValue();
byte type = (byte)(value[0] & 0x0F);
if(type == 0x0A) return;
if(type != 4) throw new RuntimeException("wrong response type");
if(value.length != 4) throw new RuntimeException("wrong response length");
ByteBuffer buffer = ByteBuffer.wrap(value);
buffer.order(ByteOrder.LITTLE_ENDIAN);
if(this.handle != buffer.getShort(1)) throw new RuntimeException("wrong response handle");
byte status = buffer.get(3);
if(status != 0) throw new RuntimeException("wrong response status");
this.isFinished = true;
this.onPrepare();
}
public void onPrepare(){}
@Override
public byte[] getStartSequence() {
return new byte[]{4};
}
@Override
public int getPayloadLength() {
return 3;
}
@Override
public boolean isFinished(){
return this.isFinished;
}
}