• 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 crate::ffi::{CInterface, CStatus, Callbacks, DataCallbacks, Ffi};
16 use android_hardware_bluetooth::aidl::android::hardware::bluetooth::IBluetoothHci::{
17     BnBluetoothHci, BpBluetoothHci, IBluetoothHci,
18 };
19 use android_hardware_bluetooth::aidl::android::hardware::bluetooth::IBluetoothHciCallbacks::IBluetoothHciCallbacks;
20 use android_hardware_bluetooth::aidl::android::hardware::bluetooth::Status::Status;
21 use binder::{DeathRecipient, ExceptionCode, IBinder, Interface, Result as BinderResult, Strong};
22 use bluetooth_offload_hci::{Module, ModuleBuilder};
23 use bluetooth_offload_leaudio_hci::LeAudioModuleBuilder;
24 use std::sync::{Arc, RwLock};
25 
26 /// Service Implementation of AIDL interface `hardware/interface/bluetoot/aidl`,
27 /// including a proxy interface usable by third party modules.
28 pub struct HciHalProxy {
29     modules: Vec<Box<dyn ModuleBuilder>>,
30     ffi: Arc<Ffi<FfiCallbacks>>,
31     state: Arc<RwLock<State>>,
32 }
33 
34 struct FfiCallbacks {
35     callbacks: Strong<dyn IBluetoothHciCallbacks>,
36     proxy: Arc<dyn Module>,
37     state: Arc<RwLock<State>>,
38 }
39 
40 struct SinkModule<T: Callbacks> {
41     ffi: Arc<Ffi<T>>,
42     callbacks: Strong<dyn IBluetoothHciCallbacks>,
43 }
44 
45 enum State {
46     Closed,
47     Opened { proxy: Arc<dyn Module>, _death_recipient: DeathRecipient },
48 }
49 
50 impl Interface for HciHalProxy {}
51 
52 impl HciHalProxy {
53     /// Create the HAL Proxy interface binded to the Bluetooth HCI HAL interface.
new(modules: Vec<Box<dyn ModuleBuilder>>, cintf: CInterface) -> Self54     pub fn new(modules: Vec<Box<dyn ModuleBuilder>>, cintf: CInterface) -> Self {
55         Self {
56             modules,
57             ffi: Arc::new(Ffi::new(cintf)),
58             state: Arc::new(RwLock::new(State::Closed)),
59         }
60     }
61 }
62 
63 impl IBluetoothHci for HciHalProxy {
initialize(&self, callbacks: &Strong<dyn IBluetoothHciCallbacks>) -> BinderResult<()>64     fn initialize(&self, callbacks: &Strong<dyn IBluetoothHciCallbacks>) -> BinderResult<()> {
65         let (ffi, callbacks) = {
66             let mut state = self.state.write().unwrap();
67 
68             if !matches!(*state, State::Closed) {
69                 let _ = callbacks.initializationComplete(Status::ALREADY_INITIALIZED);
70                 return Ok(());
71             }
72 
73             let mut proxy: Arc<dyn Module> =
74                 Arc::new(SinkModule::new(self.ffi.clone(), callbacks.clone()));
75             for m in self.modules.iter().rev() {
76                 proxy = m.build(proxy);
77             }
78 
79             let mut death_recipient = {
80                 let (ffi, state) = (self.ffi.clone(), self.state.clone());
81                 DeathRecipient::new(move || {
82                     log::info!("Bluetooth stack has died");
83                     let mut state = state.write().unwrap();
84                     ffi.client_died();
85                     *state = State::Closed;
86                 })
87             };
88             callbacks.as_binder().link_to_death(&mut death_recipient)?;
89 
90             *state = State::Opened { proxy: proxy.clone(), _death_recipient: death_recipient };
91             (
92                 self.ffi.clone(),
93                 FfiCallbacks::new(callbacks.clone(), proxy.clone(), self.state.clone()),
94             )
95         };
96 
97         ffi.initialize(callbacks);
98         Ok(())
99     }
100 
close(&self) -> BinderResult<()>101     fn close(&self) -> BinderResult<()> {
102         *self.state.write().unwrap() = State::Closed;
103         self.ffi.close();
104         Ok(())
105     }
106 
sendHciCommand(&self, data: &[u8]) -> BinderResult<()>107     fn sendHciCommand(&self, data: &[u8]) -> BinderResult<()> {
108         let State::Opened { ref proxy, .. } = *self.state.read().unwrap() else {
109             return Err(ExceptionCode::ILLEGAL_STATE.into());
110         };
111 
112         proxy.out_cmd(data);
113         Ok(())
114     }
115 
sendAclData(&self, data: &[u8]) -> BinderResult<()>116     fn sendAclData(&self, data: &[u8]) -> BinderResult<()> {
117         let State::Opened { ref proxy, .. } = *self.state.read().unwrap() else {
118             return Err(ExceptionCode::ILLEGAL_STATE.into());
119         };
120 
121         proxy.out_acl(data);
122         Ok(())
123     }
124 
sendScoData(&self, data: &[u8]) -> BinderResult<()>125     fn sendScoData(&self, data: &[u8]) -> BinderResult<()> {
126         let State::Opened { ref proxy, .. } = *self.state.read().unwrap() else {
127             return Err(ExceptionCode::ILLEGAL_STATE.into());
128         };
129 
130         proxy.out_sco(data);
131         Ok(())
132     }
133 
sendIsoData(&self, data: &[u8]) -> BinderResult<()>134     fn sendIsoData(&self, data: &[u8]) -> BinderResult<()> {
135         let State::Opened { ref proxy, .. } = *self.state.read().unwrap() else {
136             return Err(ExceptionCode::ILLEGAL_STATE.into());
137         };
138 
139         proxy.out_iso(data);
140         Ok(())
141     }
142 }
143 
144 impl<T: Callbacks> SinkModule<T> {
new(ffi: Arc<Ffi<T>>, callbacks: Strong<dyn IBluetoothHciCallbacks>) -> Self145     pub(crate) fn new(ffi: Arc<Ffi<T>>, callbacks: Strong<dyn IBluetoothHciCallbacks>) -> Self {
146         Self { ffi, callbacks }
147     }
148 }
149 
150 impl<T: Callbacks> Module for SinkModule<T> {
next(&self) -> &dyn Module151     fn next(&self) -> &dyn Module {
152         unreachable!()
153     }
154 
out_cmd(&self, data: &[u8])155     fn out_cmd(&self, data: &[u8]) {
156         self.ffi.send_command(data);
157     }
out_acl(&self, data: &[u8])158     fn out_acl(&self, data: &[u8]) {
159         self.ffi.send_acl(data);
160     }
out_iso(&self, data: &[u8])161     fn out_iso(&self, data: &[u8]) {
162         self.ffi.send_iso(data);
163     }
out_sco(&self, data: &[u8])164     fn out_sco(&self, data: &[u8]) {
165         self.ffi.send_sco(data);
166     }
167 
in_evt(&self, data: &[u8])168     fn in_evt(&self, data: &[u8]) {
169         if let Err(e) = self.callbacks.hciEventReceived(data) {
170             log::error!("Cannot send event to client: {:?}", e);
171         }
172     }
in_acl(&self, data: &[u8])173     fn in_acl(&self, data: &[u8]) {
174         if let Err(e) = self.callbacks.aclDataReceived(data) {
175             log::error!("Cannot send ACL to client: {:?}", e);
176         }
177     }
in_sco(&self, data: &[u8])178     fn in_sco(&self, data: &[u8]) {
179         if let Err(e) = self.callbacks.scoDataReceived(data) {
180             log::error!("Cannot send SCO to client: {:?}", e);
181         }
182     }
in_iso(&self, data: &[u8])183     fn in_iso(&self, data: &[u8]) {
184         if let Err(e) = self.callbacks.isoDataReceived(data) {
185             log::error!("Cannot send ISO to client: {:?}", e);
186         }
187     }
188 }
189 
190 impl FfiCallbacks {
new( callbacks: Strong<dyn IBluetoothHciCallbacks>, proxy: Arc<dyn Module>, state: Arc<RwLock<State>>, ) -> Self191     fn new(
192         callbacks: Strong<dyn IBluetoothHciCallbacks>,
193         proxy: Arc<dyn Module>,
194         state: Arc<RwLock<State>>,
195     ) -> Self {
196         Self { callbacks, proxy, state }
197     }
198 }
199 
200 impl Callbacks for FfiCallbacks {
initialization_complete(&self, status: CStatus)201     fn initialization_complete(&self, status: CStatus) {
202         let mut state = self.state.write().unwrap();
203         if status != CStatus::Success {
204             *state = State::Closed;
205         }
206         if let Err(e) = self.callbacks.initializationComplete(status.into()) {
207             log::error!("Cannot call-back client: {:?}", e);
208             *state = State::Closed;
209         }
210     }
211 }
212 
213 impl DataCallbacks for FfiCallbacks {
event_received(&self, data: &[u8])214     fn event_received(&self, data: &[u8]) {
215         self.proxy.in_evt(data);
216     }
217 
acl_received(&self, data: &[u8])218     fn acl_received(&self, data: &[u8]) {
219         self.proxy.in_acl(data);
220     }
221 
sco_received(&self, data: &[u8])222     fn sco_received(&self, data: &[u8]) {
223         self.proxy.in_sco(data);
224     }
225 
iso_received(&self, data: &[u8])226     fn iso_received(&self, data: &[u8]) {
227         self.proxy.in_iso(data);
228     }
229 }
230 
231 impl From<CStatus> for Status {
from(value: CStatus) -> Self232     fn from(value: CStatus) -> Self {
233         match value {
234             CStatus::Success => Status::SUCCESS,
235             CStatus::AlreadyInitialized => Status::ALREADY_INITIALIZED,
236             CStatus::UnableToOpenInterface => Status::UNABLE_TO_OPEN_INTERFACE,
237             CStatus::HardwareInitializationError => Status::HARDWARE_INITIALIZATION_ERROR,
238             CStatus::Unknown => Status::UNKNOWN,
239         }
240     }
241 }
242 
243 #[no_mangle]
__add_bluetooth_hci_service(cintf: CInterface)244 pub extern "C" fn __add_bluetooth_hci_service(cintf: CInterface) {
245     binder::add_service(
246         &format!("{}/default", BpBluetoothHci::get_descriptor()),
247         BnBluetoothHci::new_binder(
248             HciHalProxy::new(vec![Box::new(LeAudioModuleBuilder {})], cintf),
249             binder::BinderFeatures::default(),
250         )
251         .as_binder(),
252     )
253     .expect("Failed to register service");
254 }
255