bt_hfp/
sco.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use fidl::endpoints::Proxy;
6use fidl_fuchsia_bluetooth_bredr as bredr;
7use fuchsia_bluetooth::profile::ValidScoConnectionParameters;
8use fuchsia_bluetooth::types::PeerId;
9use fuchsia_inspect_derive::Unit;
10use futures::{Future, FutureExt};
11use profile_client::Error as ProfileError;
12use thiserror::Error;
13
14pub mod connector;
15pub mod state;
16pub mod test_utils;
17
18pub use connector::Connector;
19pub use state::{Active, InspectableState, State};
20
21/// A failure occurred connecting SCO to a peer.
22#[derive(Debug, Error)]
23pub enum ConnectError {
24    #[error("SCO connection failed")]
25    Failed,
26    #[error("SCO connection canceled by new connection request or server")]
27    Canceled,
28    #[error("SCO connection provided invalid arguments")]
29    InvalidArguments,
30    #[error("Profile client error: {:?}", source)]
31    ProfileClient {
32        #[from]
33        source: ProfileError,
34    },
35    #[error("FIDL error: {:?}", source)]
36    Fidl {
37        #[from]
38        source: fidl::Error,
39    },
40}
41
42impl From<bredr::ScoErrorCode> for ConnectError {
43    fn from(err: bredr::ScoErrorCode) -> Self {
44        match err {
45            bredr::ScoErrorCode::Cancelled => Self::Canceled,
46            bredr::ScoErrorCode::Failure => Self::Failed,
47            bredr::ScoErrorCode::InvalidArguments => Self::InvalidArguments,
48            bredr::ScoErrorCode::ParametersRejected => Self::Failed,
49            _ => Self::Failed, // Flexible enum future proofing.
50        }
51    }
52}
53
54/// The components of an active SCO connection.
55/// Dropping this struct will close the SCO connection.
56#[derive(Debug)]
57pub struct Connection {
58    /// The peer this is connected to.
59    pub peer_id: PeerId,
60    /// The parameters that this connection was set up with.
61    pub params: ValidScoConnectionParameters,
62    /// Proxy for this connection.  Used to read/write to the connection.
63    pub proxy: bredr::ScoConnectionProxy,
64}
65
66impl Unit for Connection {
67    type Data = <ValidScoConnectionParameters as Unit>::Data;
68    fn inspect_create(&self, parent: &fuchsia_inspect::Node, name: impl AsRef<str>) -> Self::Data {
69        self.params.inspect_create(parent, name)
70    }
71
72    fn inspect_update(&self, data: &mut Self::Data) {
73        self.params.inspect_update(data)
74    }
75}
76
77impl Connection {
78    pub fn on_closed(&self) -> impl Future<Output = ()> + 'static {
79        self.proxy.on_closed().extend_lifetime().map(|_| ())
80    }
81
82    pub fn is_closed(&self) -> bool {
83        self.proxy.is_closed()
84    }
85
86    // This function is intendred to be used in test code. Since it's used outside of this crate, it
87    // can't be marked as #[cfg(test)].
88    // The proxy should have been built using the params specified.
89    pub fn build(
90        peer_id: PeerId,
91        params: bredr::ScoConnectionParameters,
92        proxy: bredr::ScoConnectionProxy,
93    ) -> Self {
94        Connection { peer_id, params: params.try_into().unwrap(), proxy }
95    }
96}