mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-25 08:05:55 +01:00
Sony Headphones: Refactor V1 protocol to simplify V2 implementation
This commit is contained in:
parent
1dca054853
commit
d4ba532b11
@ -24,7 +24,6 @@ import java.util.List;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
|
@ -36,7 +36,7 @@ public class AmbientSoundControl {
|
||||
private final boolean focusOnVoice;
|
||||
private final int ambientSound;
|
||||
|
||||
public AmbientSoundControl(Mode mode, boolean focusOnVoice, int ambientSound) {
|
||||
public AmbientSoundControl(final Mode mode, final boolean focusOnVoice, final int ambientSound) {
|
||||
if (ambientSound < 0 || ambientSound > 20) {
|
||||
throw new IllegalArgumentException(String.format("Level must be between 0 and 20 (was %d)", ambientSound));
|
||||
}
|
||||
|
@ -48,6 +48,16 @@ public enum AutomaticPowerOff {
|
||||
}};
|
||||
}
|
||||
|
||||
public static AutomaticPowerOff fromCode(final byte b1, final byte b2) {
|
||||
for (AutomaticPowerOff value : AutomaticPowerOff.values()) {
|
||||
if (value.getCode()[0] == b1 && value.getCode()[1] == b2) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static AutomaticPowerOff fromPreferences(final SharedPreferences prefs) {
|
||||
return AutomaticPowerOff.valueOf(prefs.getString(DeviceSettingsPreferenceConst.PREF_SONY_AUTOMATIC_POWER_OFF, "off").toUpperCase());
|
||||
}
|
||||
|
@ -40,6 +40,16 @@ public class ButtonModes {
|
||||
public byte getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public static Mode fromCode(final byte code) {
|
||||
for (ButtonModes.Mode value : ButtonModes.Mode.values()) {
|
||||
if (value.getCode() == code) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final Mode left;
|
||||
|
@ -54,6 +54,16 @@ public enum EqualizerPreset {
|
||||
}};
|
||||
}
|
||||
|
||||
public static EqualizerPreset fromCode(final byte code) {
|
||||
for (EqualizerPreset value : EqualizerPreset.values()) {
|
||||
if (value.getCode() == code) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static EqualizerPreset fromPreferences(final SharedPreferences prefs) {
|
||||
return EqualizerPreset.valueOf(prefs.getString(DeviceSettingsPreferenceConst.PREF_SONY_EQUALIZER_MODE, "off").toUpperCase());
|
||||
}
|
||||
|
@ -208,6 +208,11 @@ public class SonyHeadphonesProtocol extends GBDeviceProtocol {
|
||||
return super.encodeSendConfiguration(config);
|
||||
}
|
||||
|
||||
if (configRequest == null) {
|
||||
LOG.warn("Failed to encode config request for {}", config);
|
||||
return super.encodeSendConfiguration(config);
|
||||
}
|
||||
|
||||
pendingAcks++;
|
||||
|
||||
return configRequest.encode(sequenceNumber);
|
||||
|
@ -25,7 +25,6 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Locale;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.PayloadType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
public class Message {
|
||||
@ -38,7 +37,7 @@ public class Message {
|
||||
* - Message Type ({@link MessageType})
|
||||
* - Sequence Number - needs to be updated with the one sent in the ACK responses
|
||||
* - Payload Length - 4-byte big endian int with number of bytes that will follow
|
||||
* - N bytes of payload data (first being the {@link PayloadType})
|
||||
* - N bytes of payload data (first being the PayloadType)
|
||||
* - Checksum (1-byte sum, excluding header)
|
||||
* - MESSAGE_TRAILER
|
||||
* <p>
|
||||
@ -87,8 +86,7 @@ public class Message {
|
||||
|
||||
public String toString() {
|
||||
if (payload.length > 0) {
|
||||
final PayloadType payloadType = PayloadType.fromCode(type, payload[0]);
|
||||
return String.format(Locale.getDefault(), "Message{Cmd=%s, Seq=%d, PayloadType=%s, Payload=%s}", type, sequenceNumber, payloadType, GB.hexdump(payload));
|
||||
return String.format(Locale.getDefault(), "Message{Cmd=%s, Seq=%d, PayloadType=%d, Payload=%s}", type, sequenceNumber, payload[0], GB.hexdump(payload));
|
||||
} else {
|
||||
return String.format(Locale.getDefault(), "Message{Cmd=%s, Seq=%d}", type, sequenceNumber);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.pro
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.MessageType;
|
||||
|
||||
public enum PayloadType {
|
||||
public enum PayloadTypeV1 {
|
||||
INIT_REQUEST(MessageType.COMMAND_1, 0x00),
|
||||
INIT_REPLY(MessageType.COMMAND_1, 0x01),
|
||||
|
||||
@ -93,7 +93,7 @@ public enum PayloadType {
|
||||
private final MessageType messageType;
|
||||
private final byte code;
|
||||
|
||||
PayloadType(final MessageType messageType, final int code) {
|
||||
PayloadTypeV1(final MessageType messageType, final int code) {
|
||||
this.messageType = messageType;
|
||||
this.code = (byte) code;
|
||||
}
|
||||
@ -106,13 +106,13 @@ public enum PayloadType {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public static PayloadType fromCode(final MessageType messageType, final byte code) {
|
||||
for (final PayloadType payloadType : values()) {
|
||||
public static PayloadTypeV1 fromCode(final MessageType messageType, final byte code) {
|
||||
for (final PayloadTypeV1 payloadType : values()) {
|
||||
if (messageType.equals(payloadType.messageType) && payloadType.code == code) {
|
||||
return payloadType;
|
||||
}
|
||||
}
|
||||
|
||||
return PayloadType.UNKNOWN;
|
||||
return PayloadTypeV1.UNKNOWN;
|
||||
}
|
||||
}
|
@ -61,7 +61,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.prot
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.BatteryType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.NoiseCancellingOptimizerStatus;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.VirtualSoundParam;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@ -74,9 +73,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request getAmbientSoundControl() {
|
||||
return new Request(
|
||||
PayloadType.AMBIENT_SOUND_CONTROL_GET.getMessageType(),
|
||||
PayloadTypeV1.AMBIENT_SOUND_CONTROL_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.AMBIENT_SOUND_CONTROL_GET.getCode(),
|
||||
PayloadTypeV1.AMBIENT_SOUND_CONTROL_GET.getCode(),
|
||||
(byte) 0x02
|
||||
}
|
||||
);
|
||||
@ -86,7 +85,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
public Request setAmbientSoundControl(final AmbientSoundControl ambientSoundControl) {
|
||||
final ByteBuffer buf = ByteBuffer.allocate(8);
|
||||
|
||||
buf.put(PayloadType.AMBIENT_SOUND_CONTROL_SET.getCode());
|
||||
buf.put(PayloadTypeV1.AMBIENT_SOUND_CONTROL_SET.getCode());
|
||||
buf.put((byte) 0x02);
|
||||
|
||||
if (AmbientSoundControl.Mode.OFF.equals(ambientSoundControl.getMode())) {
|
||||
@ -135,15 +134,15 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
break;
|
||||
}
|
||||
|
||||
return new Request(PayloadType.AMBIENT_SOUND_CONTROL_SET.getMessageType(), buf.array());
|
||||
return new Request(PayloadTypeV1.AMBIENT_SOUND_CONTROL_SET.getMessageType(), buf.array());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request getNoiseCancellingOptimizerState() {
|
||||
return new Request(
|
||||
PayloadType.NOISE_CANCELLING_OPTIMIZER_STATE_GET.getMessageType(),
|
||||
PayloadTypeV1.NOISE_CANCELLING_OPTIMIZER_STATE_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.NOISE_CANCELLING_OPTIMIZER_STATE_GET.getCode(),
|
||||
PayloadTypeV1.NOISE_CANCELLING_OPTIMIZER_STATE_GET.getCode(),
|
||||
(byte) 0x01
|
||||
}
|
||||
);
|
||||
@ -152,21 +151,21 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request getAudioCodec() {
|
||||
return new Request(
|
||||
PayloadType.AUDIO_CODEC_REQUEST.getMessageType(),
|
||||
PayloadTypeV1.AUDIO_CODEC_REQUEST.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.AUDIO_CODEC_REQUEST.getCode(),
|
||||
PayloadTypeV1.AUDIO_CODEC_REQUEST.getCode(),
|
||||
(byte) 0x00
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request getBattery(BatteryType batteryType) {
|
||||
public Request getBattery(final BatteryType batteryType) {
|
||||
return new Request(
|
||||
PayloadType.BATTERY_LEVEL_REQUEST.getMessageType(),
|
||||
PayloadTypeV1.BATTERY_LEVEL_REQUEST.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.BATTERY_LEVEL_REQUEST.getCode(),
|
||||
batteryType.getCode()
|
||||
PayloadTypeV1.BATTERY_LEVEL_REQUEST.getCode(),
|
||||
encodeBatteryType(batteryType)
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -174,9 +173,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request getFirmwareVersion() {
|
||||
return new Request(
|
||||
PayloadType.FW_VERSION_REQUEST.getMessageType(),
|
||||
PayloadTypeV1.FW_VERSION_REQUEST.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.FW_VERSION_REQUEST.getCode(),
|
||||
PayloadTypeV1.FW_VERSION_REQUEST.getCode(),
|
||||
(byte) 0x02
|
||||
}
|
||||
);
|
||||
@ -185,20 +184,20 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request getAudioUpsampling() {
|
||||
return new Request(
|
||||
PayloadType.AUDIO_UPSAMPLING_GET.getMessageType(),
|
||||
PayloadTypeV1.AUDIO_UPSAMPLING_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.AUDIO_UPSAMPLING_GET.getCode(),
|
||||
PayloadTypeV1.AUDIO_UPSAMPLING_GET.getCode(),
|
||||
(byte) 0x02
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request setAudioUpsampling(AudioUpsampling config) {
|
||||
public Request setAudioUpsampling(final AudioUpsampling config) {
|
||||
return new Request(
|
||||
PayloadType.AUDIO_UPSAMPLING_SET.getMessageType(),
|
||||
PayloadTypeV1.AUDIO_UPSAMPLING_SET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.AUDIO_UPSAMPLING_SET.getCode(),
|
||||
PayloadTypeV1.AUDIO_UPSAMPLING_SET.getCode(),
|
||||
(byte) 0x02,
|
||||
(byte) 0x00,
|
||||
(byte) (config.isEnabled() ? 0x01 : 0x00)
|
||||
@ -209,9 +208,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request getAutomaticPowerOff() {
|
||||
return new Request(
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getMessageType(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getCode(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getCode(),
|
||||
(byte) 0x04
|
||||
}
|
||||
);
|
||||
@ -220,9 +219,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request setAutomaticPowerOff(final AutomaticPowerOff config) {
|
||||
return new Request(
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getMessageType(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getCode(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getCode(),
|
||||
(byte) 0x04,
|
||||
(byte) 0x01,
|
||||
config.getCode()[0],
|
||||
@ -233,9 +232,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
|
||||
public Request getButtonModes() {
|
||||
return new Request(
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getMessageType(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getCode(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getCode(),
|
||||
(byte) 0x06
|
||||
}
|
||||
);
|
||||
@ -243,9 +242,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
|
||||
public Request setButtonModes(final ButtonModes config) {
|
||||
return new Request(
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getMessageType(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getCode(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getCode(),
|
||||
(byte) 0x06,
|
||||
(byte) 0x02,
|
||||
config.getModeLeft().getCode(),
|
||||
@ -257,9 +256,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request getPauseWhenTakenOff() {
|
||||
return new Request(
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getMessageType(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getCode(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_GET.getCode(),
|
||||
(byte) 0x03
|
||||
}
|
||||
);
|
||||
@ -268,9 +267,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request setPauseWhenTakenOff(final PauseWhenTakenOff config) {
|
||||
return new Request(
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getMessageType(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getCode(),
|
||||
PayloadTypeV1.AUTOMATIC_POWER_OFF_BUTTON_MODE_SET.getCode(),
|
||||
(byte) 0x03,
|
||||
(byte) 0x00,
|
||||
(byte) (config.isEnabled() ? 0x01 : 0x00)
|
||||
@ -281,9 +280,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request getEqualizer() {
|
||||
return new Request(
|
||||
PayloadType.EQUALIZER_GET.getMessageType(),
|
||||
PayloadTypeV1.EQUALIZER_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.EQUALIZER_GET.getCode(),
|
||||
PayloadTypeV1.EQUALIZER_GET.getCode(),
|
||||
(byte) 0x01
|
||||
}
|
||||
);
|
||||
@ -292,9 +291,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request setEqualizerPreset(final EqualizerPreset config) {
|
||||
return new Request(
|
||||
PayloadType.EQUALIZER_SET.getMessageType(),
|
||||
PayloadTypeV1.EQUALIZER_SET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.EQUALIZER_SET.getCode(),
|
||||
PayloadTypeV1.EQUALIZER_SET.getCode(),
|
||||
(byte) 0x01,
|
||||
config.getCode(),
|
||||
(byte) 0x00
|
||||
@ -306,7 +305,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
public Request setEqualizerCustomBands(final EqualizerCustomBands config) {
|
||||
final ByteBuffer buf = ByteBuffer.allocate(10);
|
||||
|
||||
buf.put(PayloadType.EQUALIZER_SET.getCode());
|
||||
buf.put(PayloadTypeV1.EQUALIZER_SET.getCode());
|
||||
buf.put((byte) 0x01);
|
||||
buf.put((byte) 0xff);
|
||||
buf.put((byte) 0x06);
|
||||
@ -317,7 +316,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
}
|
||||
|
||||
return new Request(
|
||||
PayloadType.EQUALIZER_SET.getMessageType(),
|
||||
PayloadTypeV1.EQUALIZER_SET.getMessageType(),
|
||||
buf.array()
|
||||
);
|
||||
}
|
||||
@ -325,9 +324,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request getSoundPosition() {
|
||||
return new Request(
|
||||
PayloadType.SOUND_POSITION_OR_MODE_GET.getMessageType(),
|
||||
PayloadTypeV1.SOUND_POSITION_OR_MODE_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.SOUND_POSITION_OR_MODE_GET.getCode(),
|
||||
PayloadTypeV1.SOUND_POSITION_OR_MODE_GET.getCode(),
|
||||
(byte) 0x02
|
||||
}
|
||||
);
|
||||
@ -336,9 +335,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request setSoundPosition(final SoundPosition config) {
|
||||
return new Request(
|
||||
PayloadType.SOUND_POSITION_OR_MODE_SET.getMessageType(),
|
||||
PayloadTypeV1.SOUND_POSITION_OR_MODE_SET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.SOUND_POSITION_OR_MODE_SET.getCode(),
|
||||
PayloadTypeV1.SOUND_POSITION_OR_MODE_SET.getCode(),
|
||||
VirtualSoundParam.SOUND_POSITION.getCode(),
|
||||
config.getCode()
|
||||
}
|
||||
@ -348,9 +347,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request getSurroundMode() {
|
||||
return new Request(
|
||||
PayloadType.SOUND_POSITION_OR_MODE_GET.getMessageType(),
|
||||
PayloadTypeV1.SOUND_POSITION_OR_MODE_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.SOUND_POSITION_OR_MODE_GET.getCode(),
|
||||
PayloadTypeV1.SOUND_POSITION_OR_MODE_GET.getCode(),
|
||||
VirtualSoundParam.SURROUND_MODE.getCode()
|
||||
}
|
||||
);
|
||||
@ -359,9 +358,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request setSurroundMode(final SurroundMode config) {
|
||||
return new Request(
|
||||
PayloadType.SOUND_POSITION_OR_MODE_SET.getMessageType(),
|
||||
PayloadTypeV1.SOUND_POSITION_OR_MODE_SET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.SOUND_POSITION_OR_MODE_SET.getCode(),
|
||||
PayloadTypeV1.SOUND_POSITION_OR_MODE_SET.getCode(),
|
||||
VirtualSoundParam.SURROUND_MODE.getCode(),
|
||||
config.getCode()
|
||||
}
|
||||
@ -371,9 +370,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request getTouchSensor() {
|
||||
return new Request(
|
||||
PayloadType.TOUCH_SENSOR_GET.getMessageType(),
|
||||
PayloadTypeV1.TOUCH_SENSOR_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.TOUCH_SENSOR_GET.getCode(),
|
||||
PayloadTypeV1.TOUCH_SENSOR_GET.getCode(),
|
||||
(byte) 0xd2
|
||||
}
|
||||
);
|
||||
@ -382,9 +381,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request setTouchSensor(final TouchSensor config) {
|
||||
return new Request(
|
||||
PayloadType.TOUCH_SENSOR_SET.getMessageType(),
|
||||
PayloadTypeV1.TOUCH_SENSOR_SET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.TOUCH_SENSOR_SET.getCode(),
|
||||
PayloadTypeV1.TOUCH_SENSOR_SET.getCode(),
|
||||
(byte) 0xd2,
|
||||
(byte) 0x01,
|
||||
(byte) (config.isEnabled() ? 0x01 : 0x00)
|
||||
@ -395,9 +394,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request getVoiceNotifications() {
|
||||
return new Request(
|
||||
PayloadType.VOICE_NOTIFICATIONS_GET.getMessageType(),
|
||||
PayloadTypeV1.VOICE_NOTIFICATIONS_GET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.VOICE_NOTIFICATIONS_GET.getCode(),
|
||||
PayloadTypeV1.VOICE_NOTIFICATIONS_GET.getCode(),
|
||||
(byte) 0x01,
|
||||
(byte) 0x01
|
||||
}
|
||||
@ -407,9 +406,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request setVoiceNotifications(final VoiceNotifications config) {
|
||||
return new Request(
|
||||
PayloadType.VOICE_NOTIFICATIONS_SET.getMessageType(),
|
||||
PayloadTypeV1.VOICE_NOTIFICATIONS_SET.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.VOICE_NOTIFICATIONS_SET.getCode(),
|
||||
PayloadTypeV1.VOICE_NOTIFICATIONS_SET.getCode(),
|
||||
(byte) 0x01,
|
||||
(byte) 0x01,
|
||||
(byte) (config.isEnabled() ? 0x01 : 0x00)
|
||||
@ -420,9 +419,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request startNoiseCancellingOptimizer(final boolean start) {
|
||||
return new Request(
|
||||
PayloadType.NOISE_CANCELLING_OPTIMIZER_START.getMessageType(),
|
||||
PayloadTypeV1.NOISE_CANCELLING_OPTIMIZER_START.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.NOISE_CANCELLING_OPTIMIZER_START.getCode(),
|
||||
PayloadTypeV1.NOISE_CANCELLING_OPTIMIZER_START.getCode(),
|
||||
(byte) 0x01,
|
||||
(byte) 0x00,
|
||||
(byte) (start ? 0x01 : 0x00)
|
||||
@ -433,9 +432,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
@Override
|
||||
public Request powerOff() {
|
||||
return new Request(
|
||||
PayloadType.POWER_OFF.getMessageType(),
|
||||
PayloadTypeV1.POWER_OFF.getMessageType(),
|
||||
new byte[]{
|
||||
PayloadType.POWER_OFF.getCode(),
|
||||
PayloadTypeV1.POWER_OFF.getCode(),
|
||||
(byte) 0x00,
|
||||
(byte) 0x01
|
||||
}
|
||||
@ -444,7 +443,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
|
||||
@Override
|
||||
public List<? extends GBDeviceEvent> handlePayload(final MessageType messageType, final byte[] payload) {
|
||||
final PayloadType payloadType = PayloadType.fromCode(messageType, payload[0]);
|
||||
final PayloadTypeV1 payloadType = PayloadTypeV1.fromCode(messageType, payload[0]);
|
||||
|
||||
switch (payloadType) {
|
||||
case INIT_REPLY:
|
||||
@ -493,12 +492,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
}
|
||||
|
||||
public List<? extends GBDeviceEvent> handleInitResponse(final byte[] payload) {
|
||||
if (payload.length != 4) {
|
||||
LOG.warn("Unexpected payload length {}", payload.length);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final SonyHeadphonesCoordinator coordinator = (SonyHeadphonesCoordinator) DeviceHelper.getInstance().getCoordinator(getDevice());
|
||||
final SonyHeadphonesCoordinator coordinator = getCoordinator();
|
||||
|
||||
// Populate the init requests
|
||||
final List<Request> capabilityRequests = new ArrayList<>();
|
||||
@ -530,6 +524,9 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any requests that are not supported by other protocol version
|
||||
capabilityRequests.removeAll(Collections.singleton(null));
|
||||
|
||||
return Collections.singletonList(new SonyHeadphonesEnqueueRequestEvent(capabilityRequests));
|
||||
}
|
||||
|
||||
@ -570,17 +567,10 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
boolean focusOnVoice;
|
||||
switch (payload[6]) {
|
||||
case 0x00:
|
||||
focusOnVoice = false;
|
||||
break;
|
||||
case 0x01:
|
||||
focusOnVoice = true;
|
||||
break;
|
||||
default:
|
||||
LOG.warn("Unknown focus on voice mode {}", String.format("%02x", payload[6]));
|
||||
return Collections.emptyList();
|
||||
final Boolean focusOnVoice = booleanFromByte(payload[6]);
|
||||
if (focusOnVoice == null) {
|
||||
LOG.warn("Unknown focus on voice mode {}", String.format("%02x", payload[6]));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
int ambientSound = payload[7];
|
||||
@ -606,7 +596,6 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
}
|
||||
|
||||
final NoiseCancellingOptimizerStatus status = NoiseCancellingOptimizerStatus.fromCode(payload[3]);
|
||||
|
||||
if (status == null) {
|
||||
LOG.warn("Unable to determine noise cancelling opptimizer status from {}", GB.hexdump(payload));
|
||||
return Collections.emptyList();
|
||||
@ -649,18 +638,10 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
boolean enabled;
|
||||
|
||||
switch (payload[3]) {
|
||||
case 0x00:
|
||||
enabled = false;
|
||||
break;
|
||||
case 0x01:
|
||||
enabled = true;
|
||||
break;
|
||||
default:
|
||||
LOG.warn("Unknown audio upsampling code {}", String.format("%02x", payload[3]));
|
||||
return Collections.emptyList();
|
||||
final Boolean enabled = booleanFromByte(payload[3]);
|
||||
if (enabled == null) {
|
||||
LOG.warn("Unknown audio upsampling code {}", String.format("%02x", payload[3]));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
LOG.debug("Audio Upsampling: {}", enabled);
|
||||
@ -683,15 +664,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
AutomaticPowerOff mode = null;
|
||||
|
||||
for (AutomaticPowerOff value : AutomaticPowerOff.values()) {
|
||||
if (value.getCode()[0] == payload[3] && value.getCode()[1] == payload[4]) {
|
||||
mode = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final AutomaticPowerOff mode = AutomaticPowerOff.fromCode(payload[3], payload[4]);
|
||||
if (mode == null) {
|
||||
LOG.warn("Unknown automatic power off codes {}", String.format("%02x %02x", payload[3], payload[4]));
|
||||
return Collections.emptyList();
|
||||
@ -711,22 +684,8 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
ButtonModes.Mode modeLeft = null;
|
||||
for (ButtonModes.Mode value : ButtonModes.Mode.values()) {
|
||||
if (value.getCode() == payload[3]) {
|
||||
modeLeft = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ButtonModes.Mode modeRight = null;
|
||||
for (ButtonModes.Mode value : ButtonModes.Mode.values()) {
|
||||
if (value.getCode() == payload[4]) {
|
||||
modeRight = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final ButtonModes.Mode modeLeft = ButtonModes.Mode.fromCode(payload[3]);
|
||||
final ButtonModes.Mode modeRight = ButtonModes.Mode.fromCode(payload[4]);
|
||||
if (modeLeft == null || modeRight == null) {
|
||||
LOG.warn("Unknown button mode codes {}", String.format("%02x %02x", payload[3], payload[4]));
|
||||
return Collections.emptyList();
|
||||
@ -746,21 +705,13 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
boolean enabled;
|
||||
|
||||
switch (payload[3]) {
|
||||
case 0x00:
|
||||
enabled = false;
|
||||
break;
|
||||
case 0x01:
|
||||
enabled = true;
|
||||
break;
|
||||
default:
|
||||
LOG.warn("Unknown pause when taken off code {}", String.format("%02x", payload[3]));
|
||||
return Collections.emptyList();
|
||||
final Boolean enabled = booleanFromByte(payload[3]);
|
||||
if (enabled == null) {
|
||||
LOG.warn("Unknown pause when taken off code {}", String.format("%02x", payload[3]));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
LOG.debug("Touch Sensor: {}", enabled);
|
||||
LOG.debug("Pause when taken off: {}", enabled);
|
||||
|
||||
final GBDeviceEventUpdatePreferences event = new GBDeviceEventUpdatePreferences()
|
||||
.withPreferences(new PauseWhenTakenOff(enabled).toPreferences());
|
||||
@ -769,7 +720,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
}
|
||||
|
||||
public List<? extends GBDeviceEvent> handleBattery(final byte[] payload) {
|
||||
final BatteryType batteryType = BatteryType.fromCode(payload[1]);
|
||||
final BatteryType batteryType = decodeBatteryType(payload[1]);
|
||||
|
||||
if (batteryType == null) {
|
||||
LOG.warn("Unknown battery type code {}", String.format("%02x", payload[1]));
|
||||
@ -822,8 +773,12 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final AudioCodec audioCodec = AudioCodec.fromCode(payload[2]);
|
||||
if (payload[1] != 0x00) {
|
||||
LOG.warn("Not audio codec, ignoring");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final AudioCodec audioCodec = AudioCodec.fromCode(payload[2]);
|
||||
if (audioCodec == null) {
|
||||
LOG.warn("Unable to determine audio codec from {}", GB.hexdump(payload));
|
||||
return Collections.emptyList();
|
||||
@ -843,14 +798,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
EqualizerPreset mode = null;
|
||||
for (EqualizerPreset value : EqualizerPreset.values()) {
|
||||
if (value.getCode() == payload[2]) {
|
||||
mode = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final EqualizerPreset mode = EqualizerPreset.fromCode(payload[2]);
|
||||
if (mode == null) {
|
||||
LOG.warn("Unknown equalizer preset code {}", String.format("%02x", payload[2]));
|
||||
return Collections.emptyList();
|
||||
@ -879,6 +827,11 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
public List<? extends GBDeviceEvent> handleFirmwareVersion(final byte[] payload) {
|
||||
final Pattern VERSION_REGEX = Pattern.compile("^[0-9.\\-a-zA-Z_]+$");
|
||||
|
||||
if (payload[1] != 0x02) {
|
||||
LOG.warn("Not firmware version, ignoring");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (payload.length < 4) {
|
||||
LOG.warn("Unexpected payload length {}", payload.length);
|
||||
return Collections.emptyList();
|
||||
@ -886,6 +839,12 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
|
||||
final String firmwareVersion = new String(Arrays.copyOfRange(payload, 3, payload.length));
|
||||
|
||||
final int expectedLength = payload[2] & 0xff;
|
||||
if (firmwareVersion.length() != expectedLength) {
|
||||
LOG.warn("Unexpected firmware version length {}, expected {}", firmwareVersion.length(), expectedLength);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (!VERSION_REGEX.matcher(firmwareVersion).find()) {
|
||||
LOG.warn("Unexpected characters in version '{}'", firmwareVersion);
|
||||
return Collections.emptyList();
|
||||
@ -1060,9 +1019,47 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl {
|
||||
return Collections.singletonList(event);
|
||||
}
|
||||
|
||||
private boolean supportsWindNoiseCancelling() {
|
||||
final SonyHeadphonesCoordinator coordinator = (SonyHeadphonesCoordinator) DeviceHelper.getInstance().getCoordinator(getDevice());
|
||||
protected Boolean booleanFromByte(final byte b) {
|
||||
switch (b) {
|
||||
case 0x00:
|
||||
return false;
|
||||
case 0x01:
|
||||
return true;
|
||||
default:
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean supportsWindNoiseCancelling() {
|
||||
final SonyHeadphonesCoordinator coordinator = getCoordinator();
|
||||
|
||||
return coordinator.supports(SonyHeadphonesCapabilities.WindNoiseReduction);
|
||||
}
|
||||
|
||||
protected BatteryType decodeBatteryType(final byte b) {
|
||||
switch (b) {
|
||||
case 0x00:
|
||||
return BatteryType.SINGLE;
|
||||
case 0x01:
|
||||
return BatteryType.DUAL;
|
||||
case 0x02:
|
||||
return BatteryType.CASE;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected byte encodeBatteryType(final BatteryType batteryType) {
|
||||
switch (batteryType) {
|
||||
case SINGLE:
|
||||
return 0x00;
|
||||
case DUAL:
|
||||
return 0x01;
|
||||
case CASE:
|
||||
return 0x02;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown battery type " + batteryType);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,12 @@ public enum NoiseCancellingOptimizerStatus {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public String i18n(final Context context) {
|
||||
final String stringName = String.format("sony_anc_optimizer_status_%s", name().toLowerCase(Locale.ROOT));
|
||||
final int stringId = context.getResources().getIdentifier(stringName, "string", context.getPackageName());
|
||||
return context.getString(stringId);
|
||||
}
|
||||
|
||||
public static NoiseCancellingOptimizerStatus fromCode(final byte code) {
|
||||
for (final NoiseCancellingOptimizerStatus audioCodec : values()) {
|
||||
if (audioCodec.code == code) {
|
||||
@ -47,10 +53,4 @@ public enum NoiseCancellingOptimizerStatus {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String i18n(final Context context) {
|
||||
final String stringName = String.format("sony_anc_optimizer_status_%s", name().toLowerCase(Locale.ROOT));
|
||||
final int stringId = context.getResources().getIdentifier(stringName, "string", context.getPackageName());
|
||||
return context.getString(stringId);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user