blob: 8df5c785726273c15f4087d89daba3a6a12cb6af [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
fidl_fuchsia_bluetooth_control::{PairingDelegateRequest::*, *},
fuchsia_syslog::fx_log_warn,
futures::{Future, TryStreamExt},
};
use crate::host_dispatcher::HostDispatcher;
// Number of concurrent requests allowed to the pairing delegate at a single time
const MAX_CONCURRENT_REQUESTS: usize = 100;
async fn handler(
pd: Option<PairingDelegateProxy>,
event: PairingDelegateRequest,
) -> fidl::Result<()> {
match pd {
Some(pd) => match event {
OnPairingRequest { device, method, displayed_passkey, responder } => {
handle_pairing_request(pd, device, method, displayed_passkey, responder).await
}
OnPairingComplete { device_id, status, control_handle: _ } => {
handle_pairing_complete(pd, device_id, status)
}
OnRemoteKeypress { device_id, keypress, control_handle: _ } => {
handle_remote_keypress(pd, device_id, keypress)
}
},
None => match event {
OnPairingRequest { device: _, method: _, displayed_passkey: _, responder } => {
fx_log_warn!("Rejected pairing due to no upstream pairing delegate");
let _ = responder.send(false, None);
Ok(())
}
OnPairingComplete { device_id, .. } => {
fx_log_warn!(
"Unhandled OnPairingComplete for device '{:?}': No PairingDelegate",
device_id
);
Ok(())
}
OnRemoteKeypress { device_id, .. } => {
fx_log_warn!(
"Unhandled OnRemoteKeypress for device '{:?}': No PairingDelegate",
device_id
);
Ok(())
}
},
}
}
async fn handle_pairing_request(
pd: PairingDelegateProxy,
mut device: RemoteDevice,
method: PairingMethod,
displayed_passkey: Option<String>,
responder: PairingDelegateOnPairingRequestResponder,
) -> fidl::Result<()> {
let passkey_ref = displayed_passkey.as_ref().map(|x| &**x);
let (status, passkey) = pd.on_pairing_request(&mut device, method, passkey_ref).await?;
let _ = responder.send(status, passkey.as_ref().map(String::as_str));
Ok(())
}
fn handle_pairing_complete(
pd: PairingDelegateProxy,
device_id: String,
mut status: fidl_fuchsia_bluetooth::Status,
) -> fidl::Result<()> {
if pd.on_pairing_complete(device_id.as_str(), &mut status).is_err() {
fx_log_warn!("Failed to propagate pairing cancelled upstream");
};
Ok(())
}
fn handle_remote_keypress(
pd: PairingDelegateProxy,
device_id: String,
keypress: PairingKeypressType,
) -> fidl::Result<()> {
if pd.on_remote_keypress(device_id.as_str(), keypress).is_err() {
fx_log_warn!("Failed to propagate pairing cancelled upstream");
};
Ok(())
}
pub fn start_pairing_delegate(
hd: HostDispatcher,
stream: PairingDelegateRequestStream,
) -> impl Future<Output = fidl::Result<()>> {
stream.try_for_each_concurrent(MAX_CONCURRENT_REQUESTS, move |event| {
handler(hd.pairing_delegate(), event)
})
}