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