diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/OppoHeadphonesProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/OppoHeadphonesProtocol.java index 38d8053392..c727571daa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/OppoHeadphonesProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/OppoHeadphonesProtocol.java @@ -30,6 +30,7 @@ import java.util.EnumSet; import java.util.Set; import java.util.HashSet; +import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; @@ -47,6 +48,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.oppo.commands.TouchC import nodomain.freeyourgadget.gadgetbridge.service.devices.oppo.commands.MiscConfigType; import nodomain.freeyourgadget.gadgetbridge.service.devices.oppo.commands.AncConfigType; import nodomain.freeyourgadget.gadgetbridge.service.devices.oppo.commands.AncConfigValue; +import nodomain.freeyourgadget.gadgetbridge.service.devices.oppo.commands.DeviceInfoType; import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol; import nodomain.freeyourgadget.gadgetbridge.util.preferences.DevicePrefs; @@ -143,19 +145,11 @@ public class OppoHeadphonesProtocol extends GBDeviceProtocol { events.addAll(parseBattery(payload)); break; } - case DEVICE_INFO: { - switch (payload[0]) { - case 1: // battery - events.addAll(parseBattery(payload)); - break; - case 2: // status - LOG.debug("Got status"); - // TODO handle - break; - default: - LOG.warn("Unknown device info {}", payload[0]); - } - + case DEVICE_INFO_ACK: + LOG.debug("Got device info ack, return={}", StringUtils.bytesToHex(payload)); + break; + case DEVICE_INFO_RET: { + events.addAll(parseDeviceInfo(payload)); break; } case FIRMWARE_RET: { @@ -345,6 +339,34 @@ public class OppoHeadphonesProtocol extends GBDeviceProtocol { return events; } + + private static List parseDeviceInfo(final byte[] payload) { + final List events = new ArrayList<>(); + final int typeCode = payload[0] & 0xff; + final DeviceInfoType type = DeviceInfoType.fromCode(typeCode); + if (type == null) { + LOG.warn("Unknown device info {}", payload[0]); + return events; + } + + switch (type) { + case BATTERY: { + events.addAll(parseBattery(payload)); + break; + } + case STATUS: { + LOG.debug("Got status"); + // TODO handle + break; + } + default: { + LOG.warn("Unknown device info {}", payload[0]); + break; + } + } + return events; + } + private static GBDeviceEvent parseMiscConfig(final byte[] payload) { final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences(); for (int i = 2; i + 1 < payload.length; i += 2) { @@ -623,6 +645,15 @@ public class OppoHeadphonesProtocol extends GBDeviceProtocol { return encodeMessage(OppoCommand.ANC_CONFIG_REQ, payload); } + public byte[] encodeDeviceInfoSet() { + final byte[] payload = new byte[] { + (byte) 0x09, + (byte) DeviceInfoType.BATTERY.getCode(), + (byte) DeviceInfoType.GAME_MODE.getCode(), + }; + return encodeMessage(OppoCommand.DEVICE_INFO_SET, payload); + } + private byte[] encodeMessage(final OppoCommand command, final byte[] payload) { final ByteBuffer buf = ByteBuffer.allocate(9 + payload.length).order(ByteOrder.LITTLE_ENDIAN); buf.put(CMD_PREAMBLE); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/OppoHeadphonesSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/OppoHeadphonesSupport.java index f21ddd9f0b..bd31704c48 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/OppoHeadphonesSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/OppoHeadphonesSupport.java @@ -74,6 +74,7 @@ public class OppoHeadphonesSupport extends AbstractHeadphoneSerialDeviceSupportV @Override protected TransactionBuilder initializeDevice(final TransactionBuilder builder) { + builder.write(mDeviceProtocol.encodeDeviceInfoSet()); builder.write(mDeviceProtocol.encodeFirmwareVersionReq()); final OppoHeadphonesCoordinator coordinator = (OppoHeadphonesCoordinator) getDevice().getDeviceCoordinator(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/commands/DeviceInfoType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/commands/DeviceInfoType.java new file mode 100644 index 0000000000..35f890911e --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/commands/DeviceInfoType.java @@ -0,0 +1,47 @@ +/* Copyright (C) 2024 José Rebelo + + 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 . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.oppo.commands; + +import androidx.annotation.Nullable; + +public enum DeviceInfoType { + BATTERY(0x01), + STATUS(0x02), + GAME_MODE(0x05), + ; + + private final int code; + + DeviceInfoType(final int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + @Nullable + public static DeviceInfoType fromCode(final int code) { + for (final DeviceInfoType param : DeviceInfoType.values()) { + if (param.code == code) { + return param; + } + } + + return null; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/commands/OppoCommand.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/commands/OppoCommand.java index e0e1a6dea7..603557ffd7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/commands/OppoCommand.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/oppo/commands/OppoCommand.java @@ -21,7 +21,9 @@ import androidx.annotation.Nullable; public enum OppoCommand { BATTERY_REQ(0x0106), BATTERY_RET(0x8106), - DEVICE_INFO(0x0204), + DEVICE_INFO_SET(0x0205), + DEVICE_INFO_ACK(0x8205), + DEVICE_INFO_RET(0x0204), FIRMWARE_GET(0x0105), FIRMWARE_RET(0x8105), TOUCH_CONFIG_REQ(0x0108),