[bt][host][fidl] Use fuchsia.bluetooth.PeerId and error syntax
* Changed all host.fidl methods to use fuchsia.bluetooth.PeerId rather
than string as the peer ID type.
* Changed all host.fidl methods that have a reply to use the FIDL error
syntax and the fuchsia.bluetooth.sys.Error type instead of
fuchsia.bluetooth.Status.
* Converted some of the multi-line awaits in integration tests to inline
where the former was unnecessary.
* Removed the GATT proxy setup in bt-gap's connection handling.
Bug: 35008
Test: bt-integration-tests; bt-host-unittests.
Change-Id: Icc1c38206b032d714628d86bbe5e5d8c89e28a97
diff --git a/sdk/fidl/fuchsia.bluetooth.sys/access.fidl b/sdk/fidl/fuchsia.bluetooth.sys/access.fidl
index 10bdfaa..e2f12cb 100644
--- a/sdk/fidl/fuchsia.bluetooth.sys/access.fidl
+++ b/sdk/fidl/fuchsia.bluetooth.sys/access.fidl
@@ -12,6 +12,21 @@
/// The peer designated for the operation was not found.
PEER_NOT_FOUND = 2;
+
+ /// The time limit for the operation has expired.
+ TIMED_OUT = 3;
+
+ /// The operation was canceled.
+ CANCELED = 4;
+
+ /// Operation already in progress.
+ IN_PROGRESS = 5;
+
+ /// Operation not supported.
+ NOT_SUPPORTED = 6;
+
+ /// The operation was given an invalid set of arguments.
+ INVALID_ARGUMENTS = 7;
};
/// Represents an active procedure. The validity of a handle that supports this protocol is tied to
@@ -19,7 +34,8 @@
///
/// 1. Closing a token handle ends the procedure that it is attached to.
/// 2. The system closes a token handle to communicate that a procedure was internally terminated.
-protocol ProcedureToken {};
+protocol ProcedureToken {
+};
/// Protocol that abstracts the operational modes and procedures defined in the Bluetooth Generic
/// Access Profile (see Core Specification v5.1, Vol 3, Part C).
diff --git a/src/connectivity/bluetooth/core/bt-gap/src/host_device.rs b/src/connectivity/bluetooth/core/bt-gap/src/host_device.rs
index 9e3c81b..30d6f87 100644
--- a/src/connectivity/bluetooth/core/bt-gap/src/host_device.rs
+++ b/src/connectivity/bluetooth/core/bt-gap/src/host_device.rs
@@ -5,15 +5,12 @@
use {
anyhow::format_err,
fidl::endpoints::ClientEnd,
- fidl_fuchsia_bluetooth::DeviceClass,
- fidl_fuchsia_bluetooth::PeerId as FidlPeerId,
+ fidl_fuchsia_bluetooth::{self as fbt, DeviceClass},
fidl_fuchsia_bluetooth_control::{
self as control, HostData, InputCapabilityType, OutputCapabilityType,
PairingDelegateMarker, PairingOptions,
},
- fidl_fuchsia_bluetooth_gatt::ClientProxy,
fidl_fuchsia_bluetooth_host::{HostEvent, HostProxy},
- fidl_fuchsia_bluetooth_le::CentralProxy,
fuchsia_bluetooth::{
inspect::Inspectable,
types::{BondingData, HostInfo, Peer, PeerId},
@@ -22,16 +19,15 @@
futures::{Future, FutureExt, StreamExt},
parking_lot::RwLock,
pin_utils::pin_mut,
- std::{collections::HashMap, convert::TryInto, path::PathBuf, sync::Arc},
+ std::{convert::TryInto, path::PathBuf, sync::Arc},
};
-use crate::types::{self, from_fidl_status, Error};
+use crate::types::{self, from_fidl_result, from_fidl_status, Error};
pub struct HostDevice {
pub path: PathBuf,
host: HostProxy,
info: Inspectable<HostInfo>,
- gatt: HashMap<String, (CentralProxy, ClientProxy)>,
}
// Many HostDevice methods return impl Future rather than being implemented as `async`. This has an
@@ -41,7 +37,7 @@
// the future was polled.
impl HostDevice {
pub fn new(path: PathBuf, host: HostProxy, info: Inspectable<HostInfo>) -> Self {
- HostDevice { path, host, info, gatt: HashMap::new() }
+ HostDevice { path, host, info }
}
pub fn get_host(&self) -> &HostProxy {
@@ -61,50 +57,43 @@
&self.info
}
- pub fn rm_gatt(&mut self, id: String) -> impl Future<Output = types::Result<()>> {
- let gatt_entry = self.gatt.remove(&id);
- async move {
- if let Some((central, _)) = gatt_entry {
- from_fidl_status(central.disconnect_peripheral(id.as_str()).await)
- } else {
- Err(Error::not_found("Unknown Peripheral"))
- }
- }
- }
-
pub fn set_name(&self, mut name: String) -> impl Future<Output = types::Result<()>> {
- self.host.set_local_name(&mut name).map(from_fidl_status)
+ self.host.set_local_name(&mut name).map(from_fidl_result)
}
pub fn set_device_class(
&self,
mut cod: DeviceClass,
) -> impl Future<Output = types::Result<()>> {
- self.host.set_device_class(&mut cod).map(from_fidl_status)
+ self.host.set_device_class(&mut cod).map(from_fidl_result)
}
pub fn start_discovery(&mut self) -> impl Future<Output = types::Result<()>> {
- self.host.start_discovery().map(from_fidl_status)
+ self.host.start_discovery().map(from_fidl_result)
}
- pub fn connect(&mut self, device_id: String) -> impl Future<Output = types::Result<()>> {
- self.host.connect(&device_id).map(from_fidl_status)
+ pub fn connect(&mut self, id: PeerId) -> impl Future<Output = types::Result<()>> {
+ let mut id: fbt::PeerId = id.into();
+ self.host.connect(&mut id).map(from_fidl_result)
}
- pub fn disconnect(&mut self, device_id: String) -> impl Future<Output = types::Result<()>> {
- self.host.disconnect(&device_id).map(from_fidl_status)
+ pub fn disconnect(&mut self, id: PeerId) -> impl Future<Output = types::Result<()>> {
+ let mut id: fbt::PeerId = id.into();
+ self.host.disconnect(&mut id).map(from_fidl_result)
}
pub fn pair(
&mut self,
- mut id: FidlPeerId,
+ id: PeerId,
options: PairingOptions,
) -> impl Future<Output = types::Result<()>> {
- self.host.pair(&mut id, options).map(from_fidl_status)
+ let mut id: fbt::PeerId = id.into();
+ self.host.pair(&mut id, options).map(from_fidl_result)
}
- pub fn forget(&mut self, peer_id: String) -> impl Future<Output = types::Result<()>> {
- self.host.forget(&peer_id).map(from_fidl_status)
+ pub fn forget(&mut self, id: PeerId) -> impl Future<Output = types::Result<()>> {
+ let mut id: fbt::PeerId = id.into();
+ self.host.forget(&mut id).map(from_fidl_result)
}
pub fn close(&self) -> types::Result<()> {
@@ -120,20 +109,19 @@
}
pub fn set_connectable(&self, value: bool) -> impl Future<Output = types::Result<()>> {
- self.host.set_connectable(value).map(from_fidl_status)
+ self.host.set_connectable(value).map(from_fidl_result)
}
- pub fn stop_discovery(&self) -> impl Future<Output = types::Result<()>> {
- self.host.stop_discovery().map(from_fidl_status)
+ pub fn stop_discovery(&self) -> types::Result<()> {
+ self.host.stop_discovery().map_err(|e| e.into())
}
pub fn set_discoverable(&self, discoverable: bool) -> impl Future<Output = types::Result<()>> {
- self.host.set_discoverable(discoverable).map(from_fidl_status)
+ self.host.set_discoverable(discoverable).map(from_fidl_result)
}
pub fn set_local_data(&self, mut data: HostData) -> types::Result<()> {
- self.host.set_local_data(&mut data)?;
- Ok(())
+ self.host.set_local_data(&mut data).map_err(|e| e.into())
}
pub fn enable_privacy(&self, enable: bool) -> types::Result<()> {
diff --git a/src/connectivity/bluetooth/core/bt-gap/src/host_dispatcher.rs b/src/connectivity/bluetooth/core/bt-gap/src/host_dispatcher.rs
index ac5055f..fef7c6c 100644
--- a/src/connectivity/bluetooth/core/bt-gap/src/host_dispatcher.rs
+++ b/src/connectivity/bluetooth/core/bt-gap/src/host_dispatcher.rs
@@ -5,9 +5,7 @@
use {
anyhow::{format_err, Context as _, Error},
fidl::endpoints::{self, ServerEnd},
- fidl_fuchsia_bluetooth::{
- Appearance, DeviceClass, Error as FidlError, ErrorCode, PeerId as FidlPeerId,
- },
+ fidl_fuchsia_bluetooth::{Appearance, DeviceClass, Error as FidlError, ErrorCode},
fidl_fuchsia_bluetooth_bredr::ProfileMarker,
fidl_fuchsia_bluetooth_control::{
self as control, ControlControlHandle, HostData, InputCapabilityType, LocalKey,
@@ -70,13 +68,10 @@
fn drop(&mut self) {
fx_vlog!(1, "DiscoveryRequestToken dropped");
if let Some(host) = self.adap.upgrade() {
- let await_response = host.write().stop_discovery();
- fasync::spawn(async move {
- if let Err(err) = await_response.await {
- // TODO(45325) - we should close the host channel if an error is returned
- fx_log_warn!("Unexpected error response when stopping discovery: {:?}", err);
- }
- });
+ if let Err(err) = host.write().stop_discovery() {
+ // TODO(45325) - we should close the host channel if an error is returned
+ fx_log_warn!("Unexpected error response when stopping discovery: {:?}", err);
+ }
}
}
}
@@ -461,7 +456,7 @@
for adapter in adapters {
let adapter_path = adapter.read().path.clone();
- let fut = adapter.write().forget(peer_id.to_string());
+ let fut = adapter.write().forget(peer_id);
match fut.await {
Ok(()) => adapters_removed += 1,
Err(types::Error::HostError(FidlError {
@@ -484,7 +479,7 @@
Ok(())
}
- pub async fn connect(&self, peer_id: String) -> types::Result<()> {
+ pub async fn connect(&self, peer_id: PeerId) -> types::Result<()> {
let host = self.get_active_adapter().await;
match host {
Some(host) => {
@@ -495,7 +490,7 @@
}
}
- pub async fn pair(&self, id: FidlPeerId, pairing_options: PairingOptions) -> types::Result<()> {
+ pub async fn pair(&self, id: PeerId, pairing_options: PairingOptions) -> types::Result<()> {
let host = self.get_active_adapter().await;
match host {
Some(host) => {
@@ -507,14 +502,10 @@
}
// Attempt to disconnect peer with id `peer_id` from all transports
- pub async fn disconnect(&self, peer_id: String) -> types::Result<()> {
+ pub async fn disconnect(&self, peer_id: PeerId) -> types::Result<()> {
let host = self.get_active_adapter().await;
match host {
Some(host) => {
- // Suppress the error from `rm_gatt`, as the peer not having a GATT entry
- // (i.e. not using LE) is not a failure condition
- let fut = host.write().rm_gatt(peer_id.clone());
- let _ = fut.await;
let fut = host.write().disconnect(peer_id);
fut.await
}
diff --git a/src/connectivity/bluetooth/core/bt-gap/src/services/control.rs b/src/connectivity/bluetooth/core/bt-gap/src/services/control.rs
index 1aa0d50..773e1ce 100644
--- a/src/connectivity/bluetooth/core/bt-gap/src/services/control.rs
+++ b/src/connectivity/bluetooth/core/bt-gap/src/services/control.rs
@@ -12,7 +12,10 @@
std::sync::Arc,
};
-use crate::{host_dispatcher::*, types::status_response};
+use crate::{
+ host_dispatcher::*,
+ types::{self, status_response},
+};
struct ControlSession {
discovery_token: Option<Arc<DiscoveryRequestToken>>,
@@ -42,6 +45,23 @@
Ok(())
}
+fn parse_peer_id(id: &str) -> Result<PeerId, types::Error> {
+ id.parse::<PeerId>()
+ .map_err(|_| types::Error::InternalError(format_err!("invalid peer ID: {}", id)))
+}
+
+async fn handle_connect(hd: HostDispatcher, device_id: &str) -> types::Result<()> {
+ hd.connect(parse_peer_id(device_id)?).await
+}
+
+async fn handle_forget(hd: HostDispatcher, device_id: &str) -> types::Result<()> {
+ hd.forget(parse_peer_id(device_id)?).await
+}
+
+async fn handle_disconnect(hd: HostDispatcher, device_id: &str) -> types::Result<()> {
+ hd.disconnect(parse_peer_id(device_id)?).await
+}
+
async fn handler(
hd: HostDispatcher,
session: &mut ControlSession,
@@ -49,11 +69,11 @@
) -> fidl::Result<()> {
match event {
ControlRequest::Connect { device_id, responder } => {
- let result = hd.connect(device_id).await;
+ let result = handle_connect(hd, &device_id).await;
responder.send(&mut status_response(result))
}
ControlRequest::Pair { id, options, responder } => {
- let result = hd.pair(id, options).await;
+ let result = hd.pair(id.into(), options).await;
responder.send(&mut status_response(result))
}
ControlRequest::SetDiscoverable { discoverable, responder } => {
@@ -76,17 +96,11 @@
Ok(())
}
ControlRequest::Forget { device_id, responder } => {
- let peer_id = device_id
- .parse::<PeerId>()
- .map_err(|_| format_err!(format!("Invalid peer identifier: {}", device_id)));
- let result = match peer_id {
- Ok(peer_id) => hd.forget(peer_id).await,
- Err(e) => Err(e.into()),
- };
+ let result = handle_forget(hd, &device_id).await;
responder.send(&mut status_response(result))
}
ControlRequest::Disconnect { device_id, responder } => {
- let result = hd.disconnect(device_id).await;
+ let result = handle_disconnect(hd, &device_id).await;
responder.send(&mut status_response(result))
}
ControlRequest::GetKnownRemoteDevices { responder } => {
diff --git a/src/connectivity/bluetooth/core/bt-gap/src/test/host_device.rs b/src/connectivity/bluetooth/core/bt-gap/src/test/host_device.rs
index 075c8be..18c10af 100644
--- a/src/connectivity/bluetooth/core/bt-gap/src/test/host_device.rs
+++ b/src/connectivity/bluetooth/core/bt-gap/src/test/host_device.rs
@@ -8,7 +8,6 @@
fidl_fuchsia_bluetooth_host::{HostControlHandle, HostMarker, HostRequest, HostRequestStream},
fidl_fuchsia_bluetooth_sys::{HostInfo as FidlHostInfo, TechnologyType},
fuchsia_bluetooth::{
- bt_fidl_status,
inspect::{placeholder_node, Inspectable},
types::{Address, BondingData, HostInfo, Peer, PeerId},
},
@@ -62,7 +61,7 @@
let expect_fidl = expect_call(server.clone(), |_, e| match e {
HostRequest::SetLocalName { local_name, responder } => {
info.write().local_name = Some(local_name);
- responder.send(&mut bt_fidl_status!())?;
+ responder.send(&mut Ok(()))?;
Ok(())
}
_ => Err(format_err!("Unexpected!")),
diff --git a/src/connectivity/bluetooth/core/bt-gap/src/types.rs b/src/connectivity/bluetooth/core/bt-gap/src/types.rs
index 5f6bb9c..2aa8d3b 100644
--- a/src/connectivity/bluetooth/core/bt-gap/src/types.rs
+++ b/src/connectivity/bluetooth/core/bt-gap/src/types.rs
@@ -2,15 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-use {anyhow::format_err, fidl_fuchsia_bluetooth as bt, fuchsia_bluetooth::bt_fidl_status};
+use {
+ anyhow::format_err, fidl_fuchsia_bluetooth as bt, fidl_fuchsia_bluetooth_sys as sys,
+ fuchsia_bluetooth::bt_fidl_status,
+};
/// Type representing Possible errors raised in the operation of BT-GAP
#[derive(Debug)]
pub enum Error {
- // Internal bt-gap Error
+ /// Internal bt-gap Error
InternalError(anyhow::Error),
- // Host Error
+
+ /// Host Error
HostError(bt::Error),
+
+ /// fuchsia.bluetooth.sys API errors. Used to encapsulate errors that are reported by bt-host
+ /// and for the fuchsia.bluetooth.sys.Access API.
+ SysError(sys::Error),
}
pub type Result<T> = std::result::Result<T, Error>;
@@ -20,6 +28,9 @@
match self {
Error::HostError(err) => bt::Status { error: Some(Box::new(err)) },
Error::InternalError(err) => bt_fidl_status!(Failed, format!("{}", err)),
+ Error::SysError(err) => {
+ bt::Status { error: Some(Box::new(sys_error_to_deprecated(err))) }
+ }
}
}
@@ -31,14 +42,6 @@
})
}
- pub fn not_found(desc: &str) -> Error {
- Error::HostError(bt::Error {
- error_code: bt::ErrorCode::NotFound,
- protocol_error_code: 0,
- description: Some(desc.to_string()),
- })
- }
-
pub fn as_failure(self) -> anyhow::Error {
match self {
Error::InternalError(err) => err,
@@ -46,6 +49,7 @@
"Host Error: {}",
err.description.unwrap_or("Unknown Host Error".to_string())
),
+ Error::SysError(err) => format_err!("Host Error: {:?}", err),
}
}
}
@@ -62,11 +66,18 @@
}
}
+impl From<sys::Error> for Error {
+ fn from(err: sys::Error) -> Error {
+ Error::SysError(err)
+ }
+}
+
impl From<anyhow::Error> for Error {
fn from(err: anyhow::Error) -> Error {
Error::InternalError(err)
}
}
+
impl From<fidl::Error> for Error {
fn from(err: fidl::Error) -> Error {
Error::InternalError(format_err!(format!("Internal FIDL error: {}", err)))
@@ -80,6 +91,31 @@
}
}
+pub fn from_fidl_result<T>(r: fidl::Result<std::result::Result<T, sys::Error>>) -> Result<T> {
+ match r {
+ Ok(r) => r.map_err(Error::from),
+ Err(e) => Err(Error::from(e)),
+ }
+}
+
+// Maps a fuchsia.bluetooth.sys.Error value to a fuchsia.bluetooth.Error. This is maintained for
+// compatibility until fuchsia.bluetooth.control and fuchsia.bluetooth.Status are removed.
+fn sys_error_to_deprecated(e: sys::Error) -> bt::Error {
+ bt::Error {
+ error_code: match e {
+ sys::Error::Failed => bt::ErrorCode::Failed,
+ sys::Error::PeerNotFound => bt::ErrorCode::NotFound,
+ sys::Error::TimedOut => bt::ErrorCode::TimedOut,
+ sys::Error::Canceled => bt::ErrorCode::Canceled,
+ sys::Error::InProgress => bt::ErrorCode::InProgress,
+ sys::Error::NotSupported => bt::ErrorCode::NotSupported,
+ sys::Error::InvalidArguments => bt::ErrorCode::InvalidArguments,
+ },
+ protocol_error_code: 0,
+ description: None,
+ }
+}
+
pub trait StatusExt {
fn as_result(self) -> Result<()>;
}
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/gatt_client_server.cc b/src/connectivity/bluetooth/core/bt-host/fidl/gatt_client_server.cc
index 1edd551..d8ede06 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/gatt_client_server.cc
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/gatt_client_server.cc
@@ -45,7 +45,8 @@
auto cb = [callback = std::move(callback)](bt::att::Status status, auto services) {
std::vector<ServiceInfo> out;
if (!status) {
- auto fidl_status = fidl_helpers::StatusToFidl(status, "Failed to discover services");
+ auto fidl_status =
+ fidl_helpers::StatusToFidlDeprecated(status, "Failed to discover services");
callback(std::move(fidl_status), std::move(out));
return;
}
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/gatt_remote_service_server.cc b/src/connectivity/bluetooth/core/bt-host/fidl/gatt_remote_service_server.cc
index d57e091..9f752f1 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/gatt_remote_service_server.cc
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/gatt_remote_service_server.cc
@@ -77,7 +77,7 @@
}
}
- callback(fidl_helpers::StatusToFidl(status, ""), std::move(fidl_chrcs));
+ callback(fidl_helpers::StatusToFidlDeprecated(status, ""), std::move(fidl_chrcs));
};
service_->DiscoverCharacteristics(std::move(res_cb));
@@ -95,7 +95,7 @@
value.Copy(&vec_view);
}
- callback(fidl_helpers::StatusToFidl(status), std::move(vec));
+ callback(fidl_helpers::StatusToFidlDeprecated(status), std::move(vec));
};
service_->ReadCharacteristic(CharacteristicHandle(id), std::move(cb));
@@ -115,7 +115,7 @@
value.Copy(&vec_view);
}
- callback(fidl_helpers::StatusToFidl(status), std::move(vec));
+ callback(fidl_helpers::StatusToFidlDeprecated(status), std::move(vec));
};
service_->ReadLongCharacteristic(CharacteristicHandle(id), offset, max_bytes, std::move(cb));
@@ -124,7 +124,7 @@
void GattRemoteServiceServer::WriteCharacteristic(uint64_t id, ::std::vector<uint8_t> value,
WriteCharacteristicCallback callback) {
auto cb = [callback = std::move(callback)](bt::att::Status status) {
- callback(fidl_helpers::StatusToFidl(status, ""));
+ callback(fidl_helpers::StatusToFidlDeprecated(status, ""));
};
service_->WriteCharacteristic(CharacteristicHandle(id), std::move(value), std::move(cb));
@@ -134,7 +134,7 @@
::std::vector<uint8_t> value,
WriteLongCharacteristicCallback callback) {
auto cb = [callback = std::move(callback)](bt::att::Status status) {
- callback(fidl_helpers::StatusToFidl(status, ""));
+ callback(fidl_helpers::StatusToFidlDeprecated(status, ""));
};
service_->WriteLongCharacteristic(CharacteristicHandle(id), offset, std::move(value),
@@ -158,7 +158,7 @@
value.Copy(&vec_view);
}
- callback(fidl_helpers::StatusToFidl(status), std::move(vec));
+ callback(fidl_helpers::StatusToFidlDeprecated(status), std::move(vec));
};
service_->ReadDescriptor(DescriptorHandle(id), std::move(cb));
@@ -177,7 +177,7 @@
value.Copy(&vec_view);
}
- callback(fidl_helpers::StatusToFidl(status), std::move(vec));
+ callback(fidl_helpers::StatusToFidlDeprecated(status), std::move(vec));
};
service_->ReadLongDescriptor(DescriptorHandle(id), offset, max_bytes, std::move(cb));
@@ -187,7 +187,7 @@
WriteDescriptorCallback callback) {
service_->WriteDescriptor(DescriptorHandle(id), std::move(value),
[callback = std::move(callback)](bt::att::Status status) {
- callback(fidl_helpers::StatusToFidl(status, ""));
+ callback(fidl_helpers::StatusToFidlDeprecated(status, ""));
});
}
@@ -196,7 +196,7 @@
WriteLongDescriptorCallback callback) {
service_->WriteLongDescriptor(DescriptorHandle(id), offset, std::move(value),
[callback = std::move(callback)](bt::att::Status status) {
- callback(fidl_helpers::StatusToFidl(status, ""));
+ callback(fidl_helpers::StatusToFidlDeprecated(status, ""));
});
}
@@ -218,7 +218,7 @@
service_->DisableNotifications(handle, iter->second,
[callback = std::move(callback)](bt::att::Status status) {
- callback(fidl_helpers::StatusToFidl(status, ""));
+ callback(fidl_helpers::StatusToFidlDeprecated(status, ""));
});
notify_handlers_.erase(iter);
@@ -263,7 +263,7 @@
self->notify_handlers_.erase(handle);
}
- callback(fidl_helpers::StatusToFidl(status, ""));
+ callback(fidl_helpers::StatusToFidlDeprecated(status, ""));
};
service_->EnableNotifications(handle, std::move(value_cb), std::move(status_cb));
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/helpers.cc b/src/connectivity/bluetooth/core/bt-host/fidl/helpers.cc
index ecfc8a39..0ba3abd 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/helpers.cc
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/helpers.cc
@@ -189,7 +189,7 @@
return bt::DeviceAddressBytes(bytes);
}
-ErrorCode HostErrorToFidl(bt::HostError host_error) {
+ErrorCode HostErrorToFidlDeprecated(bt::HostError host_error) {
switch (host_error) {
case bt::HostError::kFailed:
return ErrorCode::FAILED;
@@ -222,6 +222,29 @@
return status;
}
+fsys::Error HostErrorToFidl(bt::HostError error) {
+ ZX_DEBUG_ASSERT(error != bt::HostError::kNoError);
+ switch (error) {
+ case bt::HostError::kFailed:
+ return fsys::Error::FAILED;
+ case bt::HostError::kTimedOut:
+ return fsys::Error::TIMED_OUT;
+ case bt::HostError::kInvalidParameters:
+ return fsys::Error::INVALID_ARGUMENTS;
+ case bt::HostError::kCanceled:
+ return fsys::Error::CANCELED;
+ case bt::HostError::kInProgress:
+ return fsys::Error::IN_PROGRESS;
+ case bt::HostError::kNotSupported:
+ return fsys::Error::NOT_SUPPORTED;
+ case bt::HostError::kNotFound:
+ return fsys::Error::PEER_NOT_FOUND;
+ default:
+ break;
+ }
+ return fsys::Error::FAILED;
+}
+
bt::UUID UuidFromFidl(const fuchsia::bluetooth::Uuid& input) {
bt::UUID output;
// Conversion must always succeed given the defined size of |input|.
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/helpers.h b/src/connectivity/bluetooth/core/bt-host/fidl/helpers.h
index a2cb298..e7a99b5 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/helpers.h
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/helpers.h
@@ -48,21 +48,21 @@
// Functions for generating a FIDL bluetooth::Status
-fuchsia::bluetooth::ErrorCode HostErrorToFidl(bt::HostError host_error);
+fuchsia::bluetooth::ErrorCode HostErrorToFidlDeprecated(bt::HostError host_error);
fuchsia::bluetooth::Status NewFidlError(fuchsia::bluetooth::ErrorCode error_code,
std::string description);
template <typename ProtocolErrorCode>
-fuchsia::bluetooth::Status StatusToFidl(const bt::Status<ProtocolErrorCode>& status,
- std::string msg = "") {
+fuchsia::bluetooth::Status StatusToFidlDeprecated(const bt::Status<ProtocolErrorCode>& status,
+ std::string msg = "") {
fuchsia::bluetooth::Status fidl_status;
if (status.is_success()) {
return fidl_status;
}
auto error = fuchsia::bluetooth::Error::New();
- error->error_code = HostErrorToFidl(status.error());
+ error->error_code = HostErrorToFidlDeprecated(status.error());
error->description = msg.empty() ? status.ToString() : std::move(msg);
if (status.is_protocol_error()) {
error->protocol_error_code = static_cast<uint32_t>(status.protocol_error());
@@ -72,6 +72,23 @@
return fidl_status;
}
+// Convert a bt::HostError to fuchsia.bluetooth.sys.Error. This function does only
+// deals with bt::HostError types and does not support Bluetooth protocol-specific errors; to
+// represent such errors use protocol-specific FIDL error types. An |error| value of
+// HostError::kNoError is not allowed.
+fuchsia::bluetooth::sys::Error HostErrorToFidl(bt::HostError error);
+
+// Convert any bt::Status to a fit::result that uses the fuchsia.bluetooth.sys library error codes.
+template <typename ProtocolErrorCode>
+fit::result<void, fuchsia::bluetooth::sys::Error> StatusToFidl(
+ bt::Status<ProtocolErrorCode> status) {
+ if (status) {
+ return fit::ok();
+ } else {
+ return fit::error(HostErrorToFidl(status.error()));
+ }
+}
+
bt::UUID UuidFromFidl(const fuchsia::bluetooth::Uuid& input);
// Functions that convert FIDL types to library objects.
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/helpers_unittest.cc b/src/connectivity/bluetooth/core/bt-host/fidl/helpers_unittest.cc
index 3deb1e9..64f0be5 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/helpers_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/helpers_unittest.cc
@@ -19,6 +19,19 @@
namespace fidl_helpers {
namespace {
+TEST(FidlHelpersTest, HostErrorToFidl) {
+ EXPECT_EQ(fsys::Error::FAILED, HostErrorToFidl(bt::HostError::kFailed));
+ EXPECT_EQ(fsys::Error::TIMED_OUT, HostErrorToFidl(bt::HostError::kTimedOut));
+ EXPECT_EQ(fsys::Error::INVALID_ARGUMENTS, HostErrorToFidl(bt::HostError::kInvalidParameters));
+ EXPECT_EQ(fsys::Error::CANCELED, HostErrorToFidl(bt::HostError::kCanceled));
+ EXPECT_EQ(fsys::Error::IN_PROGRESS, HostErrorToFidl(bt::HostError::kInProgress));
+ EXPECT_EQ(fsys::Error::NOT_SUPPORTED, HostErrorToFidl(bt::HostError::kNotSupported));
+ EXPECT_EQ(fsys::Error::PEER_NOT_FOUND, HostErrorToFidl(bt::HostError::kNotFound));
+
+ // All other errors currently map to FAILED.
+ EXPECT_EQ(fsys::Error::FAILED, HostErrorToFidl(bt::HostError::kProtocolError));
+}
+
TEST(FIDL_HelpersTest, AddressBytesFrommString) {
EXPECT_FALSE(AddressBytesFromString(""));
EXPECT_FALSE(AddressBytesFromString("FF"));
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/host_server.cc b/src/connectivity/bluetooth/core/bt-host/fidl/host_server.cc
index 811c87d..b9d4e8a 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/host_server.cc
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/host_server.cc
@@ -4,6 +4,7 @@
#include "host_server.h"
+#include <lib/fit/result.h>
#include <zircon/assert.h>
#include "fuchsia/bluetooth/control/cpp/fidl.h"
@@ -31,14 +32,17 @@
namespace bthost {
namespace fbt = fuchsia::bluetooth;
+namespace fsys = fuchsia::bluetooth::sys;
using bt::PeerId;
using bt::sm::IOCapability;
using fidl_helpers::AddressBytesFromString;
+using fidl_helpers::HostErrorToFidl;
using fidl_helpers::NewFidlError;
using fidl_helpers::PeerIdFromString;
using fidl_helpers::SecurityLevelFromFidl;
using fidl_helpers::StatusToFidl;
+using fidl_helpers::StatusToFidlDeprecated;
using fuchsia::bluetooth::Bool;
using fuchsia::bluetooth::ErrorCode;
using fuchsia::bluetooth::Status;
@@ -165,7 +169,7 @@
if (status && self) {
self->NotifyInfoChange();
}
- callback(StatusToFidl(status, "Can't Set Local Name"));
+ callback(StatusToFidl(status));
});
}
@@ -173,19 +177,18 @@
void HostServer::SetDeviceClass(fbt::DeviceClass device_class, SetDeviceClassCallback callback) {
// Device Class values must only contain data in the lower 3 bytes.
if (device_class.value >= 1 << 24) {
- callback(NewFidlError(ErrorCode::INVALID_ARGUMENTS, "Can't Set Device Class"));
+ callback(fit::error(fsys::Error::INVALID_ARGUMENTS));
return;
}
bt::DeviceClass dev_class(device_class.value);
- adapter()->SetDeviceClass(dev_class, [callback = std::move(callback)](auto status) {
- callback(fidl_helpers::StatusToFidl(status, "Can't Set Device Class"));
- });
+ adapter()->SetDeviceClass(
+ dev_class, [callback = std::move(callback)](auto status) { callback(StatusToFidl(status)); });
}
void HostServer::StartLEDiscovery(StartDiscoveryCallback callback) {
auto le_manager = adapter()->le_discovery_manager();
if (!le_manager) {
- callback(NewFidlError(ErrorCode::BAD_STATE, "Adapter is not initialized yet."));
+ callback(fit::error(fsys::Error::FAILED));
return;
}
le_manager->StartDiscovery(
@@ -193,18 +196,18 @@
// End the new session if this AdapterServer got destroyed in the
// mean time (e.g. because the client disconnected).
if (!self) {
- callback(NewFidlError(ErrorCode::FAILED, "Adapter Shutdown"));
+ callback(fit::error(fsys::Error::FAILED));
return;
}
if (!self->requesting_discovery_) {
- callback(NewFidlError(ErrorCode::CANCELED, "Request canceled"));
+ callback(fit::error(fsys::Error::CANCELED));
return;
}
if (!session) {
bt_log(TRACE, "bt-host", "failed to start LE discovery session");
- callback(NewFidlError(ErrorCode::FAILED, "Failed to start LE discovery session"));
+ callback(fit::error(fsys::Error::FAILED));
self->bredr_discovery_session_ = nullptr;
self->requesting_discovery_ = false;
return;
@@ -222,7 +225,7 @@
// Send the adapter state update.
self->NotifyInfoChange();
- callback(Status());
+ callback(fit::ok());
});
}
@@ -232,7 +235,7 @@
if (le_discovery_session_ || requesting_discovery_) {
bt_log(TRACE, "bt-host", "discovery already in progress");
- callback(NewFidlError(ErrorCode::IN_PROGRESS, "Discovery already in progress"));
+ callback(fit::error(fsys::Error::IN_PROGRESS));
return;
}
@@ -247,19 +250,26 @@
[self = weak_ptr_factory_.GetWeakPtr(), callback = std::move(callback)](
bt::hci::Status status, auto session) mutable {
if (!self) {
- callback(NewFidlError(ErrorCode::FAILED, "Adapter Shutdown"));
+ callback(fit::error(fsys::Error::FAILED));
return;
}
if (!self->requesting_discovery_) {
- callback(NewFidlError(ErrorCode::CANCELED, "Request Canceled"));
+ callback(fit::error(fsys::Error::CANCELED));
return;
}
if (!status || !session) {
bt_log(TRACE, "bt-host", "failed to start BR/EDR discovery session");
- callback(StatusToFidl(status, "Failed to start BR/EDR discovery session"));
+
+ fit::result<void, fsys::Error> result;
+ if (!status) {
+ result = StatusToFidl(status);
+ } else {
+ result = fit::error(fsys::Error::FAILED);
+ }
self->requesting_discovery_ = false;
+ callback(std::move(result));
return;
}
@@ -268,19 +278,18 @@
});
}
-void HostServer::StopDiscovery(StopDiscoveryCallback callback) {
+void HostServer::StopDiscovery() {
bt_log(TRACE, "bt-host", "StopDiscovery()");
- if (!le_discovery_session_) {
- bt_log(TRACE, "bt-host", "no active discovery session");
- callback(NewFidlError(ErrorCode::BAD_STATE, "No discovery session in progress"));
- return;
- }
+ bool discovering = le_discovery_session_ || bredr_discovery_session_;
bredr_discovery_session_ = nullptr;
le_discovery_session_ = nullptr;
- NotifyInfoChange();
- callback(Status());
+ if (discovering) {
+ NotifyInfoChange();
+ } else {
+ bt_log(TRACE, "bt-host", "no active discovery session");
+ }
}
void HostServer::SetConnectable(bool connectable, SetConnectableCallback callback) {
@@ -288,7 +297,7 @@
auto bredr_conn_manager = adapter()->bredr_connection_manager();
if (!bredr_conn_manager) {
- callback(NewFidlError(ErrorCode::NOT_SUPPORTED, "Connectable mode not available"));
+ callback(fit::error(fsys::Error::NOT_SUPPORTED));
return;
}
bredr_conn_manager->SetConnectable(
@@ -401,44 +410,50 @@
if (!discoverable) {
bredr_discoverable_session_ = nullptr;
NotifyInfoChange();
- callback(Status());
+ callback(fit::ok());
return;
}
if (discoverable && requesting_discoverable_) {
bt_log(TRACE, "bt-host", "SetDiscoverable already in progress");
- callback(NewFidlError(ErrorCode::IN_PROGRESS, "SetDiscoverable already in progress"));
+ callback(fit::error(fsys::Error::IN_PROGRESS));
return;
}
requesting_discoverable_ = true;
auto bredr_manager = adapter()->bredr_discovery_manager();
if (!bredr_manager) {
- callback(NewFidlError(ErrorCode::FAILED, "Discoverable mode not available"));
+ callback(fit::error(fsys::Error::FAILED));
return;
}
bredr_manager->RequestDiscoverable(
[self = weak_ptr_factory_.GetWeakPtr(), callback = std::move(callback)](
bt::hci::Status status, auto session) {
if (!self) {
- callback(NewFidlError(ErrorCode::FAILED, "Adapter Shutdown"));
+ callback(fit::error(fsys::Error::FAILED));
return;
}
if (!self->requesting_discoverable_) {
- callback(NewFidlError(ErrorCode::CANCELED, "Request canceled"));
+ callback(fit::error(fsys::Error::CANCELED));
return;
}
if (!status || !session) {
bt_log(TRACE, "bt-host", "failed to set discoverable");
- callback(StatusToFidl(status, "Failed to set discoverable"));
+ fit::result<void, fsys::Error> result;
+ if (!status) {
+ result = StatusToFidl(status);
+ } else {
+ result = fit::error(fsys::Error::FAILED);
+ }
self->requesting_discoverable_ = false;
+ callback(std::move(result));
return;
}
self->bredr_discoverable_session_ = std::move(session);
self->requesting_discoverable_ = false;
self->NotifyInfoChange();
- callback(Status());
+ callback(fit::ok());
});
}
@@ -488,16 +503,12 @@
// Attempt to connect to peer identified by |peer_id|. The peer must be
// in our peer cache. We will attempt to connect technologies (LowEnergy,
// Classic or Dual-Mode) as the peer claims to support when discovered
-void HostServer::Connect(::std::string peer_id, ConnectCallback callback) {
- auto id = PeerIdFromString(peer_id);
- if (!id.has_value()) {
- callback(NewFidlError(ErrorCode::INVALID_ARGUMENTS, "invalid peer ID"));
- return;
- }
- auto peer = adapter()->peer_cache()->FindById(*id);
+void HostServer::Connect(fbt::PeerId peer_id, ConnectCallback callback) {
+ bt::PeerId id{peer_id.value};
+ auto peer = adapter()->peer_cache()->FindById(id);
if (!peer) {
// We don't support connecting to peers that are not in our cache
- callback(NewFidlError(ErrorCode::NOT_FOUND, "Cannot find peer with the given ID"));
+ callback(fit::error(fsys::Error::PEER_NOT_FOUND));
return;
}
@@ -505,35 +516,24 @@
// LowEnergy we assume LE. If a dual-mode peer, we should attempt to connect
// both protocols.
if (!peer->le()) {
- ConnectBrEdr(*id, std::move(callback));
+ ConnectBrEdr(id, std::move(callback));
return;
}
- ConnectLowEnergy(*id, std::move(callback));
+ ConnectLowEnergy(id, std::move(callback));
}
// Attempt to disconnect the peer identified by |peer_id| from all transports.
// If the peer is already not connected, return success. If the peer is
// disconnected succesfully, return success.
-void HostServer::Disconnect(::std::string peer_id, DisconnectCallback callback) {
- auto id = PeerIdFromString(peer_id);
- if (!id.has_value()) {
- callback(NewFidlError(ErrorCode::INVALID_ARGUMENTS, "invalid peer ID"));
- return;
- }
-
- auto le_disc = adapter()->le_connection_manager()->Disconnect(*id);
- auto bredr_disc = adapter()->bredr_connection_manager()->Disconnect(*id);
-
+void HostServer::Disconnect(fbt::PeerId peer_id, DisconnectCallback callback) {
+ bt::PeerId id{peer_id.value};
+ auto le_disc = adapter()->le_connection_manager()->Disconnect(id);
+ auto bredr_disc = adapter()->bredr_connection_manager()->Disconnect(id);
if (le_disc && bredr_disc) {
- callback(Status());
+ callback(fit::ok());
} else {
- if (le_disc)
- callback(NewFidlError(ErrorCode::UNKNOWN, "Failed to disconnect from Br/Edr"));
- else if (bredr_disc)
- callback(NewFidlError(ErrorCode::UNKNOWN, "Failed to disconnect from LE"));
- else
- callback(NewFidlError(ErrorCode::UNKNOWN, "Failed to disconnect from both LE and Br/Edr"));
+ callback(fit::error(fsys::Error::FAILED));
}
}
@@ -542,8 +542,8 @@
auto on_complete = [self, callback = std::move(callback), peer_id](auto status, auto connection) {
if (!status) {
ZX_ASSERT(!connection);
- bt_log(TRACE, "bt-host", "failed to connect to peer (id %s)", bt_str(peer_id));
- callback(StatusToFidl(status, "failed to connect"));
+ bt_log(TRACE, "bt-host", "failed to connect LE transport to peer (id %s)", bt_str(peer_id));
+ callback(fit::error(HostErrorToFidl(status.error())));
return;
}
@@ -551,13 +551,13 @@
ZX_ASSERT(connection);
ZX_ASSERT(peer_id == connection->peer_identifier());
- callback(Status());
+ callback(fit::ok());
if (self)
self->RegisterLowEnergyConnection(std::move(connection), false);
};
if (!adapter()->le_connection_manager()->Connect(peer_id, std::move(on_complete))) {
- callback(NewFidlError(ErrorCode::FAILED, "failed to connect"));
+ callback(fit::error(fsys::Error::FAILED));
}
}
@@ -567,8 +567,9 @@
auto on_complete = [callback = std::move(callback), peer_id](auto status, auto connection) {
if (!status) {
ZX_ASSERT(!connection);
- bt_log(TRACE, "bt-host", "failed to connect to peer (id %s)", bt_str(peer_id));
- callback(StatusToFidl(status, "failed to connect"));
+ bt_log(TRACE, "bt-host", "failed to connect BR/EDR transport to peer (id %s)",
+ bt_str(peer_id));
+ callback(fit::error(HostErrorToFidl(status.error())));
return;
}
@@ -576,39 +577,35 @@
ZX_ASSERT(connection);
ZX_ASSERT(peer_id == connection->peer_id());
- callback(Status());
+ callback(fit::ok());
};
if (!adapter()->bredr_connection_manager()->Connect(peer_id, std::move(on_complete))) {
- callback(NewFidlError(ErrorCode::FAILED, "failed to connect"));
+ callback(fit::error(fsys::Error::FAILED));
}
}
-void HostServer::Forget(::std::string peer_id, ForgetCallback callback) {
- auto id = PeerIdFromString(peer_id);
- if (!id.has_value()) {
- callback(NewFidlError(ErrorCode::INVALID_ARGUMENTS, "Invalid peer ID"));
- return;
- }
- auto peer = adapter()->peer_cache()->FindById(*id);
+void HostServer::Forget(fbt::PeerId peer_id, ForgetCallback callback) {
+ bt::PeerId id{peer_id.value};
+ auto peer = adapter()->peer_cache()->FindById(id);
if (!peer) {
- bt_log(TRACE, "bt-host", "peer %s to forget wasn't found", peer_id.c_str());
- callback(Status());
+ bt_log(TRACE, "bt-host", "peer %s to forget wasn't found", bt_str(id));
+ callback(fit::ok());
return;
}
- const bool le_disconnected = adapter()->le_connection_manager()->Disconnect(*id);
- const bool bredr_disconnected = adapter()->bredr_connection_manager()->Disconnect(*id);
- const bool peer_removed = adapter()->peer_cache()->RemoveDisconnectedPeer(*id);
+ const bool le_disconnected = adapter()->le_connection_manager()->Disconnect(id);
+ const bool bredr_disconnected = adapter()->bredr_connection_manager()->Disconnect(id);
+ const bool peer_removed = adapter()->peer_cache()->RemoveDisconnectedPeer(id);
if (!le_disconnected || !bredr_disconnected) {
const auto message =
- fxl::StringPrintf("Link(s) failed to close:%s%s", le_disconnected ? "" : " LE",
+ fxl::StringPrintf("link(s) failed to close:%s%s", le_disconnected ? "" : " LE",
bredr_disconnected ? "" : " BR/EDR");
- callback(NewFidlError(ErrorCode::FAILED, message));
+ callback(fit::error(fsys::Error::FAILED));
} else {
ZX_ASSERT(peer_removed);
- callback(Status());
+ callback(fit::ok());
}
}
@@ -618,7 +615,7 @@
auto peer = adapter()->peer_cache()->FindById(peer_id);
if (!peer) {
// We don't support pairing to peers that are not in our cache
- callback(NewFidlError(ErrorCode::NOT_FOUND, "Cannot find peer with the given ID"));
+ callback(fit::error(fsys::Error::PEER_NOT_FOUND));
return;
}
// If options specifies a transport preference for LE or BR/EDR, we use that. Otherwise, we use
@@ -639,7 +636,7 @@
if (options.has_le_security_level()) {
security_level = SecurityLevelFromFidl(options.le_security_level());
if (!security_level.has_value()) {
- callback(NewFidlError(ErrorCode::INVALID_ARGUMENTS, "invalid security level"));
+ callback(fit::error(fsys::Error::INVALID_ARGUMENTS));
return;
}
} else {
@@ -652,10 +649,10 @@
auto on_complete = [peer_id, callback = std::move(callback)](bt::sm::Status status) {
if (!status) {
bt_log(WARN, "bt-host", "failed to pair to peer (id %s)", bt_str(peer_id));
- callback(NewFidlError(fidl_helpers::HostErrorToFidl(status.error()), "Failed to pair"));
- return;
+ callback(fit::error(HostErrorToFidl(status.error())));
+ } else {
+ callback(fit::ok());
}
- callback(Status());
};
adapter()->le_connection_manager()->Pair(peer_id, *security_level, bondable_mode,
std::move(on_complete));
@@ -665,10 +662,10 @@
auto on_complete = [peer_id, callback = std::move(callback)](bt::hci::Status status) {
if (!status) {
bt_log(WARN, "bt-host", "failed to pair to peer (id %s)", bt_str(peer_id));
- callback(NewFidlError(fidl_helpers::HostErrorToFidl(status.error()), "Failed to pair"));
- return;
+ callback(fit::error(HostErrorToFidl(status.error())));
+ } else {
+ callback(fit::ok());
}
- callback(Status());
};
adapter()->bredr_connection_manager()->Pair(peer_id, std::move(on_complete));
}
@@ -746,7 +743,7 @@
void HostServer::CompletePairing(PeerId id, bt::sm::Status status) {
bt_log(TRACE, "bt-host", "pairing complete for peer: %s, status: %s", bt_str(id), bt_str(status));
ZX_DEBUG_ASSERT(pairing_delegate_);
- pairing_delegate_->OnPairingComplete(id.ToString(), StatusToFidl(status));
+ pairing_delegate_->OnPairingComplete(id.ToString(), StatusToFidlDeprecated(status));
}
void HostServer::ConfirmPairing(PeerId id, ConfirmCallback confirm) {
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/host_server.h b/src/connectivity/bluetooth/core/bt-host/fidl/host_server.h
index 77097b1..d4e5be9 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/host_server.h
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/host_server.h
@@ -89,7 +89,7 @@
SetDeviceClassCallback callback) override;
void StartDiscovery(StartDiscoveryCallback callback) override;
- void StopDiscovery(StopDiscoveryCallback callback) override;
+ void StopDiscovery() override;
void SetConnectable(bool connectable, SetConnectableCallback callback) override;
void SetDiscoverable(bool discoverable, SetDiscoverableCallback callback) override;
void EnableBackgroundScan(bool enabled) override;
@@ -98,11 +98,11 @@
::fuchsia::bluetooth::control::InputCapabilityType input,
::fuchsia::bluetooth::control::OutputCapabilityType output,
::fidl::InterfaceHandle<::fuchsia::bluetooth::control::PairingDelegate> delegate) override;
- void Connect(::std::string device_id, ConnectCallback callback) override;
- void Disconnect(::std::string device_id, DisconnectCallback callback) override;
+ void Connect(::fuchsia::bluetooth::PeerId id, ConnectCallback callback) override;
+ void Disconnect(::fuchsia::bluetooth::PeerId id, DisconnectCallback callback) override;
void Pair(::fuchsia::bluetooth::PeerId id, ::fuchsia::bluetooth::control::PairingOptions options,
PairCallback callback) override;
- void Forget(::std::string peer_id, ForgetCallback callback) override;
+ void Forget(::fuchsia::bluetooth::PeerId id, ForgetCallback callback) override;
void RequestLowEnergyCentral(
::fidl::InterfaceRequest<fuchsia::bluetooth::le::Central> central) override;
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/host_server_unittest.cc b/src/connectivity/bluetooth/core/bt-host/fidl/host_server_unittest.cc
index 1456f59..a2d25dd 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/host_server_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/host_server_unittest.cc
@@ -36,24 +36,15 @@
using bt::UpperBits;
using bt::l2cap::testing::FakeChannel;
using bt::testing::FakePeer;
-using HostPairingDelegate = bt::gap::PairingDelegate;
-using fuchsia::bluetooth::control::InputCapabilityType;
-using fuchsia::bluetooth::control::OutputCapabilityType;
-using FidlErrorCode = fuchsia::bluetooth::ErrorCode;
-using FidlStatus = fuchsia::bluetooth::Status;
-using fuchsia::bluetooth::control::PairingOptions;
-using FidlPairingDelegate = fuchsia::bluetooth::control::PairingDelegate;
-using fuchsia::bluetooth::control::PairingSecurityLevel;
-
-using FidlRemoteDevice = fuchsia::bluetooth::control::RemoteDevice;
namespace fbt = fuchsia::bluetooth;
+namespace fctrl = fuchsia::bluetooth::control;
namespace fsys = fuchsia::bluetooth::sys;
const bt::DeviceAddress kLeTestAddr(bt::DeviceAddress::Type::kLEPublic, {0x01, 0, 0, 0, 0, 0});
const bt::DeviceAddress kBredrTestAddr(bt::DeviceAddress::Type::kBREDR, {0x01, 0, 0, 0, 0, 0});
-class MockPairingDelegate : public fuchsia::bluetooth::control::testing::PairingDelegate_TestBase {
+class MockPairingDelegate : public fctrl::testing::PairingDelegate_TestBase {
public:
MockPairingDelegate(fidl::InterfaceRequest<PairingDelegate> request,
async_dispatcher_t* dispatcher)
@@ -62,14 +53,12 @@
~MockPairingDelegate() override = default;
MOCK_METHOD(void, OnPairingRequest,
- (fuchsia::bluetooth::control::RemoteDevice device,
- fuchsia::bluetooth::control::PairingMethod method, fidl::StringPtr displayed_passkey,
- OnPairingRequestCallback callback),
+ (fctrl::RemoteDevice device, fctrl::PairingMethod method,
+ fidl::StringPtr displayed_passkey, OnPairingRequestCallback callback),
(override));
MOCK_METHOD(void, OnPairingComplete, (std::string device_id, fuchsia::bluetooth::Status status),
(override));
- MOCK_METHOD(void, OnRemoteKeypress,
- (std::string device_id, fuchsia::bluetooth::control::PairingKeypressType keypress),
+ MOCK_METHOD(void, OnRemoteKeypress, (std::string device_id, fctrl::PairingKeypressType keypress),
(override));
private:
@@ -119,9 +108,9 @@
// Create and bind a MockPairingDelegate and attach it to the HostServer under test. It is
// heap-allocated to permit its explicit destruction.
[[nodiscard]] std::unique_ptr<MockPairingDelegate> SetMockPairingDelegate(
- InputCapabilityType input_capability, OutputCapabilityType output_capability) {
+ fctrl::InputCapabilityType input_capability, fctrl::OutputCapabilityType output_capability) {
using ::testing::StrictMock;
- fidl::InterfaceHandle<FidlPairingDelegate> pairing_delegate_handle;
+ fidl::InterfaceHandle<fctrl::PairingDelegate> pairing_delegate_handle;
auto pairing_delegate = std::make_unique<StrictMock<MockPairingDelegate>>(
pairing_delegate_handle.NewRequest(), dispatcher());
host_client()->SetPairingDelegate(input_capability, output_capability,
@@ -143,15 +132,15 @@
auto fake_peer = std::make_unique<FakePeer>(device_addr);
test_device()->AddPeer(std::move(fake_peer));
- // Initialize with error to ensure callback is called
- FidlStatus connect_status =
- fidl_helpers::NewFidlError(FidlErrorCode::BAD_STATE, "This should disappear");
- host_client()->Connect(peer->identifier().ToString(), [&connect_status](FidlStatus cb_status) {
- ASSERT_FALSE(cb_status.error);
- connect_status = std::move(cb_status);
+
+ std::optional<fit::result<void, fsys::Error>> connect_result;
+ host_client()->Connect(fbt::PeerId{peer->identifier().value()}, [&](auto result) {
+ ASSERT_FALSE(result.is_err());
+ connect_result = std::move(result);
});
RunLoopUntilIdle();
- if (connect_status.error != nullptr) {
+
+ if (!connect_result || connect_result->is_error()) {
peer = nullptr;
fake_chan = nullptr;
}
@@ -168,13 +157,13 @@
TEST_F(FIDL_HostServerTest, FidlIoCapabilitiesMapToHostIoCapability) {
// Isolate HostServer's private bt::gap::PairingDelegate implementation.
- auto host_pairing_delegate = static_cast<HostPairingDelegate*>(host_server());
+ auto host_pairing_delegate = static_cast<bt::gap::PairingDelegate*>(host_server());
// Getter should be safe to call when no PairingDelegate assigned.
EXPECT_EQ(bt::sm::IOCapability::kNoInputNoOutput, host_pairing_delegate->io_capability());
- auto fidl_pairing_delegate =
- SetMockPairingDelegate(InputCapabilityType::KEYBOARD, OutputCapabilityType::DISPLAY);
+ auto fidl_pairing_delegate = SetMockPairingDelegate(fctrl::InputCapabilityType::KEYBOARD,
+ fctrl::OutputCapabilityType::DISPLAY);
EXPECT_EQ(bt::sm::IOCapability::kKeyboardDisplay, host_pairing_delegate->io_capability());
}
@@ -182,9 +171,9 @@
using namespace ::testing;
// Isolate HostServer's private bt::gap::PairingDelegate implementation.
- auto host_pairing_delegate = static_cast<HostPairingDelegate*>(host_server());
- auto fidl_pairing_delegate =
- SetMockPairingDelegate(InputCapabilityType::KEYBOARD, OutputCapabilityType::DISPLAY);
+ auto host_pairing_delegate = static_cast<bt::gap::PairingDelegate*>(host_server());
+ auto fidl_pairing_delegate = SetMockPairingDelegate(fctrl::InputCapabilityType::KEYBOARD,
+ fctrl::OutputCapabilityType::DISPLAY);
// fuchsia::bluetooth::Status is move-only so check its value in a lambda.
EXPECT_CALL(*fidl_pairing_delegate, OnPairingComplete(EndsWith("c0decafe"), _))
@@ -203,24 +192,24 @@
TEST_F(FIDL_HostServerTest, HostConfirmPairingRequestsConsentPairingOverFidl) {
using namespace ::testing;
- auto host_pairing_delegate = static_cast<HostPairingDelegate*>(host_server());
- auto fidl_pairing_delegate =
- SetMockPairingDelegate(InputCapabilityType::KEYBOARD, OutputCapabilityType::DISPLAY);
+ auto host_pairing_delegate = static_cast<bt::gap::PairingDelegate*>(host_server());
+ auto fidl_pairing_delegate = SetMockPairingDelegate(fctrl::InputCapabilityType::KEYBOARD,
+ fctrl::OutputCapabilityType::DISPLAY);
auto* const peer = adapter()->peer_cache()->NewPeer(kLeTestAddr, /*connectable=*/true);
ASSERT_TRUE(peer);
EXPECT_CALL(*fidl_pairing_delegate,
- OnPairingRequest(_, fuchsia::bluetooth::control::PairingMethod::CONSENT,
- fidl::StringPtr(nullptr), _))
- .WillOnce([id = peer->identifier()](FidlRemoteDevice device, Unused, Unused,
- FidlPairingDelegate::OnPairingRequestCallback callback) {
- EXPECT_THAT(device.identifier, EndsWith(id.ToString()));
- callback(/*accept=*/true, /*entered_passkey=*/nullptr);
- });
+ OnPairingRequest(_, fctrl::PairingMethod::CONSENT, fidl::StringPtr(nullptr), _))
+ .WillOnce(
+ [id = peer->identifier()](fctrl::RemoteDevice device, Unused, Unused,
+ fctrl::PairingDelegate::OnPairingRequestCallback callback) {
+ EXPECT_THAT(device.identifier, EndsWith(id.ToString()));
+ callback(/*accept=*/true, /*entered_passkey=*/nullptr);
+ });
bool confirm_cb_value = false;
- HostPairingDelegate::ConfirmCallback confirm_cb = [&confirm_cb_value](bool confirmed) {
+ bt::gap::PairingDelegate::ConfirmCallback confirm_cb = [&confirm_cb_value](bool confirmed) {
confirm_cb_value = confirmed;
};
host_pairing_delegate->ConfirmPairing(peer->identifier(), std::move(confirm_cb));
@@ -233,19 +222,19 @@
TEST_F(FIDL_HostServerTest,
HostDisplayPasskeyRequestsPasskeyDisplayOrNumericComparisonPairingOverFidl) {
using namespace ::testing;
- auto host_pairing_delegate = static_cast<HostPairingDelegate*>(host_server());
- auto fidl_pairing_delegate =
- SetMockPairingDelegate(InputCapabilityType::KEYBOARD, OutputCapabilityType::DISPLAY);
+ auto host_pairing_delegate = static_cast<bt::gap::PairingDelegate*>(host_server());
+ auto fidl_pairing_delegate = SetMockPairingDelegate(fctrl::InputCapabilityType::KEYBOARD,
+ fctrl::OutputCapabilityType::DISPLAY);
auto* const peer = adapter()->peer_cache()->NewPeer(kLeTestAddr, /*connectable=*/true);
ASSERT_TRUE(peer);
// This call should use PASSKEY_DISPLAY to request that the user perform peer passkey entry.
- using fuchsia::bluetooth::control::PairingMethod;
- using OnPairingRequestCallback = FidlPairingDelegate::OnPairingRequestCallback;
+ using fctrl::PairingMethod;
+ using OnPairingRequestCallback = fctrl::PairingDelegate::OnPairingRequestCallback;
EXPECT_CALL(*fidl_pairing_delegate,
OnPairingRequest(_, PairingMethod::PASSKEY_DISPLAY, fidl::StringPtr("012345"), _))
- .WillOnce([id = peer->identifier()](FidlRemoteDevice device, Unused, Unused,
+ .WillOnce([id = peer->identifier()](fctrl::RemoteDevice device, Unused, Unused,
OnPairingRequestCallback callback) {
EXPECT_THAT(device.identifier, EndsWith(id.ToString()));
callback(/*accept=*/false, /*entered_passkey=*/nullptr);
@@ -256,7 +245,7 @@
EXPECT_FALSE(confirmed);
confirm_cb_called = true;
};
- using DisplayMethod = HostPairingDelegate::DisplayMethod;
+ using DisplayMethod = bt::gap::PairingDelegate::DisplayMethod;
host_pairing_delegate->DisplayPasskey(peer->identifier(), 12345, DisplayMethod::kPeerEntry,
confirm_cb);
@@ -268,7 +257,7 @@
// the local and peer devices.
EXPECT_CALL(*fidl_pairing_delegate,
OnPairingRequest(_, PairingMethod::PASSKEY_COMPARISON, fidl::StringPtr("012345"), _))
- .WillOnce([id = peer->identifier()](FidlRemoteDevice device, Unused, Unused,
+ .WillOnce([id = peer->identifier()](fctrl::RemoteDevice device, Unused, Unused,
OnPairingRequestCallback callback) {
EXPECT_THAT(device.identifier, EndsWith(id.ToString()));
callback(/*accept=*/false, /*entered_passkey=*/nullptr);
@@ -285,33 +274,32 @@
TEST_F(FIDL_HostServerTest, HostRequestPasskeyRequestsPasskeyEntryPairingOverFidl) {
using namespace ::testing;
- auto host_pairing_delegate = static_cast<HostPairingDelegate*>(host_server());
- auto fidl_pairing_delegate =
- SetMockPairingDelegate(InputCapabilityType::KEYBOARD, OutputCapabilityType::DISPLAY);
+ auto host_pairing_delegate = static_cast<bt::gap::PairingDelegate*>(host_server());
+ auto fidl_pairing_delegate = SetMockPairingDelegate(fctrl::InputCapabilityType::KEYBOARD,
+ fctrl::OutputCapabilityType::DISPLAY);
auto* const peer = adapter()->peer_cache()->NewPeer(kLeTestAddr, /*connectable=*/true);
ASSERT_TRUE(peer);
- using OnPairingRequestCallback = FidlPairingDelegate::OnPairingRequestCallback;
+ using OnPairingRequestCallback = fctrl::PairingDelegate::OnPairingRequestCallback;
EXPECT_CALL(*fidl_pairing_delegate,
- OnPairingRequest(_, fuchsia::bluetooth::control::PairingMethod::PASSKEY_ENTRY,
- fidl::StringPtr(nullptr), _))
- .WillOnce([id = peer->identifier()](FidlRemoteDevice device, Unused, Unused,
+ OnPairingRequest(_, fctrl::PairingMethod::PASSKEY_ENTRY, fidl::StringPtr(nullptr), _))
+ .WillOnce([id = peer->identifier()](fctrl::RemoteDevice device, Unused, Unused,
OnPairingRequestCallback callback) {
EXPECT_THAT(device.identifier, EndsWith(id.ToString()));
callback(/*accept=*/false, "012345");
})
- .WillOnce([id = peer->identifier()](FidlRemoteDevice device, Unused, Unused,
+ .WillOnce([id = peer->identifier()](fctrl::RemoteDevice device, Unused, Unused,
OnPairingRequestCallback callback) {
EXPECT_THAT(device.identifier, EndsWith(id.ToString()));
callback(/*accept=*/true, nullptr);
})
- .WillOnce([id = peer->identifier()](FidlRemoteDevice device, Unused, Unused,
+ .WillOnce([id = peer->identifier()](fctrl::RemoteDevice device, Unused, Unused,
OnPairingRequestCallback callback) {
EXPECT_THAT(device.identifier, EndsWith(id.ToString()));
callback(/*accept=*/true, u8"🍂");
})
- .WillOnce([id = peer->identifier()](FidlRemoteDevice device, Unused, Unused,
+ .WillOnce([id = peer->identifier()](fctrl::RemoteDevice device, Unused, Unused,
OnPairingRequestCallback callback) {
EXPECT_THAT(device.identifier, EndsWith(id.ToString()));
callback(/*accept=*/true, "012345");
@@ -387,7 +375,7 @@
info.reset();
host_server()->WatchState([&](auto value) { info = std::move(value); });
EXPECT_FALSE(info.has_value());
- host_server()->StopDiscovery([](auto) {});
+ host_server()->StopDiscovery();
RunLoopUntilIdle();
ASSERT_TRUE(info.has_value());
ASSERT_TRUE(info->has_discovering());
@@ -449,13 +437,17 @@
pairing_request_sent = true;
};
fake_chan->SetSendCallback(expect_default_bytebuffer, dispatcher());
- FidlStatus pair_status;
- PairingOptions opts;
- host_client()->Pair(fuchsia::bluetooth::PeerId{.value = peer->identifier().value()},
- std::move(opts),
- [&pair_status](FidlStatus status) { pair_status = std::move(status); });
+
+ std::optional<fit::result<void, fsys::Error>> pair_result;
+ fctrl::PairingOptions opts;
+ host_client()->Pair(fbt::PeerId{peer->identifier().value()}, std::move(opts),
+ [&](auto result) { pair_result = std::move(result); });
RunLoopUntilIdle();
- ASSERT_EQ(pair_status.error, nullptr);
+
+ // TODO(fxb/886): We don't have a good mechanism for driving pairing to completion without faking
+ // the entire SMP exchange. We should add SMP mocks that allows us to propagate a result up to the
+ // FIDL layer. For now we assert that pairing has started and remains pending.
+ ASSERT_FALSE(pair_result); // Pairing request is pending
ASSERT_TRUE(pairing_request_sent);
}
@@ -487,14 +479,17 @@
};
fake_chan->SetSendCallback(expect_default_bytebuffer, dispatcher());
- FidlStatus pair_status;
- PairingOptions opts;
- opts.set_le_security_level(PairingSecurityLevel::ENCRYPTED);
- host_client()->Pair(fuchsia::bluetooth::PeerId{.value = peer->identifier().value()},
- std::move(opts),
- [&pair_status](FidlStatus status) { pair_status = std::move(status); });
+ std::optional<fit::result<void, fsys::Error>> pair_result;
+ fctrl::PairingOptions opts;
+ opts.set_le_security_level(fctrl::PairingSecurityLevel::ENCRYPTED);
+ host_client()->Pair(fbt::PeerId{peer->identifier().value()}, std::move(opts),
+ [&](auto result) { pair_result = std::move(result); });
RunLoopUntilIdle();
- ASSERT_EQ(pair_status.error, nullptr);
+
+ // TODO(fxb/886): We don't have a good mechanism for driving pairing to completion without faking
+ // the entire SMP exchange. We should add SMP mocks that allows us to propagate a result up to the
+ // FIDL layer. For now we assert that pairing has started and remains pending.
+ ASSERT_FALSE(pair_result); // Pairing request is pending
ASSERT_TRUE(pairing_request_sent);
}
@@ -526,14 +521,17 @@
};
fake_chan->SetSendCallback(expect_default_bytebuffer, dispatcher());
- FidlStatus pair_status;
- PairingOptions opts;
+ std::optional<fit::result<void, fsys::Error>> pair_result;
+ fctrl::PairingOptions opts;
opts.set_non_bondable(true);
- host_client()->Pair(fuchsia::bluetooth::PeerId{.value = peer->identifier().value()},
- std::move(opts),
- [&pair_status](FidlStatus status) { pair_status = std::move(status); });
+ host_client()->Pair(fbt::PeerId{peer->identifier().value()}, std::move(opts),
+ [&](auto result) { pair_result = std::move(result); });
RunLoopUntilIdle();
- ASSERT_EQ(pair_status.error, nullptr);
+
+ // TODO(fxb/886): We don't have a good mechanism for driving pairing to completion without faking
+ // the entire SMP exchange. We should add SMP mocks that allows us to propagate a result up to the
+ // FIDL layer. For now we assert that pairing has started and remains pending.
+ ASSERT_FALSE(pair_result); // Pairing request is pending
ASSERT_TRUE(pairing_request_sent);
}
@@ -543,18 +541,18 @@
ASSERT_TRUE(fake_chan);
ASSERT_EQ(bt::gap::Peer::ConnectionState::kConnected, peer->le()->connection_state());
- FidlStatus pair_status;
- PairingOptions opts;
+ std::optional<fit::result<void, fsys::Error>> pair_result;
+ fctrl::PairingOptions opts;
// Set pairing option with classic
- opts.set_transport(fuchsia::bluetooth::control::TechnologyType::CLASSIC);
- auto pair_cb = [&pair_status](FidlStatus cb_status) {
- ASSERT_TRUE(cb_status.error);
- pair_status = std::move(cb_status);
+ opts.set_transport(fctrl::TechnologyType::CLASSIC);
+ auto pair_cb = [&](auto result) {
+ ASSERT_TRUE(result.is_err());
+ pair_result = std::move(result);
};
- host_client()->Pair(fuchsia::bluetooth::PeerId{.value = peer->identifier().value()},
- std::move(opts), pair_cb);
+ host_client()->Pair(fbt::PeerId{peer->identifier().value()}, std::move(opts), std::move(pair_cb));
RunLoopUntilIdle();
- ASSERT_EQ(pair_status.error->error_code, FidlErrorCode::NOT_FOUND);
+ ASSERT_TRUE(pair_result);
+ ASSERT_EQ(pair_result->error(), fsys::Error::PEER_NOT_FOUND);
}
TEST_F(FIDL_HostServerTest, WatchPeersHangsOnFirstCallWithNoExistingPeers) {
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/low_energy_central_server.cc b/src/connectivity/bluetooth/core/bt-host/fidl/low_energy_central_server.cc
index 83f69d8..ded63ba 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/low_energy_central_server.cc
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/low_energy_central_server.cc
@@ -167,7 +167,7 @@
if (!status) {
ZX_DEBUG_ASSERT(!conn_ref);
bt_log(TRACE, "bt-host", "failed to connect to connect to peer (id %s)", bt_str(peer_id));
- callback(fidl_helpers::StatusToFidl(status, "failed to connect"));
+ callback(fidl_helpers::StatusToFidlDeprecated(status, "failed to connect"));
return;
}
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/profile_server.cc b/src/connectivity/bluetooth/core/bt-host/fidl/profile_server.cc
index 7b82b81..04f2321 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/profile_server.cc
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/profile_server.cc
@@ -417,7 +417,7 @@
registered_.emplace(next, handle);
last_service_id_ = next;
- callback(fidl_helpers::StatusToFidl(bt::sdp::Status()), next);
+ callback(fidl_helpers::StatusToFidlDeprecated(bt::sdp::Status()), next);
}
void ProfileServer::RemoveService(uint64_t service_id) {
@@ -465,7 +465,7 @@
}
auto connected_cb = [cb = callback.share()](auto chan_sock) {
- cb(fidl_helpers::StatusToFidl(bt::sdp::Status()),
+ cb(fidl_helpers::StatusToFidlDeprecated(bt::sdp::Status()),
ChannelSocketToFidlChannel(std::move(chan_sock)));
};
ZX_DEBUG_ASSERT(adapter());
diff --git a/src/connectivity/bluetooth/fidl/host.fidl b/src/connectivity/bluetooth/fidl/host.fidl
index e462d17..3d8b121 100644
--- a/src/connectivity/bluetooth/fidl/host.fidl
+++ b/src/connectivity/bluetooth/fidl/host.fidl
@@ -65,10 +65,10 @@
WatchPeers() -> (vector<sys.Peer> updated, vector<bt.PeerId> removed);
/// Sets the local name for this host device.
- SetLocalName(string local_name) -> (fuchsia.bluetooth.Status status);
+ SetLocalName(string local_name) -> () error sys.Error;
/// Sets the device class for this host device.
- SetDeviceClass(bt.DeviceClass device_class) -> (fuchsia.bluetooth.Status status);
+ SetDeviceClass(bt.DeviceClass device_class) -> () error sys.Error;
/// Initiates a general discovery procedure for BR/EDR and LE devices. On success, discovered
/// peers can be monitored using the [`fuchsia.bluetooth.host/Host.WatchPeers`] method.
@@ -78,30 +78,30 @@
/// Discovery will continue until it is terminated via StopDiscovery() or if the Host protocol
/// channel gets closed. If the device does not support BR/EDR, only LE discovery will be
/// performed.
- StartDiscovery() -> (fuchsia.bluetooth.Status status);
+ StartDiscovery() -> () error sys.Error;
/// Terminates discovery if one was started via StartDiscovery().
///
/// NOTE: If another client is performing discovery (e.g. via its own le.Central interface handle),
/// then the system will continue performing device discovery even if this method results in
/// success.
- StopDiscovery() -> (fuchsia.bluetooth.Status status);
+ StopDiscovery();
/// Sets whether this host should be connectable.
- SetConnectable(bool enabled) -> (fuchsia.bluetooth.Status status);
+ SetConnectable(bool enabled) -> () error sys.Error;
/// Sets whether this host should be discoverable.
- SetDiscoverable(bool enabled) -> (fuchsia.bluetooth.Status status);
+ SetDiscoverable(bool enabled) -> () error sys.Error;
- /// Establish a BR/EDR and/or LE connection to the remote device with identifier `device_id`:
+ /// Establish a BR/EDR and/or LE connection to the peer with identifier `id`:
///
- /// - If the device is known to support the BR/EDR transport then a logical link over that
+ /// - If the peer is known to support the BR/EDR transport then a logical link over that
/// transport will be established to the device. If the connection attempt is successful,
/// local services registered using "RequestProfile()" will be available to the peer.
/// Traditional services discovered on the peer will be notified to local services
/// asynchronously.
///
- /// - If the device is known to support the LE transport then a logical link over that
+ /// - If the peer is known to support the LE transport then a logical link over that
/// transport will be established to the device. If the connection attempt is successful,
/// GATT services in the local database (populated via RequestGattServer()) will become
/// available to the peer. Similarly, remote GATT services that are discovered on the
@@ -111,15 +111,15 @@
/// The result of the procedure will be communicated via `status`. If the remote device
/// supports both BR/EDR and LE transports and a link cannot be established over both, then an
/// error Status will be returned and neither transport will be connected.
- Connect(string device_id) -> (fuchsia.bluetooth.Status status);
+ Connect(bt.PeerId id) -> () error sys.Error;
- /// Terminate all connections (BR/EDR or LE) to the remote peer with identifier `peer_id`.
+ /// Terminate all connections (BR/EDR or LE) to the remote peer with identifier `id`.
///
- /// + request `peer_id` The identifier of the peer to disconnect.
+ /// + request `id` The identifier of the peer to disconnect.
/// - response `status` Contains an error if either LE or BR/EDR transport fails to disconnect. Contains
/// success when both transports are successfully disconnected or if the peer is already
/// disconnected.
- Disconnect(string peer_id) -> (fuchsia.bluetooth.Status status);
+ Disconnect(bt.PeerId id) -> () error sys.Error;
/// Initiates pairing to the peer with the supplied `id` and `options`. Returns an error
/// variant of fuchsia.bluetooth.Status if no connected peer with `id` is found or the pairing
@@ -129,7 +129,7 @@
/// NOTE: This is intended to satisfy test scenarios that require pairing procedures to be
/// initiated without relying on service access. In normal operation, Bluetooth security is
/// enforced during service access.
- Pair(fuchsia.bluetooth.PeerId id, fuchsia.bluetooth.control.PairingOptions options) -> (fuchsia.bluetooth.Status status);
+ Pair(fuchsia.bluetooth.PeerId id, fuchsia.bluetooth.control.PairingOptions options) -> () error sys.Error;
/// Deletes a peer from the Bluetooth host. If the peer is connected, it will be disconnected.
/// `device_id` will no longer refer to any peer, even if a device with the same address is
@@ -138,7 +138,7 @@
/// Returns success after no peer exists that's identified by `device_id` (even if it didn't
/// exist before Forget), failure if the peer specified by `device_id` could not be
/// disconnected or deleted and still exists.
- Forget(string device_id) -> (fuchsia.bluetooth.Status status);
+ Forget(bt.PeerId id) -> () error sys.Error;
/// Enable or disable a passive LE background scan. When enabled, the bt-host
/// device will continuously perform a passive LE scan in the background when
diff --git a/src/connectivity/bluetooth/tests/integration/src/tests/host_driver.rs b/src/connectivity/bluetooth/tests/integration/src/tests/host_driver.rs
index 78798d6..dc3cfe8 100644
--- a/src/connectivity/bluetooth/tests/integration/src/tests/host_driver.rs
+++ b/src/connectivity/bluetooth/tests/integration/src/tests/host_driver.rs
@@ -4,9 +4,9 @@
use {
anyhow::{format_err, Context as _, Error},
- fidl_fuchsia_bluetooth::{DeviceClass, MAJOR_DEVICE_CLASS_TOY},
+ fidl_fuchsia_bluetooth::{self as fbt, DeviceClass, MAJOR_DEVICE_CLASS_TOY},
fidl_fuchsia_bluetooth_host::HostProxy,
- fidl_fuchsia_bluetooth_sys::TechnologyType,
+ fidl_fuchsia_bluetooth_sys::{self as fsys, TechnologyType},
fidl_fuchsia_bluetooth_test::{EmulatorSettings, HciError, PeerProxy},
fuchsia_async as fasync,
fuchsia_bluetooth::{
@@ -74,8 +74,7 @@
let _ = harness
.when_satisfied(emulator::expectation::local_name_is(NAME), timeout_duration())
.await?;
- let fut = expect_host_state(&harness, expectation::host_driver::name(NAME));
- fut.await?;
+ expect_host_state(&harness, expectation::host_driver::name(NAME)).await?;
Ok(())
}
@@ -83,13 +82,14 @@
// down to the controller.
async fn test_set_local_name(harness: HostDriverHarness) -> Result<(), Error> {
const NAME: &str = "test1234";
- let fut = harness.aux().proxy().set_local_name(NAME);
- fut.await?;
+ let proxy = harness.aux().proxy().clone();
+ let result = proxy.set_local_name(NAME).await?;
+ expect_eq!(Ok(()), result)?;
+
let _ = harness
.when_satisfied(emulator::expectation::local_name_is(NAME), timeout_duration())
.await?;
- let fut = expect_host_state(&harness, expectation::host_driver::name(NAME));
- fut.await?;
+ expect_host_state(&harness, expectation::host_driver::name(NAME)).await?;
Ok(())
}
@@ -97,8 +97,10 @@
// Tests that the device class assigned to a bt-host gets propagated down to the controller.
async fn test_set_device_class(harness: HostDriverHarness) -> Result<(), Error> {
let mut device_class = DeviceClass { value: MAJOR_DEVICE_CLASS_TOY + 4 };
- let fut = harness.aux().proxy().set_device_class(&mut device_class);
- fut.await?;
+ let proxy = harness.aux().proxy().clone();
+ let result = proxy.set_device_class(&mut device_class).await?;
+ expect_eq!(Ok(()), result)?;
+
let _ = harness
.when_satisfied(emulator::expectation::device_class_is(device_class), timeout_duration())
.await?;
@@ -108,25 +110,37 @@
// Tests that host state updates when discoverable mode is turned on.
// TODO(armansito): Test for FakeHciDevice state changes.
async fn test_discoverable(harness: HostDriverHarness) -> Result<(), Error> {
+ let proxy = harness.aux().proxy().clone();
+
+ // Disabling discoverable mode when not discoverable should succeed.
+ let result = proxy.set_discoverable(false).await?;
+ expect_eq!(Ok(()), result)?;
+
// Enable discoverable mode.
- let fut = harness.aux().proxy().set_discoverable(true);
- fut.await?;
+ let result = proxy.set_discoverable(true).await?;
+ expect_eq!(Ok(()), result)?;
expect_host_state(&harness, expectation::host_driver::discoverable(true)).await?;
// Disable discoverable mode
- let fut = harness.aux().proxy().set_discoverable(false);
- fut.await?;
+ let result = proxy.set_discoverable(false).await?;
+ expect_eq!(Ok(()), result)?;
expect_host_state(&harness, expectation::host_driver::discoverable(false)).await?;
+ // Disabling discoverable mode when not discoverable should succeed.
+ let result = proxy.set_discoverable(false).await?;
+ expect_eq!(Ok(()), result)?;
+
Ok(())
}
// Tests that host state updates when discovery is started and stopped.
// TODO(armansito): Test for FakeHciDevice state changes.
async fn test_discovery(harness: HostDriverHarness) -> Result<(), Error> {
+ let proxy = harness.aux().proxy().clone();
+
// Start discovery. "discovering" should get set to true.
- let fut = harness.aux().proxy().start_discovery();
- fut.await?;
+ let result = proxy.start_discovery().await?;
+ expect_eq!(Ok(()), result)?;
expect_host_state(&harness, expectation::host_driver::discovering(true)).await?;
let address = Address::Random([1, 0, 0, 0, 0, 0]);
@@ -137,8 +151,7 @@
expect_peer(&harness, peer::name("Fake").and(peer::address(address))).await?;
// Stop discovery. "discovering" should get set to false.
- let fut = harness.aux().proxy().stop_discovery();
- fut.await?;
+ let _ = proxy.stop_discovery()?;
expect_host_state(&harness, expectation::host_driver::discovering(false)).await?;
Ok(())
@@ -148,16 +161,18 @@
// TODO(armansito): Test for FakeHciDevice state changes.
async fn test_close(harness: HostDriverHarness) -> Result<(), Error> {
// Enable all procedures.
- let fut = harness.aux().proxy().start_discovery();
- fut.await?;
- let fut = harness.aux().proxy().set_discoverable(true);
- fut.await?;
+ let proxy = harness.aux().proxy().clone();
+ let result = proxy.start_discovery().await?;
+ expect_eq!(Ok(()), result)?;
+ let result = proxy.set_discoverable(true).await?;
+ expect_eq!(Ok(()), result)?;
+
let active_state = expectation::host_driver::discoverable(true)
.and(expectation::host_driver::discovering(true));
expect_host_state(&harness, active_state).await?;
// Close should cancel these procedures.
- harness.aux().proxy().close()?;
+ proxy.close()?;
let closed_state_update = expectation::host_driver::discoverable(false)
.and(expectation::host_driver::discovering(false));
@@ -191,7 +206,8 @@
// Wait for all fake devices to be discovered.
let proxy = harness.aux().proxy().clone();
- let _ = proxy.start_discovery().await?;
+ let result = proxy.start_discovery().await?;
+ expect_eq!(Ok(()), result)?;
let expected_le =
peer::address(le_peer_address).and(peer::technology(TechnologyType::LowEnergy));
let expected_bredr =
@@ -215,9 +231,11 @@
// Configure `peer2` to return an error for the connection attempt.
let _ = peer2.assign_connection_status(HciError::ConnectionTimeout).await?;
+ let proxy = harness.aux().proxy().clone();
+
// Start discovery and let bt-host process the fake devices.
- let fut = harness.aux().proxy().start_discovery();
- fut.await?;
+ let result = proxy.start_discovery().await?;
+ expect_eq!(Ok(()), result)?;
expect_peer(&harness, peer::address(address1)).await?;
expect_peer(&harness, peer::address(address2)).await?;
@@ -230,24 +248,26 @@
.iter()
.find(|x| x.1.address == address1)
.ok_or(format_err!("success peer not found"))?
- .0;
+ .0
+ .clone();
let failure_id = peers
.iter()
.find(|x| x.1.address == address2)
.ok_or(format_err!("error peer not found"))?
- .0;
+ .0
+ .clone();
+ let mut success_id: fbt::PeerId = success_id.into();
+ let mut failure_id: fbt::PeerId = failure_id.into();
// Connecting to the failure peer should result in an error.
- let fut = harness.aux().proxy().connect(&failure_id.to_string());
- let status = fut.await?;
- expect_true!(status.error.is_some())?;
+ let status = proxy.connect(&mut failure_id).await?;
+ expect_eq!(Err(fsys::Error::Failed), status)?;
// Connecting to the success peer should return success and the peer should become connected.
- let fut = harness.aux().proxy().connect(&success_id.to_string());
- let status = fut.await?;
- expect_true!(status.error.is_none())?;
+ let status = proxy.connect(&mut success_id).await?;
+ expect_eq!(Ok(()), status)?;
- let connected = peer::identifier(*success_id).and(peer::connected(true));
+ let connected = peer::identifier(success_id.into()).and(peer::connected(true));
expect_peer(&harness, connected).await?;
Ok(())
}
@@ -260,8 +280,10 @@
let proxy = fut.await?;
// Start discovery and let bt-host process the fake LE peer.
- let fut = harness.aux().proxy().start_discovery();
- fut.await?;
+ let host = harness.aux().proxy().clone();
+ let result = host.start_discovery().await?;
+ expect_eq!(Ok(()), result)?;
+
let le_dev = expectation::peer::address(address.clone());
expect_peer(&harness, le_dev).await?;
@@ -281,66 +303,62 @@
/// Disconnecting from an unknown device should succeed
async fn test_disconnect_unknown_device(harness: HostDriverHarness) -> Result<(), Error> {
- let unknown_id = "0123401234";
- let fut = harness.aux().proxy().disconnect(unknown_id);
+ let mut unknown_id = PeerId(0).into();
+ let fut = harness.aux().proxy().disconnect(&mut unknown_id);
let status = fut.await?;
- expect_eq!(status.error, None)
+ expect_eq!(Ok(()), status)
}
/// Disconnecting from a known, unconnected device should succeed
async fn test_disconnect_unconnected_device(harness: HostDriverHarness) -> Result<(), Error> {
let address = Address::Random([1, 0, 0, 0, 0, 0]);
- let (success_dev, _proxy) = wait_for_test_peer(harness.clone(), &address).await?;
- let fut = harness.aux().proxy().disconnect(&success_dev.to_string());
+ let (id, _proxy) = wait_for_test_peer(harness.clone(), &address).await?;
+ let mut id = id.into();
+ let fut = harness.aux().proxy().disconnect(&mut id);
let status = fut.await?;
- expect_eq!(status.error, None)
+ expect_eq!(Ok(()), status)
}
/// Disconnecting from a connected device should succeed and result in the device being disconnected
async fn test_disconnect_connected_device(harness: HostDriverHarness) -> Result<(), Error> {
let address = Address::Random([1, 0, 0, 0, 0, 0]);
- let (success_dev, _proxy) = wait_for_test_peer(harness.clone(), &address).await?;
- let success_dev = success_dev.to_string();
+ let (id, _proxy) = wait_for_test_peer(harness.clone(), &address).await?;
+ let mut id = id.into();
+ let proxy = harness.aux().proxy().clone();
- let fut = harness.aux().proxy().connect(&success_dev);
- let status = fut.await?;
- expect_eq!(status.error, None)?;
+ let status = proxy.connect(&mut id).await?;
+ expect_eq!(Ok(()), status)?;
let connected = peer::address(address).and(peer::connected(true));
let disconnected = peer::address(address).and(peer::connected(false));
let _ = expect_peer(&harness, connected).await?;
- let fut = harness.aux().proxy().disconnect(&success_dev);
- let status = fut.await?;
- expect_eq!(status.error, None)?;
+ let status = proxy.disconnect(&mut id).await?;
+ expect_eq!(Ok(()), status)?;
+
let _ = expect_peer(&harness, disconnected).await?;
Ok(())
}
async fn test_forget(harness: HostDriverHarness) -> Result<(), Error> {
let address = Address::Random([1, 0, 0, 0, 0, 0]);
- let (le_peer, _proxy) = wait_for_test_peer(harness.clone(), &address).await?;
+ let (id, _proxy) = wait_for_test_peer(harness.clone(), &address).await?;
+ let mut id = id.into();
+ let proxy = harness.aux().proxy().clone();
- // Start discovery and let bt-host process the fake peers.
- let fut = harness.aux().proxy().start_discovery();
- fut.await?;
-
- // Wait for fake peer to be discovered.
+ // Wait for fake peer to be discovered (`wait_for_test_peer` starts discovery).
let expected_peer = expectation::peer::address(address);
expect_peer(&harness, expected_peer.clone()).await?;
// Connecting to the peer should return success and the peer should become connected.
- let fut = harness.aux().proxy().connect(&le_peer.to_string());
- let mut status = fut.await?;
- expect_true!(status.error.is_none())?;
-
+ let status = proxy.connect(&mut id).await?;
+ expect_eq!(Ok(()), status)?;
expect_peer(&harness, expected_peer.and(expectation::peer::connected(true))).await?;
// Forgetting the peer should result in its removal.
- let fut = harness.aux().proxy().forget(&le_peer.to_string());
- status = fut.await?;
- expect_true!(status.error.is_none())?;
- expect_no_peer(&harness, le_peer).await?;
+ let status = proxy.forget(&mut id).await?;
+ expect_eq!(Ok(()), status)?;
+ expect_no_peer(&harness, id.into()).await?;
// TODO(BT-879): Test that the link closes by querying fake HCI.