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