Skip to content

Commit

Permalink
feat: add bassup update packet
Browse files Browse the repository at this point in the history
  • Loading branch information
gmallios committed Apr 28, 2024
1 parent aff515a commit 7631c28
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 19 deletions.
4 changes: 4 additions & 0 deletions soundcore-lib/src/devices/a3040.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
mod bass_up_update;
mod eq_update_command;
mod features;
mod sound_mode_update_command;

pub use bass_up_update::*;
pub use eq_update_command::*;
pub use features::*;
pub use sound_mode_update_command::*;
12 changes: 12 additions & 0 deletions soundcore-lib/src/devices/a3040/bass_up_update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use nom::{combinator::map, error::context};

use crate::{
models::BassUp,
parsers::{parse_bool, ParseError, ParseResult},
};

pub fn parse_a3040_bass_up_update<'a, E: ParseError<'a>>(
bytes: &'a [u8],
) -> ParseResult<BassUp, E> {
context("parse_a3040_bass_up_update", map(parse_bool, BassUp))(bytes)
}
11 changes: 10 additions & 1 deletion soundcore-lib/src/models/packet_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ pub enum ResponsePacketKind {
/* Packets which *should* update the state in some way */
StateUpdate,
InfoUpdate,
ThreeDimensionalEffectUpdate,
BassUpUpdate,
EqInfoUpdate,
SoundModeUpdate,
BattLevelUpdate,
BattChargingUpdate,
Expand All @@ -19,10 +22,16 @@ pub enum ResponsePacketKind {

/* We can use Generic Arg Infer "#![feature(generic_arg_infer)]" once https://github.com/rust-lang/rust/issues/85077 is stabilized */
/* This also could be dynamically be created, since the bytes match the command id bytes */
pub const PACKET_KIND_MAP: [(&[u8; 2], ResponsePacketKind); 10] = [
pub const PACKET_KIND_MAP: [(&[u8; 2], ResponsePacketKind); 13] = [
(&[0xFF, 0xFF], ResponsePacketKind::Unknown),
/* Updates */
(&[0x01, 0x01], ResponsePacketKind::StateUpdate),
(&[0x02, 0x01], ResponsePacketKind::EqInfoUpdate),
(&[0x02, 0x04], ResponsePacketKind::BassUpUpdate),
(
&[0x02, 0x06],
ResponsePacketKind::ThreeDimensionalEffectUpdate,
),
(&[0x01, 0x03], ResponsePacketKind::BattLevelUpdate),
(&[0x01, 0x04], ResponsePacketKind::BattChargingUpdate),
(&[0x01, 0x05], ResponsePacketKind::InfoUpdate),
Expand Down
23 changes: 14 additions & 9 deletions soundcore-lib/src/packets/response.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
use log::error;
use nom::error::VerboseError;

pub use info::*;
pub use sound_mode::*;
pub use state::*;

use crate::api::SoundcoreDeviceState;
use crate::parsers::TaggedData;
use crate::{
models::ResponsePacketKind,
parsers::{parse_and_check_checksum, parse_packet_header},
};

mod battery;
mod info;
mod sound_mode;
mod state;
mod bass_up;

pub use info::*;
pub use sound_mode::*;
pub use state::*;
pub use bass_up::*;

#[derive(Debug)]
pub enum ResponsePacket {
DeviceState(TaggedData<DeviceStateResponse>),
SoundModeUpdate(SoundModeUpdateResponse),
DeviceInfo(DeviceInfoResponse),
BassUpUpdate(BassUpUpdateResponse),
Unknown,
}

Expand All @@ -37,6 +45,7 @@ impl ResponsePacket {
Self::SoundModeUpdate(parse_sound_mode_update_packet(bytes)?.1)
}
ResponsePacketKind::InfoUpdate => Self::DeviceInfo(parse_device_info_packet(bytes)?.1),
ResponsePacketKind::BassUpUpdate => Self::BassUpUpdate(parse_bass_up_update(bytes)?.1),
_ => {
// TODO: Have an array of Acks and handle those properly
error!(
Expand Down Expand Up @@ -85,17 +94,13 @@ impl StateTransformationPacket for ResponsePacket {
sound_mode_update.transform_state(state)
}
ResponsePacket::DeviceState(state_update) => state_update.data.transform_state(state),
ResponsePacket::BassUpUpdate(packet) => packet.transform_state(state),
// No-op
_ => state.clone(),
}
}
}

mod battery;
mod info;
mod sound_mode;
mod state;

#[cfg(test)]
mod response_test {
use test_data::a3951::*;
Expand Down
37 changes: 37 additions & 0 deletions soundcore-lib/src/packets/response/bass_up.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use log::{debug, warn};
use nom::combinator::map;
use nom::error::context;
use serde::{Deserialize, Serialize};

use crate::api::SoundcoreDeviceState;
use crate::devices::parse_a3040_bass_up_update;
use crate::models::BassUp;
use crate::packets::StateTransformationPacket;
use crate::parsers::{ParseError, ParseResult};

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
pub struct BassUpUpdateResponse(pub BassUp);
pub fn parse_bass_up_update<'a, E: ParseError<'a>>(
bytes: &'a [u8],
) -> ParseResult<BassUpUpdateResponse, E> {
context(
"parse_bass_up_update",
map(parse_a3040_bass_up_update, BassUpUpdateResponse),
)(bytes)
}

impl StateTransformationPacket for BassUpUpdateResponse {
fn transform_state(self, state: &SoundcoreDeviceState) -> SoundcoreDeviceState {
let mut state = state.to_owned();
match state.bass_up {
Some(bass_up) => {
debug!("Updating BassUp state from {:?} to {:?}", bass_up, self.0);
state.bass_up = Some(self.0);
}
None => {
warn!("BassUpUpdateResponse received without a previous BassUp state");
}
}
state
}
}
18 changes: 9 additions & 9 deletions soundcore-lib/src/packets/response/state/a3040.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ use nom::{bytes::complete::take, number::complete::le_u8};
use nom::{error::context, sequence::tuple};
use serde::{Deserialize, Serialize};

use crate::{
models::{
AmbientSoundNotice, AutoPowerOff, BassUp, DeviceColor, FirmwareVer, HearingProtect,
InEarBeep, LDAC, PowerOnBatteryNotice, SerialNumber, SingleBattery,
SupportTwoCnn, ThreeDimensionalEffect, TouchTone, WearDetection,
},
parsers::{parse_serial_number, ParseError},
};
use crate::devices::a3040_features;
use crate::models::{
A3040ButtonModel, ButtonModel, PromptLanguage, SoundMode, StereoEQConfiguration, TwsStatus,
Expand All @@ -10,17 +18,9 @@ use crate::packets::DeviceStateResponse;
use crate::parsers::{
bool_parser, parse_a3040_button_model, parse_adaptive_sound_mode_customizable_trans,
parse_auto_power_off_on, parse_fw, parse_hearing_protect, parse_prompt_language,
parse_single_battery, parse_stereo_eq_configuration, u8_parser, TaggedData, TaggedParseResult,
parse_single_battery, parse_stereo_eq_configuration, TaggedData, TaggedParseResult, u8_parser,
};
use crate::types::SupportedModels;
use crate::{
models::{
AmbientSoundNotice, AutoPowerOff, BassUp, DeviceColor, FirmwareVer, HearingProtect,
InEarBeep, PowerOnBatteryNotice, SerialNumber, SingleBattery, SupportTwoCnn,
ThreeDimensionalEffect, TouchTone, WearDetection, LDAC,
},
parsers::{parse_serial_number, ParseError},
};

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
pub struct A3040StateResponse {
Expand Down
2 changes: 2 additions & 0 deletions soundcore-lib/src/parsers/packet_header.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use log::trace;
use nom::{
bytes::complete::take,
combinator::{map, map_opt},
Expand Down Expand Up @@ -33,6 +34,7 @@ fn parse_packet_kind<'a, E: ParseError<'a>>(bytes: &'a [u8]) -> ParseResult<Resp
context(
"parse_packet_header",
map_opt(take(2usize), |bytes: &[u8]| {
trace!("Parsing packet kind: {:?}", bytes);
PACKET_KIND_MAP
.iter()
.find(|(map_bytes, _)| map_bytes == &bytes)
Expand Down

0 comments on commit 7631c28

Please sign in to comment.