1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-12 13:09:24 +01:00

Huawei: FileUpload refactoring, fixes Watch 3/4

* replaced fileType with fileId which recived on incoming data
in 28 03 FileHashSend.Response
* width/height in WatchfaceDeviceParams could be int or short
(int is present on Watch 3, short is all other tested devices)
* use in 27 05  WatchfaceConfirm.Request data recieved in previous
WatchfaceConfirm.Response
This commit is contained in:
Vitaliy Tomin 2024-07-21 21:07:54 +08:00 committed by José Rebelo
parent 5c5c0a48d4
commit f4322eee7f
9 changed files with 68 additions and 27 deletions

View File

@ -563,11 +563,11 @@ public class HuaweiCoordinator {
}
public short getWidth() {
return watchfaceDeviceParams.width;
return (short)watchfaceDeviceParams.width;
}
public short getHeight() {
return watchfaceDeviceParams.height;
return (short)watchfaceDeviceParams.height;
}
public void setWatchfaceDeviceParams(Watchface.WatchfaceDeviceParams watchfaceDeviceParams) {

View File

@ -555,6 +555,8 @@ public class HuaweiPacket {
return new FileUpload.FileNextChunkParams(paramsProvider).fromPacket(this);
case FileUpload.FileUploadConsultAck.id:
return new FileUpload.FileUploadConsultAck.Response(paramsProvider).fromPacket(this);
case FileUpload.FileHashSend.id:
return new FileUpload.FileHashSend.Response(paramsProvider).fromPacket(this);
default:
this.isEncrypted = this.attemptDecrypt(); // Helps with debugging
return this;
@ -696,7 +698,7 @@ public class HuaweiPacket {
return retv;
}
public List<byte[]> serializeFileChunk(byte[] fileChunk, int uploadPosition, short unitSize) {
public List<byte[]> serializeFileChunk(byte[] fileChunk, int uploadPosition, short unitSize, byte fileId) {
List<byte[]> retv = new ArrayList<>();
int headerLength = 5; // Magic + (short)(bodyLength + 1) + 0x00
int sliceHeaderLenght =7;
@ -707,7 +709,6 @@ public class HuaweiPacket {
ByteBuffer buffer = ByteBuffer.wrap(fileChunk);
byte fileType = 0x01; //TODO: 1 - watchface, 2 - music
int sliceStart = uploadPosition;
for (int i = 0; i < packetCount; i++) {
@ -724,7 +725,7 @@ public class HuaweiPacket {
packet.put(this.serviceId);
packet.put(this.commandId);
packet.put(fileType); // Slice
packet.put(fileId); // Slice
packet.put((byte)i); // Flag
packet.putInt(sliceStart);

View File

@ -85,35 +85,42 @@ public class FileUpload {
public Request(ParamsProvider paramsProvider,
byte[] hash,
byte fileType) {
byte fileId) {
super(paramsProvider);
this.serviceId = FileUpload.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x01, fileType)
.put(0x01, fileId)
.put(0x03, hash);
this.complete = true;
}
}
public static class Response extends HuaweiPacket {
public byte fileId =0;
public Response (ParamsProvider paramsProvider) {
super(paramsProvider);
}
@Override
public void parseTlv() throws HuaweiPacket.ParseException {
this.fileId = this.tlv.getByte(0x01);
}
}
}
public static class FileUploadConsultAck {
public static final byte id = 0x04;
public static class Request extends HuaweiPacket {
public Request(ParamsProvider paramsProvider, byte noEncryption, byte fileType) {
public Request(ParamsProvider paramsProvider, byte noEncryption, byte fileId) {
super(paramsProvider);
this.serviceId = FileUpload.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x7f, 0x000186A0) //ok
.put(0x01, fileType);
.put(0x01, fileId);
if (noEncryption == 1)
this.tlv.put(0x09, (byte)0x01); // need on devices which generally encrypted, but files
this.complete = true;
@ -176,13 +183,13 @@ public class FileUpload {
public static final byte id = 0x07;
public static class Request extends HuaweiPacket {
public Request(ParamsProvider paramsProvider, byte fileType) {
public Request(ParamsProvider paramsProvider, byte fileId) {
super(paramsProvider);
this.serviceId = FileUpload.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x7f, 0x000186A0) //ok
.put(0x01, fileType);
.put(0x01, fileId);
this.complete = true;
}

View File

@ -29,8 +29,8 @@ public class Watchface {
public static class WatchfaceDeviceParams {
public String maxVersion = "";
public short width = 0;
public short height = 0;
public int width = 0;
public int height = 0;
public byte supportFileType = 1;
public byte sort = 1;
public String otherWatchfaceVersions = "";
@ -112,8 +112,14 @@ public class Watchface {
@Override
public void parseTlv() throws ParseException {
this.params.maxVersion = this.tlv.getString(0x01);
this.params.width = this.tlv.getShort(0x02);
this.params.height = this.tlv.getShort(0x03);
if (this.tlv.getBytes(0x02).length == 4)
this.params.width = this.tlv.getInteger(0x02);
else
this.params.width = this.tlv.getShort(0x02);
if (this.tlv.getBytes(0x03).length == 4)
this.params.height = this.tlv.getInteger(0x03);
else
this.params.height = this.tlv.getShort(0x03);
this.params.supportFileType = this.tlv.getByte(0x04);
this.params.sort = this.tlv.getByte(0x05);
this.params.otherWatchfaceVersions = this.tlv.getString(0x06);
@ -190,24 +196,35 @@ public class Watchface {
super(paramsProvider);
this.serviceId = Watchface.id;
this.commandId = id;
String file = fileName.split("_")[0];
String version = "";
try {
version = fileName.split("_")[1];
} catch (ArrayIndexOutOfBoundsException e) {
}
this.tlv = new HuaweiTLV()
.put(0x01, fileName.split("_")[0])
.put(0x02, fileName.split("_")[1])
.put(0x01, file)
.put(0x02, version)
.put(0x7f, 0x000186A0);
}
}
public static class Response extends HuaweiPacket {
public static byte reportType = 0;
public static String fileName;
public Response (ParamsProvider paramsProvider) {
super(paramsProvider);
}
@Override
public void parseTlv() throws HuaweiPacket.ParseException {
String name = this.tlv.getString(0x01);
String version = this.tlv.getString(0x02);
if(this.tlv.contains(0x03)) {
this.reportType = this.tlv.getByte(0x03);
}
this.fileName = name + "_" + version;
}
}

View File

@ -415,6 +415,10 @@ public class AsynchronousResponse {
private void handleFileUpload(HuaweiPacket response) throws Request.ResponseParseException {
if (response.serviceId == FileUpload.id) {
if (response.commandId == FileUpload.FileHashSend.id) {
if (!(response instanceof FileUpload.FileHashSend.Response))
throw new Request.ResponseTypeMismatchException(response, FileUpload.FileHashSend.Response.class);
FileUpload.FileHashSend.Response resp = (FileUpload.FileHashSend.Response) response;
support.huaweiUploadManager.setFileId(resp.fileId);
try {
SendFileUploadHash sendFileUploadHash = new SendFileUploadHash(support, support.huaweiUploadManager);
sendFileUploadHash.doPerform();
@ -431,7 +435,7 @@ public class AsynchronousResponse {
try {
support.huaweiUploadManager.setDeviceBusy();
SendFileUploadAck sendFileUploadAck = new SendFileUploadAck(support,
resp.fileUploadParams.no_encrypt, support.huaweiUploadManager.getFileType());
resp.fileUploadParams.no_encrypt, support.huaweiUploadManager.getFileId());
sendFileUploadAck.doPerform();
} catch (IOException e) {
LOG.error("Could not send fileupload ack request", e);
@ -455,7 +459,7 @@ public class AsynchronousResponse {
try {
support.huaweiUploadManager.unsetDeviceBusy();
support.onUploadProgress(R.string.updatefirmwareoperation_update_complete, 100, false);
SendFileUploadComplete sendFileUploadComplete = new SendFileUploadComplete(this.support, support.huaweiUploadManager.getFileType());
SendFileUploadComplete sendFileUploadComplete = new SendFileUploadComplete(this.support, support.huaweiUploadManager.getFileId());
sendFileUploadComplete.doPerform();
} catch (IOException e) {
LOG.error("Could not send fileupload result request", e);
@ -471,11 +475,11 @@ public class AsynchronousResponse {
if (!(response instanceof Watchface.WatchfaceConfirm.Response))
throw new Request.ResponseTypeMismatchException(response, Watchface.WatchfaceConfirm.class);
Watchface.WatchfaceConfirm.Response resp = (Watchface.WatchfaceConfirm.Response) response;
SendWatchfaceConfirm sendWatchfaceConfirm = new SendWatchfaceConfirm(this.support, this.support.huaweiUploadManager.getFileName());
SendWatchfaceConfirm sendWatchfaceConfirm = new SendWatchfaceConfirm(this.support, resp.fileName);
sendWatchfaceConfirm.doPerform();
if (resp.reportType == 0x02) {
//make uploaded watchface active
SendWatchfaceOperation sendWatchfaceOperation = new SendWatchfaceOperation(this.support, support.huaweiUploadManager.getFileName(), Watchface.WatchfaceOperation.operationActive);
SendWatchfaceOperation sendWatchfaceOperation = new SendWatchfaceOperation(this.support, resp.fileName, Watchface.WatchfaceOperation.operationActive);
sendWatchfaceOperation.doPerform();
}
} catch (IOException e) {

View File

@ -35,6 +35,7 @@ public class HuaweiUploadManager {
byte[] fileSHA256;
byte fileType = 1; // 1 - watchface, 2 - music, 3 - png for background , 7 - app
int fileSize = 0;
byte fileId = 0; // get on incoming (2803)
int currentUploadPosition = 0;
int uploadChunkSize =0;
@ -90,6 +91,14 @@ public class HuaweiUploadManager {
this.fileType = fileType;
}
public byte getFileId() {
return fileId;
}
public void setFileId(byte fileId) {
this.fileId = fileId;
}
public byte[] getFileSHA256() {
return fileSHA256;
}

View File

@ -39,7 +39,8 @@ public class SendFileUploadChunk extends Request {
return new FileUpload.FileNextChunkSend(this.paramsProvider).serializeFileChunk(
huaweiUploadManager.getCurrentChunk(),
huaweiUploadManager.getCurrentUploadPosition(),
huaweiUploadManager.getUnitSize()
huaweiUploadManager.getUnitSize(),
huaweiUploadManager.getFileId()
);
}
}

View File

@ -25,13 +25,13 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupport
public class SendFileUploadComplete extends Request {
byte fileType = 0;
public SendFileUploadComplete(HuaweiSupportProvider support, byte fileType) {
byte fileId = 0;
public SendFileUploadComplete(HuaweiSupportProvider support, byte fileId) {
super(support);
this.serviceId = FileUpload.id;
this.commandId = FileUpload.FileUploadResult.id;
this.fileType = fileType;
this.fileId = fileId;
this.addToResponse = false;
}
@ -39,7 +39,7 @@ public class SendFileUploadComplete extends Request {
@Override
protected List<byte[]> createRequest() throws RequestCreationException {
try {
return new FileUpload.FileUploadResult.Request(this.paramsProvider, this.fileType).serialize();
return new FileUpload.FileUploadResult.Request(this.paramsProvider, this.fileId).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}

View File

@ -26,10 +26,12 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiUploadM
public class SendFileUploadHash extends Request{
HuaweiUploadManager huaweiUploadManager;
private byte fileId;
public SendFileUploadHash(HuaweiSupportProvider support,
HuaweiUploadManager huaweiUploadManager) {
super(support);
this.huaweiUploadManager = huaweiUploadManager;
this.fileId = fileId;
this.serviceId = FileUpload.id;
this.commandId = FileUpload.FileHashSend.id;
this.addToResponse = false;
@ -41,7 +43,7 @@ public class SendFileUploadHash extends Request{
try {
return new FileUpload.FileHashSend.Request(this.paramsProvider,
huaweiUploadManager.getFileSHA256(),
huaweiUploadManager.getFileType()
huaweiUploadManager.getFileId()
).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);