• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use android_hardware_bluetooth_offload_leaudio::{aidl, binder};
16 
17 use crate::arbiter::Arbiter;
18 use aidl::android::hardware::bluetooth::offload::leaudio::IHciProxy::{
19     BnHciProxy, BpHciProxy, IHciProxy,
20 };
21 use aidl::android::hardware::bluetooth::offload::leaudio::IHciProxyCallbacks::IHciProxyCallbacks;
22 use binder::{BinderFeatures, ExceptionCode, Interface, Result as BinderResult, Strong};
23 use bluetooth_offload_hci::IsoData;
24 use std::collections::HashMap;
25 use std::sync::{Arc, LazyLock, Mutex, Weak};
26 
27 pub(crate) use aidl::android::hardware::bluetooth::offload::leaudio::StreamConfiguration::StreamConfiguration;
28 
29 pub(crate) struct Service {
30     state: Arc<Mutex<State>>,
31 }
32 
33 static SERVICE: LazyLock<Service> = LazyLock::new(|| {
34     let state = Arc::new(Mutex::new(State::default()));
35     HciProxy::register(state.clone());
36     Service { state }
37 });
38 
39 #[derive(Default)]
40 struct State {
41     arbiter: Weak<Arbiter>,
42     streams: HashMap<u16, StreamConfiguration>,
43     callbacks: Option<Strong<dyn IHciProxyCallbacks>>,
44 }
45 
46 impl Service {
register()47     pub(crate) fn register() {
48         LazyLock::force(&SERVICE);
49     }
50 
reset(arbiter: Weak<Arbiter>)51     pub(crate) fn reset(arbiter: Weak<Arbiter>) {
52         let mut state = SERVICE.state.lock().unwrap();
53         *state = State { arbiter, ..Default::default() }
54     }
55 
start_stream(handle: u16, config: StreamConfiguration)56     pub(crate) fn start_stream(handle: u16, config: StreamConfiguration) {
57         let mut state = SERVICE.state.lock().unwrap();
58         if let Some(callbacks) = &state.callbacks {
59             let _ = callbacks.startStream(handle.into(), &config);
60         } else {
61             log::warn!("Stream started without registered client");
62         };
63         state.streams.insert(handle, config);
64     }
65 
stop_stream(handle: u16)66     pub(crate) fn stop_stream(handle: u16) {
67         let mut state = SERVICE.state.lock().unwrap();
68         state.streams.remove(&handle);
69         if let Some(callbacks) = &state.callbacks {
70             let _ = callbacks.stopStream(handle.into());
71         };
72     }
73 }
74 
75 struct HciProxy {
76     state: Arc<Mutex<State>>,
77 }
78 
79 impl Interface for HciProxy {}
80 
81 impl HciProxy {
register(state: Arc<Mutex<State>>)82     fn register(state: Arc<Mutex<State>>) {
83         binder::add_service(
84             &format!("{}/default", BpHciProxy::get_descriptor()),
85             BnHciProxy::new_binder(Self { state }, BinderFeatures::default()).as_binder(),
86         )
87         .expect("Failed to register service");
88     }
89 }
90 
91 impl IHciProxy for HciProxy {
registerCallbacks(&self, callbacks: &Strong<dyn IHciProxyCallbacks>) -> BinderResult<()>92     fn registerCallbacks(&self, callbacks: &Strong<dyn IHciProxyCallbacks>) -> BinderResult<()> {
93         let mut state = self.state.lock().unwrap();
94         state.callbacks = Some(callbacks.clone());
95         for (handle, config) in &state.streams {
96             let _ = callbacks.startStream((*handle).into(), config);
97         }
98         Ok(())
99     }
100 
sendPacket(&self, handle: i32, seqnum: i32, data: &[u8]) -> BinderResult<()>101     fn sendPacket(&self, handle: i32, seqnum: i32, data: &[u8]) -> BinderResult<()> {
102         let handle: u16 = handle.try_into().map_err(|_| ExceptionCode::ILLEGAL_ARGUMENT)?;
103         let seqnum: u16 = seqnum.try_into().map_err(|_| ExceptionCode::ILLEGAL_ARGUMENT)?;
104 
105         let state = self.state.lock().unwrap();
106         if let Some(arbiter) = state.arbiter.upgrade() {
107             assert!(
108                 data.len() <= arbiter.max_buf_len(),
109                 "SDU Fragmentation over HCI is not supported"
110             );
111             arbiter.push_audio(&IsoData::new(handle, seqnum, data));
112         } else {
113             log::warn!("Trashing packet received in bad state");
114         }
115 
116         Ok(())
117     }
118 }
119