1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-28 04:46:51 +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() { public short getWidth() {
return watchfaceDeviceParams.width; return (short)watchfaceDeviceParams.width;
} }
public short getHeight() { public short getHeight() {
return watchfaceDeviceParams.height; return (short)watchfaceDeviceParams.height;
} }
public void setWatchfaceDeviceParams(Watchface.WatchfaceDeviceParams watchfaceDeviceParams) { public void setWatchfaceDeviceParams(Watchface.WatchfaceDeviceParams watchfaceDeviceParams) {

View File

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

View File

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

View File

@ -29,8 +29,8 @@ public class Watchface {
public static class WatchfaceDeviceParams { public static class WatchfaceDeviceParams {
public String maxVersion = ""; public String maxVersion = "";
public short width = 0; public int width = 0;
public short height = 0; public int height = 0;
public byte supportFileType = 1; public byte supportFileType = 1;
public byte sort = 1; public byte sort = 1;
public String otherWatchfaceVersions = ""; public String otherWatchfaceVersions = "";
@ -112,8 +112,14 @@ public class Watchface {
@Override @Override
public void parseTlv() throws ParseException { public void parseTlv() throws ParseException {
this.params.maxVersion = this.tlv.getString(0x01); this.params.maxVersion = this.tlv.getString(0x01);
this.params.width = this.tlv.getShort(0x02); if (this.tlv.getBytes(0x02).length == 4)
this.params.height = this.tlv.getShort(0x03); 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.supportFileType = this.tlv.getByte(0x04);
this.params.sort = this.tlv.getByte(0x05); this.params.sort = this.tlv.getByte(0x05);
this.params.otherWatchfaceVersions = this.tlv.getString(0x06); this.params.otherWatchfaceVersions = this.tlv.getString(0x06);
@ -190,24 +196,35 @@ public class Watchface {
super(paramsProvider); super(paramsProvider);
this.serviceId = Watchface.id; this.serviceId = Watchface.id;
this.commandId = id; this.commandId = id;
String file = fileName.split("_")[0];
String version = "";
try {
version = fileName.split("_")[1];
} catch (ArrayIndexOutOfBoundsException e) {
}
this.tlv = new HuaweiTLV() this.tlv = new HuaweiTLV()
.put(0x01, fileName.split("_")[0]) .put(0x01, file)
.put(0x02, fileName.split("_")[1]) .put(0x02, version)
.put(0x7f, 0x000186A0); .put(0x7f, 0x000186A0);
} }
} }
public static class Response extends HuaweiPacket { public static class Response extends HuaweiPacket {
public static byte reportType = 0; public static byte reportType = 0;
public static String fileName;
public Response (ParamsProvider paramsProvider) { public Response (ParamsProvider paramsProvider) {
super(paramsProvider); super(paramsProvider);
} }
@Override @Override
public void parseTlv() throws HuaweiPacket.ParseException { public void parseTlv() throws HuaweiPacket.ParseException {
String name = this.tlv.getString(0x01);
String version = this.tlv.getString(0x02);
if(this.tlv.contains(0x03)) { if(this.tlv.contains(0x03)) {
this.reportType = this.tlv.getByte(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 { private void handleFileUpload(HuaweiPacket response) throws Request.ResponseParseException {
if (response.serviceId == FileUpload.id) { if (response.serviceId == FileUpload.id) {
if (response.commandId == FileUpload.FileHashSend.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 { try {
SendFileUploadHash sendFileUploadHash = new SendFileUploadHash(support, support.huaweiUploadManager); SendFileUploadHash sendFileUploadHash = new SendFileUploadHash(support, support.huaweiUploadManager);
sendFileUploadHash.doPerform(); sendFileUploadHash.doPerform();
@ -431,7 +435,7 @@ public class AsynchronousResponse {
try { try {
support.huaweiUploadManager.setDeviceBusy(); support.huaweiUploadManager.setDeviceBusy();
SendFileUploadAck sendFileUploadAck = new SendFileUploadAck(support, SendFileUploadAck sendFileUploadAck = new SendFileUploadAck(support,
resp.fileUploadParams.no_encrypt, support.huaweiUploadManager.getFileType()); resp.fileUploadParams.no_encrypt, support.huaweiUploadManager.getFileId());
sendFileUploadAck.doPerform(); sendFileUploadAck.doPerform();
} catch (IOException e) { } catch (IOException e) {
LOG.error("Could not send fileupload ack request", e); LOG.error("Could not send fileupload ack request", e);
@ -455,7 +459,7 @@ public class AsynchronousResponse {
try { try {
support.huaweiUploadManager.unsetDeviceBusy(); support.huaweiUploadManager.unsetDeviceBusy();
support.onUploadProgress(R.string.updatefirmwareoperation_update_complete, 100, false); 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(); sendFileUploadComplete.doPerform();
} catch (IOException e) { } catch (IOException e) {
LOG.error("Could not send fileupload result request", e); LOG.error("Could not send fileupload result request", e);
@ -471,11 +475,11 @@ public class AsynchronousResponse {
if (!(response instanceof Watchface.WatchfaceConfirm.Response)) if (!(response instanceof Watchface.WatchfaceConfirm.Response))
throw new Request.ResponseTypeMismatchException(response, Watchface.WatchfaceConfirm.class); throw new Request.ResponseTypeMismatchException(response, Watchface.WatchfaceConfirm.class);
Watchface.WatchfaceConfirm.Response resp = (Watchface.WatchfaceConfirm.Response) response; 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(); sendWatchfaceConfirm.doPerform();
if (resp.reportType == 0x02) { if (resp.reportType == 0x02) {
//make uploaded watchface active //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(); sendWatchfaceOperation.doPerform();
} }
} catch (IOException e) { } catch (IOException e) {

View File

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

View File

@ -39,7 +39,8 @@ public class SendFileUploadChunk extends Request {
return new FileUpload.FileNextChunkSend(this.paramsProvider).serializeFileChunk( return new FileUpload.FileNextChunkSend(this.paramsProvider).serializeFileChunk(
huaweiUploadManager.getCurrentChunk(), huaweiUploadManager.getCurrentChunk(),
huaweiUploadManager.getCurrentUploadPosition(), 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 { public class SendFileUploadComplete extends Request {
byte fileType = 0; byte fileId = 0;
public SendFileUploadComplete(HuaweiSupportProvider support, byte fileType) { public SendFileUploadComplete(HuaweiSupportProvider support, byte fileId) {
super(support); super(support);
this.serviceId = FileUpload.id; this.serviceId = FileUpload.id;
this.commandId = FileUpload.FileUploadResult.id; this.commandId = FileUpload.FileUploadResult.id;
this.fileType = fileType; this.fileId = fileId;
this.addToResponse = false; this.addToResponse = false;
} }
@ -39,7 +39,7 @@ public class SendFileUploadComplete extends Request {
@Override @Override
protected List<byte[]> createRequest() throws RequestCreationException { protected List<byte[]> createRequest() throws RequestCreationException {
try { 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) { } catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e); throw new RequestCreationException(e);
} }

View File

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