1 use crate::btif::{BluetoothInterface, RawAddress, ToggleableProfile}; 2 use crate::topstack::get_dispatchers; 3 4 use std::fmt::{Debug, Formatter, Result}; 5 use std::sync::{Arc, Mutex}; 6 use topshim_macros::{cb_variant, log_args, profile_enabled_or, profile_enabled_or_default}; 7 8 use log::warn; 9 10 #[cxx::bridge(namespace = bluetooth::topshim::rust)] 11 pub mod ffi { 12 unsafe extern "C++" { 13 include!("types/raw_address.h"); 14 #[namespace = ""] 15 type RawAddress = crate::btif::RawAddress; 16 } 17 18 #[derive(Debug, Copy, Clone)] 19 pub enum BtLeAudioCodecIndex { 20 SrcLc3 = 0, 21 SrcInvalid = 1_000_000, 22 } 23 24 #[derive(Debug, Copy, Clone)] 25 pub struct BtLeAudioCodecConfig { 26 pub codec_type: i32, 27 } 28 29 #[derive(Debug, Copy, Clone)] 30 pub enum BtLeAudioConnectionState { 31 Disconnected = 0, 32 Connecting, 33 Connected, 34 Disconnecting, 35 } 36 37 #[derive(Debug, Copy, Clone)] 38 pub enum BtLeAudioGroupStatus { 39 Inactive = 0, 40 Active, 41 TurnedIdleDuringCall, 42 } 43 44 #[derive(Debug, Copy, Clone)] 45 pub enum BtLeAudioGroupNodeStatus { 46 Added = 1, 47 Removed, 48 } 49 50 #[derive(Debug, Copy, Clone)] 51 pub enum BtLeAudioUsage { 52 AudioUsageUnknown = 0, 53 AudioUsageMedia = 1, 54 AudioUsageVoiceCommunication = 2, 55 } 56 57 #[derive(Debug, Copy, Clone)] 58 pub enum BtLeAudioContentType { 59 AudioContentTypeUnknown = 0, 60 AudioContentTypeSpeech = 1, 61 AudioContentTypeMusic = 2, 62 AudioContentTypeMovie = 3, 63 AudioContentTypeSonification = 4, 64 } 65 66 #[derive(Debug, Copy, Clone)] 67 pub enum BtLeAudioSource { 68 AudioSourceDefault = 0, 69 AudioSourceMic = 1, 70 AudioSourceVoiceUplink = 2, 71 AudioSourceVoiceDownlink = 3, 72 AudioSourceVoiceCall = 4, 73 AudioSourceCamcorder = 5, 74 AudioSourceVoiceRecognition = 6, 75 AudioSourceVoiceCommunication = 7, 76 } 77 78 #[derive(Debug, Copy, Clone)] 79 #[repr(i32)] 80 pub enum BtLeStreamStartedStatus { 81 Canceled = -1, 82 Idle = 0, 83 Started = 1, 84 } 85 86 #[derive(Debug, Default)] 87 pub struct BtLePcmConfig { 88 pub data_interval_us: u32, 89 pub sample_rate: u32, 90 pub bits_per_sample: u8, 91 pub channels_count: u8, 92 } 93 94 #[derive(Debug, Copy, Clone)] 95 pub enum BtLeAudioUnicastMonitorModeStatus { 96 StreamingRequested = 0, 97 Streaming = 1, 98 StreamingSuspended = 2, 99 } 100 101 #[derive(Debug, Copy, Clone)] 102 pub enum BtLeAudioDirection { 103 Sink = 1, 104 Source = 2, 105 Both = 3, 106 } 107 108 #[derive(Debug, Copy, Clone)] 109 pub enum BtLeAudioGroupStreamStatus { 110 Idle = 0, 111 Streaming, 112 Releasing, 113 ReleasingAutonomous, 114 Suspending, 115 Suspended, 116 ConfiguredAutonomous, 117 ConfiguredByUser, 118 Destroyed, 119 } 120 121 #[derive(Debug)] 122 pub struct SourceMetadata { 123 pub usage: BtLeAudioUsage, 124 pub content_type: BtLeAudioContentType, 125 pub gain: f64, 126 } 127 128 #[derive(Debug)] 129 pub struct SinkMetadata { 130 pub source: BtLeAudioSource, 131 pub gain: f64, 132 } 133 134 unsafe extern "C++" { 135 include!("le_audio/le_audio_shim.h"); 136 137 type LeAudioClientIntf; 138 GetLeAudioClientProfile(btif: *const u8) -> UniquePtr<LeAudioClientIntf>139 unsafe fn GetLeAudioClientProfile(btif: *const u8) -> UniquePtr<LeAudioClientIntf>; 140 init(self: Pin<&mut LeAudioClientIntf>)141 fn init(self: Pin<&mut LeAudioClientIntf>); connect(self: Pin<&mut LeAudioClientIntf>, addr: RawAddress)142 fn connect(self: Pin<&mut LeAudioClientIntf>, addr: RawAddress); disconnect(self: Pin<&mut LeAudioClientIntf>, addr: RawAddress)143 fn disconnect(self: Pin<&mut LeAudioClientIntf>, addr: RawAddress); set_enable_state(self: Pin<&mut LeAudioClientIntf>, addr: RawAddress, enabled: bool)144 fn set_enable_state(self: Pin<&mut LeAudioClientIntf>, addr: RawAddress, enabled: bool); cleanup(self: Pin<&mut LeAudioClientIntf>)145 fn cleanup(self: Pin<&mut LeAudioClientIntf>); remove_device(self: Pin<&mut LeAudioClientIntf>, addr: RawAddress)146 fn remove_device(self: Pin<&mut LeAudioClientIntf>, addr: RawAddress); group_add_node(self: Pin<&mut LeAudioClientIntf>, group_id: i32, addr: RawAddress)147 fn group_add_node(self: Pin<&mut LeAudioClientIntf>, group_id: i32, addr: RawAddress); group_remove_node(self: Pin<&mut LeAudioClientIntf>, group_id: i32, addr: RawAddress)148 fn group_remove_node(self: Pin<&mut LeAudioClientIntf>, group_id: i32, addr: RawAddress); group_set_active(self: Pin<&mut LeAudioClientIntf>, group_id: i32)149 fn group_set_active(self: Pin<&mut LeAudioClientIntf>, group_id: i32); set_codec_config_preference( self: Pin<&mut LeAudioClientIntf>, group_id: i32, input_codec_config: BtLeAudioCodecConfig, output_codec_config: BtLeAudioCodecConfig, )150 fn set_codec_config_preference( 151 self: Pin<&mut LeAudioClientIntf>, 152 group_id: i32, 153 input_codec_config: BtLeAudioCodecConfig, 154 output_codec_config: BtLeAudioCodecConfig, 155 ); set_ccid_information(self: Pin<&mut LeAudioClientIntf>, ccid: i32, context_type: i32)156 fn set_ccid_information(self: Pin<&mut LeAudioClientIntf>, ccid: i32, context_type: i32); set_in_call(self: Pin<&mut LeAudioClientIntf>, in_call: bool)157 fn set_in_call(self: Pin<&mut LeAudioClientIntf>, in_call: bool); send_audio_profile_preferences( self: Pin<&mut LeAudioClientIntf>, group_id: i32, is_output_preference_le_audio: bool, is_duplex_preference_le_audio: bool, )158 fn send_audio_profile_preferences( 159 self: Pin<&mut LeAudioClientIntf>, 160 group_id: i32, 161 is_output_preference_le_audio: bool, 162 is_duplex_preference_le_audio: bool, 163 ); set_unicast_monitor_mode( self: Pin<&mut LeAudioClientIntf>, direction: BtLeAudioDirection, enable: bool, )164 fn set_unicast_monitor_mode( 165 self: Pin<&mut LeAudioClientIntf>, 166 direction: BtLeAudioDirection, 167 enable: bool, 168 ); 169 host_start_audio_request(self: Pin<&mut LeAudioClientIntf>) -> bool170 fn host_start_audio_request(self: Pin<&mut LeAudioClientIntf>) -> bool; host_stop_audio_request(self: Pin<&mut LeAudioClientIntf>)171 fn host_stop_audio_request(self: Pin<&mut LeAudioClientIntf>); peer_start_audio_request(self: Pin<&mut LeAudioClientIntf>) -> bool172 fn peer_start_audio_request(self: Pin<&mut LeAudioClientIntf>) -> bool; peer_stop_audio_request(self: Pin<&mut LeAudioClientIntf>)173 fn peer_stop_audio_request(self: Pin<&mut LeAudioClientIntf>); get_host_pcm_config(self: Pin<&mut LeAudioClientIntf>) -> BtLePcmConfig174 fn get_host_pcm_config(self: Pin<&mut LeAudioClientIntf>) -> BtLePcmConfig; get_peer_pcm_config(self: Pin<&mut LeAudioClientIntf>) -> BtLePcmConfig175 fn get_peer_pcm_config(self: Pin<&mut LeAudioClientIntf>) -> BtLePcmConfig; get_host_stream_started(self: Pin<&mut LeAudioClientIntf>) -> BtLeStreamStartedStatus176 fn get_host_stream_started(self: Pin<&mut LeAudioClientIntf>) -> BtLeStreamStartedStatus; get_peer_stream_started(self: Pin<&mut LeAudioClientIntf>) -> BtLeStreamStartedStatus177 fn get_peer_stream_started(self: Pin<&mut LeAudioClientIntf>) -> BtLeStreamStartedStatus; source_metadata_changed( self: Pin<&mut LeAudioClientIntf>, metadata: Vec<SourceMetadata>, )178 fn source_metadata_changed( 179 self: Pin<&mut LeAudioClientIntf>, 180 metadata: Vec<SourceMetadata>, 181 ); sink_metadata_changed(self: Pin<&mut LeAudioClientIntf>, metadata: Vec<SinkMetadata>)182 fn sink_metadata_changed(self: Pin<&mut LeAudioClientIntf>, metadata: Vec<SinkMetadata>); 183 } 184 185 extern "Rust" { le_audio_initialized_callback()186 fn le_audio_initialized_callback(); le_audio_connection_state_callback(state: BtLeAudioConnectionState, addr: RawAddress)187 fn le_audio_connection_state_callback(state: BtLeAudioConnectionState, addr: RawAddress); le_audio_group_status_callback(group_id: i32, group_status: BtLeAudioGroupStatus)188 fn le_audio_group_status_callback(group_id: i32, group_status: BtLeAudioGroupStatus); le_audio_group_node_status_callback( bd_addr: RawAddress, group_id: i32, node_status: BtLeAudioGroupNodeStatus, )189 fn le_audio_group_node_status_callback( 190 bd_addr: RawAddress, 191 group_id: i32, 192 node_status: BtLeAudioGroupNodeStatus, 193 ); le_audio_audio_conf_callback( direction: u8, group_id: i32, snk_audio_location: i64, src_audio_location: i64, avail_cont: u16, )194 fn le_audio_audio_conf_callback( 195 direction: u8, 196 group_id: i32, 197 snk_audio_location: i64, 198 src_audio_location: i64, 199 avail_cont: u16, 200 ); le_audio_sink_audio_location_available_callback( addr: RawAddress, snk_audio_locations: i64, )201 fn le_audio_sink_audio_location_available_callback( 202 addr: RawAddress, 203 snk_audio_locations: i64, 204 ); le_audio_audio_local_codec_capabilities_callback( local_input_capa_codec_conf: &Vec<BtLeAudioCodecConfig>, local_output_capa_codec_conf: &Vec<BtLeAudioCodecConfig>, )205 fn le_audio_audio_local_codec_capabilities_callback( 206 local_input_capa_codec_conf: &Vec<BtLeAudioCodecConfig>, 207 local_output_capa_codec_conf: &Vec<BtLeAudioCodecConfig>, 208 ); le_audio_audio_group_codec_conf_callback( group_id: i32, input_codec_conf: BtLeAudioCodecConfig, output_codec_conf: BtLeAudioCodecConfig, input_selectable_codec_conf: &Vec<BtLeAudioCodecConfig>, output_selectable_codec_conf: &Vec<BtLeAudioCodecConfig>, )209 fn le_audio_audio_group_codec_conf_callback( 210 group_id: i32, 211 input_codec_conf: BtLeAudioCodecConfig, 212 output_codec_conf: BtLeAudioCodecConfig, 213 input_selectable_codec_conf: &Vec<BtLeAudioCodecConfig>, 214 output_selectable_codec_conf: &Vec<BtLeAudioCodecConfig>, 215 ); le_audio_unicast_monitor_mode_status_callback( direction: BtLeAudioDirection, status: BtLeAudioUnicastMonitorModeStatus, )216 fn le_audio_unicast_monitor_mode_status_callback( 217 direction: BtLeAudioDirection, 218 status: BtLeAudioUnicastMonitorModeStatus, 219 ); 220 le_audio_group_stream_status_callback(group_id: i32, status: BtLeAudioGroupStreamStatus)221 fn le_audio_group_stream_status_callback(group_id: i32, status: BtLeAudioGroupStreamStatus); 222 } 223 } 224 225 pub type BtLeAudioCodecConfig = ffi::BtLeAudioCodecConfig; 226 pub type BtLeAudioCodecIndex = ffi::BtLeAudioCodecIndex; 227 pub type BtLeAudioConnectionState = ffi::BtLeAudioConnectionState; 228 pub type BtLeAudioDirection = ffi::BtLeAudioDirection; 229 pub type BtLeAudioGroupStatus = ffi::BtLeAudioGroupStatus; 230 pub type BtLeAudioGroupNodeStatus = ffi::BtLeAudioGroupNodeStatus; 231 pub type BtLePcmConfig = ffi::BtLePcmConfig; 232 pub type BtLeStreamStartedStatus = ffi::BtLeStreamStartedStatus; 233 pub type BtLeAudioUsage = ffi::BtLeAudioUsage; 234 pub type BtLeAudioContentType = ffi::BtLeAudioContentType; 235 pub type BtLeAudioSource = ffi::BtLeAudioSource; 236 pub type BtLeAudioUnicastMonitorModeStatus = ffi::BtLeAudioUnicastMonitorModeStatus; 237 pub type BtLeAudioGroupStreamStatus = ffi::BtLeAudioGroupStreamStatus; 238 pub type SourceMetadata = ffi::SourceMetadata; 239 pub type SinkMetadata = ffi::SinkMetadata; 240 241 impl From<BtLeAudioGroupStatus> for i32 { from(value: BtLeAudioGroupStatus) -> Self242 fn from(value: BtLeAudioGroupStatus) -> Self { 243 match value { 244 BtLeAudioGroupStatus::Inactive => 0, 245 BtLeAudioGroupStatus::Active => 1, 246 BtLeAudioGroupStatus::TurnedIdleDuringCall => 2, 247 _ => panic!("Invalid value {:?} to BtLeAudioGroupStatus", value), 248 } 249 } 250 } 251 252 impl From<i32> for BtLeAudioGroupStatus { from(value: i32) -> Self253 fn from(value: i32) -> Self { 254 match value { 255 0 => BtLeAudioGroupStatus::Inactive, 256 1 => BtLeAudioGroupStatus::Active, 257 2 => BtLeAudioGroupStatus::TurnedIdleDuringCall, 258 _ => panic!("Invalid value {} for BtLeAudioGroupStatus", value), 259 } 260 } 261 } 262 263 impl Default for BtLeAudioGroupStatus { default() -> Self264 fn default() -> Self { 265 BtLeAudioGroupStatus::Inactive 266 } 267 } 268 269 impl From<BtLeAudioGroupNodeStatus> for i32 { from(value: BtLeAudioGroupNodeStatus) -> Self270 fn from(value: BtLeAudioGroupNodeStatus) -> Self { 271 match value { 272 BtLeAudioGroupNodeStatus::Added => 1, 273 BtLeAudioGroupNodeStatus::Removed => 2, 274 _ => panic!("Invalid value {:?} to BtLeAudioGroupNodeStatus", value), 275 } 276 } 277 } 278 279 impl From<i32> for BtLeAudioGroupNodeStatus { from(value: i32) -> Self280 fn from(value: i32) -> Self { 281 match value { 282 1 => BtLeAudioGroupNodeStatus::Added, 283 2 => BtLeAudioGroupNodeStatus::Removed, 284 _ => panic!("Invalid value {} for BtLeAudioGroupNodeStatus", value), 285 } 286 } 287 } 288 289 impl From<BtLeAudioUsage> for i32 { from(value: BtLeAudioUsage) -> Self290 fn from(value: BtLeAudioUsage) -> Self { 291 match value { 292 BtLeAudioUsage::AudioUsageUnknown => 0, 293 BtLeAudioUsage::AudioUsageMedia => 1, 294 BtLeAudioUsage::AudioUsageVoiceCommunication => 2, 295 _ => panic!("Invalid value {:?} for BtLeAudioUsage", value), 296 } 297 } 298 } 299 300 impl From<i32> for BtLeAudioUsage { from(value: i32) -> Self301 fn from(value: i32) -> Self { 302 match value { 303 0 => BtLeAudioUsage::AudioUsageUnknown, 304 1 => BtLeAudioUsage::AudioUsageMedia, 305 2 => BtLeAudioUsage::AudioUsageVoiceCommunication, 306 _ => panic!("Invalid value {} for BtLeAudioUsage", value), 307 } 308 } 309 } 310 311 impl From<BtLeAudioContentType> for i32 { from(value: BtLeAudioContentType) -> Self312 fn from(value: BtLeAudioContentType) -> Self { 313 match value { 314 BtLeAudioContentType::AudioContentTypeUnknown => 0, 315 BtLeAudioContentType::AudioContentTypeSpeech => 1, 316 BtLeAudioContentType::AudioContentTypeMusic => 2, 317 BtLeAudioContentType::AudioContentTypeMovie => 3, 318 BtLeAudioContentType::AudioContentTypeSonification => 4, 319 _ => panic!("Invalid value {:?} for BtLeAudioContentType", value), 320 } 321 } 322 } 323 324 impl From<i32> for BtLeAudioContentType { from(value: i32) -> Self325 fn from(value: i32) -> Self { 326 match value { 327 0 => BtLeAudioContentType::AudioContentTypeUnknown, 328 1 => BtLeAudioContentType::AudioContentTypeSpeech, 329 2 => BtLeAudioContentType::AudioContentTypeMusic, 330 3 => BtLeAudioContentType::AudioContentTypeMovie, 331 4 => BtLeAudioContentType::AudioContentTypeSonification, 332 _ => panic!("Invalid value {} for BtLeAudioContentType", value), 333 } 334 } 335 } 336 337 impl From<BtLeAudioSource> for i32 { from(value: BtLeAudioSource) -> Self338 fn from(value: BtLeAudioSource) -> Self { 339 match value { 340 BtLeAudioSource::AudioSourceDefault => 0, 341 BtLeAudioSource::AudioSourceMic => 1, 342 BtLeAudioSource::AudioSourceVoiceUplink => 2, 343 BtLeAudioSource::AudioSourceVoiceDownlink => 3, 344 BtLeAudioSource::AudioSourceVoiceCall => 4, 345 BtLeAudioSource::AudioSourceCamcorder => 5, 346 BtLeAudioSource::AudioSourceVoiceRecognition => 6, 347 BtLeAudioSource::AudioSourceVoiceCommunication => 7, 348 _ => panic!("Invalid value {:?} for BtLeAudioSource", value), 349 } 350 } 351 } 352 353 impl From<i32> for BtLeAudioSource { from(value: i32) -> Self354 fn from(value: i32) -> Self { 355 match value { 356 0 => BtLeAudioSource::AudioSourceDefault, 357 1 => BtLeAudioSource::AudioSourceMic, 358 2 => BtLeAudioSource::AudioSourceVoiceUplink, 359 3 => BtLeAudioSource::AudioSourceVoiceDownlink, 360 4 => BtLeAudioSource::AudioSourceVoiceCall, 361 5 => BtLeAudioSource::AudioSourceCamcorder, 362 6 => BtLeAudioSource::AudioSourceVoiceRecognition, 363 7 => BtLeAudioSource::AudioSourceVoiceCommunication, 364 _ => panic!("Invalid value {} for BtLeAudioSource", value), 365 } 366 } 367 } 368 369 impl From<BtLeStreamStartedStatus> for i32 { from(value: BtLeStreamStartedStatus) -> Self370 fn from(value: BtLeStreamStartedStatus) -> Self { 371 match value { 372 BtLeStreamStartedStatus::Canceled => -1, 373 BtLeStreamStartedStatus::Idle => 0, 374 BtLeStreamStartedStatus::Started => 1, 375 _ => panic!("Invalid value {:?} for BtLeStreamStartedStatus", value), 376 } 377 } 378 } 379 380 impl From<i32> for BtLeStreamStartedStatus { from(value: i32) -> Self381 fn from(value: i32) -> Self { 382 match value { 383 -1 => BtLeStreamStartedStatus::Canceled, 384 0 => BtLeStreamStartedStatus::Idle, 385 1 => BtLeStreamStartedStatus::Started, 386 _ => panic!("Invalid value {} for BtLeStreamStartedStatus", value), 387 } 388 } 389 } 390 impl From<BtLeAudioUnicastMonitorModeStatus> for i32 { from(value: BtLeAudioUnicastMonitorModeStatus) -> Self391 fn from(value: BtLeAudioUnicastMonitorModeStatus) -> Self { 392 match value { 393 BtLeAudioUnicastMonitorModeStatus::StreamingRequested => 0, 394 BtLeAudioUnicastMonitorModeStatus::Streaming => 1, 395 BtLeAudioUnicastMonitorModeStatus::StreamingSuspended => 2, 396 _ => panic!("Invalid value {:?} to BtLeAudioUnicastMonitorModeStatus", value), 397 } 398 } 399 } 400 401 impl From<i32> for BtLeAudioUnicastMonitorModeStatus { from(value: i32) -> Self402 fn from(value: i32) -> Self { 403 match value { 404 0 => BtLeAudioUnicastMonitorModeStatus::StreamingRequested, 405 1 => BtLeAudioUnicastMonitorModeStatus::Streaming, 406 2 => BtLeAudioUnicastMonitorModeStatus::StreamingSuspended, 407 _ => panic!("Invalid value {} for BtLeAudioUnicastMonitorModeStatus", value), 408 } 409 } 410 } 411 412 impl From<BtLeAudioGroupStreamStatus> for i32 { from(value: BtLeAudioGroupStreamStatus) -> Self413 fn from(value: BtLeAudioGroupStreamStatus) -> Self { 414 match value { 415 BtLeAudioGroupStreamStatus::Idle => 0, 416 BtLeAudioGroupStreamStatus::Streaming => 1, 417 BtLeAudioGroupStreamStatus::Releasing => 2, 418 BtLeAudioGroupStreamStatus::ReleasingAutonomous => 3, 419 BtLeAudioGroupStreamStatus::Suspending => 4, 420 BtLeAudioGroupStreamStatus::Suspended => 5, 421 BtLeAudioGroupStreamStatus::ConfiguredAutonomous => 6, 422 BtLeAudioGroupStreamStatus::ConfiguredByUser => 7, 423 BtLeAudioGroupStreamStatus::Destroyed => 8, 424 _ => panic!("Invalid value {:?} to BtLeAudioGroupStreamStatus", value), 425 } 426 } 427 } 428 429 impl From<i32> for BtLeAudioGroupStreamStatus { from(value: i32) -> Self430 fn from(value: i32) -> Self { 431 match value { 432 0 => BtLeAudioGroupStreamStatus::Idle, 433 1 => BtLeAudioGroupStreamStatus::Streaming, 434 2 => BtLeAudioGroupStreamStatus::Releasing, 435 3 => BtLeAudioGroupStreamStatus::ReleasingAutonomous, 436 4 => BtLeAudioGroupStreamStatus::Suspending, 437 5 => BtLeAudioGroupStreamStatus::Suspended, 438 6 => BtLeAudioGroupStreamStatus::ConfiguredAutonomous, 439 7 => BtLeAudioGroupStreamStatus::ConfiguredByUser, 440 8 => BtLeAudioGroupStreamStatus::Destroyed, 441 _ => panic!("Invalid value {} to BtLeAudioGroupStreamStatus", value), 442 } 443 } 444 } 445 446 impl Default for BtLeAudioGroupStreamStatus { default() -> Self447 fn default() -> Self { 448 BtLeAudioGroupStreamStatus::Idle 449 } 450 } 451 452 impl From<BtLeAudioDirection> for i32 { from(value: BtLeAudioDirection) -> Self453 fn from(value: BtLeAudioDirection) -> Self { 454 match value { 455 BtLeAudioDirection::Sink => 1, 456 BtLeAudioDirection::Source => 2, 457 BtLeAudioDirection::Both => 3, 458 _ => panic!("Invalid value {:?} to BtLeAudioDirection", value), 459 } 460 } 461 } 462 463 impl From<i32> for BtLeAudioDirection { from(value: i32) -> Self464 fn from(value: i32) -> Self { 465 match value { 466 1 => BtLeAudioDirection::Sink, 467 2 => BtLeAudioDirection::Source, 468 3 => BtLeAudioDirection::Both, 469 _ => panic!("Invalid value {} for BtLeAudioDirection", value), 470 } 471 } 472 } 473 474 #[derive(Debug)] 475 pub enum LeAudioClientCallbacks { 476 Initialized(), 477 ConnectionState(BtLeAudioConnectionState, RawAddress), 478 GroupStatus(i32, BtLeAudioGroupStatus), 479 GroupNodeStatus(RawAddress, i32, BtLeAudioGroupNodeStatus), 480 AudioConf(u8, i32, i64, i64, u16), 481 SinkAudioLocationAvailable(RawAddress, i64), 482 AudioLocalCodecCapabilities(Vec<BtLeAudioCodecConfig>, Vec<BtLeAudioCodecConfig>), 483 AudioGroupCodecConf( 484 i32, 485 BtLeAudioCodecConfig, 486 BtLeAudioCodecConfig, 487 Vec<BtLeAudioCodecConfig>, 488 Vec<BtLeAudioCodecConfig>, 489 ), 490 UnicastMonitorModeStatus(BtLeAudioDirection, BtLeAudioUnicastMonitorModeStatus), 491 GroupStreamStatus(i32, BtLeAudioGroupStreamStatus), 492 } 493 494 pub struct LeAudioClientCallbacksDispatcher { 495 pub dispatch: Box<dyn Fn(LeAudioClientCallbacks) + Send>, 496 } 497 498 impl Debug for LeAudioClientCallbacksDispatcher { fmt(&self, f: &mut Formatter<'_>) -> Result499 fn fmt(&self, f: &mut Formatter<'_>) -> Result { 500 write!(f, "LeAudioClientCallbacksDispatcher {{}}") 501 } 502 } 503 504 type LeAudioClientCb = Arc<Mutex<LeAudioClientCallbacksDispatcher>>; 505 506 cb_variant!(LeAudioClientCb, 507 le_audio_initialized_callback -> LeAudioClientCallbacks::Initialized); 508 509 cb_variant!(LeAudioClientCb, 510 le_audio_connection_state_callback -> LeAudioClientCallbacks::ConnectionState, 511 BtLeAudioConnectionState, RawAddress); 512 513 cb_variant!(LeAudioClientCb, 514 le_audio_group_status_callback -> LeAudioClientCallbacks::GroupStatus, 515 i32, BtLeAudioGroupStatus); 516 517 cb_variant!(LeAudioClientCb, 518 le_audio_group_node_status_callback -> LeAudioClientCallbacks::GroupNodeStatus, 519 RawAddress, i32, BtLeAudioGroupNodeStatus); 520 521 cb_variant!(LeAudioClientCb, 522 le_audio_audio_conf_callback -> LeAudioClientCallbacks::AudioConf, 523 u8, i32, i64, i64, u16); 524 525 cb_variant!(LeAudioClientCb, 526 le_audio_sink_audio_location_available_callback -> LeAudioClientCallbacks::SinkAudioLocationAvailable, 527 RawAddress, i64); 528 529 cb_variant!(LeAudioClientCb, 530 le_audio_unicast_monitor_mode_status_callback -> LeAudioClientCallbacks::UnicastMonitorModeStatus, 531 BtLeAudioDirection, BtLeAudioUnicastMonitorModeStatus); 532 533 cb_variant!(LeAudioClientCb, 534 le_audio_group_stream_status_callback -> LeAudioClientCallbacks::GroupStreamStatus, 535 i32, BtLeAudioGroupStreamStatus); 536 537 cb_variant!(LeAudioClientCb, 538 le_audio_audio_local_codec_capabilities_callback -> LeAudioClientCallbacks::AudioLocalCodecCapabilities, 539 &Vec<BtLeAudioCodecConfig>, &Vec<BtLeAudioCodecConfig>, 540 { 541 let _0: Vec<BtLeAudioCodecConfig> = _0.to_vec(); 542 let _1: Vec<BtLeAudioCodecConfig> = _1.to_vec(); 543 }); 544 545 cb_variant!(LeAudioClientCb, 546 le_audio_audio_group_codec_conf_callback -> LeAudioClientCallbacks::AudioGroupCodecConf, 547 i32, BtLeAudioCodecConfig, BtLeAudioCodecConfig, 548 &Vec<BtLeAudioCodecConfig>, &Vec<BtLeAudioCodecConfig>, 549 { 550 let _3: Vec<BtLeAudioCodecConfig> = _3.to_vec(); 551 let _4: Vec<BtLeAudioCodecConfig> = _4.to_vec(); 552 }); 553 554 pub struct LeAudioClient { 555 internal: cxx::UniquePtr<ffi::LeAudioClientIntf>, 556 is_init: bool, 557 is_enabled: bool, 558 } 559 560 // For *const u8 opaque btif 561 // SAFETY: `LeAudioClientIntf` is thread-safe to make calls from. 562 unsafe impl Send for LeAudioClient {} 563 564 impl ToggleableProfile for LeAudioClient { is_enabled(&self) -> bool565 fn is_enabled(&self) -> bool { 566 self.is_enabled 567 } 568 enable(&mut self) -> bool569 fn enable(&mut self) -> bool { 570 if self.is_enabled { 571 warn!("LeAudioClient is already enabled."); 572 return false; 573 } 574 575 self.internal.pin_mut().init(); 576 self.is_enabled = true; 577 true 578 } 579 580 #[profile_enabled_or(false)] disable(&mut self) -> bool581 fn disable(&mut self) -> bool { 582 if !self.is_enabled { 583 warn!("LeAudioClient is already disabled."); 584 return false; 585 } 586 587 self.internal.pin_mut().cleanup(); 588 self.is_enabled = false; 589 true 590 } 591 } 592 593 impl LeAudioClient { 594 #[log_args] new(intf: &BluetoothInterface) -> LeAudioClient595 pub fn new(intf: &BluetoothInterface) -> LeAudioClient { 596 // SAFETY: `intf.as_raw_ptr()` is a valid pointer to a `BluetoothInterface` 597 let lea_client_if: cxx::UniquePtr<ffi::LeAudioClientIntf> = 598 unsafe { ffi::GetLeAudioClientProfile(intf.as_raw_ptr()) }; 599 600 LeAudioClient { internal: lea_client_if, is_init: false, is_enabled: false } 601 } 602 603 #[log_args] is_initialized(&self) -> bool604 pub fn is_initialized(&self) -> bool { 605 self.is_init 606 } 607 608 // `internal.init` is invoked during `ToggleableProfile::enable` 609 #[log_args] initialize(&mut self, callbacks: LeAudioClientCallbacksDispatcher) -> bool610 pub fn initialize(&mut self, callbacks: LeAudioClientCallbacksDispatcher) -> bool { 611 if self.is_init { 612 warn!("LeAudioClient has already been initialized"); 613 return false; 614 } 615 616 if get_dispatchers().lock().unwrap().set::<LeAudioClientCb>(Arc::new(Mutex::new(callbacks))) 617 { 618 panic!("Tried to set dispatcher for LeAudioClient callbacks while it already exists"); 619 } 620 621 self.is_init = true; 622 623 true 624 } 625 626 #[log_args] 627 #[profile_enabled_or] connect(&mut self, addr: RawAddress)628 pub fn connect(&mut self, addr: RawAddress) { 629 self.internal.pin_mut().connect(addr); 630 } 631 632 #[log_args] 633 #[profile_enabled_or] disconnect(&mut self, addr: RawAddress)634 pub fn disconnect(&mut self, addr: RawAddress) { 635 self.internal.pin_mut().disconnect(addr); 636 } 637 638 #[log_args] 639 #[profile_enabled_or] set_enable_state(&mut self, addr: RawAddress, enabled: bool)640 pub fn set_enable_state(&mut self, addr: RawAddress, enabled: bool) { 641 self.internal.pin_mut().set_enable_state(addr, enabled); 642 } 643 644 #[log_args] 645 #[profile_enabled_or] cleanup(&mut self)646 pub fn cleanup(&mut self) { 647 self.internal.pin_mut().cleanup(); 648 } 649 650 #[log_args] 651 #[profile_enabled_or] remove_device(&mut self, addr: RawAddress)652 pub fn remove_device(&mut self, addr: RawAddress) { 653 self.internal.pin_mut().remove_device(addr); 654 } 655 656 #[log_args] 657 #[profile_enabled_or] group_add_node(&mut self, group_id: i32, addr: RawAddress)658 pub fn group_add_node(&mut self, group_id: i32, addr: RawAddress) { 659 self.internal.pin_mut().group_add_node(group_id, addr); 660 } 661 662 #[log_args] 663 #[profile_enabled_or] group_remove_node(&mut self, group_id: i32, addr: RawAddress)664 pub fn group_remove_node(&mut self, group_id: i32, addr: RawAddress) { 665 self.internal.pin_mut().group_remove_node(group_id, addr); 666 } 667 668 #[log_args] 669 #[profile_enabled_or] group_set_active(&mut self, group_id: i32)670 pub fn group_set_active(&mut self, group_id: i32) { 671 self.internal.pin_mut().group_set_active(group_id); 672 } 673 674 #[log_args] 675 #[profile_enabled_or] set_codec_config_preference( &mut self, group_id: i32, input_codec_config: BtLeAudioCodecConfig, output_codec_config: BtLeAudioCodecConfig, )676 pub fn set_codec_config_preference( 677 &mut self, 678 group_id: i32, 679 input_codec_config: BtLeAudioCodecConfig, 680 output_codec_config: BtLeAudioCodecConfig, 681 ) { 682 self.internal.pin_mut().set_codec_config_preference( 683 group_id, 684 input_codec_config, 685 output_codec_config, 686 ); 687 } 688 689 #[log_args] 690 #[profile_enabled_or] set_ccid_information(&mut self, ccid: i32, context_type: i32)691 pub fn set_ccid_information(&mut self, ccid: i32, context_type: i32) { 692 self.internal.pin_mut().set_ccid_information(ccid, context_type); 693 } 694 695 #[log_args] 696 #[profile_enabled_or] set_in_call(&mut self, in_call: bool)697 pub fn set_in_call(&mut self, in_call: bool) { 698 self.internal.pin_mut().set_in_call(in_call); 699 } 700 701 #[log_args] 702 #[profile_enabled_or] send_audio_profile_preferences( &mut self, group_id: i32, is_output_preference_le_audio: bool, is_duplex_preference_le_audio: bool, )703 pub fn send_audio_profile_preferences( 704 &mut self, 705 group_id: i32, 706 is_output_preference_le_audio: bool, 707 is_duplex_preference_le_audio: bool, 708 ) { 709 self.internal.pin_mut().send_audio_profile_preferences( 710 group_id, 711 is_output_preference_le_audio, 712 is_duplex_preference_le_audio, 713 ); 714 } 715 716 #[log_args] 717 #[profile_enabled_or] set_unicast_monitor_mode(&mut self, direction: BtLeAudioDirection, enable: bool)718 pub fn set_unicast_monitor_mode(&mut self, direction: BtLeAudioDirection, enable: bool) { 719 self.internal.pin_mut().set_unicast_monitor_mode(direction, enable); 720 } 721 722 #[log_args] 723 #[profile_enabled_or(false)] host_start_audio_request(&mut self) -> bool724 pub fn host_start_audio_request(&mut self) -> bool { 725 self.internal.pin_mut().host_start_audio_request() 726 } 727 728 #[log_args] 729 #[profile_enabled_or] host_stop_audio_request(&mut self)730 pub fn host_stop_audio_request(&mut self) { 731 self.internal.pin_mut().host_stop_audio_request(); 732 } 733 734 #[log_args] 735 #[profile_enabled_or(false)] peer_start_audio_request(&mut self) -> bool736 pub fn peer_start_audio_request(&mut self) -> bool { 737 self.internal.pin_mut().peer_start_audio_request() 738 } 739 740 #[log_args] 741 #[profile_enabled_or] peer_stop_audio_request(&mut self)742 pub fn peer_stop_audio_request(&mut self) { 743 self.internal.pin_mut().peer_stop_audio_request(); 744 } 745 746 #[log_args] 747 #[profile_enabled_or_default] get_host_pcm_config(&mut self) -> BtLePcmConfig748 pub fn get_host_pcm_config(&mut self) -> BtLePcmConfig { 749 self.internal.pin_mut().get_host_pcm_config() 750 } 751 752 #[log_args] 753 #[profile_enabled_or_default] get_peer_pcm_config(&mut self) -> BtLePcmConfig754 pub fn get_peer_pcm_config(&mut self) -> BtLePcmConfig { 755 self.internal.pin_mut().get_peer_pcm_config() 756 } 757 758 #[log_args] 759 #[profile_enabled_or(BtLeStreamStartedStatus::Idle)] get_host_stream_started(&mut self) -> BtLeStreamStartedStatus760 pub fn get_host_stream_started(&mut self) -> BtLeStreamStartedStatus { 761 self.internal.pin_mut().get_host_stream_started() 762 } 763 764 #[log_args] 765 #[profile_enabled_or(BtLeStreamStartedStatus::Idle)] get_peer_stream_started(&mut self) -> BtLeStreamStartedStatus766 pub fn get_peer_stream_started(&mut self) -> BtLeStreamStartedStatus { 767 self.internal.pin_mut().get_peer_stream_started() 768 } 769 770 #[log_args] 771 #[profile_enabled_or] source_metadata_changed(&mut self, metadata: Vec<SourceMetadata>)772 pub fn source_metadata_changed(&mut self, metadata: Vec<SourceMetadata>) { 773 self.internal.pin_mut().source_metadata_changed(metadata); 774 } 775 776 #[log_args] 777 #[profile_enabled_or] sink_metadata_changed(&mut self, metadata: Vec<SinkMetadata>)778 pub fn sink_metadata_changed(&mut self, metadata: Vec<SinkMetadata>) { 779 self.internal.pin_mut().sink_metadata_changed(metadata); 780 } 781 } 782