diff --git a/manager-app/src/main.rs b/manager-app/src/main.rs index 7fe9ae0..28c1069 100644 --- a/manager-app/src/main.rs +++ b/manager-app/src/main.rs @@ -8,15 +8,14 @@ use std::sync::Arc; use log::trace; use mpsc::channel; -use soundcore_lib::api::SoundcoreDeviceState; -use soundcore_lib::btaddr::BluetoothAdrr; - -use tauri::async_runtime::{Mutex, RwLock}; use tauri::{AppHandle, Manager}; +use tauri::async_runtime::{Mutex, RwLock}; use tauri_plugin_log::LogTarget; use tokio::sync::mpsc; -use soundcore_lib::types::SupportedModels; +use soundcore_lib::api::SoundcoreDeviceState; +use soundcore_lib::btaddr::BluetoothAdrr; +use soundcore_lib::types::KnownProductCodes; use crate::async_bridge::{async_bridge, BridgeCommand, BridgeResponse}; @@ -26,7 +25,7 @@ pub(crate) mod async_bridge; // mod tray; struct SoundcoreAppState { - model: Arc>>, + model: Arc>>, bridge_tx: Mutex>, scan_in_progress: Arc>, last_states: Arc>>, diff --git a/manager-ui/src/assets/a3947_img_device.png b/manager-ui/src/assets/a3947_img_device.png new file mode 100644 index 0000000..e5c1083 Binary files /dev/null and b/manager-ui/src/assets/a3947_img_device.png differ diff --git a/manager-ui/src/components/DeviceStateCard/deviceStateCard.tsx b/manager-ui/src/components/DeviceStateCard/deviceStateCard.tsx index 501ed70..d7bd3ff 100644 --- a/manager-ui/src/components/DeviceStateCard/deviceStateCard.tsx +++ b/manager-ui/src/components/DeviceStateCard/deviceStateCard.tsx @@ -13,10 +13,7 @@ export const DeviceStateCard: React.FC = () => { - + diff --git a/manager-ui/src/types/soundcore-lib.ts b/manager-ui/src/types/soundcore-lib.ts index b3bd701..6adbc6f 100644 --- a/manager-ui/src/types/soundcore-lib.ts +++ b/manager-ui/src/types/soundcore-lib.ts @@ -6,6 +6,13 @@ export type CustomANCValue = number; export type CustomTransparencyValue = number; +/** + * This u8 is a char which based on it fetches the apropriate image for the device (Reference: OtaBaseActivity/renderProductIcon). + * Perhaps this can be internally mapped to our product images. + * Further investigation is needed. + */ +export type DeviceColor = number; + export type HearIDType = number; export type HearIDMusicType = number; @@ -92,7 +99,7 @@ export type EQConfiguration = | { type: 'stereo'; value: StereoEQConfiguration } | { type: 'mono'; value: MonoEQConfiguration }; -export enum SupportedModels { +export enum KnownProductCodes { A3027 = 'A3027', A3028 = 'A3028', A3029 = 'A3029', @@ -100,12 +107,13 @@ export enum SupportedModels { A3930 = 'A3930', A3931 = 'A3931', A3935 = 'A3935', - A3951 = 'A3951' + A3951 = 'A3951', + A3947 = 'A3947' } export interface SerialNumber { value: string; - model?: SupportedModels; + model?: KnownProductCodes; } export interface FirmwareVer { @@ -119,6 +127,22 @@ export type ButtonModel = export type HearID = { type: 'base'; value: BaseHearID } | { type: 'custom'; value: CustomHearID }; +export interface AutoPowerOff { + enabled: boolean; + index: number; +} + +export enum PromptLanguage { + English = 'English', + Chinese = 'Chinese' +} + +export interface HearingProtect { + enabled: boolean; + db: number; + freq: number; +} + /** This is a generalized version of the state for all devices */ export interface SoundcoreDeviceState { featureSet: DeviceFeatureSet; @@ -127,14 +151,28 @@ export interface SoundcoreDeviceState { eqConfiguration: EQConfiguration; serial?: SerialNumber; fw?: FirmwareVer; - hostDevice?: number; - twsStatus?: TwsStatus; buttonModel?: ButtonModel; + hostDevice?: number; sideTone?: SideTone; + ageRange?: AgeRange; + /** HearID */ hearidEqPreset?: number; - wearDetection?: WearDetection; hearId?: HearID; - ageRange?: AgeRange; + hearIdHasData?: boolean; + touchTone?: TouchTone; + twsStatus?: TwsStatus; + wearDetection?: WearDetection; + bassUp?: BassUp; + autoPowerOff?: AutoPowerOff; + supportTwoCnn?: SupportTwoCnn; + inEarBeep?: InEarBeep; + ambientSoundNotice?: AmbientSoundNotice; + powerOnBatteryNotice?: PowerOnBatteryNotice; + threeDimensionalEffect?: ThreeDimensionalEffect; + deviceColor?: DeviceColor; + ldac?: LDAC; + promptLanguage?: PromptLanguage; + hearingProtect?: HearingProtect; } export interface BluetoothAdrr { @@ -151,7 +189,7 @@ export interface DiscoveredDevice { /** The BLE device descriptor. */ descriptor: BLEDeviceDescriptor; /** The model of the device, resolved using the device's advertised name. */ - model?: SupportedModels; + model?: KnownProductCodes; } export enum Action { @@ -249,8 +287,7 @@ export enum EQProfile { Daya = 'Daya', CedricGervais = 'CedricGervais', TheInfamousStringdusters = 'TheInfamousStringdusters', - JohnPaulWhite = 'JohnPaulWhite', - SoundcoreSignatureBassUp = 'SoundcoreSignatureBassUp' + JohnPaulWhite = 'JohnPaulWhite' } export interface StereoEQConfiguration { @@ -335,11 +372,6 @@ export enum NonCustomizableTransparencyMode { Vocal = 'vocal' } -export enum PromptLanguage { - English = 'English', - Chinese = 'Chinese' -} - export enum SceneBasedANCMode { Transport = 'Transport', Outdoor = 'Outdoor', diff --git a/manager-ui/src/utils/modelToImgMap.ts b/manager-ui/src/utils/modelToImgMap.ts index a6ace0a..178359e 100644 --- a/manager-ui/src/utils/modelToImgMap.ts +++ b/manager-ui/src/utils/modelToImgMap.ts @@ -5,6 +5,7 @@ import A3028Img from '@assets/a3028_img_device.webp'; import A3029Img from '@assets/a3029_img_device.webp'; import A3040Img from '@assets/a3040_img_device.webp'; import A3935Img from '@assets/a3935_img_device.webp'; +import A3947Img from '@assets/a3947_img_device.png'; export type ImageData = { img: string; @@ -19,7 +20,8 @@ const ModelSingleImageMap: { A3027: { img: A3027Img, height: 90 }, A3028: { img: A3028Img, height: 90 }, A3029: { img: A3029Img, height: 90 }, - A3935: { img: A3935Img, height: 90 } + A3935: { img: A3935Img, height: 90 }, + A3947: { img: A3947Img, height: 90 } }; const ModelDoubleImageMap: { diff --git a/soundcore-lib/src/device.rs b/soundcore-lib/src/device.rs index 329d214..ff2b733 100644 --- a/soundcore-lib/src/device.rs +++ b/soundcore-lib/src/device.rs @@ -15,7 +15,7 @@ use crate::packets::{ StateTransformationPacket, }; use crate::parsers::TaggedData; -use crate::types::SupportedModels; +use crate::types::KnownProductCodes; pub struct SoundcoreBLEDevice where @@ -24,7 +24,7 @@ where connection: Arc, state_channel: Arc>>, state_channel_handle: JoinHandle<()>, - model: SupportedModels, + model: KnownProductCodes, } impl SoundcoreBLEDevice @@ -117,7 +117,7 @@ where // TODO: Add test data to mocked device so initial state can be fetched if cfg!(test) || cfg!(feature = "mock") { return Ok(TaggedData { - tag: SupportedModels::A3951, + tag: KnownProductCodes::A3951, data: SoundcoreDeviceState::default(), }); } diff --git a/soundcore-lib/src/device_manager.rs b/soundcore-lib/src/device_manager.rs index bdc365a..cf8f935 100644 --- a/soundcore-lib/src/device_manager.rs +++ b/soundcore-lib/src/device_manager.rs @@ -1,25 +1,25 @@ +use std::{sync::Arc, time::Duration}; use std::collections::hash_map::Entry; use std::collections::HashMap; -use std::{sync::Arc, time::Duration}; -use crate::ble::BLEAdapterEvent; -#[cfg(any(test, feature = "mock"))] -use crate::mocks::*; +use serde::{Deserialize, Serialize}; +use tokio::sync::RwLock; +use typeshare::typeshare; + use crate::{ ble::{BLEConnectionManager, BLEDeviceDescriptor}, btaddr::BluetoothAdrr, device::SoundcoreBLEDevice, error::SoundcoreLibResult, - types::{SupportedModels, SOUNDCORE_NAME_MODEL_MAP}, + types::{KnownProductCodes, SOUNDCORE_NAME_PRODUCT_CODE_MAP}, }; -use serde::{Deserialize, Serialize}; -use tokio::sync::RwLock; -use typeshare::typeshare; - +use crate::ble::BLEAdapterEvent; // TODO: Specify clippy & fmt features #[allow(unused_imports)] #[cfg(all(feature = "btleplug-backend", not(feature = "mock")))] use crate::ble::btleplug::manager::BtlePlugBLEManager; +#[cfg(any(test, feature = "mock"))] +use crate::mocks::*; pub struct DeviceManager where @@ -111,7 +111,7 @@ where } fn resolve_model(discovered_device: DiscoveredDevice) -> DiscoveredDevice { - match SOUNDCORE_NAME_MODEL_MAP + match SOUNDCORE_NAME_PRODUCT_CODE_MAP .into_iter() .find(|(k, _v)| discovered_device.descriptor.name.contains(**k)) { @@ -132,7 +132,7 @@ pub struct DiscoveredDevice { /// The BLE device descriptor. pub descriptor: BLEDeviceDescriptor, /// The model of the device, resolved using the device's advertised name. - pub model: Option, + pub model: Option, } #[cfg(all( diff --git a/soundcore-lib/src/models/auto_power.rs b/soundcore-lib/src/models/auto_power.rs index 73e4bd1..7efe60f 100644 --- a/soundcore-lib/src/models/auto_power.rs +++ b/soundcore-lib/src/models/auto_power.rs @@ -1,7 +1,9 @@ use serde::{Deserialize, Serialize}; +use typeshare::typeshare; #[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash)] #[serde(rename_all = "camelCase", tag = "type")] +#[typeshare] pub struct AutoPowerOff { pub enabled: bool, pub index: u8, //TODO: Search for possible values and map to enum diff --git a/soundcore-lib/src/models/device_color.rs b/soundcore-lib/src/models/device_color.rs index 12ff1a9..109a3ac 100644 --- a/soundcore-lib/src/models/device_color.rs +++ b/soundcore-lib/src/models/device_color.rs @@ -1,5 +1,6 @@ use derive_more::From; use serde::{Deserialize, Serialize}; +use typeshare::typeshare; /// This u8 is a char which based on it fetches the apropriate image for the device (Reference: OtaBaseActivity/renderProductIcon). /// Perhaps this can be internally mapped to our product images. @@ -7,4 +8,5 @@ use serde::{Deserialize, Serialize}; #[derive( Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Default, Hash, From, )] +#[typeshare] pub struct DeviceColor(pub u8); diff --git a/soundcore-lib/src/models/hearing_protect.rs b/soundcore-lib/src/models/hearing_protect.rs index bd154ae..3a8e633 100644 --- a/soundcore-lib/src/models/hearing_protect.rs +++ b/soundcore-lib/src/models/hearing_protect.rs @@ -1,9 +1,11 @@ use derive_more::From; use serde::{Deserialize, Serialize}; +use typeshare::typeshare; #[derive( Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Default, Hash, From, )] +#[typeshare] pub struct HearingProtect { pub enabled: bool, pub db: u8, diff --git a/soundcore-lib/src/models/serial.rs b/soundcore-lib/src/models/serial.rs index 68c410b..f5c9e10 100644 --- a/soundcore-lib/src/models/serial.rs +++ b/soundcore-lib/src/models/serial.rs @@ -3,13 +3,13 @@ use std::sync::Arc; use serde::{Deserialize, Serialize}; use typeshare::typeshare; -use crate::types::SupportedModels; +use crate::types::KnownProductCodes; #[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Clone, Hash)] #[typeshare] pub struct SerialNumber { value: Arc, - model: Option, + model: Option, } impl SerialNumber { @@ -17,11 +17,11 @@ impl SerialNumber { &self.value } - pub fn to_model(&self) -> Option { + pub fn to_model(&self) -> Option { self.model } - fn extract_model(value: &str) -> Option { + fn extract_model(value: &str) -> Option { match value.get(0..4) { Some(v) => ("A".to_owned() + v).parse().ok(), None => None, @@ -54,7 +54,7 @@ mod serial_number { #[test] fn returns_correct_model() { let serial = SerialNumber::from("3040EAC356CCEEE8"); - assert_eq!(serial.to_model(), Some(SupportedModels::A3040)); + assert_eq!(serial.to_model(), Some(KnownProductCodes::A3040)); } #[test] diff --git a/soundcore-lib/src/packets/command/sound_mode.rs b/soundcore-lib/src/packets/command/sound_mode.rs index 45dfca2..afe59bb 100644 --- a/soundcore-lib/src/packets/command/sound_mode.rs +++ b/soundcore-lib/src/packets/command/sound_mode.rs @@ -2,23 +2,23 @@ use crate::{ devices::{A3040SoundModeUpdateCommand, A3951SoundModeUpdateCommand}, models::{ANCMode, SoundMode, TransparencyMode}, packets::Packet, - types::SupportedModels, + types::KnownProductCodes, }; pub struct SoundModeCommandBuilder { sound_mode: SoundMode, - model: SupportedModels, + model: KnownProductCodes, } impl SoundModeCommandBuilder { - pub fn new(sound_mode: SoundMode, model: SupportedModels) -> Self { + pub fn new(sound_mode: SoundMode, model: KnownProductCodes) -> Self { Self { sound_mode, model } } pub fn build(self) -> Vec { match self.model { - SupportedModels::A3040 => A3040SoundModeUpdateCommand::new(self.sound_mode).bytes(), - SupportedModels::A3951 => A3951SoundModeUpdateCommand::new(self.sound_mode).bytes(), + KnownProductCodes::A3040 => A3040SoundModeUpdateCommand::new(self.sound_mode).bytes(), + KnownProductCodes::A3951 => A3951SoundModeUpdateCommand::new(self.sound_mode).bytes(), _ => self.find_builder(), } } @@ -38,9 +38,10 @@ impl SoundModeCommandBuilder { #[cfg(test)] mod tests { - use super::*; use crate::models::{ANCMode, CurrentSoundMode, CustomANCValue, SoundMode, TransparencyMode}; + use super::*; + #[test] fn test_find_builder() { let sound_mode = SoundMode { @@ -52,7 +53,7 @@ mod tests { custom_anc: CustomANCValue::from_u8(0), custom_trans: None, }; - let builder = SoundModeCommandBuilder::new(sound_mode, SupportedModels::A3027); + let builder = SoundModeCommandBuilder::new(sound_mode, KnownProductCodes::A3027); let bytes = builder.build(); assert_eq!(bytes, [8, 238, 0, 0, 0, 6, 129, 14, 0, 2, 1, 0, 0, 142]); } diff --git a/soundcore-lib/src/packets/request.rs b/soundcore-lib/src/packets/request.rs index 4004e78..68be7d6 100644 --- a/soundcore-lib/src/packets/request.rs +++ b/soundcore-lib/src/packets/request.rs @@ -1,5 +1,5 @@ use crate::packets::Packet; -use crate::types::SupportedModels; +use crate::types::KnownProductCodes; pub enum RequestPacketKind { State, @@ -8,7 +8,7 @@ pub enum RequestPacketKind { pub struct RequestPacketBuilder { kind: RequestPacketKind, - model: Option, + model: Option, } // TODO: Add different packets for different models (if required) @@ -17,7 +17,7 @@ impl RequestPacketBuilder { Self { kind, model: None } } - pub fn model(mut self, model: SupportedModels) -> Self { + pub fn model(mut self, model: KnownProductCodes) -> Self { self.model = Some(model); self } diff --git a/soundcore-lib/src/packets/response/state/a3027.rs b/soundcore-lib/src/packets/response/state/a3027.rs index 1bb120b..6714012 100644 --- a/soundcore-lib/src/packets/response/state/a3027.rs +++ b/soundcore-lib/src/packets/response/state/a3027.rs @@ -16,12 +16,11 @@ use crate::{ u8_parser, }, }; - use crate::parsers::{ bool_parser, parse_gender, parse_sound_mode, parse_stereo_eq_configuration, ParseError, TaggedData, TaggedParseResult, }; -use crate::types::SupportedModels; +use crate::types::KnownProductCodes; use super::DeviceStateResponse; @@ -83,7 +82,7 @@ pub fn parse_a3027_state_response<'a, E: ParseError<'a>>( Ok(( bytes, TaggedData { - tag: SupportedModels::A3027, + tag: KnownProductCodes::A3027, data: A3027StateResponse { tws_status: TwsStatus(true), battery, diff --git a/soundcore-lib/src/packets/response/state/a3028.rs b/soundcore-lib/src/packets/response/state/a3028.rs index 6f49f64..b0ce1d5 100644 --- a/soundcore-lib/src/packets/response/state/a3028.rs +++ b/soundcore-lib/src/packets/response/state/a3028.rs @@ -16,7 +16,7 @@ use crate::parsers::{ parse_gender, parse_sound_mode, parse_stereo_eq_configuration, ParseError, TaggedData, TaggedParseResult, }; -use crate::types::SupportedModels; +use crate::types::KnownProductCodes; use super::DeviceStateResponse; @@ -69,7 +69,7 @@ pub fn parse_a3028_state_response<'a, E: ParseError<'a>>( Ok(( bytes, TaggedData { - tag: SupportedModels::A3028, + tag: KnownProductCodes::A3028, data: A3028StateResponse { tws_status: TwsStatus(true), battery, diff --git a/soundcore-lib/src/packets/response/state/a3029.rs b/soundcore-lib/src/packets/response/state/a3029.rs index 509fbdb..d0e8727 100644 --- a/soundcore-lib/src/packets/response/state/a3029.rs +++ b/soundcore-lib/src/packets/response/state/a3029.rs @@ -1,12 +1,6 @@ use nom::{combinator::all_consuming, error::context, number::complete::le_u8, sequence::tuple}; use serde::{Deserialize, Serialize}; -use crate::devices::a3029_features; -use crate::parsers::{ - parse_gender, parse_sound_mode, parse_stereo_eq_configuration, ParseError, TaggedData, - TaggedParseResult, -}; -use crate::types::SupportedModels; use crate::{ models::{ AgeRange, BaseHearID, DeviceFirmware, Gender, HearID, SerialNumber, SingleBattery, @@ -16,6 +10,12 @@ use crate::{ parse_base_hear_id, parse_dual_fw, parse_serial_number, parse_single_battery, u8_parser, }, }; +use crate::devices::a3029_features; +use crate::parsers::{ + parse_gender, parse_sound_mode, parse_stereo_eq_configuration, ParseError, TaggedData, + TaggedParseResult, +}; +use crate::types::KnownProductCodes; use super::DeviceStateResponse; @@ -75,7 +75,7 @@ pub fn parse_a3029_state_response<'a, E: ParseError<'a>>( Ok(( bytes, TaggedData { - tag: SupportedModels::A3029, + tag: KnownProductCodes::A3029, data: A3029StateResponse { tws_status: TwsStatus(true), battery, diff --git a/soundcore-lib/src/packets/response/state/a3040.rs b/soundcore-lib/src/packets/response/state/a3040.rs index b82210d..fc159bc 100644 --- a/soundcore-lib/src/packets/response/state/a3040.rs +++ b/soundcore-lib/src/packets/response/state/a3040.rs @@ -20,7 +20,7 @@ use crate::parsers::{ parse_auto_power_off_on, parse_fw, parse_hearing_protect, parse_prompt_language, parse_single_battery, parse_stereo_eq_configuration, TaggedData, TaggedParseResult, u8_parser, }; -use crate::types::SupportedModels; +use crate::types::KnownProductCodes; #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)] pub struct A3040StateResponse { @@ -102,7 +102,7 @@ pub fn parse_a3040_state_response<'a, E: ParseError<'a>>( Ok(( bytes, TaggedData { - tag: SupportedModels::A3040, + tag: KnownProductCodes::A3040, data: A3040StateResponse { battery, fw, diff --git a/soundcore-lib/src/packets/response/state/a3930.rs b/soundcore-lib/src/packets/response/state/a3930.rs index 39079c2..d10563f 100644 --- a/soundcore-lib/src/packets/response/state/a3930.rs +++ b/soundcore-lib/src/packets/response/state/a3930.rs @@ -19,7 +19,7 @@ use crate::parsers::{ bool_parser, parse_a3909_button_model, parse_custom_hear_id, parse_dual_battery, parse_gender, parse_sound_mode, parse_stereo_eq_configuration, ParseError, TaggedData, TaggedParseResult, }; -use crate::types::SupportedModels; +use crate::types::KnownProductCodes; use super::DeviceStateResponse; @@ -99,7 +99,7 @@ pub fn parse_a3930_state_response<'a, E: ParseError<'a>>( Ok(( bytes, TaggedData { - tag: SupportedModels::A3930, + tag: KnownProductCodes::A3930, data: A3930StateResponse { host_device, tws_status, diff --git a/soundcore-lib/src/packets/response/state/a3951.rs b/soundcore-lib/src/packets/response/state/a3951.rs index 20df32c..03738e1 100644 --- a/soundcore-lib/src/packets/response/state/a3951.rs +++ b/soundcore-lib/src/packets/response/state/a3951.rs @@ -14,12 +14,11 @@ use crate::{ }, parsers::u8_parser, }; - use crate::parsers::{ bool_parser, parse_a3909_button_model, parse_custom_hear_id, parse_dual_battery, parse_gender, parse_sound_mode, parse_stereo_eq_configuration, ParseError, TaggedData, TaggedParseResult, }; -use crate::types::SupportedModels; +use crate::types::KnownProductCodes; use super::DeviceStateResponse; @@ -107,7 +106,7 @@ pub fn parse_a3951_state_response<'a, E: ParseError<'a>>( Ok(( bytes, TaggedData { - tag: SupportedModels::A3951, + tag: KnownProductCodes::A3951, data: A3951StateResponse { host_device, tws_status, diff --git a/soundcore-lib/src/parsers.rs b/soundcore-lib/src/parsers.rs index b03339b..a8a0607 100644 --- a/soundcore-lib/src/parsers.rs +++ b/soundcore-lib/src/parsers.rs @@ -21,7 +21,7 @@ pub use prompt_language::*; pub use serial::*; pub use sound_mode::*; -use crate::types::SupportedModels; +use crate::types::KnownProductCodes; mod a3040_button_model; mod a3909_button_model; @@ -52,7 +52,7 @@ impl<'a> ParseError<'a> for nom::error::VerboseError<&'a [u8]> {} #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)] pub struct TaggedData { pub data: T, - pub tag: SupportedModels, + pub tag: KnownProductCodes, } #[cfg(test)] diff --git a/soundcore-lib/src/types.rs b/soundcore-lib/src/types.rs index 8ca5444..c9984c5 100644 --- a/soundcore-lib/src/types.rs +++ b/soundcore-lib/src/types.rs @@ -7,7 +7,7 @@ use typeshare::typeshare; Debug, Serialize, Deserialize, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, EnumString, )] #[typeshare] -pub enum SupportedModels { +pub enum KnownProductCodes { A3027, A3028, A3029, @@ -16,16 +16,18 @@ pub enum SupportedModels { A3931, A3935, A3951, + A3947, } -pub static SOUNDCORE_NAME_MODEL_MAP: phf::Map<&'static str, SupportedModels> = phf_map! { - "Q35" => SupportedModels::A3027, - "Q30" => SupportedModels::A3028, - "BES_BLE" => SupportedModels::A3028, /* Q30 has a FW Bug causing it to appear sometimes as BES_BLE */ - "Life Tune" => SupportedModels::A3029, - "Q45" => SupportedModels::A3040, - "A2 NC" => SupportedModels::A3935, - "Liberty Air 2 Pro" => SupportedModels::A3951, +pub static SOUNDCORE_NAME_PRODUCT_CODE_MAP: phf::Map<&'static str, KnownProductCodes> = phf_map! { + "Q35" => KnownProductCodes::A3027, + "Q30" => KnownProductCodes::A3028, + "BES_BLE" => KnownProductCodes::A3028, /* Q30 has a FW Bug causing it to appear sometimes as BES_BLE */ + "Life Tune" => KnownProductCodes::A3029, + "Q45" => KnownProductCodes::A3040, + "A2 NC" => KnownProductCodes::A3935, + "Liberty Air 2 Pro" => KnownProductCodes::A3951, + "4 NC" => KnownProductCodes::A3947, }; // impl EQWave { diff --git a/soundcore-lib/tests/a3951.rs b/soundcore-lib/tests/a3951.rs index 658db52..5000774 100644 --- a/soundcore-lib/tests/a3951.rs +++ b/soundcore-lib/tests/a3951.rs @@ -1,7 +1,7 @@ use soundcore_lib::{ models::{EQConfiguration, EQProfile}, packets::ResponsePacket, - types::SupportedModels, + types::KnownProductCodes, }; use test_data::a3951::{A3951_STATE_UPDATE_BYTES, A3951_STATE_UPDATE_BYTES_2}; @@ -11,7 +11,7 @@ fn parse_a3951_state_update() { match packet { ResponsePacket::DeviceState(resp) => { // TODO: Assert state - assert_eq!(resp.tag, SupportedModels::A3951); + assert_eq!(resp.tag, KnownProductCodes::A3951); if let EQConfiguration::Stereo(stereo) = resp.data.eq { assert_eq!(stereo.profile, EQProfile::Custom); } else { @@ -27,7 +27,7 @@ fn parse_a3951_state_update_2() { let packet = ResponsePacket::from_bytes(&A3951_STATE_UPDATE_BYTES_2).unwrap(); match packet { ResponsePacket::DeviceState(resp) => { - assert_eq!(resp.tag, SupportedModels::A3951); + assert_eq!(resp.tag, KnownProductCodes::A3951); if let EQConfiguration::Stereo(stereo) = resp.data.eq { assert_eq!(stereo.profile, EQProfile::JohnPaulWhite); } else {