1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-24 17:45:50 +01:00

Fossil Hybrid: refactored fileGetRequest

This commit is contained in:
Daniel Dakhno 2020-10-17 03:40:12 +02:00
parent 0c3c749149
commit 45df4cd35c
10 changed files with 166 additions and 133 deletions

View File

@ -64,7 +64,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.Activ
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.file.FileDeleteRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileLookupRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayCallNotificationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest;
@ -548,9 +548,9 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
}
});
}else{
queueWrite(new FileGetRequest(handle, this) {
queueWrite(new FileGetRawRequest(handle, this) {
@Override
public void handleFileData(byte[] fileData) {
public void handleFileRawData(byte[] fileData) {
logger.debug("downloaded regular file");
handleFileDownload(handle, fileData);
}

View File

@ -22,15 +22,15 @@ import java.nio.ByteOrder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig.ConfigPayload;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;
public class ButtonConfigurationGetRequest extends FileGetRequest {
public class ButtonConfigurationGetRequest extends FileGetRawRequest {
public ButtonConfigurationGetRequest(FossilWatchAdapter adapter) {
super(FileHandle.SETTINGS_BUTTONS, adapter);
}
@Override
public void handleFileData(byte[] fileData) {
public void handleFileRawData(byte[] fileData) {
log("fileData");
ByteBuffer buffer = ByteBuffer.wrap(fileData);

View File

@ -21,16 +21,15 @@ import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileLookupAndGetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;
public class ConfigurationGetRequest extends FileGetRequest {
public class ConfigurationGetRequest extends FileGetRawRequest {
public ConfigurationGetRequest(FossilWatchAdapter adapter) {
super(FileHandle.CONFIGURATION, adapter);
}
@Override
public void handleFileData(byte[] fileData) {
public void handleFileRawData(byte[] fileData) {
byte[] data = new byte[fileData.length - 12 - 4];
System.arraycopy(fileData, 12, data, 0, data.length);

View File

@ -3,13 +3,12 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fo
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReferenceArray;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;
public class GetDeviceInfoRequest extends FileGetRequest {
public class GetDeviceInfoRequest extends FileGetRawRequest {
enum INFO_CLASS{
SUPPORTED_FILE_VERSIONS((short) 0x0a, SupportedFileVersionsInfo.class),
;
@ -42,7 +41,7 @@ public class GetDeviceInfoRequest extends FileGetRequest {
}
@Override
public void handleFileData(byte[] fileData) {
public void handleFileRawData(byte[] fileData) {
ByteBuffer buffer = ByteBuffer.wrap(fileData);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.position(12);

View File

@ -0,0 +1,136 @@
/* Copyright (C) 2019-2020 Daniel Dakhno
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file;
import android.bluetooth.BluetoothGattCharacteristic;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.UUID;
import java.util.zip.CRC32;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.ResultCode;
public abstract class FileGetRawRequest extends FossilRequest {
private short handle;
private FossilWatchAdapter adapter;
private ByteBuffer fileBuffer;
private byte[] fileData;
private boolean finished = false;
public FileGetRawRequest(short handle, FossilWatchAdapter adapter) {
this.handle = handle;
this.adapter = adapter;
this.data =
createBuffer()
.putShort(handle)
.putInt(0)
.putInt(0xFFFFFFFF)
.array();
}
public FileGetRawRequest(FileHandle handle, FossilWatchAdapter adapter){
this(handle.getHandle(), adapter);
}
public FossilWatchAdapter getAdapter() {
return adapter;
}
@Override
public boolean isFinished(){
return finished;
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
byte first = value[0];
if(characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")){
if((first & 0x0F) == 1){
ByteBuffer buffer = ByteBuffer.wrap(value);
buffer.order(ByteOrder.LITTLE_ENDIAN);
short handle = buffer.getShort(1);
int size = buffer.getInt(4);
byte status = buffer.get(3);
ResultCode code = ResultCode.fromCode(status);
if(!code.inidicatesSuccess()){
throw new RuntimeException("FileGet error: " + code + " (" + status + ")");
}
if(this.handle != handle){
throw new RuntimeException("handle: " + handle + " expected: " + this.handle);
}
log("file size: " + size);
fileBuffer = ByteBuffer.allocate(size);
}else if((first & 0x0F) == 8){
this.finished = true;
ByteBuffer buffer = ByteBuffer.wrap(value);
buffer.order(ByteOrder.LITTLE_ENDIAN);
short handle = buffer.getShort(1);
if(this.handle != handle){
throw new RuntimeException("handle: " + handle + " expected: " + this.handle);
}
CRC32 crc = new CRC32();
crc.update(this.fileData);
int crcExpected = buffer.getInt(8);
if((int) crc.getValue() != crcExpected){
throw new RuntimeException("handle: " + handle + " expected: " + this.handle);
}
this.handleFileRawData(this.fileData);
}
}else if(characteristic.getUuid().toString().equals("3dda0004-957f-7d4a-34a6-74696673696d")){
fileBuffer.put(value, 1, value.length - 1);
if((first & 0x80) == 0x80){
this.fileData = fileBuffer.array();
}
}
}
@Override
public UUID getRequestUUID() {
return UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d");
}
@Override
public byte[] getStartSequence() {
return new byte[]{1};
}
@Override
public int getPayloadLength() {
return 11;
}
abstract public void handleFileRawData(byte[] fileData);
}

View File

@ -16,124 +16,25 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file;
import android.bluetooth.BluetoothGattCharacteristic;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.UUID;
import java.util.zip.CRC32;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
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_hr.file.ResultCode;
public abstract class FileGetRequest extends FossilRequest {
private short handle;
private FossilWatchAdapter adapter;
private ByteBuffer fileBuffer;
private byte[] fileData;
private boolean finished = false;
public abstract class FileGetRequest extends FileGetRawRequest {
public FileGetRequest(short handle, FossilWatchAdapter adapter) {
this.handle = handle;
this.adapter = adapter;
this.data =
createBuffer()
.putShort(handle)
.putInt(0)
.putInt(0xFFFFFFFF)
.array();
super(handle, adapter);
}
public FileGetRequest(FileHandle handle, FossilWatchAdapter adapter){
this(handle.getHandle(), adapter);
}
public FossilWatchAdapter getAdapter() {
return adapter;
public FileGetRequest(FileHandle handle, FossilWatchAdapter adapter) {
super(handle, adapter);
}
@Override
public boolean isFinished(){
return finished;
public void handleFileRawData(byte[] fileData) {
byte[] file = new byte[fileData.length - 12 - 4]; // 12 = header 4 = crc end
System.arraycopy(fileData, 12, file, 0, file.length);
this.handleFileData(file);
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
byte first = value[0];
if(characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")){
if((first & 0x0F) == 1){
ByteBuffer buffer = ByteBuffer.wrap(value);
buffer.order(ByteOrder.LITTLE_ENDIAN);
short handle = buffer.getShort(1);
int size = buffer.getInt(4);
byte status = buffer.get(3);
ResultCode code = ResultCode.fromCode(status);
if(!code.inidicatesSuccess()){
throw new RuntimeException("FileGet error: " + code + " (" + status + ")");
}
if(this.handle != handle){
throw new RuntimeException("handle: " + handle + " expected: " + this.handle);
}
log("file size: " + size);
fileBuffer = ByteBuffer.allocate(size);
}else if((first & 0x0F) == 8){
this.finished = true;
ByteBuffer buffer = ByteBuffer.wrap(value);
buffer.order(ByteOrder.LITTLE_ENDIAN);
short handle = buffer.getShort(1);
if(this.handle != handle){
throw new RuntimeException("handle: " + handle + " expected: " + this.handle);
}
CRC32 crc = new CRC32();
crc.update(this.fileData);
int crcExpected = buffer.getInt(8);
if((int) crc.getValue() != crcExpected){
throw new RuntimeException("handle: " + handle + " expected: " + this.handle);
}
this.handleFileData(this.fileData);
}
}else if(characteristic.getUuid().toString().equals("3dda0004-957f-7d4a-34a6-74696673696d")){
fileBuffer.put(value, 1, value.length - 1);
if((first & 0x80) == 0x80){
this.fileData = fileBuffer.array();
}
}
}
@Override
public UUID getRequestUUID() {
return UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d");
}
@Override
public byte[] getStartSequence() {
return new byte[]{1};
}
@Override
public int getPayloadLength() {
return 11;
}
abstract public void handleFileData(byte[] fileData);
public abstract void handleFileData(byte[] fileData);
}

View File

@ -25,9 +25,9 @@ public abstract class FileLookupAndGetRequest extends FileLookupRequest {
@Override
public void handleFileLookup(short fileHandle){
getAdapter().queueWrite(new FileGetRequest(getHandle(), getAdapter()) {
getAdapter().queueWrite(new FileGetRawRequest(getHandle(), getAdapter()) {
@Override
public void handleFileData(byte[] fileData) {
public void handleFileRawData(byte[] fileData) {
FileLookupAndGetRequest.this.handleFileData(fileData);
}
}, true);

View File

@ -21,16 +21,16 @@ import java.nio.ByteOrder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;
import nodomain.freeyourgadget.gadgetbridge.util.CRC32C;
public class NotificationFilterGetRequest extends FileGetRequest {
public class NotificationFilterGetRequest extends FileGetRawRequest {
public NotificationFilterGetRequest(FossilWatchAdapter adapter) {
super(FileHandle.NOTIFICATION_FILTER, adapter);
}
@Override
public void handleFileData(byte[] fileData) {
public void handleFileRawData(byte[] fileData) {
log("handleFileData");
ByteBuffer buffer = ByteBuffer.wrap(fileData);
buffer.order(ByteOrder.LITTLE_ENDIAN);

View File

@ -16,9 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileLookupRequest;
public abstract class FileEncryptedLookupAndGetRequest extends FileLookupRequest {

View File

@ -6,15 +6,15 @@ import java.util.ArrayList;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRawRequest;
public abstract class TranslationsGetRequest extends FileGetRequest {
public abstract class TranslationsGetRequest extends FileGetRawRequest {
public TranslationsGetRequest(FossilWatchAdapter adapter) {
super(FileHandle.ASSET_TRANSLATIONS, adapter);
}
@Override
public void handleFileData(byte[] fileData) {
public void handleFileRawData(byte[] fileData) {
ByteBuffer buffer = ByteBuffer.wrap(fileData);
buffer.order(ByteOrder.LITTLE_ENDIAN);