Huawei: permission check request processing

This commit is contained in:
Me7c7 2025-01-03 20:31:15 +02:00 committed by José Rebelo
parent 86e32f0713
commit b7641f6e45
5 changed files with 108 additions and 15 deletions

View File

@ -463,6 +463,8 @@ public class HuaweiPacket {
return new DeviceConfig.ActivityType.Response(paramsProvider).fromPacket(this); return new DeviceConfig.ActivityType.Response(paramsProvider).fromPacket(this);
case DeviceConfig.SettingRelated.id: case DeviceConfig.SettingRelated.id:
return new DeviceConfig.SettingRelated.Response(paramsProvider).fromPacket(this); return new DeviceConfig.SettingRelated.Response(paramsProvider).fromPacket(this);
case DeviceConfig.PermissionCheck.id:
return new DeviceConfig.PermissionCheck.PermissionCheckRequest(paramsProvider).fromPacket(this);
case DeviceConfig.SecurityNegotiation.id: case DeviceConfig.SecurityNegotiation.id:
return new DeviceConfig.SecurityNegotiation.Response(paramsProvider).fromPacket(this); return new DeviceConfig.SecurityNegotiation.Response(paramsProvider).fromPacket(this);
case DeviceConfig.WearStatus.id: case DeviceConfig.WearStatus.id:

View File

@ -18,18 +18,11 @@ package nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
import java.util.TreeMap; import java.util.TreeMap;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -1688,6 +1681,48 @@ public class DeviceConfig {
} }
public static class PermissionCheck {
public static final byte id = 0x38;
// NOTE: request from the watch
public static class PermissionCheckRequest extends HuaweiPacket {
public short permission = 0;
public PermissionCheckRequest(ParamsProvider paramsProvider) {
super(paramsProvider);
this.serviceId = DeviceConfig.id;
this.commandId = id;
}
@Override
public void parseTlv() throws ParseException {
if (this.tlv.contains(0x01))
this.permission = this.tlv.getShort(0x01);
}
}
public static class PermissionCheckResponse extends HuaweiPacket {
public PermissionCheckResponse(
ParamsProvider paramsProvider,
short permission,
short status
) {
super(paramsProvider);
this.serviceId = DeviceConfig.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x01, permission)
.put(0x02, status);
this.complete = true;
}
}
}
public static class WearStatus { public static class WearStatus {
public static final int id = 0x3D; public static final int id = 0x3D;

View File

@ -125,13 +125,15 @@ public class Notifications {
this.tlv.put(0x11, sourceAppId); this.tlv.put(0x11, sourceAppId);
if(addParams != null) { if(addParams != null) {
if (addParams.supportsSyncKey)
this.tlv.put(0x18, (addParams.notificationKey != null) ? addParams.notificationKey : "");
if(!TextUtils.isEmpty(addParams.category)) { //TODO: device type >=34 if(!TextUtils.isEmpty(addParams.category)) { //TODO: device type >=34
this.tlv.put(0x12, addParams.category); // "imcall" also possible value, not standard for android this.tlv.put(0x12, addParams.category); // "imcall" also possible value, not standard for android
} }
if (addParams.supportsSyncKey)
this.tlv.put(0x18, (addParams.notificationKey != null) ? addParams.notificationKey : "");
//if(addParams.repeatedNotifySupports) { //if(addParams.repeatedNotifySupports) {
// this.tlv.put(0x13, 0); // 0x13 - reminder 15 = vibrate, 0 - default // this.tlv.put(0x13, 0); // 0x13 - reminder 15 = vibrate, 0 - default
//} //}
@ -388,7 +390,7 @@ public class Notifications {
public ReplyResponse(ParamsProvider paramsProvider) { public ReplyResponse(ParamsProvider paramsProvider) {
super(paramsProvider); super(paramsProvider);
this.serviceId = MusicControl.id; this.serviceId = Notifications.id;
this.commandId = id; this.commandId = id;
} }
@ -427,9 +429,5 @@ public class Notifications {
this.complete = true; this.complete = true;
} }
} }
} }
} }

View File

@ -63,14 +63,15 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Watchface;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetBatteryLevelRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetBatteryLevelRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Request;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetPhoneInfoRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetPhoneInfoRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Request;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadComplete; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadComplete;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsStatusRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsStatusRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendMenstrualModifyTimeRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendMenstrualModifyTimeRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadAck; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadAck;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadChunk; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadChunk;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadHash; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadHash;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendPermissionCheckResponse;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWatchfaceConfirm; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWatchfaceConfirm;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWatchfaceOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWatchfaceOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetMusicStatusRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetMusicStatusRequest;
@ -129,6 +130,7 @@ public class AsynchronousResponse {
handleEphemerisUploadService(response); handleEphemerisUploadService(response);
handleAsyncBattery(response); handleAsyncBattery(response);
handleNotifications(response); handleNotifications(response);
handlePermissionCheck(response);
} catch (Request.ResponseParseException e) { } catch (Request.ResponseParseException e) {
LOG.error("Response parse exception", e); LOG.error("Response parse exception", e);
} }
@ -737,4 +739,29 @@ public class AsynchronousResponse {
support.getHuaweiNotificationsManager().onReplyResponse((Notifications.NotificationReply.ReplyResponse) response); support.getHuaweiNotificationsManager().onReplyResponse((Notifications.NotificationReply.ReplyResponse) response);
} }
} }
private void handlePermissionCheck(HuaweiPacket response) {
if (response.serviceId == DeviceConfig.id && response.commandId == DeviceConfig.PermissionCheck.id) {
if (!(response instanceof DeviceConfig.PermissionCheck.PermissionCheckRequest)) {
return;
}
DeviceConfig.PermissionCheck.PermissionCheckRequest permissionCheckResp = (DeviceConfig.PermissionCheck.PermissionCheckRequest) response;
// short status = 1;
// // TODO: we should check ability to perform specific action. I do not know which action can be here,
// // 1 is SMS permission
// if(permissionCheckResp.permission == 1) {
// status = 0;
// }
// TODO: return no permission for now. Return status 1 for activate call reject replies. Something should be set on notification to enable processing.
// Currently watch does not send call reject to the GB. Additional research required.
short status = 0;
SendPermissionCheckResponse getPhoneInfoReq = new SendPermissionCheckResponse(this.support, permissionCheckResp.permission, status);
try {
getPhoneInfoReq.doPerform();
} catch (IOException e) {
LOG.error("Failed to send permission check ACK", e);
}
}
}
} }

View File

@ -0,0 +1,31 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.DeviceConfig;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class SendPermissionCheckResponse extends Request {
short permission;
short status;
public SendPermissionCheckResponse(HuaweiSupportProvider support, short permission, short status) {
super(support);
this.serviceId = DeviceConfig.id;
this.commandId = DeviceConfig.PermissionCheck.id;
this.permission = permission;
this.status = status;
this.addToResponse = false;
}
@Override
protected List<byte[]> createRequest() throws Request.RequestCreationException {
try {
return new DeviceConfig.PermissionCheck.PermissionCheckResponse(this.paramsProvider, this.permission, this.status).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new Request.RequestCreationException(e);
}
}
}